Kvalifikátory variabilného rozsahu → volatile
Popis :
volatile
je kľúčové slovo známe ako kvalifikátor premennej,
zvyčajne sa používa pred dátovým typom premennej na úpravu spôsobu, akým kompilátor a následný program zaobchádzajú s premennou. Vyhlásenie premennej volatile je pokyn pre kompilátor. Kompilátor je softvér, ktorý prekladá váš kód do strojového kódu, čo sú skutočné inštrukcie pre čip Atmega v Arduine.
Konkrétne nariaďuje kompilátoru, aby načítal premennú z RAM a nie z úložného registra, čo je dočasné miesto v pamäti, kde sa ukladajú a manipulujú s premennými programu.
Za určitých podmienok môže byť hodnota premennej uložená v registroch nepresná. Premenná by mala byť vyhlásená za nestálu vždy, keď môže byť jej hodnota zmenená niečím, čo je mimo kontroly sekcie kódu, v ktorej sa vyskytuje, ako napríklad súbežne prebiehajúce vlákno. Jediným miestom, kde sa to pravdepodobne vyskytne, sú v Arduine časti kódu spojené s prerušeniami, ktoré sa nazývajú rutina služby prerušenia.
int alebo long volatiles
Ak je volatile premenná väčšia ako bajt (napr. 16-bitová int alebo 32-bitová long), mikrokontrolér ju nedokáže prečítať v jednom kroku, pretože ide o 8-bitový mikrokontrolér. To znamená, že zatiaľ čo vaša hlavná časť kódu (napr. loop) číta prvých 8 bitov premennej, prerušenie už môže zmeniť druhých 8 bitov. To vytvorí náhodné hodnoty pre premennú.
Kým sa premenná číta, prerušenia musia byť deaktivované, aby sa počas čítania nemohli pohrávať s bitmi. Existuje niekoľko spôsobov, ako to urobiť:
• použite makro ATOMIC_BLOCK. Atómové operácie sú jednotlivé operácie MCU – najmenšia možná jednotka.
Príklad kódu :
Volatilný modifikátor zaisťuje, že zmeny zmenenej premennej sú okamžite viditeľné v loop(). Bez nestáleho modifikátora môže byť zmenená premenná načítaná do registra pri vstupe do funkcie a už by sa neaktualizovala, kým sa funkcia neskončí.
// Ak sa vstup zmenil, bliká LED na 1 s
// v predchádzajúcej sekunde.
volatile byte changed = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), toggle, CHANGE);
}
void loop() {
if (changed == 1) {
//toggle() bolo volané z prerušení!
// Resetovanie zmenené na 0
changed = 0;
// LED bliká 200 ms
digitalWrite(LED_BUILTIN, HIGH);
delay(200);
digitalWrite(LED_BUILTIN, LOW);
}
}
void toggle() {
changed = 1;
}
Na prístup k premennej s veľkosťou väčšou ako 8-bitová dátová zbernica mikrokontroléra použite makro ATOMIC_BLOCK. Makro zaisťuje, že premenná sa číta v atómovej operácii, t. j. jej obsah sa počas čítania nedá meniť.
#include <util/atomic.h> //táto knižnica obsahuje makro ATOMIC_BLOCK.
volatile int input_from_interrupt;
// Niekde v kóde, napr. vnútorná slučka ()
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
// kód so zablokovanými prerušeniami (po sebe idúce atómové operácie nebudú prerušené)
int result = input_from_interrupt;
}
Pridaj komentár