const
oznacza, że zmienna nie może być modyfikowana przez kod c, a nie że nie może się zmienić. Oznacza to, że żadna instrukcja nie może zapisać do zmiennej, ale jej wartość może się zmienić.
volatile
oznacza, że zmienna może się zmienić w dowolnym momencie i dlatego nie można używać żadnych wartości z pamięci podręcznej; każdy dostęp do zmiennej musi być wykonywany na adres jej pamięci.
Ponieważ pytanie jest oznaczone jako „osadzone” i zakładając, że temp
jest to zmienna zadeklarowana przez użytkownika, a nie rejestr związany ze sprzętem (ponieważ są one zwykle obsługiwane w oddzielnym pliku .h), rozważ:
Wbudowany procesor, który ma zarówno ulotną pamięć danych do odczytu i zapisu (RAM), jak i nieulotną pamięć danych tylko do odczytu, na przykład pamięć FLASH w architekturze von-Neumanna, w której przestrzeń danych i programów współdzielą wspólną magistralę danych i adresów.
Jeśli zadeklarujesz, const temp
że masz wartość (przynajmniej różną od 0), kompilator przypisze zmienną do adresu w przestrzeni FLASH, ponieważ nawet jeśli byłaby przypisana do adresu RAM, nadal potrzebuje pamięci FLASH do przechowywania wartości początkowej zmiennej, przez co adres RAM jest marnowaniem miejsca, ponieważ wszystkie operacje są tylko do odczytu.
W konsekwencji:
int temp;
to zmienna przechowywana w pamięci RAM, inicjowana do 0 przy starcie (cstart), mogą być używane wartości z pamięci podręcznej.
const int temp;
jest zmienną przechowywaną w (read-ony) FLASH, zainicjowaną na 0 w czasie kompilacji, mogą być używane wartości z pamięci podręcznej.
volatile int temp;
jest zmienną przechowywaną w pamięci RAM, zainicjowaną do 0 podczas uruchamiania (cstart), wartości zapisane w pamięci podręcznej NIE będą używane.
const volatile int temp;
jest zmienną przechowywaną w (read-ony) FLASH, zainicjowaną na 0 w czasie kompilacji, wartości z pamięci podręcznej NIE będą używane
Oto przydatna część:
Obecnie większość procesorów Embedded ma możliwość dokonywania zmian w swojej pamięci nieulotnej tylko do odczytu za pomocą specjalnego modułu funkcyjnego, który const int temp
można zmienić w czasie wykonywania, choć nie bezpośrednio. Mówiąc inaczej, funkcja może modyfikować wartość pod adresem, pod którym temp
jest przechowywana.
Praktycznym przykładem może być użycie temp
numeru seryjnego urządzenia. Przy pierwszym uruchomieniu wbudowany procesor temp
będzie równy 0 (lub zadeklarowana wartość) i funkcja może wykorzystać ten fakt do uruchomienia testu podczas produkcji i jeśli się powiedzie, poprosić o nadanie numeru seryjnego i zmodyfikować wartość temp
za pomocą o specjalnej funkcji. Niektóre procesory mają specjalny zakres adresów z pamięcią OTP (jednorazowo programowalną) tylko do tego.
Ale oto różnica:
Jeśli const int temp
jest to identyfikator, który można modyfikować zamiast jednorazowo programowalnego numeru seryjnego i NIE jest zadeklarowany volatile
, wartość z pamięci podręcznej może być używana do następnego uruchomienia, co oznacza, że nowy identyfikator może nie być ważny do następnego ponownego uruchomienia lub, co gorsza, niektóre funkcje może używać nowej wartości, podczas gdy inne mogą używać starszej wartości z pamięci podręcznej do ponownego uruchomienia. Jeśli const int temp
jest zadeklarowane voltaile
, zmiana ID zacznie obowiązywać natychmiast.
const volatile int temp;
w zakresie blokowym (tj. Wewnątrz{ }
), nie ma tam zastosowania.