Ten bardzo krótki post chciałbym poświęcić zagadnieniu modyfikatorowi volatile, która jest najczęściej wykorzystywana w procedurze obsługi przerwania.
Zmienna volatile jest tzw. zmienną ulotną. Wartość z takim parametrem nie będzie brana do optymalizacji programu. Dla kompilatora jest to informacja, że wartość tej zmiennej może się zmienić w różnych momentach, nieprzewidywalnych momentach. Czyli wartość nie będzie brana z rejestrów, jak w przypadku wykonywania szeregu operacji na zmiennej, tylko bezpośrednio z pamięci. Dodatkowo kolejność działań wykonywanych na zmiennej nie ulegnie zmianie.
W przypadku nie zastosowania takiej zmiennej mogą wystąpić problemy po włączeniu optymalizacji w programie, niepoprawne działanie podczas wywoływania zmiennej w przerwaniach, operacji na rejestrach czy zmiennych globalnych wykorzystywanych w wielu elementach w programie.
Specyfikator volatile musi być zastosowany w zmiennych wykorzystywanych w przerwaniach.
Cały program najlepiej zademonstrować na funkcji przerwania dla mikrokontrolerów. Przykładowe funkcje obsługi przerwania zostały opisane w sekcji bloga poświęconej STM32.
Zmienną typu volatile deklaruje się w następujący sposób.
Zmienną typu volatile deklaruje się w następujący sposób.
- volatile uint8_t zmienna = 0;
Modyfikator volatile można użyć także do zmiennych wskaźnikowych:
- volatile uint8_t * val1;
- uint8_t volatile * val2;
- uint16_t volatile * volatile val3;
Pierwszy wskaźnik wskazuje na zmienną typu volatile, drugi wskaźnik wskazuje na zmienną bez modyfikatora volatile. Trzeci wskaźnik jest wskaźnikiem volatile na zmienną volatile.
W przypadku struktur jako volatile można zapisać całą zdeklarowaną strukturę lub pojedyncze pola.
Jako podsumowanie należy pamiętać o tym, że zmienna volatile może ulec zmianie w każdym momencie. Co oznacza, że np. przy zdeklarowaniu tablicy volatile to podczas kopiowania, lub sprawdzania zapisanych danych informacje mogą zostać zamienione. Dlatego należy wyłączyć możliwość zmiany tych danych z innego miejsca niż aktualnie obsługiwane (np. wyłączenie wywoływania przerwań, utworzenie flagi nie pozwalające na modyfikację zmiennych itp.).
Źródła: