Seluruh kebenaran tentang RTOS dari Colin Walls. Artikel # 4. Tugas, pengalihan konteks, dan interupsi

Pengidentifikasi tugas


Anda harus dapat mengidentifikasi setiap tugas dalam sistem. Persyaratan ini penting untuk objek kernel lain, tetapi ada beberapa nuansa dalam tugas yang sesuai dengan topik artikel ini.



Pengembang RTOS menggunakan pendekatan berbeda untuk mengidentifikasi tugas, tetapi empat strategi umum dapat dibedakan:

  • Tugas diidentifikasi menggunakan pointer ke "blok kontrol". Pointer selalu unik dan juga nyaman digunakan, karena akses ke unit kontrol diperlukan untuk banyak panggilan API. Ini menyiratkan bahwa semua data tugas disimpan dalam memori akses acak (RAM), yang bisa jadi tidak efisien. Pointer biasanya membutuhkan sekitar 32 bit memori.
  • Suatu tugas dapat didefinisikan menggunakan "nomor indeks" yang berubah-ubah. Nilai ini mungkin berguna ketika memberikan akses ke catatan di tabel tertentu. Pengidentifikasi semacam itu dapat menempati delapan atau kurang bit memori, tergantung pada batasan jumlah tugas yang didukung RTOS.
  • Beberapa RTOS hanya mengizinkan satu tugas per tingkat prioritas dan karenanya menggunakan prioritas untuk mengidentifikasi tugas secara unik. Ini berarti bahwa prioritas tugas tidak dapat diubah. Pendekatan ini merupakan variasi dari pendekatan sebelumnya.
  • Tugas dapat memiliki nama yang merupakan string karakter. Ini mungkin berguna untuk debugging, tetapi tidak mungkin menjadi cara yang efektif untuk mengidentifikasi tugas secara unik. RTOS yang mendukung penamaan tugas biasanya memiliki pengenal tambahan (seperti pointer) yang digunakan oleh panggilan API, dll. Untuk sebagian besar sistem yang disematkan, nama teks adalah overhead; debugger yang baik memungkinkan Anda untuk memanggil mereka secara lokal di host.

Artikel sebelumnya dalam seri:
Artikel # 3. Tugas dan Perencanaan
Artikel # 2. RTOS: Struktur dan mode waktu-nyata
Artikel # 1. RTOS: pengantar.

Sakelar konteks


Pergantian konteks adalah proses mentransfer kontrol dari satu tugas ke tugas lainnya. Topik ini layak ditelusuri lebih dekat, karena bagaimana pengalihan konteks bekerja adalah prinsip dasar RTOS.

Apa itu tugas?


Kita tahu bahwa tugas adalah program semi-independen yang membagi waktu prosesor dengan sejumlah tugas lain di bawah kendali RTOS. Tetapi Anda perlu memikirkan apa yang benar-benar menjadi ciri tugas tersebut.

Daftar diatur


Suatu tugas pada akhirnya adalah seperangkat nilai register prosesor yang unik. Mereka dimasukkan ke dalam register prosesor (yaitu, tugas saat ini), atau disimpan di suatu tempat hingga waktu eksekusi yang dijadwalkan. Dalam dunia yang ideal, prosesor sentral akan memiliki beberapa set register, dan masing-masing dapat ditugaskan untuk tugas yang terpisah. Ini telah diterapkan untuk acara-acara khusus. Bertahun-tahun yang lalu, seri Texas Instruments TI 9900 memiliki banyak set register untuk setiap pekerjaan, tetapi mereka diimplementasikan dalam memori utama, yang kinerjanya terbatas. Arsitektur SPARC (sebelumnya digunakan pada sistem desktop Unix) mendukung banyak set register di "struktur cincin", tetapi jumlah set masih terbatas.

Data internal


Tugas mungkin akan memiliki tumpukan sendiri, yang ukurannya dapat diatur secara terpisah untuk setiap tugas atau dapat menjadi parameter global untuk semua tugas dalam sistem. Ini, bersama dengan register, menyediakan penyimpanan data untuk tugas-tugas tertentu. Mungkin ada area memori lain untuk menyimpan data untuk tugas tertentu.

Sumber daya bersama


Hampir semua sumber daya dapat dibagi di antara tugas-tugas. Kode dapat bersifat umum: baik fungsi tertentu, atau seluruh kode tugas. Penting untuk memastikan bahwa kode tersebut reentrant, pertama-tama, variabel statis tidak boleh digunakan (ditentukan sebagai statis atau tepat di luar fungsi). Hati-hati dengan modul perpustakaan standar yang tidak dimaksudkan untuk penggunaan built-in; mereka biasanya memiliki banyak fungsi yang tidak dapat diandalkan.

Berbagi data juga dimungkinkan, tetapi kontrol akses yang cermat diperlukan. Idealnya, hanya satu tugas adalah "pemilik" data pada waktu tertentu.

Bagaimana menjaga konteks


Ketika tugas dijadwal ulang (yaitu, ia berhenti menjadi saat ini), set registernya harus disimpan di suatu tempat. Setidaknya ada dua kemungkinan:

  • Register dapat disimpan dalam tabel khusus untuk tugas-tugas. Dapat menjadi bagian dari blok kontrol tugas (TCB). Ukuran adalah nilai yang dapat diprediksi dan konstan (untuk arsitektur CPU tertentu).
  • Register dapat didorong ke tumpukan tugas. Ini membutuhkan alokasi ruang stack tambahan yang cukup dan penyimpanan pointer (mungkin di TCB).

Pilihan mekanisme tergantung pada fitur-fitur RTOS tertentu dan pada prosesor target. Beberapa perangkat (biasanya 32-bit) dapat mengakses tumpukan secara efisien; sisanya (misalnya, 8-bit) mungkin lebih optimal ketika bekerja dengan tabel.

Pembuatan tugas dinamis


Aspek utama dari arsitektur RTOS adalah bahwa RTOS adalah "statis" atau "dinamis".

Saat menggunakan RTOS statis, semuanya ditentukan selama pembuatan aplikasi, khususnya, jumlah tugas dalam sistem. Ini adalah solusi logis untuk aplikasi tertanam, yang biasanya memiliki fungsi terbatas.

Dynamic RTOS meluncurkan satu tugas (yang dapat menjadi tugas "utama" khusus), dan juga membuat dan menghapus tugas lain sesuai kebutuhan. Ini memungkinkan sistem untuk beradaptasi dengan kebutuhan yang berubah dan merupakan analog yang lebih dekat dari sistem desktop, yang berperilaku seperti ini. Tampilan statis / dinamis juga berlaku untuk objek kernel lainnya.

Persyaratan Pembuatan Tugas Dinamis


Fitur ini termasuk dalam sebagian besar RTOS komersial. Namun, hanya sebagian kecil dari aplikasi yang benar-benar membutuhkan mode operasi yang dinamis. Sangat sering, sistem dinyalakan, membuat semua tugas yang diperlukan (dan objek lainnya), dan kemudian tidak pernah membuat dan menghancurkan kode aplikasi lagi. Kemampuan untuk membuat tugas yang dinamis telah menjadi formalitas. Satu pemasok memperkenalkannya, semua yang lain mengikuti.

Patut dicatat bahwa standar OSEK / VDX membutuhkan arsitektur statis, meskipun ini mungkin berlaku untuk aplikasi yang cukup kompleks. Hasil dari persyaratan ini adalah ketidakmampuan untuk mengimplementasikan OSEK / VDX dengan pembungkus, lapisan perantara di atas RTOS (dinamis) reguler.

Jebakan penciptaan tugas dinamis


Ada beberapa masalah dengan mode operasi dinamis yang dapat mengganggu.

Pertama, sistem menjadi lebih kompleks, yang berarti bahwa untuk struktur data yang menggambarkan tugas (TCB), informasi tambahan diperlukan. Sebagai aturan, mereka diimplementasikan dalam bentuk daftar dua arah, yang mengarah pada biaya yang terkait dengan jumlah memori.
Semua data yang menggambarkan tugas harus disimpan dalam RAM. Ini tidak efisien, karena kebanyakan dari mereka mungkin hanya elemen data persisten yang disalin dari ROM. Selain itu, pada prosesor tingkat yang lebih rendah (mikrokontroler) mungkin tidak mendapatkan RAM.

Mungkin yang paling mengkhawatirkan adalah kemungkinan kekurangan sumber daya yang tidak terduga, yang dapat menyebabkan ketidakmampuan untuk membuat objek baru. Karena esensi dari sistem waktu-nyata adalah prediktabilitasnya, ini tidak dapat diterima. Oleh karena itu, kehati-hatian harus diambil ketika menggunakan penciptaan tugas dinamis (dan objek lainnya).

Gangguan


Ada kemungkinan bahwa sistem real-time tertanam dapat diimplementasikan tanpa menggunakan interupsi, tetapi ini tidak khas.

Interupsi dan Kernel


Saat menggunakan RTOS, interrupt handler (ISR) dibuat semudah mungkin untuk "mencuri" jumlah minimum waktu prosesor dari tugas yang dijadwalkan. Seringkali perangkat dapat dengan mudah diservis, dan tugas apa pun yang diperlukan akan diantrikan untuk diproses. Selain itu, sulit untuk berbicara secara umum tentang interupsi dan interaksinya dengan kernel, hanya karena sangat bervariasi. Di satu sisi, pengembang RTOS dapat memastikan bahwa interupsi tidak berhubungan dengan kernel sama sekali, dan programmer harus memastikan bahwa penjadwal tugas tidak kelebihan beban, menggunakan banyak waktu prosesor dalam ISR. Di sisi lain, RTOS dapat sepenuhnya mengendalikan seluruh subsistem interupsi. Tidak ada satu pun dari pendekatan yang dijelaskan itu benar atau salah, mereka hanya berbeda.

Menyimpan Konteks


ISR selalu perlu mempertahankan "konteks" sehingga kode yang dapat terputus tidak terpengaruh oleh perhitungan ISR. Dalam suatu sistem yang diimplementasikan tanpa RTOS, ini hanyalah masalah menyimpan register yang digunakan oleh ISR (biasanya di stack) dan mengembalikannya sebelum kembali. Beberapa prosesor memiliki tumpukan ISR khusus, sementara yang lain hanya menggunakan tumpukan yang sama dengan kode aplikasi.

Saat menggunakan RTOS, pendekatannya mungkin persis sama. Dengan cara yang sama, tumpukan yang digunakan oleh ISR dapat "dipinjam" dari tugas saat ini, atau bisa juga tumpukan lain yang dialokasikan untuk interupsi. Beberapa core menerapkan fitur ini, bahkan jika prosesor itu sendiri tidak mendukung stack interrupt. Situasi menjadi rumit jika ISR membuat panggilan API yang memengaruhi penjadwal tugas. Ini dapat menyebabkan interupsi untuk kembali ke tugas lain dari yang dimulai ketika interupsi terjadi.

Interupsi dan Penjadwal


Ada beberapa keadaan di mana kode eksekusi ISR โ€‹โ€‹dapat kembali ke tugas lain:

  • ISR dapat menetapkan prioritas yang lebih tinggi untuk tugas yang sudah selesai, daripada yang sekarang, jika penjadwal tugas prioritas digunakan.
  • ISR dapat menjeda tugas saat ini.
  • Dengan menggunakan Time-Slice Scheduler (TS), pengendali penghitung waktu sistem akan mengontrol interval waktu dan dapat memanggil penjadwal jika perlu.

Timer Jam (Centang Jam)


Dalam sistem embedded, penggunaan "timer waktu" berkala (irisan waktu) sering ditemukan. Dalam beberapa RTOS, itu adalah komponen yang diperlukan. Biasanya, keberadaan timer jam adalah opsional, dan ketidakhadirannya hanya menghalangi ketersediaan layanan tertentu. Timer interrupt handler biasanya menyediakan empat fungsi:

  • Jika penjadwal slot waktu digunakan, pengendali interupsi timer akan mengontrol penghitung waktu dan menjadwalkan tugas baru setiap kali waktu habis.
  • Memberikan dukungan waktu sistem. Ini terutama variabel 32-bit yang ditambahkan oleh penghitung waktu dan dapat ditentukan atau diminta oleh tugas.
  • Jika RTOS menyediakan aplikasi dengan penghitung waktu, maka itu akan didukung oleh pengatur waktu penghenti yang akan bertanggung jawab untuk kedaluwarsa dan penjadwalan ulang.
  • Jika RTOS mendukung timeout dalam memblokir panggilan API atau tugas mungkin dalam kondisi tidur, maka interval waktu ini akan didukung oleh penangan interupsi timer.

Ketika kami sedang mengerjakan sistem operasi OSRV MAX real-time kami (sebelumnya saya telah menerbitkan artikel tentang itu), tim kami โ€œmenemukanโ€ blog Colin Walls, seorang ahli mikroelektronika dan firmware di Mentor Graphics. Artikel-artikel tampak menarik, menerjemahkannya untuk diri mereka sendiri, tetapi agar tidak "menulis ke meja" mereka memutuskan untuk menerbitkan. Saya harap mereka juga bermanfaat bagi Anda. Jika demikian, maka kami berencana untuk menerbitkan semua artikel yang diterjemahkan dalam seri.

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: blogs.mentor.com/colinwalls, email: colin_walls@mentor.com

Baca artikel pertama, kedua, dan ketiga dalam seri yang diterbitkan sebelumnya.

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


All Articles