Seluruh kebenaran tentang RTOS. Artikel # 18. Grup Bendera Acara: Layanan Pembantu dan Struktur Data



Artikel ini terus menggambarkan grup bendera acara.

Artikel sebelumnya dalam seri:

Artikel # 17. Grup Bendera Acara: Pengantar dan Layanan Dasar
Artikel # 16. Sinyal
Artikel # 15. Partisi Memori: Layanan dan Struktur Data
Artikel # 14. Bagian memori: pengantar dan layanan dasar
Artikel # 13. Struktur data tugas dan panggilan API yang tidak didukung
Artikel # 12. Layanan untuk bekerja dengan tugas
Artikel # 11. Tugas: konfigurasi dan pengantar API
Artikel # 10. Penjadwal: fitur canggih dan pelestarian konteks
Artikel # 9. Penjadwal: implementasi
Artikel # 8. Nucleus SE: Desain dan Penyebaran Internal
Artikel # 7. Nucleus SE: Pendahuluan
Artikel # 6. Layanan RTOS lainnya
Artikel # 5. Interaksi tugas dan sinkronisasi
Artikel # 4. Tugas, pengalihan konteks, dan interupsi
Artikel # 3. Tugas dan Perencanaan
Artikel # 2. RTOS: Struktur dan mode waktu-nyata
Artikel # 1. RTOS: pengantar.


Layanan Pembantu Grup Bendera Acara


Nucleus RTOS memiliki tiga panggilan API yang menyediakan fungsi pembantu untuk grup bendera acara: mengambil informasi grup, mengambil informasi tentang jumlah grup bendera acara dalam aplikasi, dan mengambil pointer ke semua grup bendera acara. Dua tantangan pertama diimplementasikan dalam Nucleus SE.

Mengambil Informasi Bendera Grup Acara


Panggilan utilitas ini mengembalikan informasi tentang kelompok bendera acara. Implementasi panggilan ini di Nucleus SE berbeda dari implementasi di Nucleus RTOS karena lebih sedikit informasi yang dikembalikan, karena penamaan objek dan urutan jeda tugas tidak didukung, dan jeda tugas itu sendiri dapat dinonaktifkan.

Panggilan untuk mengambil informasi grup acara di Nucleus RTOS
Prototipe panggilan layanan:
STATUS NU_Event_Group_Information (NU_EVENT_GROUP * grup, CHAR * nama, UNSIGNED * event_flags, UNSIGNED * task_waiting, NU_TASK ** first_task);

Parameter:
grup - pointer ke blok kontrol yang disediakan pengguna untuk sekelompok bendera acara;
name - pointer ke wilayah 8 karakter untuk nama grup flag acara, ini juga termasuk nol penghentian;
event_flags - penunjuk ke variabel yang akan mengambil nilai saat ini dari kelompok bendera acara yang ditentukan;
task_waiting - penunjuk ke variabel yang akan mengambil jumlah tugas yang ditangguhkan dalam kelompok ini bendera acara;
first_task - pointer ke variabel tipe NU_TASK , yang akan membawa pointer ke tugas pertama yang ditangguhkan.

Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_GROUP - penunjuk yang tidak valid ke sekelompok bendera acara.

Panggilan untuk mengambil informasi grup acara di Nucleus SE
Panggilan ini mendukung fungsionalitas inti dari Nucleus RTOS API.

Prototipe panggilan layanan:
STATUS NUSE_Event_Group_Information (NUSE_EVENT_GROUP grup, U8 * event_flags, U8 * task_waiting, NUSE_TASK * first_task);

Parameter:
grup - indeks kelompok bendera acara tentang informasi mana yang diminta;
event_flags - penunjuk ke variabel yang akan mengambil nilai saat ini dari kelompok bendera acara yang ditentukan;
task_waiting - pointer ke variabel yang akan mengambil jumlah tugas yang ditangguhkan dalam grup ini flag acara (tidak ada yang dikembalikan jika penangguhan tugas dinonaktifkan);
first_task - pointer ke variabel tipe NUSE_TASK , yang akan mengambil indeks tugas yang ditangguhkan pertama (tidak ada yang dikembalikan jika penangguhan tugas dinonaktifkan).

Nilai pengembalian:
NUSE_SUCCESS - panggilan berhasil diselesaikan;
NUSE_INVALID_GROUP - indeks grup bendera acara tidak valid.

Implementasi informasi grup acara di Nucleus SE
Menerapkan panggilan API ini cukup sederhana:

*event_flags = NUSE_Event_Group_Data[group]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Event_Group_Blocking_Count[group]; if (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)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif return NUSE_SUCCESS; 

Fungsi mengembalikan nilai kelompok bendera acara. Kemudian, jika pemblokiran panggilan API diaktifkan, jumlah tugas yang tertunda dan indeks yang pertama akan dikembalikan (jika tidak, kedua parameter ini disetel ke nol).

Mendapatkan jumlah grup bendera acara


Panggilan utilitas ini mengembalikan jumlah grup bendera acara dalam aplikasi. Dalam Nucleus RTOS, nilai ini berubah seiring waktu, dan nilai kembali menunjukkan jumlah grup saat ini, sementara di Nucleus SE nilai ini ditentukan selama perakitan dan tidak berubah seiring waktu.

Memanggil konter grup bendera acara di Nucleus RTOS
Prototipe panggilan layanan:
NU_Establised_Event_Groups (VOID) UNSIGNED;

Parameter:
Tidak ada.

Nilai pengembalian:
Jumlah saat ini grup bendera acara dibuat.

Memanggil Konter Grup Bendera Acara di Nucleus SE
Prototipe panggilan layanan:
U8 NUSE_Event_Group_Count (batal);

Parameter:
Tidak ada.

Nilai pengembalian:
Jumlah grup bendera acara yang dikonfigurasi.

Menerapkan konter grup bendera acara di Nucleus SE
Implementasi panggilan API ini cukup sepele: nilai simbol #define NUSE_EVENT_GROUP_NUMBER dikembalikan .

Struktur data


Seperti semua objek Nucleus SE lainnya, grup bendera acara menggunakan satu atau dua array struktur data (keduanya terletak di RAM), ukuran array tergantung pada jumlah grup yang ditentukan dalam pengaturan.

Saya sangat merekomendasikan bahwa kode aplikasi tidak menggunakan akses langsung ke struktur data ini, tetapi merujuknya melalui fungsi API yang disediakan. Ini akan menghindari ketidakcocokan dengan versi Nucleus SE di masa depan dan efek samping yang tidak diinginkan, serta menyederhanakan porting aplikasi ke Nucleus RTOS. Untuk pemahaman yang lebih baik tentang kode panggilan layanan dan debugging, tinjauan rinci struktur data disediakan di bawah ini.

Data RAM


Data ini memiliki struktur sebagai berikut:
NUSE_Event_Group_Data [] - larik data tipe U8 yang memiliki satu catatan untuk setiap kelompok bendera yang dikonfigurasi; itu menyimpan data flag event.
NUSE_Event_Group_Blocking_Count [] - larik tipe U8 yang berisi penghitung tugas yang diblokir di setiap grup bendera acara. Array ini hanya ada ketika fungsi penguncian di API diaktifkan.

Struktur data ini diinisialisasi dengan nol di fungsi NUSE_Init_Event_Group () ketika Nucleus SE dimulai. Salah satu artikel berikut akan memberikan deskripsi lengkap tentang prosedur startup Nucleus SE.

Berikut ini adalah deskripsi struktur data ini dalam file nuse_init.c :

 RAM U8 NUSE_Event_Group_Data[NUSE_EVENT_GROUP_NUMBER]; #if NUSE_BLOCKING_ENABLE RAM U8 NUSE_Event_Group_Blocking_Count[NUSE_EVENT_GROUP_NUMBER]; #endif 

Data ROM


Untuk mengimplementasikan grup bendera acara, data dalam ROM tidak digunakan.

Ukuran memori untuk grup bendera acara


Seperti dengan semua objek kernel Nucleus SE, jumlah memori yang diperlukan untuk grup bendera acara dapat diprediksi.

Jumlah data dalam ROM untuk semua grup bendera acara dalam aplikasi adalah 0.

Jumlah memori dalam RAM untuk semua grup bendera acara dengan fungsi penguncian API yang diaktifkan adalah NUSE_EVENT_GROUP_NUMBER * 2 .

Kalau tidak, itu adalah NUSE_EVENT_GROUP_NUMBER .

Panggilan API yang belum direalisasi


Tiga panggilan API untuk grup bendera acara yang dapat ditemukan di Nucleus RTOS tidak diterapkan di Nucleus SE.

Membuat Grup Bendera Acara


Panggilan API ini membuat sekelompok bendera acara. Nucleus SE tidak memerlukan panggilan ini karena grup bendera acara dibuat secara statis.

Prototipe panggilan layanan:
STATUS NU_Create_Event_Group (NU_EVENT_GROUP * grup, CHAR * nama);

Parameter:

grup - pointer ke blok kontrol yang disediakan pengguna untuk sekelompok bendera acara; Digunakan sebagai deskriptor untuk mengelola grup bendera acara di panggilan API lainnya
name - pointer ke nama 8 karakter grup flag acara dengan terminasi null byte yang termasuk dalam area ini.

Nilai pengembalian:

NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_GROUP - pointer nol ke unit kontrol grup bendera acara ( NULL ) atau sudah digunakan.

Menghapus sekelompok bendera acara


Panggilan API ini menghapus grup bendera acara yang dibuat sebelumnya. Nucleus SE tidak memerlukan panggilan ini karena grup bendera acara dibuat secara statis dan tidak dapat dihapus.

Prototipe panggilan layanan:

STATUS NU_Delete_Event_Group (NU_EVENT_GROUP * grup);

Parameter:

grup - penunjuk ke blok kontrol grup bendera acara.

Nilai pengembalian:

NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_GROUP - penunjuk yang tidak valid ke sekelompok bendera acara.

Pointer Grup Bendera Acara


Panggilan API ini membuat daftar pointer berurutan untuk semua grup bendera acara dalam sistem. Nucleus SE tidak memerlukan panggilan ini karena grup bendera acara memiliki indeks sederhana, bukan petunjuk.

Prototipe panggilan layanan:

UNSIGNED NU_Event_Group_Pointers (NU_EVENT_GROUP * pointer_list, maksimum_pointers UNSIGNED);

Parameter:

pointer_list - pointer ke array pointer NU_EVENT_GROUP , array ini diisi dengan pointer ke grup bendera acara yang dibuat dalam sistem;
maximum_pointers - jumlah maksimum pointer dalam array.

Nilai pengembalian:

Jumlah NU_EVENT_GROUP pointer dalam array.

Kompatibel dengan RTOS Inti


Ketika mengembangkan Nucleus SE, tujuan saya adalah untuk memastikan tingkat maksimum kompatibilitas kode dengan Nucleus RTOS. Kelompok bendera acara tidak terkecuali, dan, dari sudut pandang pengembang, mereka diimplementasikan dengan cara yang hampir sama dengan di RTOS Inti. Ada beberapa ketidakcocokan yang saya anggap valid, mengingat bahwa kode akhir akan menjadi lebih mudah dipahami dan lebih efisien dalam hal jumlah memori yang diperlukan. Jika tidak, panggilan Nucleus RTOS API dapat digunakan hampir secara langsung sebagai panggilan Nucleus SE.

Pengidentifikasi Objek


Dalam Nucleus RTOS, semua objek dijelaskan oleh struktur data (unit kontrol) dari tipe tertentu. Penunjuk ke unit kontrol ini adalah pengidentifikasi untuk sekelompok bendera acara. Saya memutuskan bahwa dalam Nucleus SE, diperlukan pendekatan berbeda untuk penggunaan memori yang efisien: semua objek kernel dijelaskan oleh beberapa tabel dalam RAM dan / atau ROM. Ukuran tabel ini ditentukan oleh jumlah objek yang dikonfigurasi dari setiap jenis. Pengidentifikasi objek tertentu adalah indeks dalam tabel ini. Jadi saya mendefinisikan NUSE_EVENT_GROUP sebagai setara dengan U8 , variabel jenis ini (bukan pointer) berfungsi sebagai pengidentifikasi kelompok bendera acara. Ketidakcocokan sedikit ini mudah ditangani jika kode porting dari Nucleus SE ke Nucleus RTOS dan sebaliknya. Biasanya, tidak ada operasi yang dilakukan pada pengidentifikasi objek selain memindahkan dan menyimpan.

Nucleus RTOS juga mendukung penamaan grup bendera acara. Nama-nama ini hanya digunakan untuk debugging. Saya mengecualikan mereka dari Nucleus SE untuk menghemat memori.

Jumlah bendera dalam grup


Dalam Nucleus RTOS, grup bendera acara masing-masing berisi 32 bendera, di Nucleus SE I mengurangi jumlahnya menjadi delapan, karena ini cukup untuk aplikasi sederhana dan menghemat RAM. Nucleus SE dapat dengan mudah dimodifikasi jika kelompok yang lebih besar dari bendera acara diperlukan.

Fungsi penyerapan bendera


Nucleus RTOS memiliki fungsi untuk menghapus (menyerap) flag event setelah membacanya. Saya memutuskan untuk mengecualikan fungsi ini dari Nucleus SE untuk menyederhanakan sistem, karena penyerapan (penghapusan) bendera terjadi ketika semua tugas yang diblokir menerima bendera untuk dibaca, dan ini akan sulit untuk diterapkan. Jika perlu, tugas membaca bendera selalu dapat menghapusnya menggunakan panggilan API terpisah.

Panggilan API yang belum direalisasi


Nucleus RTOS mendukung tujuh panggilan utilitas untuk bekerja dengan grup bendera acara. Dari jumlah tersebut, tiga tidak diimplementasikan dalam Nucleus SE. Rincian tantangan ini, serta keputusan untuk mengeluarkannya dari Nucleus SE, telah dijelaskan di atas.
Artikel selanjutnya akan melihat semaphores.

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.

Source: https://habr.com/ru/post/id428890/


All Articles