Atomos hozzáférés a változókhoz, avr, programozás

A beágyazott alkalmazások hibakeresése során nehezebb olyan hibákat felvenni, amelyek nem mindig állandóak, hanem csak időről időre. Az ilyen hibák egyik oka: olyan változók, amelyek aszinkron módon érkeznek. Az ilyen változókat megfelelően meg kell határozni, és megfelelő védelmet kell biztosítani.

A meghatározásnak tartalmaznia kell a kulcsszó változékony. Értesíti a fordítót, hogy egy változó nem csak a jelenlegi végrehajtható kódról, hanem más helyről is módosítható. Ezután a fordító elkerüli a változók bizonyos optimalizálását.

Egy közös változó védelme érdekében minden egyes hozzáférési műveletnek atomnak kell lennie. Vagyis nem szabad félbeszakítani a végéig. Például egy 32 bites vagy 16 bites változó elérése egy 8 bites architektúrán nem atomikus, mivel az olvasási vagy írási műveletekhez több utasítás szükséges.

Tekintsünk egy tipikus példát egy nyilvános változóra - egy programidőzítőre. A megszakításkezelőben az értéke megváltozik, és a fő kódban olvasható. Ha más megszakítások le vannak tiltva a kezelőben, például akkor, ha az AVR mikrokontrollerekben az alapértelmezett beállítás történik, akkor a változó változtatásának működése atomos, és nem lép fel.

Másrészt a fő hurokban a megszakítási programok leggyakrabban megoldódnak, és a nem biztonságos kód változata így néz ki:

Ez a kód nem biztonságos, mert a változó rendszer_timer olvasásának működése nem atomi. A változó rendszer_timer egyik byte-jának olvasása közben megszakadhat TIMER0_COMP, és a kezelő megváltoztatja az értékét. Ezután a fő programra való visszatérés után a változó többi részét már az új értékről olvassuk le. Bizonyos esetekben a régi és az új értékek keveréke nem okoz hibákat, de másokban nagymértékben befolyásolja a program viselkedését. Nos, például, ha a system_timer régi értéke 0x00ffffff, az új pedig 0x01000000.

A változó rendszer_timerhez való hozzáférés védelme érdekében használhatja a monitorfunkciót, ehhez a _monitor kulcsszó meg van adva a függvény neve előtt.

A monitor funkció egy olyan funkció, amely a bemeneten tárolja a SREG regisztert, letiltja a megszakításokat a végrehajtás időtartamára, és visszaállítja a SREG tartalmát a kimenet előtt.

Ha azt szeretné, hogy a megszakítások letilthatók legyenek a kód egy adott területén, akkor belső funkciókat használhat.

A C ++ eszközök segítségével integrálhatja ezt a logikát az osztályba.

Az m objektum létrehozásakor a konstruktor tárolja a SREG regisztert, és letiltja a megszakításokat. A blokk végén a megsemmisítő visszaállítja a SREG tartalmát. Gyönyörű, mi?

Általánosságban elmondható, hogy az atomi műveletekkel való kód írása mindenütt létezik, és számos végrehajtási lehetőség létezik. Például egy változó elérésekor nem tilthat meg minden megszakítást, csak azok, akik ezt a változót használják.

A probléma egy 8 bites változóval lehetséges. Egy olyan műveletet, mint a system_timer - = 100 összeállítódik több szerelői utasításba, és a fő kód is megszakítható a rendszer_timer olvasása és az eredmény írása között. Van egy másik mód a multibyte aszinkron számlálók olvasására (a megszakítások megszakítása nélkül) - kétszer meg kell számolni a változót, és összehasonlítani kell a bájtokat, kivéve a fiatalokat. Ha a példányok bájtja egyenlő - adja meg az utolsó olvasott értéket, ha nem egyenlő -, amíg a bájtok utolsó két olvasási értéke egyenlő. A számlálók alacsony bájtja megváltozhat az átvitel nélkül, ezért nem vesz részt az ellenőrzésben.

Amint a példákból látható, a kód az IAR fordítóhoz tartozik. A WinAVR-ben egy hasonló probléma megoldható az atomic.h fájl beillesztésével, amelyben makrók vannak definiálva az atomi hozzáférés megvalósításához. Például:

1. Atomikus hozzáférés a változók oldalához: chipenable.ru - az eredeti cikk.

Kapcsolódó cikkek