- Bagaimana RTOS bekerja?
- Istilah yang sering digunakan di RTOS
- Menginstal Perpustakaan Arduino FreeRTOS
- Diagram Sirkuit
- Contoh Arduino FreeRTOS- Membuat tugas FreeRTOS di Arduino IDE
- Implementasi Tugas FreeRTOS di Arduino IDE
OS yang ada di dalam perangkat yang disematkan disebut RTOS (Sistem Operasi Real-Time). Di perangkat yang disematkan, tugas waktu nyata sangat penting di mana waktu memainkan peran yang sangat penting. Tugas real-time bersifat Time Deterministic artinya waktu respon terhadap suatu kejadian selalu konstan sehingga dapat dijamin bahwa setiap kejadian tertentu akan terjadi pada waktu yang tetap. RTOS dirancang untuk menjalankan aplikasi dengan waktu yang sangat tepat dan tingkat keandalan yang tinggi. RTOS juga membantu dalam multi-tasking dengan satu inti.
Kami sudah membahas tutorial tentang cara menggunakan RTOS dalam sistem tertanam di mana Anda dapat mengetahui lebih banyak tentang RTOS, perbedaan antara OS tujuan umum dan RTOS, berbagai jenis RTOS, dll.
Dalam tutorial ini, kita akan mulai dengan FreeRTOS. FreeRTOS adalah kelas RTOS untuk perangkat tertanam yang cukup kecil untuk dijalankan pada mikrokontroler 8/16-bit, meskipun penggunaannya tidak terbatas pada mikrokontroler ini. Ini sepenuhnya open-source dan kodenya tersedia di github. Jika kita mengetahui beberapa konsep dasar RTOS, maka sangat mudah menggunakan FreeRTOS karena memiliki API yang terdokumentasi dengan baik yang dapat langsung digunakan dalam kode tanpa mengetahui bagian belakang pengkodean. Dokumentasi FreeRTOS lengkap dapat ditemukan di sini.
Karena FreeRTOS dapat berjalan pada MCU 8-bit sehingga dapat juga dijalankan pada papan Arduino Uno. Kami hanya perlu mengunduh pustaka FreeRTOS dan kemudian mulai menerapkan kode menggunakan API. Tutorial ini dimaksudkan untuk pemula yang lengkap, di bawah ini adalah topik yang akan kita bahas dalam tutorial Arduino FreeRTOS ini:
- Bagaimana RTOS bekerja
- Beberapa istilah yang sering digunakan di RTOS
- Menginstal FreeRTOS di Arduino IDE
- Cara membuat Tugas FreeRTOS dengan contoh
Bagaimana RTOS bekerja?
Sebelum memulai dengan RTOS, mari kita lihat apa itu Tugas. Tugas adalah bagian kode yang dapat dijadwalkan pada CPU untuk dieksekusi. Jadi, jika Anda ingin melakukan suatu tugas, maka itu harus dijadwalkan menggunakan penundaan kernel atau menggunakan interupsi. Pekerjaan ini dilakukan oleh Scheduler yang ada di kernel. Dalam prosesor inti tunggal, penjadwal membantu tugas-tugas untuk dijalankan dalam irisan waktu tertentu tetapi sepertinya tugas-tugas yang berbeda sedang dijalankan secara bersamaan. Setiap tugas berjalan sesuai dengan prioritas yang diberikan padanya.
Sekarang, mari kita lihat apa yang terjadi di kernel RTOS jika kita ingin membuat tugas untuk LED berkedip dengan interval satu detik dan menempatkan tugas ini pada prioritas tertinggi.
Selain tugas LED, akan ada satu tugas lagi yang dibuat oleh kernel, yang dikenal sebagai tugas idle. Tugas idle dibuat saat tidak ada tugas yang tersedia untuk dieksekusi. Tugas ini selalu berjalan pada prioritas terendah yaitu 0 prioritas. Jika kita menganalisis grafik waktu yang diberikan di atas, dapat dilihat bahwa eksekusi dimulai dengan tugas LED dan berjalan untuk waktu yang ditentukan kemudian untuk waktu yang tersisa, tugas idle berjalan hingga terjadi interupsi centang. Kemudian kernel memutuskan tugas mana yang harus dijalankan sesuai dengan prioritas tugas dan total waktu berlalu dari tugas LED. Ketika 1 detik selesai, kernel memilih lagi tugas yang dipimpin untuk dijalankan karena memiliki prioritas lebih tinggi daripada tugas diam, kita juga dapat mengatakan bahwa tugas LED mendahului tugas diam. Jika ada lebih dari dua tugas dengan prioritas yang sama maka tugas tersebut akan berjalan secara round-robin untuk waktu yang ditentukan.
Di bawah diagram status karena menunjukkan pengalihan tugas yang tidak berjalan menjadi status berjalan.
Setiap tugas yang baru dibuat berada dalam status Siap (bagian dari status tidak berjalan). Jika tugas yang dibuat (Tugas1) memiliki prioritas tertinggi daripada tugas lainnya, maka itu akan berpindah ke status berjalan. Jika tugas yang sedang berjalan ini mendahului tugas lain, maka itu akan kembali ke status siap lagi. Jika tidak, tugas1 diblokir dengan menggunakan API pemblokiran, CPU tidak akan terlibat dengan tugas ini hingga waktu tunggu yang ditentukan oleh pengguna.
Jika Task1 ditangguhkan dalam status berjalan menggunakan API Tangguhkan, maka Task1 akan masuk ke status Ditangguhkan dan tidak tersedia lagi untuk penjadwal. Jika Anda melanjutkan Task1 dalam status ditangguhkan maka itu akan kembali ke status siap seperti yang Anda lihat di diagram blok.
Ini adalah ide dasar tentang bagaimana Tasks menjalankan dan mengubah statusnya. Dalam tutorial ini, kami akan mengimplementasikan dua tugas di Arduino Uno menggunakan FreeRTOS API.
Istilah yang sering digunakan di RTOS
1. Tugas: Ini adalah bagian dari kode yang dapat dieksekusi di CPU.
2. Scheduler: Bertanggung jawab untuk memilih tugas dari daftar status siap ke status berjalan. Penjadwal sering diimplementasikan sehingga mereka membuat semua sumber daya komputer sibuk (seperti dalam load balancing).
3. Preemption: Ini adalah tindakan menghentikan sementara tugas yang sudah dijalankan dengan tujuan untuk menghapusnya dari status berjalan tanpa kerjasama.
4. Pengalihan Konteks: Dalam preemption berbasis prioritas, penjadwal membandingkan prioritas tugas yang sedang berjalan dengan prioritas daftar tugas yang siap pada setiap interupsi systick . Jika ada tugas apa pun dalam daftar yang prioritasnya lebih tinggi daripada menjalankan tugas maka sakelar konteks akan terjadi. Pada dasarnya, dalam proses ini, konten tugas yang berbeda disimpan di memori tumpukan masing-masing.
5. Jenis kebijakan Penjadwalan:
- Penjadwalan Terlebih Dahulu: Dalam jenis penjadwalan ini, tugas dijalankan dengan pembagian waktu yang sama tanpa mempertimbangkan prioritas.
- Preemptive Berbasis Prioritas: Tugas berprioritas tinggi akan dijalankan terlebih dahulu.
- Penjadwalan Koperatif: Peralihan konteks hanya akan terjadi dengan kerja sama dari tugas yang berjalan. Tugas akan berjalan terus menerus sampai hasil tugas dipanggil.
6. Objek Kernel: Untuk menandakan tugas untuk melakukan beberapa pekerjaan, proses sinkronisasi digunakan. Untuk melakukan proses ini, objek kernel digunakan. Beberapa objek Kernel adalah Events, Semaphore, Queues, Mutex, Mailboxes, dll. Kita akan melihat bagaimana menggunakan objek ini dalam tutorial mendatang.
Dari pembahasan di atas, kami telah mendapatkan beberapa ide dasar tentang konsep RTOS dan sekarang kami dapat mengimplementasikan proyek FreeRTOS di Arduino. Jadi, mari kita mulai dengan menginstal pustaka FreeRTOS di Arduino IDE.
Menginstal Perpustakaan Arduino FreeRTOS
1. Buka Arduino IDE dan pergi ke Sketch -> Include Library -> Manage Libraries . Cari FreeRTOS dan instal perpustakaan seperti yang ditunjukkan di bawah ini.
Anda dapat mengunduh perpustakaan dari github dan Tambahkan file.zip di Sketch-> Sertakan Perpustakaan -> Tambahkan file .zip .
Sekarang, mulai ulang Arduino IDE. Library ini menyediakan beberapa kode contoh, juga dapat ditemukan di File -> Contoh -> FreeRTOS seperti yang ditunjukkan di bawah ini.
Di sini kita akan menulis kode dari awal untuk memahami cara kerjanya, nanti Anda dapat memeriksa kode contoh dan menggunakannya.
Diagram Sirkuit
Di bawah ini adalah diagram rangkaian untuk membuat tugas LED Blinking menggunakan FreeRTOS di Arduino:
Contoh Arduino FreeRTOS- Membuat tugas FreeRTOS di Arduino IDE
Mari kita lihat struktur dasar untuk menulis proyek FreeRTOS.
1. Pertama, sertakan file header Arduino FreeRTOS sebagai
#include
2. Berikan prototipe fungsi dari semua fungsi yang Anda tulis untuk eksekusi yang ditulis sebagai
void Task1 (void * pvParameters); void Task2 (void * pvParameters); .. ….
3. Sekarang, dalam fungsi void setup () , buat tugas dan mulai penjadwal tugas.
Untuk membuat tugas, xTaskCreate () API dipanggil dalam fungsi setup dengan parameter / argumen tertentu.
xTaskCreate (TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask);
Ada 6 argumen yang harus dilalui saat membuat tugas apa pun. Mari kita lihat apa argumen ini
- pvTaskCode: Ini hanyalah penunjuk ke fungsi yang mengimplementasikan tugas (pada dasarnya, hanya nama fungsinya).
- pcName: Nama deskriptif untuk tugas tersebut. Ini tidak digunakan oleh FreeRTOS. Ini disertakan murni untuk tujuan debugging.
- usStackDepth: Setiap tugas memiliki tumpukan uniknya sendiri yang dialokasikan oleh kernel ke tugas saat tugas dibuat. Nilai menentukan jumlah kata yang dapat ditampung tumpukan, bukan jumlah byte. Misalnya, jika tumpukan berukuran lebar 32-bit dan usStackDepth diteruskan sebagai 100, maka 400 byte ruang tumpukan akan dialokasikan (100 * 4 byte) dalam RAM. Gunakan ini dengan bijak karena Arduino Uno hanya memiliki RAM 2Kbytes.
- pvParameters: Parameter input tugas (bisa NULL).
- uxPriority: Prioritas tugas (0 adalah prioritas terendah).
- pxCreatedTask: Ini dapat digunakan untuk membagikan pegangan ke tugas yang sedang dibuat. Tuas ini kemudian dapat digunakan untuk mereferensikan tugas dalam panggilan API yang, misalnya, mengubah prioritas tugas atau menghapus tugas (bisa NULL).
Contoh pembuatan tugas
xTaskCreate (task1, "task1", 128, NULL, 1, NULL); xTaskCreate (task2, "task2", 128, NULL, 2, NULL);
Di sini, Task2 memiliki prioritas lebih tinggi dan karenanya dijalankan terlebih dahulu.
4. Setelah membuat tugas, mulai penjadwal dalam pengaturan void menggunakan vTaskStartScheduler (); API.
5. Fungsi Void loop () akan tetap kosong karena kita tidak ingin menjalankan tugas apa pun secara manual dan tanpa batas. Karena eksekusi tugas sekarang ditangani oleh Scheduler.
6. Sekarang, kita harus mengimplementasikan fungsi tugas dan menulis logika yang ingin Anda jalankan di dalam fungsi ini. Nama fungsi harus sama dengan argumen pertama xTaskCreate () API.
void task1 (void * pvParameters) { while (1) { .. ..//yourlogic } }
7. Sebagian besar kode membutuhkan fungsi penundaan untuk menghentikan tugas yang sedang berjalan tetapi di RTOS tidak disarankan untuk menggunakan fungsi Delay () karena menghentikan CPU dan karenanya RTOS juga berhenti bekerja. Jadi FreeRTOS memiliki API kernel untuk memblokir tugas untuk waktu tertentu.
vTaskDelay (const TickType_t xTicksToDelay);
API ini dapat digunakan untuk tujuan penundaan. API ini menunda tugas untuk sejumlah centang tertentu. Waktu aktual untuk tetap memblokir tugas bergantung pada tick rate. PortTICK_PERIOD_MS konstan dapat digunakan untuk menghitung waktu nyata dari tingkat tick.
Ini berarti jika Anda menginginkan penundaan 200ms, tulis saja baris ini
vTaskDelay (200 / portTICK_PERIOD_MS);
Jadi untuk tutorial ini, kami akan menggunakan FreeRTOS API ini untuk mengimplementasikan tiga tugas.
API yang akan digunakan:
- xTaskCreate ();
- vTaskStartScheduler ();
- vTaskDelay ();
Tugas yang akan dibuat untuk tutorial ini:
- LED berkedip pada pin 8 Digital dengan frekuensi 200ms
- LED berkedip pada pin 7 Digital dengan frekuensi 300ms
- Cetak nomor di monitor serial dengan frekuensi 500ms.
Implementasi Tugas FreeRTOS di Arduino IDE
1. Dari penjelasan struktur dasar di atas, sertakan file header Arduino FreeRTOS. Kemudian buat prototipe fungsi. Karena kami memiliki tiga tugas, jadi buatlah tiga fungsi dan prototipe itu.
#include void TaskBlink1 (void * pvParameters); void TaskBlink2 (void * pvParameters); void Taskprint (void * pvParameters);
2. Dalam fungsi void setup () , inisialisasi komunikasi serial pada 9600 bit per detik dan buat ketiga tugas menggunakan xTaskCreate () API. Awalnya, buat prioritas semua tugas sebagai '1' dan mulai penjadwal.
void setup () { 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, terapkan ketiga fungsi seperti yang ditunjukkan di bawah ini untuk kedipan LED task1.
batal TaskBlink1 (batal * pvParameters) { pinMode (8, OUTPUT); sementara (1) { digitalWrite (8, HIGH); vTaskDelay (200 / portTICK_PERIOD_MS); digitalWrite (8, LOW); vTaskDelay (200 / portTICK_PERIOD_MS); } }
Demikian pula, terapkan fungsi TaskBlink2. Fungsi Task3 akan ditulis sebagai
void Taskprint (void * pvParameters) { int counter = 0; sementara (1) { counter ++; Serial.println (penghitung); vTaskDelay (500 / portTICK_PERIOD_MS); } }
Itu dia. Kami telah berhasil menyelesaikan proyek FreeRTOS Arduino untuk Arduino Uno. Anda dapat menemukan kode lengkap bersama dengan video di akhir tutorial ini.
Terakhir, sambungkan dua LED pada pin digital 7 dan 8 dan unggah kode pada papan Arduino Anda dan buka monitor Serial. Anda akan melihat penghitung berjalan sekali dalam 500ms dengan nama tugas seperti yang ditunjukkan di bawah ini.
Selain itu, amati LED yang berkedip pada interval waktu yang berbeda. Cobalah untuk bermain dengan argumen prioritas dalam fungsi xTaskCreate . Ubah nomor dan amati perilaku pada monitor serial dan LED.
Sekarang, Anda dapat memahami dua contoh kode pertama di mana tugas baca analog dan pembacaan digital dibuat. Dengan cara ini, Anda dapat membuat proyek yang lebih maju hanya dengan menggunakan Arduino Uno dan FreeRTOS API.