Illékony változók használata si
Értékelés: 5/5
Megfigyelted a kódot a C vagy C ++ kóddal végzett munka során az alábbi helyzetekben?
- kód, ami jól működik, amíg engedélyezi az optimalizálást
- kód, amely a megszakítások letiltásáig jól működik
- Az RTOS-feladatok kiválóan működnek elszigetelten, amíg egy másik feladat létre nem jön
Ha válaszol "igen" az egyik ilyen állításra, akkor valószínűleg nem használja az illékony kulcsszót. Nem vagy egyedül. Ennek a minősítésnek a használatát sok programozó kevéssé ismeri, mivel a C programozás legtöbb könyve nem foglalkozik ezzel a témával.
Az illékony kulcsszó a deklarált változó adattípusát megelőzően vagy után íródik.
illékony intfoo;
int volatilefoo;
Az illékony változókra mutató mutatókat a következőképpen deklaráljuk.
illékony int * pReg;
int volatile * pReg;
Az illékony mutatók a nem illékony változók számára rendkívül ritkák (azt hiszem, csak egyszer használtam őket), de csak abban az esetben, ha én adtam nekik a szintaxist:
int * illékony p;
És a teljesség kedvéért, ha illékony mutatóra van szükség egy változó változóhoz, akkor írj:
int illékony * illékony p;
Ha strukturális vagy szakszervezeti volatilitást használ, akkor a specifikáló tevékenység a szervezet / unió teljes tartalmára terjed. Ha ezt nem szeretné, alkalmazhatja az illékony specifikát a struktúra / egyesülés egyes elemeire.
A VOLATILE specifikátor megfelelő használata
Egy változót az illékony kulcsszóval kell deklarálni, ha az értéke váratlanul megváltozhat.
uint8_t * pReg = (uint8_t *) 0x1234;
// Várja meg, hogy a regiszter nem nulla legyen
Ebben az esetben szinte biztosan hiba lesz, amint engedélyezi az optimalizálást. A fordító ehhez hasonló kódot hoz létre:
Az optimalizáló logikája meglehetősen egyszerű: a változó értékének az akkumulátorban való számozásával (a kód második sorában) nincs szükség újból olvasásra, mivel az érték mindig ugyanaz lesz. Így a harmadik sorban végtelen hurokba kerülünk. Ha a fordítót arra kényszerítjük, hogy tegyen meg mindent, amire szükségünk van, megváltoztatjuk a leírást:
uint8_t illékony * pReg = (uint8_t illékony *) 0x1234;
Az assembler kód most így néz ki:
Elértük a kívánt folyamatok előrehaladását.
Elképesztő problémák adódhatnak olyan nyilvántartásokban, amelyek sajátos jellemzőkkel bírnak. Például sok periféria olyan regisztereket tartalmaz, amelyeket egyszerűen elolvasta. Néhány további olvasás az Ön szándékaitól (vagy fordítva, kevesebb, mint tervezett) vezethet ezekben az esetekben váratlan eredményekhez.
Ami az AVR mikrokontrollerek programozását illeti, nincs szükség arra, hogy a perifériás regiszterekhez mutatókat használjunk, mert a kód ebben az esetben rendkívül nehézkesnek bizonyul. Pashgan.
A megszakítási szolgáltatás rutin (ISR)
A megszakítás kezelői gyakran beállítják a kód fő testében ellenőrzött változók értékét. Például egy soros port-megszakítással ellenőrizheti az egyes fogadott karaktereket, hogy lássa-e, hogy ez egy végvonalbeli karakter (feltételezhetően az üzenet végét jelzi). Ha a karakter a vonal vége, a megszakításkezelő beállíthatja a globális zászlót. A helytelen végrehajtás ebben az esetben a következő lehet:
int etx_rcvd = FALSE;