Sudah didokumentasikan dengan jelas bahwa ketika data global dibagikan dengan ISR dan program utama, data perlu dinyatakan volatile
untuk menjamin visibilitas memori (dan itu hanya cukup untuk data 1-byte; apa pun yang lebih besar memerlukan pengaturan khusus untuk menjamin juga keaslian) . Di sini kami memiliki aturan yang baik:
- Variabel yang hanya digunakan di luar ISR tidak boleh volatil.
- Variabel yang hanya digunakan di dalam ISR tidak boleh volatil.
- Variabel yang digunakan baik di dalam maupun di luar ISR harus volatile.
Tetapi apakah volatile
diperlukan ketika variabel diakses dari> 1 ISR, tetapi tidak dibagikan di luar ISR? Misalnya, saya memiliki fungsi yang mempertahankan keadaan internal menggunakan static
variabel:
void func() {
static volatile long counter; // volatile or not?
// Do stuff with counter etc.
}
Fungsi itu disebut dalam dua cara: dari pin interrupt, dan dari perpustakaan TimerOne :
attachInterrupt(0, func, CHANGE);
Timer1.attachInterrupt(func);
Tidak ada masalah atomisitas, karena ketika ISR dimasukkan, interupsi secara otomatis dinonaktifkan , tetapi ini volatile
lebih merupakan pertanyaan kompiler: apa yang di-cache dan apa yang tidak.
Lebih baik aman daripada menyesal, tentu saja ...
volatile
, karena itu tidak dimodifikasi oleh apa pun selain kode yang dihasilkan; kompiler dapat "berasumsi" bahwa ISR dijalankan secara linear, dan itu terjadi, selama interupsi tidak bersarang. Itu masuk akal. Terima kasih!