
Pada artikel ini, kami akan terus mempertimbangkan antrian.
Layanan Antrian Sekunder
Nucleus RTOS memiliki empat panggilan API yang menyediakan fungsi tambahan yang terkait dengan antrian: mengatur ulang antrian, menerima informasi antrian, mendapatkan jumlah antrian dalam suatu aplikasi, dan mendapatkan pointer ke semua antrian dalam suatu aplikasi. Tiga fungsi pertama diimplementasikan dalam Nucleus SE.
Artikel sebelumnya dalam seri:
Artikel # 23. Antrian: pengantar dan layanan dasarArtikel # 22. Kotak Surat: Layanan Tambahan dan Struktur DataArtikel # 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.Reset Antrian
Panggilan API ini mengatur ulang antrian ke kondisi aslinya, yang tidak digunakan. Pesan apa pun yang disimpan dalam antrian akan hilang. Tugas apa pun yang dijeda dalam antrian akan dilanjutkan dengan kode pengembalian
NUSE_QUEUE_WAS_RESET .
Atur Ulang Antrian di Nucleus RTOSPrototipe panggilan layanan:
STATUS NU_Reset_Queue (NU_QUEUE * antrian);Parameter:
queue - pointer ke blok kontrol antrian yang disediakan oleh pengguna.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_QUEUE - penunjuk antrian tidak valid.
Atur Ulang Antrian di Nucleus SEPanggilan utilitas ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
STATUS NUSE_Queue_Reset (antrian NUSE_QUEUE);Parameter:
antrian - indeks (ID) dari antrian yang dibuang.
Nilai pengembalian:
NUSE_SUCCESS - panggilan berhasil diselesaikan;
NUSE_INVALID_QUEUE - indeks antrian tidak valid.
Menerapkan Reset Antrian di Nucleus SEKode fungsi
NUSE_Queue_Reset (setelah memeriksa parameter) cukup sederhana. Indeks kepala dan ekor antrian, serta penghitung pesan dalam antrian, diberi nilai nol.
Jika penguncian tugas diaktifkan, kode tambahan bertanggung jawab untuk mengembalikan tugas yang ditangguhkan:
while (NUSE_Queue_Blocking_Count[queue] != 0) { U8 index; /* check whether any tasks are blocked */ /* on this queue */ for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == queue)) { NUSE_Task_Blocking_Return[index] = NUSE_QUEUE_WAS_RESET; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Queue_Blocking_Count[queue]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif
Setiap tugas yang dijeda dalam antrian diberi status "siap" dengan kode pengembalian
NUSE_QUEUE_WAS_RESET . Setelah proses ini selesai, jika penjadwal Prioritas digunakan, fungsi
NUSE_Reschedule () dipanggil , karena satu atau lebih tugas dengan prioritas tinggi dapat siap untuk dieksekusi.
Mendapatkan Informasi Antrian
Panggilan layanan ini menyediakan informasi antrian. Implementasi panggilan ini dalam Nucleus SE berbeda dari Nucleus RTOS dalam hal ia mengembalikan lebih sedikit informasi karena penamaan objek, panjang pesan variabel, dan urutan jeda tugas tidak didukung, dan penguncian tugas dapat dinonaktifkan.
Panggilan untuk Informasi Antrian di Nucleus RTOSPrototipe panggilan layanan:
STATUS NU_Queue_Information (NU_QUEUE * antrian, CHAR * nama, VOID ** start_address, UNSIGNED * queue_size, UNSIGNED * tersedia, pesan UNSIGNED *, OPSI * message_type, UNSIGNED * message_size, OPTION * suspend_type, UNDKA_taskded_t_taskht_t_t_t_type, tanpa tanda kutip)Parameter:
queue - pointer ke blok kontrol antrian yang disediakan oleh pengguna;
name - penunjuk ke wilayah 8 karakter untuk nama pesan dalam antrian;
start_address - pointer ke pointer ke mana alamat awal area data antrian akan ditulis;
queue_size - pointer ke variabel untuk menyimpan jumlah elemen
UNSIGNED dalam antrian;
available - pointer ke variabel untuk menyimpan jumlah elemen
UNSIGNED yang tersedia dalam antrian;
pesan - penunjuk ke variabel untuk menyimpan jumlah pesan saat ini dalam antrian;
message_type - pointer ke variabel untuk menyimpan jenis pesan yang didukung oleh antrian. Nilai yang valid adalah
NU_FIXED_SIZE dan
NU_VARIABLE ;
message_size - pointer ke variabel untuk menyimpan jumlah elemen data
TANDA TANGAN di setiap pesan dari antrian. Jika antrian mendukung pesan panjang variabel, nomor ini menunjukkan panjang pesan maksimum;
suspend_type - pointer ke variabel untuk menyimpan jenis penangguhan tugas. Nilai yang valid adalah
NU_FIFO dan
NU_PRIORITY ;
task_waiting - pointer ke variabel untuk menyimpan jumlah tugas yang ditangguhkan dalam antrian ini;
first_task - penunjuk ke penunjuk tugas, tempat penunjuk tugas yang ditangguhkan pertama kali ditempatkan.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_QUEUE - penunjuk antrian tidak valid.
Panggilan untuk Informasi Antrian di Nucleus SEPanggilan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
STATUS NUSE_Queue_Information (NUSE_QUEUE antrian, ADDR * start_address, U8 * queue_size, U8 * tersedia, pesan U8 *, U8 * tugas_menunggu, NUSE_TASK * first_task);Parameter:
antrian - indeks antrian tentang informasi mana yang diminta;
start_address - penunjuk ke variabel tipe
ADDR , yang akan menyimpan alamat awal area data antrian;
queue_size - pointer ke variabel tipe
U8 , yang akan menyimpan jumlah total pesan yang bisa masuk dalam antrian;
tersedia - pointer ke variabel tipe
U8 , yang akan menyimpan jumlah tempat bebas dalam antrian;
messages - penunjuk ke variabel tipe
U8 , yang akan menyimpan jumlah pesan saat ini dalam antrian;
task_waiting - pointer ke variabel di mana jumlah tugas yang ditangguhkan pada antrian ini akan disimpan (tidak ada yang dikembalikan jika penguncian tugas dinonaktifkan);
first_task - pointer ke variabel dari tipe
NUSE_TASK di mana indeks tugas yang ditangguhkan pertama akan disimpan (tidak ada yang dikembalikan jika kunci tugas dinonaktifkan).
Nilai pengembalian:
NUSE_SUCCESS - panggilan berhasil diselesaikan;
NUSE_INVALID_QUEUE - indeks antrian tidak valid;
NUSE_INVALID_POINTER - satu atau beberapa parameter pointer salah.
Menerapkan Tampilan Informasi Antrian di Nucleus SEMenerapkan panggilan API ini cukup sederhana:
*start_address = NUSE_Queue_Data[queue]; *queue_size = NUSE_Queue_Size[queue]; *available = NUSE_Queue_Size[queue] - NUSE_Queue_Items[queue]; *messages = NUSE_Queue_Items[queue]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Queue_Blocking_Count[queue]; if (NUSE_Queue_Blocking_Count[queue] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == queue)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif
Fungsi mengembalikan status antrian. Kemudian, jika penguncian tugas diaktifkan, jumlah tugas yang tertunda dan indeks yang pertama dikembalikan (jika tidak, kedua parameter ditetapkan ke 0).
Mendapatkan jumlah antrian
Panggilan utilitas ini mengembalikan jumlah antrian yang dikonfigurasi dalam aplikasi. Dalam Nucleus RTOS, jumlah mereka dapat berubah seiring waktu, dan nilai kembali akan menunjukkan jumlah antrian saat ini. Dalam Nucleus SE, nilai kembali diatur selama fase build dan tidak dapat diubah.
Memanggil Penghitung Antrian di Nucleus RTOSPrototipe panggilan layanan:
NU_Established_Queues (VOID) UNSIGNED;Parameter:
Tidak ada.
Nilai pengembalian:
Jumlah antrian yang dibuat dalam sistem.
Memanggil Penghitung Antrian di Nucleus SEPanggilan API ini mendukung fungsionalitas inti API Nucleus RTOS.
Prototipe panggilan layanan:
U8 NUSE_Queue_Count (batal);Parameter:
Tidak ada.
Nilai pengembalian:
Jumlah antrian yang dikonfigurasi dalam aplikasi.
Menerapkan Penghitung Antrian di Nucleus SEImplementasi panggilan API ini sangat sederhana: nilai simbol
#define NUSE_QUEUE_NUMBER dikembalikan .
Struktur data
Antrian menggunakan lima atau enam struktur data (baik dalam RAM atau ROM), yang merupakan kumpulan tabel (seperti objek Nucleus SE lainnya), jumlah dan ukurannya sesuai dengan jumlah antrian dalam aplikasi dan parameter yang dipilih.
Data kernel dalam RAM
Data ini memiliki struktur sebagai berikut:
NUSE_Queue_Head [] adalah array pointer dari tipe
U8 , memiliki satu entri untuk setiap antrian yang dikonfigurasi, dan menunjuk ke kepala antrian pesan. Digunakan sebagai indeks alamat di
NUSE_Queue_Data [] (lihat di bawah);
NUSE_Queue_Tail [] adalah larik tipe
U8 , memiliki satu entri untuk setiap antrian yang dikonfigurasi dalam aplikasi, dan menunjuk ke ujung antrian pesan. Digunakan sebagai indeks alamat di
NUSE_Queue_Data [] (lihat di bawah);
NUSE_Queue_Items [] adalah larik tipe
U8 , memiliki satu entri untuk setiap antrian yang dikonfigurasi, dan merupakan penghitung pesan dalam antrian. Data ini dapat dianggap berlebihan, karena nilai-nilai ini dapat diperoleh melalui indeks awal dan akhir antrian, namun, menyimpan penghitung menyederhanakan kode;
NUSE_Queue_Blocking_Count [] - array tipe
U8 ini berisi penghitung jumlah tugas yang ditangguhkan pada setiap antrian. Array ini hanya dibuat jika dukungan kunci tugas diaktifkan.
Struktur data ini diinisialisasi ke nol oleh fungsi
NUSE_Init_Queue () ketika Nucleus SE dimulai. Ini logis, karena semua antrian dibuat kosong (tidak digunakan).
Berikut ini adalah definisi dari struktur ini dalam file
nuse_init.c :
RAM U8 NUSE_Queue_Head[NUSE_QUEUE_NUMBER]; RAM U8 NUSE_Queue_Tail[NUSE_QUEUE_NUMBER]; RAM U8 NUSE_Queue_Items[NUSE_QUEUE_NUMBER]; #if NUSE_BLOCKING_ENABLE RAM U8 NUSE_Queue_Blocking_Count[NUSE_QUEUE_NUMBER]; #endif
Data pengguna RAM
Pengguna bertanggung jawab untuk menyediakan area RAM untuk menyimpan setiap antrian. Ukuran area ini harus berisi larik jenis
ADDR , di mana setiap catatan sesuai dengan satu pesan dalam antrian
Data ROM
Data ini memiliki struktur sebagai berikut:
NUSE_Queue_Data [] - larik jenis
ADDR , memiliki satu entri untuk setiap antrian yang dikonfigurasi dan menunjuk ke area data antrian (lihat. Data RAM pengguna);
NUSE_Queue_Size [] - larik tipe
U8 , memiliki satu entri untuk setiap antrian yang dikonfigurasi dan menunjukkan jumlah maksimum pesan yang dapat diterima setiap antrian.
Struktur data ini dideklarasikan dan diinisialisasi (secara statis) dalam file
nuse_config.c :
ROM ADDR *NUSE_Queue_Data[NUSE_QUEUE_NUMBER] = { /* addresses of queue data areas ------ */ }; ROM U8 NUSE_Queue_Size[NUSE_QUEUE_NUMBER] = { /* queue sizes ------ */ };
Jumlah memori untuk antrian
Seperti semua objek kernel Nucleus SE, jumlah memori yang dibutuhkan untuk antrian mudah diprediksi.
Jumlah data dalam ROM (dalam byte) untuk semua antrian dalam aplikasi dapat dihitung sebagai berikut:
NUSE_QUEUE_NUMBER * (sizeof (ADDR) + 1)Jumlah data kernel dalam RAM (dalam byte) untuk semua antrian dalam aplikasi dengan penguncian tugas yang diaktifkan dihitung sebagai berikut:
NUSE_QUEUE_NUMBER * 3Jika kunci dinonaktifkan:
NUSE_QUEUE_NUMBER * 4Jumlah data pengguna dalam RAM (dalam byte) untuk antrian dengan indeks
antrian :
NUSE_Queue_Size [antrian] * sizeof (ADDR)Panggilan API yang belum direalisasi
Empat panggilan API yang dapat ditemukan di Nucleus RTOS tidak diterapkan di Nucleus SE:
Pembuatan antrian
Panggilan API ini membuat antrian; di Nucleus SE, ini tidak perlu, karena antrian dibuat secara statis.
Prototipe panggilan layanan:
STATUS NU_Create_Queue (NU_QUEUE * antrian, char * nama, VOID * start_address, queue_size TANDA, OPTION message_type, message_size TANDA TANGAN, message_size TANDA TANGAN, OPTION suspend_type);Parameter:
queue - penunjuk ke unit kontrol yang disediakan oleh pengguna, digunakan untuk mengelola antrian dalam panggilan API lainnya;
name - pointer ke nama antrian 7 karakter dengan byte terminasi nol;
start_address - alamat awal antrian;
message_type - jenis pesan yang didukung oleh antrian. Itu dapat mengambil nilai
NU_FIXED_SIZE atau
NU_VARIABLE_SIZE ;
message_size - jika antrian mendukung pesan dengan panjang tetap, parameter ini menetapkan panjang pasti setiap pesan, jika tidak, antrian mendukung pesan dengan panjang variabel, nilai ini adalah panjang pesan maksimum;
suspend_type - Menentukan jenis tugas yang ditangguhkan dalam antrian. 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_QUEUE - null pointer ke blok kontrol antrian (
NULL ), atau pointer sudah digunakan;
NU_INVALID_MEMORY - area memori tidak valid yang ditentukan dalam
start_address ;
NU_INVALID_MESSAGE - parameter
message_type tidak valid;
NU_INVALID_SIZE - antrian tidak mendukung pesan dengan panjang ini, atau ukuran antrian dan / atau panjang pesan adalah 0;
NU_INVALID_SUSPEND - parameter
suspend_type tidak valid.
Hapus antrian
Panggilan API ini menghapus antrian yang dibuat sebelumnya. Nucleus SE tidak memerlukan ini karena antrian dibuat secara statis dan tidak dapat dihapus.
Prototipe panggilan layanan:
STATUS NU_Delete_Queue (NU_QUEUE * antrian);Parameter:
queue - pointer ke blok kontrol antrian.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_QUEUE - penunjuk antrian tidak valid.
Pointer Antrian
Panggilan API ini membuat daftar pointer berurutan untuk semua antrian dalam sistem. Nucleus SE tidak memerlukan ini karena antrian diidentifikasi menggunakan indeks sederhana, bukan pointer.
Prototipe panggilan layanan:
NU_Queue_Pointers TIDAK DITANDATANGANI (NU_QUEUE ** pointer_list, maksimum_pointers UNSIGNED);Parameter:
pointer_list - pointer ke array pointer
NU_QUEUE . Array ini akan diisi dengan pointer ke antrian yang dibuat dalam sistem;
maximum_pointers - jumlah maksimum pointer dalam array.
Nilai pengembalian:
Jumlah
NU_QUEUE pointer dalam array.
Antrian (Siaran ke Antrian)
Panggilan API ini meneruskan pesan ke semua tugas yang ditangguhkan dalam antrian yang sedang menunggu pesan dari antrian yang ditentukan. Fitur ini tidak diterapkan di Nucleus SE karena menambah redundansi.
Prototipe panggilan layanan:
STATUS NU_Broadcast_To_Queue (NU_QUEUE * antrian, pesan VOID *, ukuran UNSIGNED, suspend UNSIGNED);Parameter:
queue - pointer ke blok kontrol antrian;
message - penunjuk ke pesan yang dikirimkan;
size - jumlah elemen
TANDA TANGAN dalam pesan. Jika antrian mendukung pesan panjang variabel, parameter ini harus sama dengan atau kurang dari panjang pesan yang didukung oleh antrian. Jika antrian mendukung pesan dengan panjang tetap, parameter ini harus sama dengan panjang pesan yang didukung oleh antrian;
suspen - menunjukkan apakah akan menunda tugas panggilan jika antrian sudah penuh. Ini bisa berupa
NU_NO_SUSPEND ,
NU_SUSPEND, atau nilai batas waktu.
Nilai pengembalian:
NU_SUCCESS - panggilan berhasil diselesaikan;
NU_INVALID_QUEUE - penunjuk antrian tidak valid;
NU_INVALID_POINTER - null pointer ke pesan (
NULL );
NU_INVALID_SIZE - panjang pesan yang ditentukan tidak kompatibel dengan panjang yang ditentukan saat membuat antrian;
NU_INVALID_SUSPEND - berupaya menjeda tugas dari utas yang tidak terkait dengan tugas;
NU_QUEUE_FULL - tidak ada cukup ruang dalam antrian untuk pesan;
NU_TIMEOUT - antrian masih penuh setelah batas waktu berakhir;
NU_QUEUE_DELETED - antrian dihapus saat tugas ditangguhkan;
NU_QUEUE_RESET - Antrian 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. Antrian tidak terkecuali dan, dari sudut pandang pengguna, mereka diimplementasikan dengan cara yang sama seperti pada Nucleus RTOS. Ada juga ketidakcocokan tertentu, yang saya anggap dapat diterima, mengingat bahwa sebagai hasilnya, kode tersebut akan menjadi lebih mudah dimengerti dan lebih efisien dalam hal jumlah memori yang diperlukan. Jika tidak, panggilan Nucleus RTOS API dapat diangkut hampir secara langsung ke Nucleus SE.
Pengidentifikasi Objek
Dalam Nucleus RTOS, semua objek dijelaskan oleh struktur data (unit kontrol) yang memiliki tipe data tertentu. Penunjuk ke unit kontrol ini adalah pengidentifikasi antrian. 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_QUEUE sebagai setara dengan
U8 , variabel (bukan pointer) dari tipe ini berfungsi sebagai pengidentifikasi antrian. 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 antrian. Nama-nama ini hanya digunakan untuk debugging. Saya mengecualikan mereka dari Nucleus SE untuk menghemat memori.
Ukuran dan jenis pesan
Dalam Nucleus RTOS, antrian dapat dikonfigurasi untuk memproses pesan yang terdiri dari sejumlah elemen yang
tidak ditandatangani . Dalam Nucleus SE, Antrian disederhanakan dan hanya mendukung pesan jenis
ADDR tunggal. Saluran data Nucleus SE sedikit lebih fleksibel dan dapat menjadi alternatif yang berguna untuk antrian dalam beberapa kasus. Saluran akan dibahas dalam dua artikel berikutnya dari seri ini.
Nucleus SE juga mendukung antrian pesan panjang variabel, yang hanya menentukan panjang pesan maksimum selama pembuatan. Panjang pesan variabel tidak didukung oleh Nucleus SE
Ukuran Antrian
Dalam Nucleus SE, jumlah maksimum pesan dalam antrian adalah 256, karena semua variabel dan konstanta bertipe
U8 . Nucleus RTOS tidak memiliki batasan seperti itu.
Panggilan API yang belum direalisasi
Nucleus RTOS mendukung sepuluh panggilan manajemen antrian. Dari jumlah tersebut, empat tidak diimplementasikan dalam Nucleus SE. Detail panggilan ini, serta alasan keputusan semacam itu, dapat ditemukan di artikel di atas, di bagian "Panggilan API yang Tidak Direalisasi".
Artikel selanjutnya akan membahas saluran transmisi data.
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.