Seluruh kebenaran tentang RTOS. Artikel # 33. Menggunakan Sistem Operasi Real-Time Nucleus SE

Sejauh ini dalam seri artikel ini, kami telah melihat fitur apa yang disediakan Nucleus SE. Sekarang saatnya untuk melihat bagaimana itu dapat digunakan dalam aplikasi firmware nyata.



Artikel sebelumnya dalam seri:
Artikel # 32. Migrasi SE Inti: Fitur dan Kompatibilitas yang Tidak Direalisasikan
Artikel # 31. Diagnostik dan pengecekan kesalahan RTOS
Artikel # 30. Inisialisasi Nucleus SE dan Prosedur Memulai
Artikel # 29. Gangguan pada Nucleus SE
Artikel # 28. Pengatur waktu perangkat lunak
Artikel # 27. Waktu sistem
Artikel # 26. Saluran: layanan tambahan dan struktur data
Artikel # 25. Saluran Data: Pengantar dan Layanan Dasar
Artikel # 24. Antrian: layanan tambahan dan struktur data
Artikel # 23. Antrian: pengantar dan layanan dasar
Artikel # 22. Kotak Surat: Layanan Tambahan dan Struktur Data
Artikel # 21. Kotak Surat: Pengantar dan Layanan Dasar
Artikel # 20. Semaphores: Layanan Tambahan dan Struktur Data
Artikel # 19. Semaphores: pengantar dan layanan dasar
Artikel # 18. Grup Bendera Acara: Layanan Pembantu dan Struktur Data
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.

Apa itu Nucleus SE?


Kita tahu bahwa Nucleus SE adalah inti dari sistem operasi waktu-nyata, tetapi Anda perlu memahami bagaimana hal itu sesuai dengan aplikasi lainnya. Dan itu hanya cocok, karena tidak seperti sistem operasi desktop (misalnya, Windows), aplikasi tidak dimulai pada Nucleus SE; kernel hanyalah bagian dari program yang berjalan pada perangkat tertanam. Ini adalah kasus penggunaan yang paling umum untuk RTOS.

Dari sudut pandang tingkat tinggi, aplikasi tertanam adalah semacam kode yang dimulai ketika CPU dimulai. Dalam hal ini, lingkungan perangkat keras dan perangkat lunak diinisialisasi, dan kemudian fungsi main () dipanggil, yang meluncurkan kode aplikasi utama.

Saat menggunakan Nucleus SE (dan banyak kernel serupa lainnya), perbedaannya adalah bahwa fungsi main () adalah bagian dari kode kernel. Fungsi ini hanya menginisialisasi struktur data kernel, dan kemudian memanggil scheduler, yang mengarah pada peluncuran kode aplikasi (tugas). Pengguna dapat menambahkan kode inisialisasi asli ke fungsi utama () .

Nucleus SE juga mencakup serangkaian fungsi - antarmuka pemrograman aplikasi (API) yang menyediakan serangkaian fungsi seperti komunikasi dan sinkronisasi tugas, bekerja dengan penghitung waktu, alokasi memori, dll. Semua fungsi API dijelaskan sebelumnya dalam artikel dalam seri ini.

Semua perangkat lunak Nucleus SE disediakan sebagai kode sumber (terutama dalam bahasa C). Untuk mengkonfigurasi kode sesuai dengan persyaratan aplikasi tertentu, kompilasi bersyarat digunakan. Ini dijelaskan secara rinci dalam artikel ini di bagian Konfigurasi.

Setelah kode dikompilasi, modul objek Nucleus SE yang terkait dikaitkan dengan modul kode aplikasi, menghasilkan gambar biner tunggal, yang biasanya ditempatkan dalam memori flash perangkat tertanam. Hasil dari pengikatan statis ini adalah bahwa semua informasi simbolik tetap tersedia baik dari kode aplikasi dan kode kernel. Ini berguna untuk debugging, namun diperlukan kehati-hatian untuk menghindari penyalahgunaan data Nucleus SE.

Dukungan CPU dan alat


Karena Nucleus SE datang sebagai kode sumber, itu harus portabel. Namun, kode berjalan pada tingkat rendah (ketika menggunakan penjadwal di mana pengalihan konteks diperlukan, yaitu, selain dari Run to Completion), tidak dapat sepenuhnya independen dari bahasa assembly. Saya meminimalkan ketergantungan ini, dan untuk porting ke pemrograman tingkat rendah CPU baru hampir tidak diperlukan. Menggunakan seperangkat alat pengembangan baru (compiler, assembler, linker, dll.) Juga dapat menyebabkan masalah porting.

Menyiapkan aplikasi Nucleus SE


Kunci untuk penggunaan Nucleus SE yang efisien adalah pengaturan yang tepat. Mungkin terlihat rumit, tetapi pada kenyataannya, semuanya cukup logis dan hanya membutuhkan pendekatan sistematis. Hampir semua konfigurasi dilakukan dengan mengedit dua file: nuse_config.h dan nuse_config.c .

Pengaturan Nuse_config.h


File ini hanyalah serangkaian karakter dari direktif #define , yang diberi nilai yang sesuai untuk mendapatkan konfigurasi kernel yang diperlukan. Dalam file nuse_config.h, secara default, semua karakter ada, tetapi mereka diberikan pengaturan minimum.

Penghitung Objek
Jumlah objek kernel dari setiap jenis diatur oleh nilai simbol dari formulir NUSE_SEMAPHORE_NUMBER . Untuk sebagian besar objek, nilai ini dapat bervariasi dari 0 hingga 15. Tugas adalah pengecualian, harus ada setidaknya satu. Sinyal, pada kenyataannya, bukan objek independen, karena mereka terkait dengan tugas dan dihidupkan dengan menetapkan NUSE_SIGNAL_SUPPOR T ke TRUE .

Penggerak fungsi API
Setiap fungsi Nucleus SE API dapat diaktifkan secara terpisah dengan menetapkan simbol yang namanya cocok dengan nama fungsi (misalnya, NUSE_PIPE_JAM ) ke TRUE . Ini mengarah ke pencantuman kode fungsi dalam aplikasi.

Pilihan dan pengaturan penjadwal
Nucleus SE mendukung empat jenis penjadwal, seperti yang dijelaskan dalam artikel sebelumnya. Penjadwal yang digunakan diatur dengan menetapkan NUSE_SCHEDULER_TYPE ke salah satu nilai berikut: NUSE_RUN_TO_COMPLETION_SCHEDULER , NUSE_TIME_SLICE_SCHEDULER , NUSE_ROUND_ROBIN_SCHEDULER atau NUSE_PRIORITY_SCHEDULER .

Anda dapat mengkonfigurasi parameter penjadwal lainnya:
NUSE_TIME_SLICE_TICKS menunjukkan jumlah ticks per slot untuk penjadwal Time Slice. Jika penjadwal lain digunakan, parameter ini harus ditetapkan ke 0.
NUSE_SCHEDULE_COUNT_SUPPORT dapat disetel ke TRUE atau FALSE untuk mengaktifkan / menonaktifkan mekanisme penghitung penjadwal.
NUSE_SUSPEND_ENABLE memungkinkan penguncian tugas (penangguhan) untuk banyak fungsi API. Ini berarti bahwa panggilan ke fungsi seperti itu dapat menyebabkan penangguhan tugas panggilan hingga sumber daya dirilis. Untuk memilih opsi ini, NUSE_SUSPEND_ENABLE juga harus disetel ke TRUE .

Pilihan lain
Beberapa parameter lain juga dapat diberi nilai TRUE atau FALSE untuk mengaktifkan / menonaktifkan fungsi kernel lainnya:
NUSE_API_PARAMETER_CHECKING menambahkan kode verifikasi parameter panggilan fungsi API. Biasa digunakan untuk debugging.
NUSE_INITIAL_TASK_STATE_SUPPORT menetapkan status awal semua tugas sebagai NUSE_READY atau NUSE_PURE_SUSPEND . Jika parameter ini dinonaktifkan, semua tugas akan memiliki status awal NUSE_READY .
NUSE_SYSTEM_TIME_SUPPORT - dukungan untuk waktu sistem.
NUSE_INCLUDE_EVERYTHING - parameter yang menambahkan jumlah fungsi maksimum ke konfigurasi Nucleus SE. Ini mengarah ke aktivasi semua fungsi opsional dan setiap fungsi API dari objek yang dikonfigurasi. Digunakan untuk dengan cepat membuat konfigurasi Nucleus SE untuk memverifikasi porting baru dari kode kernel.

Pengaturan nuse_config.c


Setelah menentukan konfigurasi kernel di nuse_config.h, perlu menginisialisasi berbagai struktur data yang disimpan dalam ROM. Ini dilakukan dalam file nuse_config.c . Definisi struktur data dikendalikan oleh kompilasi bersyarat, sehingga semua struktur terkandung dalam salinan file nuse_config.c default.

Data tugas
Array NUSE_Task_Start_Address [] harus diinisialisasi dengan nilai alamat mulai dari setiap tugas. Ini biasanya hanya daftar nama fungsi, tanpa tanda kurung. Prototipe fungsi entri tugas juga harus terlihat. Dalam file default, tugas dikonfigurasikan dengan nama NUSE_Idle_Task () , ini dapat diubah ke tugas aplikasi.

Jika Anda menggunakan penjadwal apa pun kecuali Jalankan ke Penyelesaian, setiap tugas memerlukan tumpukannya sendiri. Untuk setiap tumpukan tugas, Anda harus membuat array dalam RAM. Array ini harus bertipe ADDR , dan alamat masing-masing harus disimpan dalam NUSE_Task_Stack_Base [] . Sulit untuk memprediksi ukuran array, jadi lebih baik menggunakan pengukuran (lihat bagian "Debugging" nanti dalam artikel ini). Ukuran setiap larik (yaitu jumlah kata pada tumpukan) harus disimpan dalam NUSE_Task_Stack_Size [] .

Jika suatu fungsi telah diaktifkan untuk menunjukkan status awal tugas (menggunakan parameter NUSE_INITIAL_TASK_STATE_SUPPORT ), larik NUSE_Task_Initial_State [] harus diinisialisasi dengan status NUSE_READY atau NUSE_PURE_SUSPEND .

Data Pool Partisi
Jika setidaknya satu kumpulan partisi dikonfigurasi, sebuah array (tipe U8 ) harus dibuat untuk masing-masingnya dalam ROM. Ukuran array ini dihitung sebagai berikut: (jumlah partisi * (ukuran partisi + 1)). Alamat bagian ini (yaitu, namanya) harus ditetapkan ke elemen NUSE_Part__Pool_Data_Address [] yang sesuai. Untuk setiap kumpulan, jumlah partisi dan ukurannya masing-masing harus ditempatkan di NUSE_Partition_Pool_Partition_Number [] dan NUSE_Partition_Message_Size [] .

Data Antrian
Jika setidaknya satu antrian dikonfigurasi, maka array (dari jenis ADDR ) harus dibuat untuk masing-masing dalam RAM. Ukuran array ini adalah jumlah elemen dalam setiap antrian. Alamat array ini (yaitu, namanya) harus ditetapkan ke elemen NUSE_Queue_Data [] yang sesuai. Ukuran setiap antrian harus ditetapkan untuk elemen NUSE_Queue_Size [] yang sesuai.

Data Link Data
Jika setidaknya satu saluran data dikonfigurasi, sebuah array (bertipe U8 ) harus dibuat dalam RAM untuknya (atau untuk masing-masingnya). Ukuran array ini dihitung sebagai berikut: (ukuran saluran * ukuran pesan di saluran). Alamat array ini (yaitu, namanya) harus ditetapkan ke elemen NUSE_Pipe_Data [] yang sesuai. Untuk setiap saluran, ukuran dan ukuran pesannya harus ditetapkan ke masing-masing elemen NUSE_Pipe_Size [] dan NUSE_Pipe_Message_Size [] yang sesuai .

Data semaphore
Jika setidaknya satu semaphore dikonfigurasikan, array NUSE_Semaphore_Initial_Value [] harus diinisialisasi dengan nilai awal hitung mundur.

Data Pengatur Waktu Aplikasi
Jika setidaknya satu timer dikonfigurasikan, array NUSE_Timer_Initial_Time [] harus diinisialisasi dengan nilai awal dari penghitung. Selain itu, NUSE_Timer_Reschedule_Time [] harus diberi nilai mulai ulang. Nilai-nilai timer ini akan digunakan setelah siklus timer pertama berakhir. Jika nilai restart diatur ke 0, penghitung akan berhenti setelah satu siklus.

Jika dukungan untuk mekanisme penyelesaian akun dikonfigurasikan (dengan mengatur NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT parameter ke TRUE ), dua array lagi harus dibuat. Alamat mekanisme penyelesaian (hanya daftar nama fungsi, tanpa tanda kurung) harus ditempatkan di NUSE_Timer_Expiration_Routine_Address [] . Array NUSE_Timer_Expiration_Routine_Parameter [] harus diinisialisasi dengan nilai-nilai parameter penyelesaian.

API yang mana?


Semua sistem operasi dalam satu bentuk atau lainnya memiliki API (antarmuka pemrograman aplikasi). Nucleus SE tidak terkecuali, dan fungsi-fungsi yang membentuk API telah dijelaskan secara rinci dalam seri artikel ini.

Mungkin tampak jelas bahwa ketika menulis aplikasi menggunakan Nucleus SE, Anda perlu menggunakan API seperti yang dijelaskan dalam artikel sebelumnya. Namun, ini tidak selalu terjadi.

Untuk sebagian besar pengguna, Nucleus SE API akan menjadi sesuatu yang baru, bahkan mungkin pengalaman pertama mereka menggunakan sistem operasi API. Dan karena ini cukup sederhana, ini bisa menjadi pengantar yang bagus untuk topik tersebut. Dalam hal ini, prosedurnya jelas.

Untuk beberapa pengguna, API alternatif mungkin merupakan opsi yang lebih menarik. Ada tiga situasi yang jelas di mana ini dimungkinkan.
  1. Nucleus SE hanya bagian dari sistem yang menggunakan sistem operasi lain untuk komponen lain. Oleh karena itu, portabilitas kode, dan, yang lebih penting, pengalaman menggunakan berbagai sistem operasi terlihat sangat menggoda.
  2. Pengguna memiliki pengalaman luas menggunakan API sistem operasi lain. Menggunakan pengalaman ini juga sangat disarankan.
  3. Pengguna ingin menggunakan kembali kode yang ditulis untuk API sistem operasi lain. Mengubah panggilan API dimungkinkan, tetapi menghabiskan waktu.


Karena kode sumber lengkap Nucleus SE tersedia untuk semua orang, tidak ada yang menghentikan Anda dari mengedit setiap fungsi API sehingga terlihat setara dengan sistem operasi lain. Namun, itu akan memakan banyak waktu dan akan sangat tidak produktif. Pendekatan yang lebih tepat adalah menulis "pembungkus". Ada beberapa cara untuk melakukan ini, tetapi cara termudah adalah membuat file header ( #include ) yang berisi sekumpulan #define macro yang akan memetakan fungsi API pihak ketiga ke fungsi Nucleus SE API.

Pembungkus yang mentransfer fungsi Nucleus RTOS API (sebagian) ke Nucleus SE didistribusikan dengan Nucleus SE. Mungkin bermanfaat bagi pengembang yang berpengalaman menggunakan Nucleus RTOS, atau di mana di masa mendatang dimungkinkan untuk beralih ke RTOS ini. Pembungkus ini juga bisa berfungsi sebagai contoh ketika mengembangkan hal serupa.

Aplikasi Debugging Nucleus SE


Menulis aplikasi tertanam menggunakan kernel multitasking adalah tugas yang kompleks. Memastikan kode berfungsi dan mendeteksi kesalahan bisa menjadi tugas yang menakutkan. Terlepas dari kenyataan bahwa ini hanya kode yang berjalan pada prosesor, eksekusi simultan dari beberapa tugas membuatnya agak sulit untuk fokus pada utas eksekusi spesifik. Ini lebih rumit ketika beberapa tugas berbagi kode umum. Yang terburuk, ketika dua tugas memiliki kode yang persis sama (tetapi bekerja dengan data yang berbeda). Juga menyulitkan adalah penguraian struktur data yang digunakan untuk mengimplementasikan objek kernel untuk melihat informasi yang bermakna.

Untuk men-debug aplikasi yang dibangun menggunakan Nucleus SE, tidak ada perpustakaan tambahan atau layanan lain yang diperlukan. Semua kode kernel dapat dibaca oleh debugger. Karena itu, semua informasi simbolis tersedia untuk dipelajari. Saat bekerja dengan aplikasi Nucleus SE, alat debugging modern apa pun dapat digunakan.

Menggunakan debugger


Alat debugging yang dirancang khusus untuk sistem tertanam telah menjadi sangat kuat dalam 30 tahun yang telah ada. Karakteristik utama dari aplikasi tertanam, dibandingkan dengan program desktop, adalah bahwa semua sistem tertanam berbeda (dan semua komputer pribadi sangat mirip satu sama lain). Debugger tertanam yang baik harus fleksibel dan memiliki pengaturan yang cukup untuk mencocokkan berbagai sistem tertanam dan persyaratan pengguna. Kustomisasi debugger dinyatakan dalam berbagai bentuk, tetapi biasanya ada kemungkinan membuat skrip. Fitur inilah yang memungkinkan debugger bekerja dengan baik dengan aplikasi tingkat kernel. Di bawah ini saya akan membahas beberapa kasus menggunakan debugger.

Perlu dicatat bahwa biasanya debugger adalah kumpulan alat, bukan hanya satu program. Debugger dapat memiliki berbagai mode operasi, yang membantu ketika mengembangkan kode pada sistem virtual atau pada perangkat keras nyata.

Breakpoint yang sensitif terhadap tugas


Jika program memiliki kode yang umum untuk beberapa tugas, penggunaan breakpoint konvensional selama proses debug rumit. Kemungkinan besar, Anda memerlukan kode untuk berhenti hanya ketika breakpoint dicapai dalam konteks tugas tertentu yang sedang Anda debug. Untuk melakukan ini, Anda memerlukan breakpoint yang akan mempertimbangkan tugas.

Untungnya, kemampuan untuk membuat skrip pada debugger modern dan ketersediaan data karakter Nucleus SE membuat implementasi breakpoint spesifik tugas menjadi hal yang cukup sederhana. Yang diperlukan hanyalah menulis skrip sederhana yang akan dikaitkan dengan breakpoint yang ingin Anda ajarkan untuk membedakan antara tugas. Skrip ini akan mengambil parameter: indeks (ID) dari tugas yang Anda minati. Script hanya akan membandingkan nilai ini dengan indeks tugas saat ini ( NUSE_Task_Active ). Jika nilainya cocok, program berhenti. Jika mereka berbeda, eksekusi berlanjut. Perlu dicatat bahwa eksekusi skrip ini akan memengaruhi eksekusi aplikasi secara real time ( catatan penerjemah: ini berarti bahwa eksekusi program akan melambat relatif terhadap operasi normalnya ). Namun, jika skrip tidak dalam satu lingkaran yang akan dieksekusi sangat sering, efek ini akan minimal.

Informasi Objek Kernel


Kebutuhan nyata untuk men-debug aplikasi Nucleus SE adalah kemampuan untuk mendapatkan informasi tentang objek kernel: apa karakteristik mereka dan apa status mereka saat ini. Ini memungkinkan Anda mendapatkan jawaban atas pertanyaan seperti: "Berapa besar antrian ini dan berapa banyak pesan yang ada di dalamnya sekarang?"

Ini dapat digunakan dengan menambahkan kode debug tambahan ke aplikasi Anda, yang akan menggunakan panggilan API "informatif" (seperti NUSE_Queue_Information ). Tentu saja, ini berarti bahwa aplikasi Anda sekarang berisi kode tambahan, yang tidak akan diperlukan setelah implementasi aplikasi. Menggunakan #define untuk menghidupkan dan mematikan kode ini menggunakan kompilasi bersyarat akan menjadi keputusan yang logis.

Beberapa debugger dapat membuat panggilan fungsi yang ditargetkan, yaitu, langsung memanggil fungsi API untuk mengambil informasi.Ini menghilangkan kebutuhan untuk kode tambahan, tetapi fungsi API ini harus dikonfigurasi untuk debugger untuk menggunakannya.

Alternatif, lebih fleksibel, tetapi kurang "non-penuaan" pendekatan adalah akses langsung ke struktur data objek kernel. Kemungkinan besar, yang terbaik adalah melakukan ini menggunakan skrip debugger. Dalam contoh kami, ukuran antrian dapat diperoleh dari NUSE_Queue_Size [] , dan penggunaan saat ini dari NUSE_Queue_Data [] . Selain itu, pesan dalam antrian dapat ditampilkan menggunakan alamat area data antrian (dari NUSE_Queue_Data [] ).

Nilai pengembalian panggilan API


Banyak fungsi API mengembalikan nilai status yang menunjukkan seberapa sukses panggilan selesai. Akan bermanfaat untuk melacak nilai-nilai ini dan untuk menandai kasus yang tidak sama dengan NUSE_SUCCESS (yaitu, mereka memiliki nilai nol). Karena pelacakan ini hanya untuk debugging, kompilasi bersyarat cukup tepat. Definisi variabel global (katakanlah, NUSE_API_Call_Status ) dapat dikompilasi secara kondisional (di bawah kendali simbol petunjuk #define). Kemudian, bagian dari definisi panggilan API, yaitu NUSE_API_Call_Status = , juga dapat dikompilasi secara kondisional. Misalnya, untuk keperluan debugging, panggilan yang biasanya terlihat seperti ini:

NUSE_Mailbox_Send (mbox, msg, NUSE_SUSPSEND);

akan mengambil formulir berikut:

NUSE_API_Call_Status = NUSE_Mailbox_Send(mbox, msg, NUSE_SUSPEND);

, API , . , API, API .


Topik perlindungan stack overflow dibahas dalam artikel sebelumnya (# 31). Ada beberapa kemungkinan lain selama debugging.

Area memori tumpukan dapat diisi dengan nilai karakteristik: sesuatu yang lain daripada semua yang ada atau semua nol. Setelah itu, debugger dapat digunakan untuk memantau area memori dan berapa banyak nilai yang akan diubah, yang akan memungkinkan kita untuk memahami tingkat kepenuhan tumpukan. Jika semua area memori telah diubah, ini tidak berarti bahwa tumpukannya penuh, tetapi dapat berarti bahwa ukurannya hampir tidak cukup, yang berbahaya. Ini harus ditingkatkan dan pengujian dilanjutkan.

Seperti yang dijelaskan dalam artikel # 31, ketika menerapkan diagnostik, area tambahan, "kata pelindung", dapat ditemukan di salah satu tepi area memori tumpukan. Debugger dapat digunakan untuk melacak akses ke kata-kata ini, karena setiap upaya untuk menulis kepada mereka berarti meluap atau habisnya tumpukan.

Daftar Periksa Konfigurasi Nucleus SE


Karena Nucleus SE dirancang sebagai sistem yang sangat fleksibel dan dapat disesuaikan untuk memenuhi persyaratan aplikasi, Nucleus SE membutuhkan sejumlah besar parameter yang dapat disesuaikan. Itulah sebabnya seluruh artikel ini, pada kenyataannya, dikhususkan untuk konfigurasi Nucleus SE. Untuk memastikan kami tidak melewatkan apa pun, berikut ini adalah daftar periksa semua langkah utama yang perlu Anda ikuti untuk membuat Aplikasi Tertanam Nucleus SE.
  1. Nucleus SE. , Nucleus SE , Nucleus SE .
  2. CPU/. .
  3. . , , .
  4. . . . , . 16 .
  5. . - main() ?
  6. . 4 , .
  7. , .
  8. .
  9. . , .
  10. . , .
  11. . , . . — 16 .
  12. . , .
  13. . , (, ).
  14. API. API, .


Artikel berikutnya (yang terakhir dalam seri ini) akan merangkum keseluruhan cerita dengan Nucleus SE, dan juga akan memberikan informasi yang akan membantu dalam menciptakan implementasi Nucleus SE dan penggunaannya.

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.

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


All Articles