- Bagaimana RTOS berfungsi?
- Istilah yang sering digunakan dalam RTOS
- Memasang Perpustakaan Arduino FreeRTOS
- Rajah Litar
- Contoh Arduino FreeRTOS- Membuat tugas FreeRTOS di Arduino IDE
- Pelaksanaan Tugas FreeRTOS di Arduino IDE
OS yang terdapat di dalam peranti tertanam disebut RTOS (Real-Time Operating System). Dalam peranti terbenam, tugas masa nyata sangat penting di mana masa memainkan peranan yang sangat penting. Tugas masa nyata adalah Time Deterministic bermaksud masa tindak balas terhadap sesuatu peristiwa selalu berterusan sehingga dapat dijamin bahawa setiap peristiwa tertentu akan berlaku pada waktu yang tetap. RTOS direka untuk menjalankan aplikasi dengan masa yang tepat dan tahap kebolehpercayaan yang tinggi. RTOS juga membantu dalam pelbagai tugas dengan satu teras.
Kami telah membahas tutorial bagaimana menggunakan RTOS dalam sistem terbenam di mana anda boleh mengetahui lebih lanjut mengenai RTOS, perbezaan antara OS tujuan umum dan RTOS, pelbagai jenis RTOS, dll.
Dalam tutorial ini, kita akan mulakan dengan FreeRTOS. FreeRTOS adalah kelas RTOS untuk peranti tertanam yang cukup kecil untuk dijalankan pada mikrokontroler 8/16-bit, walaupun penggunaannya tidak terhad pada mikrokontroler ini. Ini adalah sumber terbuka sepenuhnya dan kodnya terdapat di github. Sekiranya kita mengetahui beberapa konsep asas RTOS, maka sangat mudah untuk menggunakan FreeRTOS kerana mempunyai API yang didokumentasikan dengan baik yang boleh digunakan secara langsung dalam kod tanpa mengetahui bahagian belakang pengekodan. Dokumentasi FreeRTOS lengkap boleh didapati di sini.
Sebagai FreeRTOS boleh dijalankan pada MCU 8-bit sehingga dapat juga dijalankan di papan Arduino Uno. Kita hanya perlu memuat turun perpustakaan FreeRTOS dan kemudian mula menerapkan kod menggunakan API. Tutorial ini bertujuan untuk pemula yang lengkap, di bawah ini adalah topik-topik yang akan kami bahas dalam tutorial Arduino FreeRTOS ini:
- Bagaimana RTOS berfungsi
- Beberapa istilah yang sering digunakan dalam RTOS
- Memasang FreeRTOS di Arduino IDE
- Cara membuat Tugas FreeRTOS dengan contoh
Bagaimana RTOS berfungsi?
Sebelum memulakan dengan RTOS berfungsi, mari kita lihat apa itu Tugas. Tugas adalah sekeping kod yang dapat dijadwalkan pada CPU untuk dilaksanakan. Jadi, jika anda ingin melakukan beberapa tugas, maka ia harus dijadualkan menggunakan kernel delay atau menggunakan interupts. Kerja ini dilakukan oleh Penjadual yang ada di kernel. Dalam pemproses satu teras, penjadual membantu tugas untuk dilaksanakan dalam jangka masa tertentu tetapi sepertinya tugas yang berbeza dilaksanakan secara serentak. Setiap tugas berjalan mengikut keutamaan yang diberikan kepadanya.
Sekarang, mari kita lihat apa yang berlaku di kernel RTOS jika kita ingin membuat tugas untuk LED berkedip dengan selang satu saat dan meletakkan tugas ini pada keutamaan tertinggi.
Selain tugas LED, akan ada satu tugas lagi yang dibuat oleh kernel, ia dikenali sebagai tugas terbiar. Tugas terbiar dibuat apabila tidak ada tugas yang tersedia untuk pelaksanaan. Tugas ini selalu berjalan pada keutamaan terendah iaitu keutamaan 0. Sekiranya kita menganalisis grafik masa yang diberikan di atas, dapat dilihat bahawa pelaksanaan dimulakan dengan tugas LED dan berjalan untuk waktu yang ditentukan kemudian untuk waktu yang tersisa, tugas terbiar berjalan sehingga gangguan centang berlaku. Kemudian kernel memutuskan tugas mana yang harus dilaksanakan sesuai dengan keutamaan tugas dan jumlah masa tugas LED yang telah berlalu. Apabila 1 saat selesai, kernel memilih tugas yang dipimpin sekali lagi untuk dilaksanakan kerana mempunyai keutamaan yang lebih tinggi daripada tugas siaga, kita juga dapat mengatakan bahawa tugas LED lebih awal daripada tugas tidak aktif. Sekiranya terdapat lebih dari dua tugas dengan keutamaan yang sama maka mereka akan berjalan dengan cara round-robin untuk waktu yang ditentukan.
Di bawah rajah keadaan seperti menunjukkan pertukaran tugas yang tidak berjalan ke keadaan berjalan.
Setiap tugas yang baru dibuat berjalan dalam keadaan Sedia (sebahagian daripada keadaan tidak berjalan). Sekiranya tugas yang dibuat (Task1) mempunyai keutamaan tertinggi daripada tugas lain, maka tugas tersebut akan beralih ke keadaan berjalan. Sekiranya tugas yang dijalankan ini diprioritaskan oleh tugas yang lain, maka tugas ini akan kembali ke keadaan siap semula. Jika tidak, task1 disekat dengan menggunakan blocking API, maka CPU tidak akan terlibat dengan tugas ini sehingga timeout ditentukan oleh pengguna.
Sekiranya Task1 ditangguhkan dalam keadaan berjalan menggunakan Suspend APIs, maka Task1 akan menuju ke status Suspended dan tidak tersedia lagi untuk penjadual. Sekiranya anda menyambung semula Task1 dalam keadaan yang digantung maka ia akan kembali ke keadaan siap seperti yang anda lihat dalam rajah blok.
Ini adalah idea asas bagaimana Tugas dijalankan dan mengubah keadaannya. Dalam tutorial ini, kami akan melaksanakan dua tugas di Arduino Uno menggunakan FreeRTOS API.
Istilah yang sering digunakan dalam RTOS
1. Tugas: Ini adalah sekeping kod yang dapat dijadwalkan pada CPU untuk dijalankan.
2. Penjadual: Bertanggungjawab memilih tugas dari senarai keadaan siap ke keadaan berjalan. Penjadual sering dilaksanakan sehingga mereka membuat semua sumber komputer sibuk (seperti dalam pengimbangan beban).
3. Preemption: Ini adalah tindakan menghentikan sementara tugas yang sudah dilaksanakan dengan tujuan untuk menghapusnya dari keadaan berjalan tanpa kerjasama.
4. Pengalihan Konteks: Dalam penentuan berdasarkan keutamaan, penjadual membandingkan keutamaan menjalankan tugas dengan keutamaan senarai tugas siap pada setiap gangguan systick . Sekiranya terdapat tugas dalam senarai yang keutamaannya lebih tinggi daripada menjalankan tugas, maka pertukaran konteks berlaku. Pada dasarnya, dalam proses ini kandungan tugas yang berbeza disimpan dalam memori timbunan masing-masing.
5. Jenis polisi Penjadualan:
- Penjadualan Preemptive: Dalam penjadualan jenis ini, tugas dijalankan dengan potongan masa yang sama tanpa mempertimbangkan keutamaan.
- Preemptive berdasarkan keutamaan: Tugas keutamaan tinggi akan dijalankan terlebih dahulu.
- Penjadualan Koperasi: Peralihan konteks akan berlaku hanya dengan kerjasama menjalankan tugas. Tugas akan berjalan berterusan sehingga hasil tugas dipanggil.
6. Objek Kernel: Untuk memberi isyarat kepada tugas untuk melakukan beberapa kerja, proses penyegerakan digunakan. Untuk melakukan proses ini objek Kernel digunakan. Beberapa objek Kernel adalah Acara, Semaphores, Antrian, Mutex, Kotak Surat, dan lain-lain. Kami akan melihat bagaimana menggunakan objek ini dalam tutorial yang akan datang.
Dari perbincangan di atas, kami mendapat beberapa idea asas mengenai konsep RTOS dan sekarang kami dapat melaksanakan projek FreeRTOS di Arduino. Oleh itu, mari kita mulakan dengan memasang perpustakaan FreeRTOS di Arduino IDE.
Memasang Perpustakaan Arduino FreeRTOS
1. Buka Arduino IDE dan pergi ke Sketsa -> Sertakan Perpustakaan -> Uruskan Perpustakaan . Cari FreeRTOS dan pasang perpustakaan seperti gambar di bawah.
Anda boleh memuat turun pustaka dari github dan Tambahkan fail.zip di Sketch-> Sertakan Perpustakaan -> Tambah fail .zip .
Sekarang, mulakan semula Arduino IDE. Perpustakaan ini menyediakan beberapa kod contoh, yang juga terdapat dalam Fail -> Contoh -> FreeRTOS seperti yang ditunjukkan di bawah.
Di sini kita akan menulis kod dari awal untuk memahami cara kerjanya, kemudian anda boleh menyemak contoh kod dan menggunakannya.
Rajah Litar
Berikut adalah rajah litar untuk membuat tugas LED Berkelip menggunakan FreeRTOS di Arduino:
Contoh Arduino FreeRTOS- Membuat tugas FreeRTOS di Arduino IDE
Mari lihat struktur asas untuk menulis projek FreeRTOS.
1. Pertama, sertakan fail header Arduino FreeRTOS sebagai
#sertakan
2. Berikan prototaip fungsi dari semua fungsi yang anda tulis untuk pelaksanaan yang ditulis sebagai
void Task1 (void * pvParameters); kosongkan Tugas2 (void * pvParameters); .. ….
3. Sekarang, dalam fungsi setup void () , buat tugas dan mulakan penjadual tugas.
Untuk membuat tugas, xTaskCreate () API dipanggil dalam fungsi persediaan dengan parameter / argumen tertentu.
xTaskCreate (TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask);
Terdapat 6 argumen yang harus dilalui semasa membuat sebarang tugas. Mari lihat apa hujah-hujah ini
- pvTaskCode: Ini hanyalah penunjuk kepada fungsi yang melaksanakan tugas (sebenarnya, hanya nama fungsi).
- pcName: Nama deskriptif untuk tugas. Ini tidak digunakan oleh FreeRTOS. Ia disertakan semata-mata untuk tujuan penyahpepijatan.
- usStackDepth: Setiap tugas mempunyai timbunan tersendiri yang diperuntukkan oleh kernel untuk tugas ketika tugas dibuat. Nilai menentukan bilangan perkataan yang dapat ditahan oleh timbunan, bukan jumlah bait. Sebagai contoh, jika timbunan selebar 32-bit dan usStackDepth dilewatkan sebagai 100, maka 400 bait ruang tumpukan akan diperuntukkan (100 * 4 bait) dalam RAM. Gunakan ini dengan bijak kerana Arduino Uno hanya mempunyai RAM 2Kbytes.
- pvParameters: Parameter input tugas (boleh NULL).
- uxPriority: Keutamaan tugas (0 adalah keutamaan terendah).
- pxCreatedTask: Ia dapat digunakan untuk melepaskan pegangan untuk tugas yang dibuat. Pemegang ini kemudian dapat digunakan untuk merujuk tugas dalam panggilan API yang, misalnya, mengubah keutamaan tugas atau menghapus tugas (dapat NULL).
Contoh pembuatan tugas
xTaskCreate (task1, "task1", 128, NULL, 1, NULL); xTaskCreate (task2, "task2", 128, NULL, 2, NULL);
Di sini, Task2 mempunyai keutamaan yang lebih tinggi dan oleh itu dilaksanakan terlebih dahulu.
4. Setelah membuat tugas, mulakan penjadual dalam penyediaan kosong menggunakan vTaskStartScheduler (); API.
5. Fungsi loop kosong () akan tetap kosong kerana kami tidak mahu menjalankan tugas secara manual dan tanpa batas. Kerana pelaksanaan tugas kini ditangani oleh Penjadual.
6. Sekarang, kita harus melaksanakan fungsi tugas dan menulis logik yang ingin anda laksanakan di dalam fungsi-fungsi ini. Nama fungsi harus sama dengan argumen pertama API xTaskCreate () .
void task1 (void * pvParameters) { sementara (1) { .. ..// logik anda } }
7. Sebilangan besar kod memerlukan fungsi kelewatan untuk menghentikan tugas yang sedang berjalan tetapi di RTOS tidak disarankan untuk menggunakan fungsi Delay () kerana ia menghentikan CPU dan oleh itu RTOS juga berhenti berfungsi. Jadi FreeRTOS mempunyai API kernel untuk menyekat tugas untuk waktu tertentu.
vTaskDelay (const TickType_t xTicksToDelay);
API ini boleh digunakan untuk tujuan kelewatan. API ini melambatkan tugas untuk jumlah kutu tertentu. Masa sebenar yang tugasnya disekat bergantung pada kadar centang. PortTICK_PERIOD_MS yang tetap boleh digunakan untuk mengira masa nyata dari kadar kutu.
Ini bermaksud jika anda mahu kelewatan 200ms, tulis baris ini
vTaskDelay (200 / portTICK_PERIOD_MS);
Jadi untuk tutorial ini, kami akan menggunakan API FreeRTOS ini untuk melaksanakan tiga tugas.
API yang akan digunakan:
- xTaskCreate ();
- vTaskStartScheduler ();
- vTaskDelay ();
Tugas yang akan dibuat untuk tutorial ini:
- LED berkelip pada pin Digital 8 dengan frekuensi 200ms
- LED berkelip pada pin Digital 7 dengan frekuensi 300ms
- Cetak nombor dalam monitor bersiri dengan frekuensi 500ms.
Pelaksanaan Tugas FreeRTOS di Arduino IDE
1. Dari penjelasan struktur asas di atas, sertakan fail tajuk Arduino FreeRTOS. Kemudian buat prototaip fungsi. Oleh kerana kami mempunyai tiga tugas, jadi buat tiga fungsi dan itu adalah prototaip.
# include tidak sah TaskBlink1 (* pvParameters tidak sah); batal TaskBlink2 (batal * pvParameters); kekosongan Cetakan Tugas (void * pvParameters);
2. Dalam fungsi setup void () , mulakan komunikasi bersiri pada 9600 bit per saat dan buat ketiga-tiga tugas menggunakan API xTaskCreate () . Pada mulanya, buat keutamaan semua tugas sebagai '1' dan mulakan penjadual.
persediaan tidak sah () { Serial.begin (9600); xTaskCreate (TaskBlink1, "Task1", 128, NULL, 1, NULL); xTaskCreate (TaskBlink2, "Task2", 128, NULL, 1, NULL); xTaskCreate (Taskprint, "Task3", 128, NULL, 1, NULL); vTaskStartScheduler (); }
3. Sekarang, laksanakan ketiga-tiga fungsi seperti yang ditunjukkan di bawah ini untuk task1 LED berkedip.
batal TaskBlink1 (void * pvParameters) { pinMode (8, OUTPUT); sementara (1) { digitalWrite (8, TINGGI); vTaskDelay (200 / portTICK_PERIOD_MS); digitalWrite (8, RENDAH); vTaskDelay (200 / portTICK_PERIOD_MS); } }
Begitu juga, melaksanakan fungsi TaskBlink2. Fungsi Task3 akan ditulis sebagai
kekosongan Tugas cetak (void * pvParameters) { int counter = 0; sementara (1) { kaunter ++; Serial.println (kaunter); vTaskDelay (500 / portTICK_PERIOD_MS); } }
Itu sahaja. Kami berjaya menyelesaikan projek FreeRTOS Arduino untuk Arduino Uno. Anda boleh mendapatkan kod penuh bersama dengan video di akhir tutorial ini.
Akhirnya, sambungkan dua LED pada pin digital 7 dan 8 dan muat naik kod pada papan Arduino anda dan buka monitor Serial. Anda akan melihat kaunter berjalan sekali dalam 500ms dengan nama tugas seperti gambar di bawah.
Juga, perhatikan LED, mereka berkedip pada selang waktu yang berbeza. Cuba mainkan dengan argumen keutamaan dalam fungsi xTaskCreate . Tukar nombor dan perhatikan tingkah laku pada monitor bersiri dan LED.
Sekarang, anda dapat memahami dua contoh kod pertama di mana tugas membaca analog dan membaca digital dibuat. Dengan cara ini, anda boleh membuat lebih banyak projek maju dengan hanya menggunakan Arduino Uno dan FreeRTOS API.