Kvalifikátory variabilného rozsahu → volatile

Popis :

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.

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ť:

noInterrupts()

• 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

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *

Nemôžete kopírovať obsah tejto stránky