arm cm3 dsb instrukce

Jiří Nesvacil nesvacil na posys.eu
Úterý Červen 16 08:27:02 CEST 2020


Zdravim,

ldrex/strex ma M3 implementovan jako jeden priznak pres cely CPU tj. 
jakmile dva z jakekoliv adresy ctou pres ldrex nebo pri preruseni, tak 
se shodi a musi jit znovu.

Pokud mate jedno vlakno/ci hlavni smycku na nastaveni priznaku a v 
preruseni priznak shazujete, jen jako 1/0, tak s volatile vystacite.

Atomicky zapis je doopravdy v mistech, kdy chteji oba delat nejakou akci.

Priklad: v preruseni prirpravuji data, kdyz jsou pripravena reknu vem si 
je priznakem. V hlavni smycce/threadu si prevezmy data a shodim priznak, 
tak to je ok. Nesmeji byt dve vlakna, ktere by prebiraly data zaroven, 
pokud to bude jedno vlakno/hlavni smycka, tak to bude vzdy ok a v tom je 
zakopany pes.

Jirka


Dne 15.06.2020 v 18:28 Miroslav Mraz napsal(a):
> Tak mě tahle diskuze vyprovokovala to celé otestovat. Největší problém 
> není ani s tím, že by std::atomic nefungovalo, ale přesvědčit se, že 
> pouhá volatilní proměnná fungovat nemůže, pokud do ní zapisuji ze dvou 
> různých konců.
> To by jeden ani nevěřil, co to dá práce najít způsob jak se s 
> přerušením trefit do těch dvou kritických instrukcí, kde se proměnná 
> modifikuje a ukázat, že je to špatně. Zdálo by se, že když udělám 
> hlavní smyčku dostatečně krátkou a budu přerušovat hodně svižně, musí 
> to zhavarovat dost často. Není tomu tak. Obvyklé použití je asi takovéto:
> static volatile int lock;
> static const int step = 4;
> //...
> int main () {
>   for (;;) {
>     if (lock >= step) {
>       lock -= step; // kritická operace
>     }
>   }
> }
> a přitom lock v přerušení inkrementuji o 1. A právě ten test na 
> velikost lock ve většině případů kritickou operaci úplně vyhodí, takže 
> chyba se projeví tak zhruba v jednom případě přerušení z několika 
> milionů. O to je to záludnější.
>
> Ale proč jsem si s tím vlastně hrál. To primitivum std::atomic 
> normálně používám, trochu tuším, že na Cortex-M3,4 používá dvojici 
> LDREX/STREX, nikdy mě však nenapadlo se v tom nějak víc šťourat. Proto 
> mě dost překvapilo, že v přerušení (a podobně v main) se používá asi 
> takováto sekvence
> 200001aa:    f3bf 8f5f     dmb    sy
> 200001ae:    e851 0f00     ldrex    r0, [r1]
> 200001b2:    3001          adds    r0, #1    @ v main bude naopak subs
> 200001b4:    e841 0e00     strex    lr, r0, [r1]
> 200001b8:    f1be 0f00     cmp.w    lr, #0
> 200001bc:    d1f7          bne.n    200001ae
> 200001be:    f3bf 8f5f     dmb    sy
> Jenže když mám proměnnou v main uzamčenu, takhle na první pohled by to 
> mělo skončit v nekonečné smyčce. Není tomu tak - je to docela chytře 
> vymyšleno, výjimka exkluzivitu zruší, takže zápis v přerušení je vždy 
> úspěšný. V main se samozřejmě zjistí exkluzivní zápis a proměnná se 
> znovu načte. Takže to funguje v pohodě a bez velkého přemýšlení i v 
> bare-metal programování.
> Metoda se zákazem a opětovným povolením přerušení v kritické sekci 
> funguje ovšem také i když malinko a nepodstatně odlišně (při změně v 
> main se do přerušení prostě nedostanete), u Cortex-M0 a jiných 
> procesorů stejně nic jiného většinou nezbývá.
>
> Mrazík
>
>
> Dne 05. 06. 20 v 10:20 Jan Waclawek napsal(a):
>>> Jinak øeèeno - pokud máte napøíklad globální
>>> promìnnou, kterou sdílíte mezi smyèkou hlavního programu a pøerušením,
>>> nestaèí jí deklarovat jako volatile, musíte použít nìco jako
>>> std::atomic<type>.
>>
>> U Cortex-M3/M4 toto nie je potrebne riesit (s vynimkou LDM/STM, ktore 
>> su z
>> principu problematicke operacie, hojne sa vyskytujuce aj v ARM 
>> erratach, a
>> pochybujem, ze by ich nejaky prekladac generoval pre volatile premenne),
>> vid napr. Cortex-M4 TRM, 3.5 Write buffer:
>>
>> If an interrupt
>> comes in while  DMB or  DSB is waiting for the write buffer to drain, 
>> the
>> processor returns to the
>> instruction following the  DMB or  DSB after the interrupt completes. 
>> This
>> is because interrupt
>> processing acts as a memory barrier operation.
>>
>> wek
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list


Další informace o konferenci Hw-list