Penafian. Penulis tidak menganjurkan penggunaan sistem operasi multitasking untuk mikrokontroler.
Life tanpa ampun memaksa penggunaan sistem operasi (OS) untuk mikrokontroler. Ada sejumlah besar sistem seperti itu di pasaran. Pengembang sistem operasi, yang saling bersaing, berusaha memaksimalkan fungsionalitas produk mereka. Ini sering mengarah pada peningkatan "berat" sistem, dan juga secara signifikan meningkatkan "ambang batas" untuk seorang programmer yang mengembangkan perangkat lunak untuk sistem embedded.
Agar tidak tersiksa dengan pilihan OS untuk proyek-proyek saya, serta tidak mengaburkan pikiran saya dengan mempelajari produk orang lain, serta untuk menguasai teknik penulisan aplikasi yang tertanam untuk sistem operasi, dan juga untuk mencari tahu apa itu semua, saya memutuskan untuk menulis OS saya. Bukan bau.
OS yang diusulkan (OS, bahasa tidak berani menyebut OS-nya, dan terutama OSRV) kooperatif dengan tugas-tugas statis. Seperti disebutkan di atas, saya bukan pendukung penggunaan OS untuk mikrokontroler, tetapi lebih dari itu saya bukan pendukung penggunaan sistem operasi preemptive pada mikrokontroler. Multitasking preemptive, dibandingkan dengan koperasi, tidak hanya prosedur switching konteks yang rumit, tetapi juga sinkronisasi utas yang intensif sumber daya. Penggunaan tugas dinamis juga secara signifikan mempersulit sistem operasi.
Sistem operasi dikembangkan untuk prosesor keluarga Cortex-M0. Dengan perubahan kecil pada aturan untuk menyimpan dan memulihkan konteks, ini dapat digunakan untuk jenis prosesor lainnya.
Kode sumber
File IntorOS.h#ifndef __INTOROS_H #define __INTOROS_H
File IntorOS.c #define _INTOROS_C #include "stm32l0xx.h" #include "IntorOS.h"
File IntorOSSleepIAR.s #define SHT_PROGBITS 0x1 EXTERN KolvoTask EXTERN TaskList EXTERN TaskNum PUBLIC Sleep SECTION `.text`:CODE:NOROOT(2) THUMB
File IntorOSSleepGCC.s .cpu cortex-m0 .text .cfi_sections .debug_frame .section .text.Sleep,"ax",%progbits .align 1 .global Sleep .syntax unified .thumb .thumb_func .type Sleep, %function .extern KolvoTask .extern TaskList .extern TaskNum .cfi_startproc
Konstanta kompilasi OS
#define IntorOSMaxKolvoZadach (2)
Untuk alasan agama, saya tidak dapat menggunakan alokasi memori dinamis, sehingga jumlah memori yang diperlukan harus ditentukan pada tahap kompilasi.
Layanan OS OS
void InitTask(void (*TaskPointer)(void), unsigned long Stek);
Inisialisasi tugas. Tugas dieksekusi dalam bentuk fungsi, penunjuk ke fungsi diteruskan ke prosedur inisialisasi. Selama inisialisasi, Anda harus menentukan ukuran tumpukan yang dialokasikan untuk tugas tersebut. Urutan tugas yang diinisialisasi menentukan pengidentifikasi mereka. Tugas yang diinisialisasi pertama memiliki pengidentifikasi 0. Jika Anda menentukan ukuran tumpukan total lebih besar dari yang dipesan, kesalahan akan terjadi. Ketika tugas diinisialisasi, pointer ke tumpukan tugas diatur, tumpukan dimuat oleh konteks tugas.
void StartOS(unsigned long Num);
Mulai dari sistem operasi. Sebagai argumen ke fungsi, pengidentifikasi tugas untuk memulai eksekusi dilewatkan. Ketika sistem operasi dimulai, timer sistem diatur ke kuantum satu milidetik. Konteks dihapuskan dari tumpukan tugas yang diluncurkan dan tugas tersebut disebut.
void Sleep(unsigned long ms);
Perencana Ketika fungsi ini dipanggil dari tugas, kontrol ditransfer ke sistem operasi. Sistem operasi memilih tugas yang siap untuk dieksekusi dari daftar dan mentransfer kontrol ke sana. Argumen fungsi adalah waktu dalam milidetik setelah itu perlu untuk mengembalikan kontrol ke tugas saat ini. Ketika suatu fungsi dipanggil dengan argumen 0xFFFFFFFF, kontrol tidak akan pernah kembali.
Tidak mungkin untuk menulis fungsi ini dalam C, sehingga algoritma operasinya benar-benar menghancurkan logika bahasa. Kode sumber berisi tes program bahasa assembly untuk sistem pemrograman IAR dan GCC. Untuk penderita, kode dalam C diberikan. Tetapi saya ingin mencatat bahwa dia dapat mengkompilasi dengan benar hanya dengan "fase bulan" tertentu. Dalam kasus saya, ini terjadi hanya ketika menggunakan optimasi tingkat menengah, pada level rendah dan tinggi kode dikompilasi secara keliru.
File Sleep.c extern Task_t TaskList[IntorOSMaxKolvoZadach];
void EndTask(void);
Penyelesaian tugas. Seperti disebutkan di atas, tugas-tugas itu statis, tugas-tugas bongkar tidak mungkin. Jika Anda perlu menyelesaikan tugas, Anda dapat menggunakan fungsi ini. Tugas tetap ada dalam daftar, tetapi kontrol tidak ditransfer ke sana.
void StopTask(unsigned long Num); void StartTask(unsigned long Num);
Hentikan atau mulai tugas. Argumen adalah pengidentifikasi tugas. Fungsi-fungsi ini memungkinkan Anda untuk mengimplementasikan task manager. Perlu dicatat bahwa Anda hanya dapat memulai tugas yang sebelumnya dihentikan, waktu sampai dimulainya adalah 0xFFFFFFFF.
Menggunakan OS
Misalnya, mikrokontroler tradisional "helword" untuk sistem operasi yang dikembangkan.
#include "stm32l0xx.h" #include "stm32l0xx_ll_gpio.h" #include "IntorOS.h"
Sebagai kesimpulan, saya ingin dengan tulus berharap bahwa ini, untuk bersenang-senang, OS yang dikembangkan akan menarik dan bermanfaat bagi pengembang perangkat lunak untuk sistem embedded.