
Artikel ini melanjutkan ulasan kotak surat yang dimulai pada artikel sebelumnya di seri "The Truth About RTOS".
Artikel sebelumnya dalam seri:
Artikel # 21. Kotak Surat: Pengantar dan Layanan DasarArtikel # 20. Semaphores: Layanan Tambahan dan Struktur DataArtikel # 19. Semaphores: pengantar dan layanan dasarArtikel # 18. Grup Bendera Acara: Layanan Pembantu dan Struktur DataArtikel # 17. Grup Bendera Acara: Pengantar dan Layanan DasarArtikel # 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.
Layanan Kotak Pesan Bantu
Nucleus RTOS memiliki empat panggilan API yang menyediakan fungsi tambahan yang terkait dengan kotak surat: membuang kotak surat, mengambil informasi tentang kotak surat, mengambil jumlah kotak surat dalam suatu aplikasi, dan mengambil penunjuk ke semua kotak surat dalam suatu aplikasi. Tiga fitur pertama diimplementasikan dalam Nucleus SE.
Atur ulang kotak surat
Panggilan layanan API ini mengatur ulang kotak surat ke kondisi awal, yang tidak digunakan. Pesan yang disimpan di kotak surat akan hilang. Tugas apa pun yang ditangguhkan di kotak surat akan dilanjutkan dengan kode pengembalian
NUSE_MAILBOX_WAS_RESET .
Panggil untuk mengatur ulang kotak surat di Nucleus RTOSPrototipe panggilan layanan:
STATUS NU_Reset_Mailbox (NU_MAILBOX * kotak surat);Parameter:
kotak surat - penunjuk ke unit kontrol kotak surat.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_MAILBOX - penunjuk kotak surat tidak valid.
Panggil untuk mengatur ulang kotak surat di Nucleus SEPanggilan layanan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
STATUS NUSE_Mailbox_Reset (NUSE_MAILBOX mailbox);Parameter:
kotak surat - indeks (ID) dari kotak surat yang dibuang.
Nilai pengembalian:NUSE_SUCCESS - panggilan berhasil diselesaikan;
NUSE_INVALID_MAILBOX - indeks kotak surat tidak valid.
Menerapkan Reset Kotak Pesan di Nucleus SEKode opsi untuk fungsi
NUSE_Mailbox_Reset (setelah memeriksa parameter) dipilih menggunakan kompilasi bersyarat, tergantung pada apakah dukungan untuk memblokir (menjeda) tugas diaktifkan atau tidak. Kami akan mempertimbangkan kedua opsi ini.
Jika kunci tidak diaktifkan, kode untuk fungsi API ini cukup sederhana. Kotak surat ditandai sebagai tidak digunakan dengan mengatur parameter
NUSE_Mailbox_Status [] ke
FALSE .
Jika kunci diaktifkan, kode menjadi lebih kompleks:
while (NUSE_Mailbox_Blocking_Count[mailbox] != 0) { U8 index; /* check whether any tasks are blocked */ /* on this mailbox */ for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_MAILBOX_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == mailbox)) { NUSE_Task_Blocking_Return[index] = NUSE_MAILBOX_WAS_RESET; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Mailbox_Blocking_Count[mailbox]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif
Kotak surat diatur ulang ke status "Kosong".
Setiap tugas yang ditangguhkan di kotak surat diberi status "Siap" dengan kode pengembalian
NUSE_MAILBOX_WAS_RESET . Setelah proses ini selesai, jika penjadwal Prioritas digunakan, panggilan layanan
NUSE_Reschedule () dibuat , karena satu atau lebih tugas dengan prioritas yang lebih tinggi dapat menjadi siap dan menunggu izin untuk dieksekusi.
Mengambil Informasi Kotak Pesan
Panggilan layanan ini menyediakan satu set informasi kotak surat. Implementasi panggilan ini dalam Nucleus SE berbeda dari Nucleus RTOS dalam hal ia mengembalikan lebih sedikit informasi, karena penamaan objek dan urutan jeda tidak didukung, dan tugas jeda dapat dinonaktifkan.
Panggil untuk Nucleus RTOS Information MailboxPanggilan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
STATUS NU_Mailbox_Information (NU_MAILBOX * kotak surat, CHAR * nama, OPTION * suspend_type, DATA_ELEMENT * message_present, UNSIGNED * task_waiting, NU_TASK ** first_task);Parameter:
kotak surat - penunjuk ke unit kontrol kotak surat;
name - pointer 8 karakter ke nama kotak surat. Pengakhiran null byte juga termasuk dalam area ini;
suspend_type - penunjuk ke variabel tempat jenis penangguhan tugas disimpan. Itu dapat mengambil nilai
NU_FIFO dan
NU_PRIORITY ;
message_present - pointer ke variabel yang akan mengambil nilai
NU_TRUE atau
NU_FALSE , tergantung pada apakah kotak surat penuh atau tidak;
task_waiting - pointer ke variabel yang akan mengambil jumlah tugas yang ditangguhkan di kotak surat ini;
first_task - penunjuk ke penunjuk tugas yang akan membawa penunjuk ke tugas yang dijeda pertama.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_MAILBOX - penunjuk kotak surat tidak valid.
Panggilan untuk Nucleus SE Mailbox InformationPanggilan layanan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
STATUS NUSE_Mailbox_Information (NUSE_MAILBOX mailbox, U8 * message_present, U8 * task_waiting, NUSE_TASK * first_task);Parameter:
kotak surat - indeks kotak surat tentang informasi mana yang diminta;
message_present - pointer ke variabel yang mengambil nilai
TRUE atau
FALSE , tergantung pada apakah kotak surat penuh atau tidak;
task_waiting - pointer ke variabel yang akan mengambil jumlah tugas yang ditangguhkan di kotak surat ini (tidak ada yang dikembalikan jika penangguhan tugas dinonaktifkan);
first_task - pointer ke variabel dari 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_MAILBOX - indeks kotak surat tidak valid;
NUSE_INVALID_POINTER - satu atau beberapa parameter pointer salah.
Menerapkan Informasi Kotak Pesan di Nucleus SEImplementasi panggilan API ini cukup sederhana:
*message_present = NUSE_Mailbox_Status[mailbox]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Mailbox_Blocking_Count[mailbox]; if (NUSE_Mailbox_Blocking_Count[mailbox] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_MAILBOX_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == mailbox)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif return NUSE_SUCCESS;
Fungsi mengembalikan status kotak surat. Kemudian, jika panggilan layanan untuk memblokir tugas diaktifkan, jumlah tugas yang ditangguhkan dan indeks yang pertama dikembalikan (jika tidak, parameter ini diatur ke 0).
Mendapatkan jumlah kotak surat
Panggilan utilitas ini mengembalikan jumlah kotak surat di aplikasi. Sementara di Nucleus RTOS jumlah mereka dapat berubah dari waktu ke waktu, dan nilai kembali akan menunjukkan jumlah kotak surat saat ini, di Nucleus SE jumlah kotak surat diatur pada tahap pembuatan dan tidak dapat diubah.
Memanggil Penghitung Kotak Pesan di Nucleus RTOSPanggilan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
NU_Established_Mailboxes (VOID) UNSIGNED;Parameter:
Tidak ada.
Nilai pengembalian:
Jumlah kotak surat yang dibuat dalam aplikasi.
Memanggil Penghitung Kotak Pesan di Nucleus SEPanggilan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
U8 NUSE_Mailbox_Count (batal);Parameter:
Tidak ada.
Nilai pengembalian:
Jumlah kotak surat yang dikonfigurasi dalam aplikasi.
Menerapkan Penghitung Kotak Pesan di Nucleus SEPelaksanaan panggilan API ini sangat sederhana: nilai arahan
#define NUSE_MAILBOX_NUMBER dikembalikan .
Struktur data
Kotak surat menggunakan dua atau tiga larik struktur data (yang semuanya terletak di RAM), yang, seperti objek Nucleus SE lainnya, adalah seperangkat tabel yang ukurannya tergantung pada jumlah kotak surat yang dikonfigurasi dan parameternya.
Saya sangat merekomendasikan bahwa kode aplikasi tidak menggunakan akses langsung ke struktur data ini, tetapi merujuknya melalui fungsi API yang disediakan. Ini menghindari ketidakcocokan dengan versi Nucleus SE di masa depan dan efek samping yang tidak diinginkan, dan juga menyederhanakan porting aplikasi ke Nucleus RTOS. Berikut ini adalah ikhtisar terperinci dari struktur data untuk pemahaman yang lebih baik tentang cara kerja kode panggilan layanan dan untuk debugging.
Data RAM
Data ini memiliki struktur sebagai berikut:
NUSE_Mailbox_Data [] - larik jenis
ADDR yang memiliki satu entri untuk setiap kotak surat yang dikonfigurasi, ia menyimpan data kotak surat.
NUSE_Mailbox_Status [] adalah larik
U8 yang memiliki satu entri untuk setiap kotak surat yang dikonfigurasi, ia memantau penggunaan kotak surat. Nilai bukan nol (
BENAR ) menunjukkan bahwa kotak surat penuh.
NUSE_Mailbox_Blocking_Count [] - larik tipe
U8 , berisi konter tugas yang diblokir untuk setiap kotak surat. Array ini hanya dibuat jika fungsionalitas pemblokiran panggilan API diaktifkan.
Struktur data ini diinisialisasi dengan nol di fungsi
NUSE_Init_Mailbox () ketika Nucleus SE dimulai. Ini logis, karena setiap kotak surat dibuat kosong (tidak digunakan).
Berikut ini adalah definisi dari struktur data ini dari file
nuse_init.c .
RAM ADDR NUSE_Mailbox_Data[NUSE_MAILBOX_NUMBER]; RAM U8 NUSE_Mailbox_Status[NUSE_MAILBOX_NUMBER]; #if NUSE_BLOCKING_ENABLE RAM U8 NUSE_Mailbox_Blocking_Count[NUSE_MAILBOX_NUMBER]; #endif
Data ROM
Untuk implementasi kotak surat, data dalam ROM tidak digunakan.
Jumlah memori untuk kotak surat
Seperti semua objek kernel Nucleus SE, jumlah memori yang diperlukan untuk kotak surat sudah diketahui sebelumnya.
Jumlah memori untuk data dalam ROM untuk semua kotak surat dalam aplikasi adalah 0.
Jumlah data dalam RAM untuk semua kotak surat dalam aplikasi (dalam byte) dengan panggilan API yang diaktifkan untuk memblokir tugas dapat dihitung sebagai berikut:
NUSE_MAILBOX_NUMBER * (sizeof (ADDR) +2)Jika tidak:
NUSE_MAILBOX_NUMBER * (sizeof (ADDR) +1)Panggilan API yang belum direalisasi
Keempat panggilan utilitas yang dapat ditemukan di Nucleus RTOS tidak diterapkan di Nucleus SE.
Buat Kotak Surat
Panggilan layanan API ini membuat kotak surat. Nucleus SE tidak membutuhkannya, karena kotak surat dibuat secara statis.
Prototipe panggilan layanan:
STATUS NU_Create_Mailbox (NU_MAILBOX * kotak surat, nama CHAR *, suspend_type OPS TIDAK TANDA TANDA);Parameter:
kotak surat - penunjuk ke unit kontrol kotak surat yang disediakan oleh pengguna; Digunakan untuk mengelola kotak surat di panggilan API lainnya
name - penunjuk ke nama 7-karakter kotak surat dengan nol terminasi byte;
suspend_type - Menunjukkan prinsip penangguhan tugas di kotak surat. Ini dapat mengambil nilai
NU_FIFO dan
NU_PRIORITY , yang berarti prinsip FIFO (First-In-First-Out) atau prinsip prioritas penangguhan tugas masing-masing.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_MAILBOX - null pointer ke unit kontrol kotak surat (
NULL ), atau pointer sudah digunakan;
NU_INVALID_SUSPEND - parameter
suspend_type tidak valid.
Hapus kotak surat
Panggilan layanan API ini menghapus kotak surat yang dibuat sebelumnya. Nucleus SE tidak memerlukan ini, karena kotak surat dibuat secara statis dan tidak dapat dihapus.
Prototipe panggilan layanan:
STATUS NU_Delete_Mailbox (NU_MAILBOX * kotak surat);Parameter:
kotak surat - penunjuk ke unit kontrol kotak surat.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_MAILBOX - penunjuk kotak surat tidak valid.
Petunjuk Kotak Surat
Panggilan API ini membuat daftar pointer berurutan ke semua kotak surat di sistem. Nucleus SE tidak membutuhkannya, karena kotak surat diidentifikasi oleh indeks sederhana, bukan pointer.
Prototipe panggilan layanan:
NU_Mailbox_Pointers UNSIGNED (NU_MAILBOX ** pointer_list, maksimum_pointers UNSIGNED);Parameter:
pointer_list - pointer ke array pointer
NU_MAILBOX ; array ini akan diisi dengan pointer ke kotak surat yang dibuat dalam sistem;
maximum_pointers - jumlah maksimum pointer dalam array.
Nilai pengembalian:
Jumlah pointer
NU_MAILBOX dalam array.
Rekam pesan di kotak surat untuk pengiriman ke semua penerima
Panggilan layanan ini mengirim pesan ke semua tugas yang menunggu pesan dari kotak surat tertentu. Dalam Nucleus SE, panggilan utilitas ini tidak diterapkan, karena akan menambah kompleksitas yang tidak perlu.
Prototipe panggilan layanan:
STATUS NU_Broadcast_To_Mailbox (NU_MAILBOX * kotak surat, pesan VOID *, ditangguhkan tanpa ditandatangani);Parameter:
kotak surat - penunjuk ke unit kontrol kotak surat;
message - penunjuk ke pesan yang dikirimkan;
ditangguhkan - menunjukkan apakah akan menangguhkan tugas panggilan jika kotak surat sudah berisi pesan; dapat berupa
NU_NO_SUSPEND ,
NU_SUSPEND, atau nilai batas waktu.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_MAILBOX - pointer kotak surat tidak valid;
NU_INVALID_POINTER - null pointer ke pesan (
NULL );
NU_INVALID_SUSPEND - upaya untuk menangguhkan dari utas yang tidak terkait tugas;
NU_MAILBOX_FULL - kotak surat sudah berisi pesan;
NU_TIMEOUT - setelah batas waktu habis, kotak surat masih penuh;
NU_MAILBOX_DELETED - Kotak surat dihapus saat tugas ditangguhkan.
NU_MAILBOX_RESET - kotak surat diatur ulang saat tugas ditangguhkan.
Kompatibel dengan RTOS Inti
Seperti semua objek Nucleus SE lainnya, tujuan saya adalah untuk memaksimalkan kompatibilitas kode aplikasi dengan Nucleus RTOS. Kotak surat tidak terkecuali dan, dari sudut pandang pengguna, mereka diimplementasikan dengan cara yang sama seperti di Nucleus RTOS. Ada juga ketidakcocokan tertentu, yang saya anggap dapat diterima mengingat bahwa, sebagai akibatnya, kode akan menjadi lebih mudah dimengerti dan lebih efisien dalam hal jumlah memori yang diperlukan. Jika tidak, panggilan Nucleus RTOS API dapat langsung dipindahkan ke Nucleus SE.
Pengidentifikasi Objek
Dalam Nucleus RTOS, semua objek dijelaskan oleh struktur data (unit kontrol) dari tipe tertentu. Penunjuk ke unit kontrol ini berfungsi sebagai pengidentifikasi untuk kotak surat. Saya memutuskan bahwa dalam Nucleus SE, diperlukan pendekatan yang berbeda untuk penggunaan memori yang efisien: semua objek kernel dijelaskan oleh seperangkat 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_MAILBOX sebagai setara dengan
U8 , variabel (bukan pointer) dari tipe ini berfungsi sebagai pengidentifikasi kotak surat. 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 kotak surat. Nama-nama ini hanya digunakan untuk debugging. Saya mengecualikan mereka dari Nucleus SE untuk menghemat memori.
Ukuran dan jenis pesan
Dalam Nucleus RTOS, pesan kotak surat terdiri dari empat kata 32-bit. Dalam Nucleus SE, saya memutuskan untuk mengurangi nilai ini menjadi satu variabel tipe
ADDR . Perubahan ini menghasilkan penghematan memori yang signifikan dan mengurangi waktu pelaksanaan tugas. Ini juga menunjukkan bahwa penggunaan kotak surat yang biasa adalah untuk meneruskan informasi dari satu tugas ke tugas lainnya. Ketidakcocokan ini tidak akan menyebabkan masalah besar saat porting aplikasi ke Nucleus RTOS. Nucleus SE dapat dimodifikasi jika diperlukan format pesan yang berbeda.
Panggilan API yang belum direalisasi
Nucleus RTOS mendukung sembilan panggilan kantor kotak surat. Dari jumlah tersebut, empat tidak diimplementasikan dalam Nucleus SE. Rincian dari tantangan ini, serta alasan mengapa mereka dikeluarkan dari Nucleus SE, dijelaskan di atas.
Artikel selanjutnya akan melihat antrian.
Tentang Pengarang: Colin Walls telah bekerja di industri elektronik selama lebih dari tiga puluh tahun, mencurahkan sebagian besar waktunya untuk firmware. Dia sekarang adalah 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.