Tentang penyalahgunaan penggunaan sistem operasi dalam proyek untuk mikrokontroler

Mikrokontroler modern memiliki kinerja yang cukup tinggi dan ini memberi banyak programmer kesempatan untuk berpikir kira-kira sebagai berikut: - β€œTidak apa-apa jika 1-5% kinerja digunakan untuk pemeliharaan sistem operasi. Tetapi kode saya akan mudah didebug dan eksplisit! " Pemikiran ini didukung oleh sejumlah besar memori (flash) non-volatile untuk menyimpan kode sistem operasi dan memori operasional (RAM / SRAM) untuk mengalokasikan tumpukannya sendiri untuk setiap tugas. Namun, dalam banyak kasus ide ini keliru. Dan dalam artikel ini saya akan memberi tahu Anda alasannya.

Tentang proyek tempat saya bekerja


Dalam praktik saya, saya sering harus bekerja dengan "desainer". Saya menggambarkan pendekatan ini secara rinci dalam artikel saya sebelumnya tentang penggunaan C ++ di mikrokontroler . Maka saya tidak memberi tahu hal yang paling penting. Sebagian besar "blok" dari "konstruktor" ini entah bagaimana terikat pada sistem operasi waktu-nyata. Sebagian besar "blok" memiliki aliran sendiri (tugas, dalam hal sistem operasi real-time FreeRTOS yang digunakan). Dan itu, rata-rata, proyek ini memiliki sekitar 10-15 tugas. Terkadang nilai ini mencapai 35-40.

Di mana begitu banyak?


Berikut adalah daftar singkat tugas yang dihadapi dalam setiap proyek:
  • Pemeliharaan ADC (setiap modul dilayani oleh alirannya sendiri);
  • pemeliharaan wdt (jika OS crash, tugas tidak akan mengatur ulang dan perangkat akan reboot);
  • bekerja dengan halaman pengaturan (aliran terpisah mengontrol pekerjaan dengan memori flash);
  • pemeliharaan protokol interaksi dengan dunia luar (hilir ke antarmuka. Misalnya, uart);

Kemudian sudah ada hal-hal spesifik untuk setiap perangkat, seperti aliran untuk servis termistor (menerima data dari aliran pengukuran ADC dan mengubah data ini ke suhu), polling periferal eksternal dan sebagainya.

Kesederhanaan yang tampak


Terlepas dari kenyataan bahwa ada banyak tugas dalam proyek, masing-masing dari mereka "tersembunyi" di dalam objek dari kelas yang sesuai (ingat bahwa konstruktor dalam C ++, tetapi ini juga dapat ditiru dalam C menggunakan "pemrograman dalam C dalam gaya berorientasi objek." Tapi lebih baik tidak perlu ). Karena objek "konstruktor" ini bersifat global dan FreeRTOS 9 digunakan dalam proyek-proyek, yang mendukung pembuatan entitas mereka sendiri dalam buffer yang dialokasikan oleh pengguna, penggunaan memori dapat dikontrol pada saat menghubungkan. Jadi dari sudut pandang pemantauan kebocoran memori - semuanya lebih atau kurang normal. Namun ada beberapa nuansa berikut:
  • perlu dipahami dengan jelas berapa banyak tumpukan yang dibutuhkan untuk setiap utas. Dalam hal ini:
    • kasus kritis harus diperhitungkan (misalnya, bersarang dengan perilaku tertentu);
    • jika fungsi dari perpustakaan standar digunakan, maka juga tahu bagaimana mereka diatur, atau setidaknya memiliki gagasan tentang seberapa banyak mereka akan mengkonsumsi tumpukan;

Terlepas dari kenyataan ini, tampaknya menggunakan sistem operasi hanya akan meningkatkan logika kode dan membuatnya lebih jelas.

Penyalahgunaan fungsi sistem operasi


Masalah utama dimulai pada saat Anda mulai melupakan apa yang Anda tulis khusus untuk mikrokontroler. OS membebankan biaya untuk bekerja dengan entitasnya sendiri (seperti semafor, mutex, antrian). Berikut adalah contoh kelas UART untuk mengimplementasikan fungsi terminal . Dalam interupsi, sebuah byte diterima, setelah itu, jika melewati rentang dengan karakter input yang valid, ia ditambahkan ke antrian dengan penggantian yang sesuai (misalnya, '\ n' berubah ke urutan "\ n \ r"). Ini dilakukan untuk mengamankan port untuk pengiriman (karena port dapat berfungsi tidak hanya sebagai terminal. Data log juga dapat dikirim melaluinya). Di satu sisi, ini memastikan bahwa respons akan dikirim sesegera mungkin dan tidak akan mengganggu pengiriman data prioritas yang lebih tinggi (selain itu, sementara data prioritas yang lebih tinggi dikirim, ia terakumulasi dalam buffer, yang memungkinkan DMA digunakan untuk mengirim respons). Namun, mulai dari saat ini Anda mendapatkan jalur yang licin. Alih-alih menulis banyak melalui antrian, orang hanya bisa mengkonfigurasi dengan benar gangguan pada buffer non-kosong yang saat ini tidak berfungsi pada UART dan ketika DMA berakhir. Pendekatan ini membutuhkan pemahaman yang jelas tentang cara kerja perangkat. Namun, ini mengurangi biaya ke minimum absolut, membuat kebutuhan untuk solusi seperti itu nol.

Mengabaikan fungsionalitas perangkat keras mikrokontroler


Dalam praktik saya, saya bertemu proyek dengan 18 pengatur waktu perangkat lunak sistem operasi yang disetel ke frekuensi yang sama. Pada saat yang sama, ada sekitar 10 timer dalam mikrokontroler, yang hanya digunakan systic. Untuk mencatat penjadwal sistem operasi. Keputusan ini dijelaskan oleh kurangnya keinginan untuk "mengacaukan perangkat keras" dari mikrokontroler. Pada saat yang sama, sekitar 10 kb dialokasikan ke stack untuk fungsi yang disebut oleh pengatur waktu perangkat lunak. Bahkan, sekitar 1 kb digunakan (pendek). Ini disebabkan oleh "ambiguitas apa yang terjadi di dalam perpustakaan yang disebut."
Dalam hal ini, dimungkinkan untuk memilih TIM6 dengan aman (dalam kasus menggunakan stm32f4), yang akan menghasilkan interupsi dengan frekuensi yang diberikan dan di dalamnya hanya akan memanggil fungsi yang diperlukan.

Menggunakan infinite loop sebagai ganti mesin negara


Sebagai kolom terpisah, saya akan memilih ketidakmampuan beberapa programmer untuk menulis mesin negara hingga, dan bukannya membuat aliran di mana ada loop tak terbatas yang memulai kerjanya dengan mendapatkan sesuatu dari antrian. Menariknya, cara membuat mesin negara terbatas hingga melalui bahasa itu sendiri ditulis dalam artikel ini .

Mengabaikan "penjadwal perangkat keras"


Banyak mikrokontroler 32 bit memiliki pengontrol interupsi yang dipikirkan dengan baik dengan sistem prioritas yang dapat disesuaikan. Dalam kasus stm32f4, ia memiliki nama NVIC, dan memiliki kemampuan untuk menetapkan prioritas interupsi dengan 16 level (tanpa mempertimbangkan sub-level).
Sebagian besar aplikasi di bawah FreeRTOS yang harus saya tangani dapat ditulis sebagai mesin negara yang disebut interupsi dengan prioritas yang dikonfigurasi dengan benar. Dan jika prosesor kembali ke "eksekusi normal" - pergi ke "tidur". Dalam hal ini, tidak perlu memblokir akses ke sebagian besar sumber daya (variabel dan lainnya). Aplikasi akan kehilangan tingkat abstraksi ekstra. Dan dalam hal ini - jauh dari gratis. Namun, pendekatan ini memerlukan perencanaan arsitektur yang bijaksana untuk setiap proyek. Dalam proyek, "desainer" - semua interupsi memiliki satu prioritas dan, pada kenyataannya, diperlukan untuk "menyaring" data. Kemudian masukkan sisa-sisa dalam antrian, dari mana aliran objek kelas yang sesuai akan mengambilnya.

Ringkasan


Dalam artikel ini saya berbicara tentang masalah dasar yang harus Anda hadapi ketika menggunakan sistem operasi dalam proyek-proyek untuk mikrokontroler, dan juga memeriksa kasus-kasus umum menggunakan sistem operasi ketika ini bisa dihindari tanpa kehilangan keterbacaan dan logika kode.

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


All Articles