Antrian diperkenalkan di artikel sebelumnya. Mereka menyediakan cara yang lebih fleksibel untuk menyampaikan pesan sederhana antar tugas daripada kotak surat.
Menggunakan Antrian
Di Nucleus SE, antrian dikonfigurasi pada waktu pembuatan. Mungkin ada maksimum 16 antrian yang dikonfigurasi untuk suatu aplikasi. Jika tidak ada antrian yang dikonfigurasi, tidak ada struktur data atau kode panggilan layanan yang berkaitan dengan antrian yang disertakan dalam aplikasi.
Antrian hanyalah sekumpulan lokasi penyimpanan, masing-masing cukup besar untuk menampung satu item data bertipe ADDR , akses yang dikendalikan sehingga dapat digunakan dengan aman oleh banyak tugas. Tugas dapat menulis ke antrian berulang kali sampai semua lokasi penuh. Tugas dapat dibaca dari antrian dan data biasanya diterima berdasarkan first in first out (FIFO). Mencoba mengirim ke antrean penuh atau membaca dari antrean kosong dapat mengakibatkan kesalahan atau penangguhan tugas, bergantung pada opsi yang dipilih dalam panggilan API dan konfigurasi Nucleus SE.
Antrian dan Pipa
Nucleus SE juga mendukung pipa, yang juga diperkenalkan di artikel sebelumnya dan dibahas secara rinci di artikel mendatang. Perbedaan utama antara antrian dan pipa adalah ukuran pesan. Antrean membawa pesan yang terdiri dari satu ADDR – ini biasanya berupa petunjuk. Sebuah pipa membawa pesan dengan jumlah byte yang berubah-ubah; ukurannya ditetapkan untuk setiap pipa dalam aplikasi dan disetel pada waktu konfigurasi.
Mengonfigurasi Antrian
Jumlah Antrian
Seperti kebanyakan aspek Nucleus SE, konfigurasi antrian terutama dikendalikan oleh #define pernyataan di nuse_config.h . Setelan kuncinya adalah NUSE_QUEUE_NUMBER , yang menentukan berapa banyak antrian yang dikonfigurasi untuk aplikasi. Pengaturan default adalah 0 (yaitu tidak ada antrian yang digunakan) dan Anda dapat mengaturnya ke nilai apa pun hingga 16. Nilai yang salah akan menghasilkan kesalahan waktu kompilasi, yang dihasilkan oleh pengujian di nuse_config_check.h (ini termasuk dalam nuse_config.c dan karenanya dikompilasi dengan modul ini) menghasilkan #error pernyataan sedang dikompilasi.
Memilih nilai bukan nol adalah "master enable" untuk antrian. Ini menghasilkan beberapa struktur data yang didefinisikan dan berukuran sesuai, yang lebih banyak di artikel berikutnya. Ini juga mengaktifkan pengaturan pengaktifan API.
API Diaktifkan
Setiap fungsi API (panggilan layanan) di Nucleus SE memiliki #define enabling yang memungkinkan simbol di nuse_config.h . Untuk antrian, ini adalah:
Secara default, semua ini disetel ke FALSE , sehingga menonaktifkan setiap panggilan layanan dan menghambat penyertaan kode implementasi apa pun. Untuk mengonfigurasi antrean aplikasi, Anda harus memilih panggilan API yang ingin Anda gunakan dan menyetel simbol pengaktifnya ke TRUE .
Berikut ini adalah ekstrak dari file nuse_config.h default.
#define NUSE_QUEUE_NUMBER 0 /* Jumlah antrean di sistem - 0-16 * / / * Layanan call enabler * / # define NUSE_QUEUE_SEND SALAH # define NUSE_QUEUE_RECEIVE SALAH # define NUSE_QUEUE_JAM SALAH # define NUSE_QUEUE_RESET FALSE #define NUSE_QUEUE_INFORMATION FALSE #define NUSE_QUEUE_COUNT FALSE
Kesalahan waktu kompilasi akan terjadi jika fungsi API antrian diaktifkan dan tidak ada antrian yang dikonfigurasi (kecuali untuk NUSE_Queue_Count() yang selalu diizinkan). Jika kode Anda menggunakan panggilan API, yang belum diaktifkan, kesalahan waktu tautan akan terjadi, karena tidak ada kode implementasi yang disertakan dalam aplikasi.
Panggilan Layanan Antrian
Nucleus RTOS mendukung sepuluh panggilan layanan yang berhubungan dengan antrian, yang menyediakan fungsi berikut:
Kirim pesan ke antrean. Diimplementasikan oleh NUSE_Queue_Send() di Nucleus SE.
Terima pesan dari antrian. Diimplementasikan oleh NUSE_Queue_Receive() di Nucleus SE.
Kirim pesan ke bagian depan antrian. Diimplementasikan oleh NUSE_Queue_Jam() di Nucleus SE.
Pulihkan antrean ke status tidak digunakan, tanpa tugas yang ditangguhkan (reset). Diimplementasikan oleh NUSE_Queue_Reset() di Nucleus SE.
Berikan informasi tentang antrian yang ditentukan. Diimplementasikan oleh NUSE_Queue_Information() di Nucleus SE.
Mengembalikan hitungan berapa banyak antrian yang (saat ini) dikonfigurasi untuk aplikasi. Diimplementasikan oleh NUSE_Queue_Count() di Nucleus SE.
Tambahkan antrian baru ke aplikasi (buat). Tidak diimplementasikan di Nucleus SE.
Hapus antrian dari aplikasi (hapus). Tidak diimplementasikan di Nucleus SE.
Kembalikan pointer ke semua antrian (saat ini) dalam aplikasi. Tidak diimplementasikan di Nucleus SE.
Kirim pesan ke semua tugas yang ditangguhkan dalam antrian (siaran). Tidak diimplementasikan di Nucleus SE.
Implementasi dari setiap panggilan layanan ini diperiksa secara mendetail.
Layanan Tulis dan Baca Antrian
Operasi dasar, yang dapat dilakukan pada antrian, adalah menulis data ke antrian – yang kadang-kadang disebut mengirim – dan membaca data darinya – yang juga disebut menerima . Dimungkinkan juga untuk menulis data ke depan antrian – yang juga disebut jamming . Nucleus RTOS dan Nucleus SE masing-masing menyediakan tiga panggilan API dasar untuk operasi ini, yang akan dibahas di sini.
Menulis ke Antrean
Panggilan API Nucleus RTOS untuk menulis ke antrian sangat fleksibel, memungkinkan Anda untuk menangguhkan tanpa batas waktu, atau dengan batas waktu, jika operasi tidak dapat diselesaikan segera; yaitu Anda mencoba menulis ke antrian penuh. Nucleus SE menyediakan layanan yang sama, kecuali penangguhan tugas bersifat opsional dan batas waktu tidak diterapkan.
Nucleus RTOS juga menawarkan fasilitas untuk menyiarkan ke antrian, tetapi ini tidak didukung oleh Nucleus SE. Ini dijelaskan di bawah API yang Tidak Diimplementasikan di artikel berikutnya.
Panggilan Nucleus RTOS API untuk Mengirim ke Antrean
Prototipe panggilan layanan:
STATUS NU_Send_To_Queue(NU_QUEUE *queue, VOID *message, UNSIGNED size, UNSIGNED suspend);
Parameter:
antrian – penunjuk ke blok kontrol antrian yang disediakan pengguna
pesan – penunjuk ke pesan yang akan dikirim
ukuran – jumlah TIDAK TANDA TANDATANGANI elemen data dalam pesan. Jika antrian mendukung pesan dengan panjang variabel, parameter ini harus sama dengan atau kurang dari ukuran pesan yang didukung oleh antrian. Jika antrean mendukung pesan berukuran tetap, parameter ini harus sama persis dengan ukuran pesan yang didukung oleh antrean.
tangguhkan – spesifikasi untuk penangguhan tugas; mungkin NU_NO_SUSPEND atau NU_SUSPEND atau nilai batas waktu
Pengembalian:
NU_SUCCESS – panggilan berhasil diselesaikan
NU_INVALID_QUEUE – penunjuk antrian tidak valid
NU_INVALID_POINTER – penunjuk pesan adalah NULL
NU_INVALID_SIZE – ukuran pesan tidak sesuai dengan ukuran pesan yang didukung oleh antrian
NU_INVALID_SUSPEND – penangguhan dicoba dari utas non-tugas
NU_QUEUE_FULL – antrian penuh dan penangguhan tidak ditentukan
NU_TIMEOUT – antrian masih penuh bahkan setelah ditangguhkan untuk nilai batas waktu yang ditentukan
NU_QUEUE_DELETED – antrian telah dihapus saat tugas ditangguhkan
NU_QUEUE_RESET – antrian disetel ulang saat tugas ditangguhkan
Panggilan API Nucleus SE untuk Mengirim ke Antrean
Panggilan API ini mendukung fungsionalitas utama dari Nucleus RTOS API.
Prototipe panggilan layanan:
STATUS NUSE_Queue_Send(NUSE_QUEUE queue, ADDR *message, U8 suspend);
Parameter:
antrian – indeks (ID) antrian yang akan digunakan
pesan – penunjuk ke pesan yang akan dikirim, yang merupakan variabel tunggal bertipe ADDR
tangguhkan – spesifikasi untuk penangguhan tugas; mungkin NUSE_NO_SUSPEND atau NUSE_SUSPEND
Pengembalian:
NUSE_SUCCESS – panggilan berhasil diselesaikan
NUSE_INVALID_QUEUE – indeks antrian tidak valid
NUSE_INVALID_POINTER – penunjuk pesan adalah NULL
NUSE_INVALID_SUSPEND – penangguhan dicoba dari utas non-tugas atau saat memblokir panggilan API tidak diaktifkan
NUSE_QUEUE_FULL – antrian penuh dan penangguhan tidak ditentukan
NUSE_QUEUE_WAS_RESET – antrian disetel ulang saat tugas ditangguhkan
Implementasi Nucleus SE dari Antrian ASend
Sebagian besar kode NUSE_Queue_Send() Fungsi API – setelah pemeriksaan parameter – dipilih oleh kompilasi bersyarat, bergantung pada apakah dukungan untuk memblokir (penangguhan tugas) panggilan API diaktifkan. Kita akan melihat dua varian secara terpisah di sini.
Jika pemblokiran tidak diaktifkan, kode untuk panggilan API ini cukup sederhana:
if (NUSE_Queue_Items[queue] ==NUSE_Queue_Size[queue]) /* antrian penuh */{ return_value =NUSE_QUEUE_FULL;}else /* elemen antrian tersedia */{ NUSE_Queue_Data[antrian][NUSE_Queue_Head[antrian]++] =*pesan; if (NUSE_Queue_Head[antrian] ==NUSE_Queue_Size[antrian]) { NUSE_Queue_Head[antrian] =0; } NUSE_Queue_Items[antrian]++; return_value =NUSE_SUCCESS;}
Fungsi ini hanya memeriksa apakah ada ruang dalam antrian dan menggunakan NUSE_Queue_Head[] index untuk menyimpan pesan di area data antrian.
Saat pemblokiran diaktifkan, kode menjadi lebih kompleks:
lakukan{ if (NUSE_Queue_Items[queue] ==NUSE_Queue_Size[queue]) /* antrian penuh */ { if (suspend ==NUSE_NO_SUSPEND) { return_value =NUSE_QUEUE_FULL; } else { /* blok tugas */ NUSE_Queue_Blocking_Count[antrian]++; NUSE_Suspend_Task(NUSE_Task_Active, (antrian <<4) | NUSE_QUEUE_SUSPEND); return_value =NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (nilai_pengembalian !=NUSE_SUCCESS) { suspend =NUSE_NO_SUSPEND; } } } else { /* elemen antrian tersedia */ NUSE_Queue_Data[antrian][NUSE_Queue_Head[antrian]++] =*pesan; if (NUSE_Queue_Head[antrian] ==NUSE_Queue_Size[antrian]) { NUSE_Queue_Head[antrian] =0; } NUSE_Queue_Items[antrian]++; if (NUSE_Queue_Blocking_Count[antrian] !=0) { indeks U8; /* memeriksa apakah tugas diblokir pada antrian ini */ NUSE_Queue_Blocking_Count[antrian]--; for (indeks=0; indeks
Beberapa penjelasan tentang kode ini mungkin berguna:
Kode diapit dengan do…sementara loop, yang berlanjut saat parameter suspend memiliki nilai NUSE_SUSPEND .
Jika antrean penuh dan tangguhkan disetel ke NUSE_NO_SUSPEND , panggilan API keluar dengan NUSE_QUEUE_FULL . Jika penangguhan disetel ke NUSE_SUSPEND , tugas ditangguhkan. Saat kembali (yaitu saat tugas dibangunkan), jika nilai yang dikembalikan adalah NUSE_SUCCESS , menunjukkan bahwa tugas dibangunkan karena sebuah pesan telah dibaca (sebagai lawan dari reset antrian) kode loop kembali ke atas.
Jika antrian tidak penuh, pesan yang diberikan disimpan menggunakan NUSE_Queue_Head[] indeks untuk menyimpan pesan di area data antrian. Pemeriksaan dilakukan pada apakah ada tugas yang ditangguhkan (menunggu untuk diterima) pada antrian. Jika ada tugas yang menunggu, yang pertama dibangunkan. penangguhan variabel disetel ke NUSE_NO_SUSPEND dan panggilan API keluar dengan NUSE_SUCCESS .