
Kelompok bendera acara sudah disebutkan sebelumnya di salah satu artikel sebelumnya (# 5). Dalam Nucleus SE, mereka mirip dengan sinyal, tetapi lebih fleksibel. Mereka menyediakan cara yang murah dan fleksibel untuk mentransfer pesan sederhana antar tugas.
Artikel sebelumnya dalam seri:
Artikel # 16. SinyalArtikel # 15. Partisi Memori: Layanan dan Struktur DataArtikel # 14. Bagian memori: pengantar dan layanan dasarArtikel # 13. Struktur data tugas dan panggilan API yang tidak didukungArtikel # 12. Layanan untuk bekerja dengan tugasArtikel # 11. Tugas: konfigurasi dan pengantar APIArtikel # 10. Penjadwal: fitur canggih dan pelestarian konteksArtikel # 9. Penjadwal: implementasiArtikel # 8. Nucleus SE: Desain dan Penyebaran InternalArtikel # 7. Nucleus SE: PendahuluanArtikel # 6. Layanan RTOS lainnyaArtikel # 5. Interaksi tugas dan sinkronisasiArtikel # 4. Tugas, pengalihan konteks, dan interupsiArtikel # 3. Tugas dan PerencanaanArtikel # 2. RTOS: Struktur dan mode waktu-nyata
Artikel # 1. RTOS: pengantar.
Menggunakan Bendera Acara
Dalam Nucleus SE, flag event didefinisikan selama fase build. Jumlah maksimum grup bendera acara dalam aplikasi adalah 16. Jika grup bendera acara tidak ditentukan, maka kode yang terkait dengan struktur data dan panggilan layanan grup bendera acara tidak akan dimasukkan dalam aplikasi.
Kelompok bendera acara - satu set bendera delapan bit, akses yang diatur sehingga beberapa tugas dapat menggunakan satu bendera dengan aman. Satu tugas dapat mengatur atau menghapus kombinasi flag acara. Tugas lain adalah membaca sekelompok bendera kapan saja, dan itu juga dapat menunggu urutan bendera tertentu (dengan polling atau dengan jeda).
Mengkonfigurasi grup bendera acara
Jumlah grup bendera acara
Seperti kebanyakan objek Nucleus SE, konfigurasi grup flag event ditentukan oleh arahan
#define di
nuse_config.h . Parameter utama adalah
NUSE_EVENT_GROUP_NUMBER , yang menentukan berapa banyak kelompok bendera acara yang akan ditentukan dalam aplikasi. Secara default, parameter ini diatur ke 0 (yaitu, grup acara bendera tidak digunakan) dan dapat memiliki nilai apa pun hingga 16. Nilai yang salah akan menyebabkan kesalahan kompilasi, yang akan dihasilkan dengan memeriksa
nuse_config_check.h (diaktifkan oleh
nuse_config.c , yang artinya dikompilasi dengan modul ini), sebagai hasilnya, arahan
#error akan berfungsi. Memilih nilai bukan nol berfungsi sebagai penggerak utama grup bendera acara. Parameter ini digunakan ketika mendefinisikan struktur data dan ukurannya tergantung pada nilainya (lebih lanjut tentang ini dalam artikel berikut). Selain itu, nilai bukan nol mengaktifkan pengaturan API.
Aktifkan Panggilan API
Setiap fungsi API (panggilan utilitas) di Nucleus SE diaktifkan oleh arahan
#define di
nuse_config.h . Untuk grup bendera acara, ini termasuk:
NUSE_EVENT_GROUP_SET
NUSE_EVENT_GROUP_RETRIEVE
NUSE_EVENT_GROUP_INFORMATION
NUSE_EVENT_GROUP_COUNT
Secara default, mereka diatur ke
FALSE , sehingga menonaktifkan setiap panggilan layanan dan memblokir masuknya kode yang mengimplementasikannya. Untuk mengonfigurasi grup bendera acara, Anda harus memilih panggilan API yang diperlukan dan mengatur arahan terkait ke
TRUE .
Berikut ini adalah kutipan dari file nuse_config.h default.
#define NUSE_EVENT_GROUP_NUMBER 0 #define NUSE_EVENT_GROUP_SET FALSE #define NUSE_EVENT_GROUP_RETRIEVE FALSE #define NUSE_EVENT_GROUP_INFORMATION FALSE #define NUSE_EVENT_GROUP_COUNT FALSE
Fungsi API yang diaktifkan jika tidak ada grup bendera acara dalam aplikasi akan menyebabkan kesalahan kompilasi (kecuali untuk
NUSE_Event_Group_Count () , yang selalu diaktifkan). Jika kode Anda menggunakan panggilan API yang belum diaktifkan, kesalahan tata letak akan terjadi karena kode implementasi tidak termasuk dalam aplikasi.
Panggilan Utilitas Panggilan Acara
Nucleus RTOS mendukung tujuh panggilan utilitas yang menyediakan fungsionalitas berikut:
- Tetapkan bendera acara. Nucleus SE diimplementasikan dalam fungsi NUSE_Event_Group_Set () .
- Membaca bendera acara. Di Nucleus SE, diterapkan di NUSE_Event_Group_Retrieve () .
- Memberikan informasi tentang kelompok bendera acara tertentu. Di Nucleus SE, diterapkan di NUSE_Event_Group_Information () .
- Mengembalikan jumlah grup bendera acara yang saat ini dikonfigurasi dalam aplikasi. Di Nucleus SE, diterapkan di NUSE_Event_Group_Count () .
- Menambahkan grup baru bendera acara ke aplikasi. Nucleus SE tidak diimplementasikan.
- Menghapus sekelompok bendera acara dari aplikasi. Nucleus SE tidak diimplementasikan.
- Mengembalikan pointer ke semua grup bendera acara dalam aplikasi. Nucleus SE tidak diimplementasikan.
Implementasi dari masing-masing panggilan overhead ini dibahas secara rinci di bawah ini.
Perlu dicatat bahwa tidak ada fungsi reset di Nucleus RTOS atau Nucleus SE. Ini dilakukan dengan sengaja. Fungsi reset menyiratkan prevalensi status khusus dari bendera. Untuk grup bendera acara, satu-satunya negara "khusus" adalah mengatur ulang semua bendera, yang dapat dilakukan menggunakan
NUSE_Event_Group_Set () .
Panggilan layanan untuk pengaturan dan membaca grup bendera acara
Operasi mendasar yang dapat dilakukan pada sekelompok bendera acara adalah menetapkan nilai satu atau lebih bendera, serta membaca nilai bendera saat ini. Nucleus RTOS dan Nucleus SE menyediakan empat panggilan API dasar untuk operasi ini.
Karena flag event adalah bit, mereka lebih baik divisualisasikan sebagai angka biner. Karena standar C secara historis tidak mendukung representasi konstanta biner (hanya oktal dan heksadesimal), Nucleus SE memiliki file header yang bermanfaat
nuse_binary.h yang berisi karakter
#define seperti
b01010101 untuk semua 256 nilai 8-bit.
Tetapkan Bendera Acara
Panggilan utilitas Nucleus RTOS API untuk menandai sangat fleksibel dan memungkinkan Anda untuk mengatur dan menghapus nilai bendera menggunakan operasi
AND dan
OR . Nucleus SE menyediakan fungsionalitas yang serupa, tetapi tugas jeda adalah opsional.
Panggilan untuk mengatur bendera di Nucleus RTOSPrototipe panggilan layanan:
STATUS NU_Set_Events (NU_EVENT_GROUP * grup, event_flags TIDAK DITANDATANGANI, operasi OPTION);Parameter:
grup - pointer ke blok kontrol yang disediakan pengguna untuk sekelompok bendera acara;
event_flags - nilai topeng bit dari grup bendera;
operasi -
operasi yang akan dilakukan,
NU_OR (untuk mengatur bendera) atau
NU_AND (untuk membersihkan bendera).
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_GROUP - penunjuk yang tidak valid ke sekelompok bendera acara;
NU_INVALID_OPERATION - Operasi yang ditentukan berbeda dari
NU_OR dan
NU_AND .
Panggilan untuk mengatur bendera di Nucleus SEPanggilan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
STATUS NUSE_Event_Group_Set (NUSE_EVENT_GROUP grup, U8 event_flags, operasi OPTION);Parameter:
grup - indeks (ID) dari grup acara yang benderanya ditetapkan / dihapus;
event_flags - nilai bit maxi dari sekelompok bendera;
operasi -
operasi yang akan dilakukan,
NUSE_OR (untuk mengatur flags) atau
NUSE_AND (untuk membersihkan flags).
Nilai pengembalian:
NUSE_SUCCESS - panggilan berhasil diselesaikan;
NUSE_INVALID_GROUP - indeks sekelompok bendera acara tidak valid;
NUSE_INVALID_OPERATION - Operasi yang ditentukan berbeda dari
NUSE_OR dan
NUSE_AND .
Melaksanakan pemasangan bendera acara di Nucleus SEKode awal fungsi API
NUSE_Event_Group_Set () bersifat umum (setelah memeriksa parameter), terlepas dari apakah API mendukung panggilan pemblokiran (menangguhkan tugas) atau tidak. Logikanya cukup sederhana:
NUSE_CS_Enter(); if (operation == NUSE_OR) { NUSE_Event_Group_Data[group] |= event_flags; } else /* NUSE_AND */ { NUSE_Event_Group_Data[group] &= event_flags; }
Bitmask event_flags ditumpangkan (menggunakan operasi
AND atau
OR ) pada nilai grup flag acara yang dipilih.
Kode yang tersisa diaktifkan hanya ketika penguncian tugas diaktifkan:
#if NUSE_BLOCKING_ENABLE while (NUSE_Event_Group_Blocking_Count[group] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_EVENT_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == group)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Event_Group_Blocking_Count[group]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif #endif NUSE_CS_Exit(); return NUSE_SUCCESS;
Jika ada tugas yang dijeda (untuk dibaca) dari kelompok bendera ini, mereka melanjutkan. Ketika mereka memiliki kesempatan untuk melanjutkan eksekusi (itu tergantung pada penjadwal), mereka dapat menentukan apakah kondisi untuk dimulainya kembali mereka puas atau tidak (lihat membaca bendera acara).
Membaca bendera acara
Panggilan utilitas Nucleus RTOS API untuk membaca sangat fleksibel dan memungkinkan Anda untuk menjeda tugas tanpa batas waktu atau dengan batas waktu tertentu jika operasi tidak dapat segera dilakukan (misalnya, jika Anda mencoba membaca urutan tertentu dari peristiwa bendera yang tidak mewakili keadaan saat ini). Nucleus SE menyediakan fitur yang sama, hanya jeda tugas yang opsional, dan batas waktu tidak diterapkan.
Bendera Tantangan di RTOS IntiPrototipe panggilan layanan:
STATUS NU_Retrieve_Events (NU_EVENT_GROUP * grup, UNSIGNED asked_events, operasi OPTION, UNSIGNED * recoverved_events, suspend UNSIGNED);Parameter:
grup - pointer ke blok kontrol yang disediakan pengguna untuk sekelompok bendera acara;
asked_events - topeng bit yang mendefinisikan flag untuk dibaca;
operasi - empat
operasi tersedia:
NU_AND ,
NU_AND_CONSUME ,
NU_OR dan
NU_OR_CONSUME . Operasi
NU_AND dan
NU_AND_CONSUME menunjukkan bahwa semua bendera yang diminta diperlukan. Operasi
NU_OR dan
NU_OR_CONSUME menunjukkan bahwa satu atau beberapa flag yang diminta sudah cukup. Parameter
CONSUME secara otomatis menghapus flag yang ada setelah permintaan berhasil;
recoverved_events - pointer penyimpanan untuk nilai-nilai flag acara baca;
menangguhkan - spesifikasi untuk menjeda tugas; dapat mengambil nilai
NU_NO_SUSPEND atau
NU_SUSPEND , atau nilai batas waktu dalam clock
ticks (dari 1 hingga 4.294.967.293).
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_NOT_PRESENT - operasi yang ditentukan tidak mengembalikan peristiwa (bukan peristiwa tunggal dalam kasus NU_OR dan tidak semua peristiwa dalam kasus NU_AND);
NU_INVALID_GROUP - penunjuk yang tidak valid ke sekelompok bendera acara;
NU_INVALID_OPERATION - operasi yang ditentukan salah;
NU_INVALID_POINTER - null pointer ke penyimpanan flag acara (NULL);
NU_INVALID_SUSPEND - upaya untuk menjeda dari utas yang tidak terkait tugas;
NU_TIMEOUT - kombinasi flag acara yang diperlukan tidak disetel bahkan setelah batas waktu yang ditentukan;
NU_GROUP_DELETED - grup bendera acara dihapus saat tugas ditangguhkan.
Bendera Tantangan di Nucleus SEPanggilan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
STATUS NUSE_Event_Group_Retrieve (grup NUSE_EVENT_GROUP, U8 Request_events, operasi OPTION, U8 * recoverved_events, U8 menangguhkan);Parameter:
grup - indeks (ID) dari grup yang dibaca dari bendera acara;
asked_events - topeng bit yang mendefinisikan flag untuk dibaca;
operasi - spesifikasi yang menunjukkan jumlah bendera yang diperlukan:
NUSE OR (beberapa flag) atau
NUSE AND (semua flag);
recoverved_events - pointer ke store untuk nilai aktual dari flag event baca (dengan operasi
NUSE_AND, ini akan sama seperti yang dilewatkan dalam parameter yang
diminta_events );
menangguhkan - spesifikasi untuk menjeda tugas, dapat mengambil nilai
NUSE_NO_SUSPEND atau
NUSE_SUSPEND .
Nilai pengembalian:
NUSE_SUCCESS - panggilan berhasil diselesaikan;
NUSE_NOT_PRESENT - operasi yang ditentukan tidak mengembalikan peristiwa (tidak satu peristiwa dalam kasus
NUSE_OR dan tidak semua peristiwa dalam kasus
NUSE_AND );
NUSE_INVALID_GROUP - indeks sekelompok bendera acara tidak valid;
NUSE_INVALID_OPERATION - operasi yang ditentukan berbeda dari
NUSE_OR atau
NUSE_AND ;
NUSE_INVALID_POINTER - pointer nol ke penyimpanan flag acara baca (
NULL );
NUSE_INVALID_SUSPEND - upaya untuk menjeda dari aliran non-tugas atau ketika dukungan untuk memblokir panggilan API dinonaktifkan.
Menerapkan pembacaan bendera acara di Nucleus SEVersi kode fungsi API
NUSE_Event_Group_Retrieve () (setelah memeriksa parameter) dipilih selama kompilasi bersyarat tergantung pada apakah dukungan untuk panggilan API untuk memblokir (menangguhkan) tugas diaktifkan atau tidak. Mari kita pertimbangkan dua opsi ini secara terpisah.
Jika kunci dinonaktifkan, kode lengkap untuk panggilan API ini akan terlihat seperti ini:
temp_events = NUSE_Event_Group_Data[group] & requested_events; if (operation == NUSE_OR) { if (temp_events != 0) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } } else /* operation == NUSE_AND */ { if (temp_events == requested_events) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } }
Bendera acara yang diperlukan dipilih dari grup bendera acara yang ditentukan. Nilai tersebut dibandingkan dengan peristiwa yang diperlukan, dengan mempertimbangkan operasi
AND / OR , serta hasil yang dikembalikan dan nilai langsung dari bendera yang diminta.
Jika penguncian tugas diaktifkan, kode menjadi lebih kompleks:
do { temp_events = NUSE_Event_Group_Data[group] & requested_events; if (operation == NUSE_OR) { if (temp_events != 0) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } } else { if (temp_events == requested_events) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } } if (return_value == NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } else { if (suspend == NUSE_SUSPEND) { NUSE_Event_Group_Blocking_Count[group]++; NUSE_Suspend_Task(NUSE_Task_Active, (group << 4) | NUSE_EVENT_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } } while (suspend == NUSE_SUSPEND);
Kode ditempatkan dalam
loop do ... while , yang berfungsi saat parameter
menangguhkan adalah
NUSE_SUSPEND .
Bendera acara yang diminta dibaca seolah-olah dipanggil tanpa diblokir. Jika pembacaan tidak
berhasil dan parameter
penangguhan adalah
NUSE_NO_SUSPEND , panggilan API diatur ke
NUSE_NOT_PRESENT . Jika parameter
penangguhan ditetapkan ke
NUSE_SUSPEND , tugas akan dijeda. Saat kembali (ketika tugas dilanjutkan), jika nilai kembali adalah
NUSE_SUCCESS , yang menunjukkan bahwa tugas dilanjutkan karena bendera acara dalam grup ini disetel atau dihapus, siklus dimulai dari awal, bendera dibaca dan diperiksa. Karena tidak ada fungsi API untuk mengatur ulang grup bendera acara, ini adalah satu-satunya alasan tugas dilanjutkan, tetapi proses
pemeriksaan NUSE_Task_Blocking_Return [] telah ditinggalkan pada sistem untuk kompatibilitas kontrol penguncian dengan jenis objek lainnya.
Artikel berikut akan menjelaskan panggilan API tambahan yang terkait dengan grup bendera acara, serta struktur datanya.
Tentang Pengarang: Colin Walls telah bekerja di industri elektronik selama lebih dari tiga puluh tahun, mencurahkan sebagian besar waktunya untuk firmware. Dia sekarang seorang insinyur firmware di Mentor Embedded (sebuah divisi dari Mentor Graphics). Colin Walls sering berbicara di konferensi dan seminar, penulis berbagai artikel teknis dan dua buku tentang firmware. Tinggal di Inggris.
Blog profesional
Colin , email: colin_walls@mentor.com.