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