Fwd: STM32F103 UART DMA

Jaroslav Buchta jaroslav.buchta na hascomp.cz
Středa Prosinec 27 18:58:25 CET 2023


Mam spravny pocit, ze dokonceni vsech zapisu by mela zajistit instrukce 
DSB? Nebo nejaka podobna z tech cca 3, se mi furt pletou.
Ale asi az u novejsich.
Mam ale vyzkouseno, ze kdyz to melo byt rychle (simulace SPI kdyz se 
netrefily piny...), nasazel jsem za sebe instrukce zapisu do 32b 
registru S/R, kazda menila hodiny , kazda druha data a chodilo to jak 
vino maximalni rychlosti, kdyz jsem vyhazel DSB, tak rychleji  ale stale 
dobre. Sbernice mely stejnou frekvenci a byl to tusim M4.
Tak se toho asi netreba uplne bat a cekam, ze to je nejak interne poresene.

Dne 27.12.2023 v 18:06 dresler napsal(a):
> Bavíme-li se klasických STM32, zápisy se neztrácejí. Podle typu 
> architektury je tam 0-1 write buffer mezi jádrem a hlavní sběrnicí, 
> pak (AXI-)AHB-APB bridge. Zde je zpoždění dané tím, že se data 
> resynchronizují mezi různými hodinami, kde platí nejdelší zpoždění 
> (1+ratio) a zpoždění vnější periferie. Není tedy potřeba psát opakovaně.
>
> Aby se zajistilo, že program pokračuje po dokončení zápisu do 
> registru, prostě ten registr přečtěte zpět.
>
> Tomáš
>
>
>
> Odesláno z mého zařízení Galaxy
>
>
> -------- Původní zpráva --------
> Od: Petr Labaj <labaj na volny.cz>
> Datum: 26.12.23 22:27 (GMT+01:00)
> Komu: hw-list na list.hw.cz
> Předmět: Re: Fwd: STM32F103 UART DMA
>
> Tak v tom případě i já pošlu odpověď, kterou jsem Vám posílal soukromě,
> do konference:
>
> Hmmm.
> A díval jste se prosím na to, čeho se Vámi vysmívaná "rada nad zlato"
> vlastně týkala?
> Psal jsem o prvním zápisu do nějakého registru, kdy obecně nemusím
> vědět, jaký je předchozí stav daného registru.
> Takže pokud tam zapíšu ORem, tak tam můžou zůstat nahozené nějaké bity,
> které nechci, ale byly tam v jedničce už dřív.
>
> V tomto případě přece naplatí, že by se mohl ztratit nějaký zápis kvůli
> asynchronnosti přístupu na danou periferii.
> Jedná se o _první_ zápis na tuto periferii.
> Všechny případné další zápisy už samozřejmě musí být ORem, protože jinak
> by zmizela předchozí konfigurace.
>
> PL
>
> *****************
>
> Dne 26.12.2023 v 22:06 František Burian napsal(a):
> > Omlouvám se, asi jsem to neposlal do konference ale p. Labajovi, ale
> > mířilo to do konference.
> >
> >
> >
> >
> > Zdravíčko,
> >
> >   Obvykle nepřispívám ale tady musím, protože zde je nastíněna "rada
> > nad zlato", která tomu, kdo se jí bude řídit způsobí mnoho bezesných
> > nocí.
> >
> >   Nezapomínejte, že ARM je architektura mnoha sběrnic, různých keší a
> > to, co napíšete do programu nikdy není to, co se provede. Zkuste si
> > udělat
> > rychlý program, který bude pouze zapisovat do GPIO portu a nahazovat
> > všechny bity na 1 a shazovat všechny bity do 0, připojte osciloskop k
> > pinu
> > a pozorujte, co uvidíte.
> >
> > Operace = je převedena do instrukce STRB která nezapisuje na paměťové
> > místo, ale do cache, která to posílá na pomalejší sběrnici. A pokud se
> > sejdou dva STRB do stejné paměťové pozice, je předchozí zápis ztracen
> > a na pomalejší sběrnici se populuje později zapsaná hodnota. GPIO 
> jsou na
> > STMku za dvěma takovými cachemi, AHB, APB a dokážete si představit
> > jakýpak krásný náhodný děj se na GPIO povede vyrobit.
> >
> > Aby byly zápisy jednoznačně orderované, musí mezi nimi být LDRB který
> > počká na úplnou invalidaci všech keší po cestě před další instrukcí.
> > Když tedy
> > převedete původní sekvenci (pseudokód)
> >
> > while (1) { PORTB = 0; PORTB=255;  }
> >
> > na
> >
> > while (1) { PORTB &=0; PORTB|=255; }
> >
> > dosáhnete výrazně pomalejšího programu, ale krásného obdélníku ikdyž z
> > logiky věci by ty programy měly dělat totéž. Ještě krásnější je, že
> > druhý příklad se může přeložit na první kvůli optimalizacím překladače
> > když někdo při definici PORTB zapoměl na volatile u každého prvku.
> >
> > Toto samosemou platí pro každý přístup na jakoukoliv paměť která má po
> > cestě nějakou cache (tedy je na pomalejší sběrnici). Proto musí být
> > všechny přístupy k řídícím registrům které musí být vždy sekvenční
> > (nejprv nastav tento bit, pak tento bit) buďto provedeny pomocí 
> operátorů
> > |= nebo &= nebo použít instrukci dmb, která ale čeká na všechny cache,
> > ne jen na tu, kterou chcete zapsat, takže ještě víc zpomalí.
> >
> > Registry konfigurace periferií jsou přesně ty, které mají v podmínkách
> > nejprv toto pak toto a když na tento postup nemyslíte, "ono to nějak
> > funguje"
> > ale jednou za čas to selže a daná periferie se jeví jako zmrzlá
> > protože jste nastavili bity ve stejný okamžik, ne jeden po druhém.
> >
> > Cache mezi sběrnicemi má omeznou velokost, takže pokud za sebou
> > zapíšete dostatečný počet zápisů do stejné sběrnice, tak můžete zase ten
> > první, protože se čeká na ostatní zápisy. Jak je cache dlouhá je
> > nedokumentovaná funkce a mění se to mezi výrobními dávkami
> > (odpozorováno 2-8
> > zápisů u stejného čipu jen z jiných dávek, dokonce jsem nabyl dojmu že
> > se hloubka mění podle poměru frekvencí ale tam nemám ověřeno) takže
> > nelze spoléhat na konkrétní velikost cache.
> >
> > Stejný problém je když takto přistoupíte na dvě po sobě jdoucí
> > paměťové místa, tak ty čipy s delší cachí zápis uvnitř keše převedou
> > na jeden přístup
> > do paměti s delším slovem a na některých architekturách hard fault
> > jako vyšitý, když ale použijete RMW, hardfault zmizí. (Nevím jestli to
> > je aktuální,
> > takto se chovaly staré čipy)
> >
> > Pokud se podíváte do implementace CMSIS, je tam vždy RMW operace s
> > registry, nikdy to není čistý zápis právě kvůli tomuto fenoménu.
> >
> > S tímto jsem si při psaní vlastních rychlých knihoven užil více než
> > dost. Probíralo se to i v intelektuálním klubu v Patronce, je dobré
> > číst backlogy
> > nebo se účastnit :-)
> >
> > S pozdravem a přáním pěkných svátků
> >
> >   František Burian
> >
> >
> > Dne 26. 12. 23 v 17:14 Petr Labaj napsal(a):
> >> Můžu drobnou poznámku, která je ale obecnější a s daným problémem
> >> nesouvisí?
> >>
> >> Vy všude používáte "orování" parametrů, které zadáváte do řídících
> >> registrů.
> >> Např.:
> >> USART2->CR1 |= USART_CR1_TE | USART_CR1_RE;
> >> nebo
> >> DMA1_Channel6->CCR |= DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_TCIE;
> >>
> >> Ale používáte to i při prvním zápisu do daného registru.
> >> Tedy jinými slovy spoléháte na to, že předtím tam byly samé nuly.
> >> Což může být velice zrádné, když tu konstrukci použijete třeba i
> >> někdy později, kdy už v těch registrech něco je.
> >>
> >> Takže by podle mě měl první zápis vypadat takhle:
> >> USART2->CR1 = USART_CR1_TE | USART_CR1_RE;
> >> nebo
> >> DMA1_Channel6->CCR = DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_TCIE;
> >>
> >> A orování použít až když tam už dodatečně něco přidáváte.
> >>
> >> PL
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
>
> _______________________________________________
> HW-list mailing list  -  sponsored bywww.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list

------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20231227/dc4ab3df/attachment-0001.htm>


Další informace o konferenci Hw-list