Semaphore diperkenalkan di artikel sebelumnya. Penggunaan utamanya adalah kontrol akses ke sumber daya.
Menggunakan Semaphore
Di Nucleus SE, semaphore dikonfigurasi pada waktu pembuatan. Mungkin ada maksimal 16 semaphore dikonfigurasi untuk aplikasi. Jika tidak ada semaphore yang dikonfigurasi, tidak ada struktur data atau kode panggilan layanan yang berhubungan dengan semaphore yang disertakan dalam aplikasi.
Semaphore hanyalah penghitung tipe U8 , akses yang dikendalikan sehingga dapat digunakan dengan aman oleh banyak tugas. Sebuah tugas dapat mengurangi (mendapatkan) semaphore dan meningkatkan (melepaskannya). Mencoba mendapatkan semaphore yang memiliki nilai nol dapat mengakibatkan kesalahan atau penangguhan tugas, tergantung pada opsi yang dipilih dalam panggilan API dan konfigurasi Nucleus SE.
Mengonfigurasi Semaphore
Jumlah Semafor
Seperti kebanyakan aspek Nucleus SE, konfigurasi semaphore terutama dikendalikan oleh #define pernyataan di nuse_config.h . Setelan kuncinya adalah NUSE_SEMAPHORE_NUMBER , yang menentukan berapa banyak semaphore yang dikonfigurasi untuk aplikasi. Pengaturan default adalah 0 (yaitu tidak ada semaphore 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 #kesalahan pernyataan sedang dikompilasi.
Memilih nilai bukan nol adalah "master enable" untuk semaphore. Ini menghasilkan beberapa struktur data yang ditentukan dan ukurannya sesuai, yang lebih lanjut di artikel ini. 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 semaphore, ini adalah:
Secara default, semua ini disetel ke FALSE , sehingga menonaktifkan setiap panggilan layanan dan menghambat penyertaan kode implementasi apa pun. Untuk mengonfigurasi semafor untuk aplikasi, Anda harus memilih panggilan API yang ingin Anda gunakan dan menyetel simbol pengaktifnya ke TRUE .
Berikut ini adalah ekstrak dari nuse_config.h default berkas.
#define NUSE_SEMAPHORE_NUMBER 0 /* Jumlah semaphore dalam sistem - 0-16 */#define NUSE_SEMAPHORE_OBTAIN FALSE /* Service call enabler */#define NUSE_SEMAPHORE_RELEASE FALSE /* Service call enabler */#define NUSE_SEMAPHORE Service pengaktif panggilan */#define NUSE_SEMAPHORE_INFORMATION FALSE /* Pengaktif panggilan layanan */#define NUSE_SEMAPHORE_COUNT FALSE /* Pengaktif panggilan layanan */
Kesalahan waktu kompilasi akan terjadi jika fungsi API semaphore diaktifkan dan tidak ada semaphore yang dikonfigurasi (kecuali untuk NUSE_Semaphore_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 Semaphore
Nucleus RTOS mendukung delapan panggilan layanan yang berhubungan dengan semaphore, yang menyediakan fungsionalitas berikut:
Dapatkan semaphore. Diimplementasikan oleh NUSE_Semaphore_Obtain() di Nucleus SE.
Lepaskan semaphore. Diimplementasikan oleh NUSE_Semaphore_Release() di Nucleus SE.
Kembalikan semaphore ke status tidak digunakan, tanpa tugas yang ditangguhkan (reset). Diimplementasikan oleh NUSE_Semaphore_Reset() di Nucleus SE.
Berikan informasi tentang semaphore yang ditentukan. Diimplementasikan oleh NUSE_Semaphore_Information() di Nucleus SE.
Mengembalikan hitungan berapa banyak semaphore yang (saat ini) dikonfigurasi untuk aplikasi. Diimplementasikan oleh NUSE_Semaphore_Count() di Nucleus SE.
Tambahkan semaphore baru ke aplikasi (buat). Tidak diimplementasikan di Nucleus SE.
Hapus semaphore dari aplikasi (hapus). Tidak diimplementasikan di Nucleus SE.
Kembalikan pointer ke semua semaphore (saat ini) dalam aplikasi. Tidak diimplementasikan di Nucleus SE.
Implementasi dari setiap panggilan layanan ini diperiksa secara mendetail.
Semaphore Dapatkan dan Rilis Layanan
Operasi dasar, yang dapat dilakukan pada semaphore, adalah memperoleh (mengurangi) dan melepaskan (menambah) itu. Nucleus RTOS dan Nucleus SE masing-masing menyediakan dua panggilan API dasar untuk operasi ini, yang akan dibahas di sini.
Mendapatkan Semafor
Panggilan API Nucleus RTOS untuk mendapatkan semaphore sangat fleksibel, memungkinkan Anda untuk menangguhkan tanpa batas waktu, atau dengan batas waktu, jika operasi tidak dapat diselesaikan segera; yaitu Anda mencoba untuk mendapatkan semaphore yang saat ini memiliki nilai nol. Nucleus SE menyediakan layanan yang sama, kecuali penangguhan tugas bersifat opsional dan batas waktu tidak diterapkan.
Panggilan Nucleus RTOS API untuk Mendapatkan Semaphore
Prototipe panggilan layanan:
STATUS NU_Obtain_Semaphore(NU_SEMAPHORE *semaphore, TIDAK TANDA TANGAN ditangguhkan);
Parameter:
semafor – penunjuk ke blok kontrol semaphore yang disediakan pengguna
tangguhkan – spesifikasi untuk penangguhan tugas; mungkin NU_NO_SUSPEND atau NU_SUSPEND atau nilai batas waktu
Pengembalian:
NU_SUCCESS – panggilan berhasil diselesaikan
NU_UNAVAILABLE – semaphore memiliki nilai nol
NU_INVALID_SEMAPHORE – penunjuk semaphore tidak valid
NU_INVALID_SUSPEND – penangguhan dicoba dari non-tugas
NU_SEMAPHORE_WAS_RESET – semaphore disetel ulang saat tugas ditangguhkan
Panggilan Nucleus SE API untuk Mendapatkan Semaphore
Panggilan API ini mendukung fungsionalitas utama dari Nucleus RTOS API.
Prototipe panggilan layanan:
STATUS NUSE_Semaphore_Obtain(NUSE_SEMAPHORE semaphore, U8 ditangguhkan);
Parameter:
semafor – indeks (ID) semaphore yang akan digunakan
tangguhkan – spesifikasi untuk penangguhan tugas; mungkin NUSE_NO_SUSPEND atau NUSE_SUSPEND
Pengembalian:
NUSE_SUCCESS – panggilan berhasil diselesaikan
NUSE_UNAVAILABLE – semaphore memiliki nilai nol
NUSE_INVALID_SEMAPHORE – indeks semaphore tidak valid
NUSE_INVALID_SUSPEND – penangguhan dicoba dari utas non-tugas atau saat memblokir panggilan API tidak diaktifkan
NUSE_SEMAPHORE_WAS_RESET – semaphore disetel ulang saat tugas ditangguhkan
Implementasi Nucleus SE dari Obtain Semaphore
Sebagian besar kode NUSE_Semaphore_Obtain() 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, logika untuk panggilan API ini cukup sederhana:
if (NUSE_Semaphore_Counter[semaphore] !=0) /* semaphore tersedia */{ NUSE_Semaphore_Counter[semaphore]--; return_value =NUSE_SUCCESS;}else /* semaphore tidak tersedia */{ return_value =NUSE_UNAVAILABLE;}
Nilai semaphore diuji dan, jika bukan nol, dikurangi.
Saat pemblokiran diaktifkan, logikanya menjadi lebih kompleks:
lakukan{ if (NUSE_Semaphore_Counter[semaphore] !=0) /* semaphore tersedia */ { NUSE_Semaphore_Counter[semaphore]--; return_value =NUSE_SUCCESS; menangguhkan =NUSE_NO_SUSPEND; } else /* semaphore tidak tersedia */ { if (suspend ==NUSE_NO_SUSPEND) { return_value =NUSE_UNAVAILABLE; } else { /* blok tugas */ NUSE_Semaphore_Blocking_Count[semaphore]++; NUSE_Suspend_Task(NUSE_Task_Active, semaphore <<4) | NUSE_SEMAPHORE_SUSPEND); return_value =NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (nilai_pengembalian !=NUSE_SUCCESS) { suspend =NUSE_NO_SUSPEND; } } }} while (suspend ==NUSE_SUSPEND);
Beberapa penjelasan tentang kode ini mungkin berguna:
Kode diapit dengan do…sementara loop, yang berlanjut saat parameter suspend memiliki nilai NUSE_SUSPEND .
Jika semaphore bukan nol, maka akan dikurangi. penangguhan variabel disetel ke NUSE_NO_SUSPEND dan panggilan API keluar dengan NUSE_SUCCESS .
Jika semaphore adalah nol dan suspend disetel ke NUSE_NO_SUSPEND , panggilan API keluar dengan NUSE_UNAVAILBLE . 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 semaphore telah dirilis (sebagai lawan dari reset semaphore) kode loop kembali ke atas.
Melepaskan Semafor
Panggilan Nucleus RTOS API untuk merilis semaphore cukup sederhana; semaphore bertambah dan sukses dilaporkan. Nucleus SE menyediakan layanan yang sama, kecuali pemeriksaan luapan dilakukan.
Panggilan Nucleus RTOS API untuk Merilis Semaphore
Prototipe panggilan layanan:
STATUS NU_Release_Semaphore(NU_SEMAPHORE *semaphore);
Parameter:
semafor – penunjuk ke blok kontrol semaphore yang disediakan pengguna
Pengembalian:
NU_SUCCESS – panggilan berhasil diselesaikan
NU_INVALID_SEMAPHORE – penunjuk semaphore tidak valid
Panggilan Nucleus SE API untuk Merilis Semaphore
Panggilan API ini mendukung fungsionalitas utama dari Nucleus RTOS API.
Prototipe panggilan layanan:
STATUS NUSE_Semaphore_Release(NUSE_SEMAPHORE semaphore);
Parameter:
semafor – indeks (ID) semaphore yang akan dirilis
Pengembalian:
NUSE_SUCCESS – panggilan berhasil diselesaikan
NUSE_INVALID_SEMAPHORE – indeks semaphore tidak valid
NUSE_UNAVAILABLE – semaphore memiliki nilai 255 dan tidak dapat ditambah
Implementasi Nucleus SE dari Semaphore Rilis
Kode awal NUSE_Semaphore_Release() Fungsi API – setelah pemeriksaan parameter – adalah umum, apakah pemblokiran tugas diaktifkan atau tidak. Nilai semaphore diperiksa dan, jika kurang dari 255, dikurangi.
Kode lebih lanjut dipilih dengan kompilasi bersyarat, jika dukungan untuk memblokir (penangguhan tugas) panggilan API diaktifkan:
NUSE_CS_Enter();if (NUSE_Semaphore_Counter[semaphore] <255){ NUSE_Semaphore_Counter[semaphore]++; return_value =NUSE_SUCCESS; #if NUSE_BLOCKING_ENABLE if (NUSE_Semaphore_Blocking_Count[semaphore] !=0) { indeks U8; /* memeriksa apakah tugas diblokir */ /* pada semaphore ini */ NUSE_Semaphore_Blocking_Count[semaphore]--; for (indeks=0; indeks
Jika ada tugas yang ditangguhkan pada semaphore ini, yang pertama akan dibangunkan.
Artikel berikutnya akan membahas beberapa panggilan API tambahan yang terkait dengan grup flag peristiwa, bersama dengan struktur data yang relevan.
Colin Walls memiliki pengalaman lebih dari tiga puluh tahun di industri elektronik, sebagian besar didedikasikan untuk perangkat lunak yang disematkan. Sering menjadi presenter di konferensi dan seminar dan penulis berbagai artikel teknis dan dua buku tentang perangkat lunak tertanam, Colin adalah teknolog perangkat lunak tertanam dengan Mentor Embedded [Divisi Perangkat Lunak Tertanam Grafis Mentor], dan berbasis di Inggris. Blog regulernya terletak di:http://blogs.mentor.com/colinwalls. Dia dapat dihubungi melalui email di [email protected]