Saya sedang mencari untuk mengembangkan perangkat lunak bertenaga baterai menggunakan pengontrol EFM Gekko (http://energymicro.com/) dan ingin pengontrol tertidur setiap kali tidak ada yang berguna untuk dilakukan. Instruksi WFI (Wait For Interrupt) digunakan untuk tujuan ini; itu akan membuat prosesor tidur sampai terjadi gangguan.
Jika tidur diaktifkan dengan menyimpan sesuatu di suatu tempat, seseorang dapat menggunakan operasi load-eksklusif / toko-eksklusif untuk melakukan sesuatu seperti:
// dont_sleep akan dimuat dengan 2 setiap kali sesuatu terjadi itu // harus memaksa loop utama untuk berputar setidaknya sekali. Jika ada interupsi // Terjadi yang menyebabkannya diatur ulang ke 2 selama pernyataan berikut, // perilaku akan seolah-olah interupsi terjadi setelahnya. store_exclusive (load_exclusive (dont_sleep) >> 1); while (! dont_sleep) { // Jika interupsi terjadi antara pernyataan berikutnya dan store_exclusive, jangan tidur load_exclusive (SLEEP_TRIGGER); if (! dont_sleep) store_exclusive (SLEEP_TRIGGER); }
Jika terjadi interupsi antara operasi load_exclusive dan store_exclusive, efeknya akan melewatkan store_exclusive, sehingga menyebabkan sistem untuk menjalankan loop sekali lagi (untuk melihat apakah interupsi telah mengatur dont_sleep). Sayangnya, Gekko menggunakan instruksi WFI daripada alamat tulis untuk memicu mode tidur; menulis kode suka
if (! dont_sleep) WFI ();
akan menjalankan risiko bahwa interupsi dapat terjadi antara 'jika' dan 'wfi' dan mengatur dont_sleep, tetapi wfi akan tetap melanjutkan dan mengeksekusi. Apa pola terbaik untuk mencegah itu? Atur PRIMASK ke 1 untuk mencegah interupsi mengganggu prosesor sesaat sebelum menjalankan WFI, dan menghapusnya segera setelah itu? Atau ada trik yang lebih baik?
EDIT
Saya bertanya-tanya tentang bit Event. Secara umum, ini dimaksudkan untuk dukungan multi-prosesor, tetapi bertanya-tanya apakah sesuatu seperti yang berikut ini bisa berfungsi:
if (dont_sleep) SEV (); / * Akan membuat mengikuti bendera acara WFE yang jelas tetapi tidak tidur * / WFE ();
Setiap interupsi yang diset jangan_sleep juga harus menjalankan instruksi SEV, jadi jika interupsi terjadi setelah tes "jika", WFE akan menghapus flag event tetapi tidak pergi tidur. Apakah itu terdengar seperti paradigma yang baik?