免責事項 著者は、マイクロコントローラ用のマルチタスクオペレーティングシステムの使用を支持していません。
人生は容赦なく、マイクロコントローラーにオペレーティングシステム(OS)の使用を強制します。 市場には非常に多くのそのようなシステムがあります。 互いに競合するオペレーティングシステム開発者は、製品の機能を最大限に活用しようとしています。 これはしばしばシステムの「重さ」の増加につながり、組み込みシステム用のソフトウェアを開発するプログラマーの「エントリーしきい値」も大幅に増加します。
私のプロジェクトでOSの選択に悩まされたり、他人の製品の研究に頭を悩ませたり、オペレーティングシステム用の組み込みアプリケーションを書く技術を習得したり、それが何であるかを理解したりするために、私は自分のOSを書くことにしました。 その匂いはありません。
提案されたOS(OS、言語はあえてOS、特にOSRVと呼ぶことを敢えてしない)は、静的タスクと協力します。 上記のように、私はマイクロコントローラー用のOSの使用を支持していませんが、マイクロコントローラーでプリエンプティブオペレーティングシステムを使用することの支持者でもありません。 協調的と比較して、プリエンプティブマルチタスクは、複雑なコンテキストスイッチング手順だけでなく、スレッドのリソース集約型の同期でもあります。 動的タスクを使用すると、オペレーティングシステムが大幅に複雑になります。
オペレーティングシステムは、Cortex-M0ファミリのプロセッサ用に開発されました。 コンテキストを保存および復元するためのルールにわずかな変更を加えることで、他のタイプのプロセッサーに使用できます。
ソースコード
ファイルIntorOS.h#ifndef __INTOROS_H #define __INTOROS_H
IntorOS.cファイル #define _INTOROS_C #include "stm32l0xx.h" #include "IntorOS.h"
ファイルIntorOSSleepIAR.s #define SHT_PROGBITS 0x1 EXTERN KolvoTask EXTERN TaskList EXTERN TaskNum PUBLIC Sleep SECTION `.text`:CODE:NOROOT(2) THUMB
ファイル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
OSコンパイル定数
#define IntorOSMaxKolvoZadach (2)
宗教的な理由から、動的なメモリ割り当てを使用できないため、必要なメモリの量はコンパイル段階で指定する必要があります。
OS OSサービス
void InitTask(void (*TaskPointer)(void), unsigned long Stek);
タスクの初期化。 タスクは関数の形式で実行され、関数へのポインターが初期化プロシージャに渡されます。 初期化中に、タスクに割り当てられたスタックサイズを指定する必要があります。 タスクが初期化される順序によって識別子が決まります。 最初に初期化されるタスクの識別子は0です。予約されたスタックサイズより大きい合計スタックサイズを指定すると、エラーが発生します。 タスクが初期化されると、タスクスタックへのポインターが設定され、スタックはタスクコンテキストによってロードされます。
void StartOS(unsigned long Num);
オペレーティングシステムの起動。 関数の引数として、実行を開始するタスクの識別子が渡されます。 オペレーティングシステムが起動すると、システムタイマーは1ミリ秒のクォンタムに設定されます。 コンテキストは、起動されたタスクのスタックから書き出され、タスクが呼び出されます。
void Sleep(unsigned long ms);
プランナー この関数がタスクから呼び出されると、制御はオペレーティングシステムに転送されます。 オペレーティングシステムは、リストから実行準備が整ったタスクを選択し、制御をそのタスクに渡します。 関数の引数は、現在のタスクに制御を戻す必要があるミリ秒単位の時間です。 関数が引数0xFFFFFFFFで呼び出された場合、制御は戻りません。
この関数をCで記述することは不可能であるため、その操作のアルゴリズムは言語のロジックを完全に破壊します。 ソースコードには、IARおよびGCCプログラミングシステム用のアセンブリ言語プログラムのテストが含まれています。 被災者のために、Cのコードが提供されています。 ただし、特定の「月の満ち欠け」でのみ正しくコンパイルできることに注意してください。 私の場合、これは中間レベルの最適化を使用した場合にのみ発生し、低レベルと高レベルでコードが誤ってコンパイルされました。
ファイルSleep.c extern Task_t TaskList[IntorOSMaxKolvoZadach];
void EndTask(void);
タスクの完了。 上記のように、タスクは静的であり、タスクのアンロードは不可能です。 タスクを完了する必要がある場合は、この機能を使用できます。 タスクはリストに残りますが、制御はそれに移されません。
void StopTask(unsigned long Num); void StartTask(unsigned long Num);
タスクを停止または開始します。 引数はタスクの識別子です。 これらの関数を使用すると、タスクマネージャーを実装できます。 以前に停止したタスクのみを開始できることに注意してください。開始するまでの時間は0xFFFFFFFFです。
OSを使用する
たとえば、開発されたオペレーティングシステム用の従来のマイクロコントローラ「helword」。
#include "stm32l0xx.h" #include "stm32l0xx_ll_gpio.h" #include "IntorOS.h"
結論として、私はこれが、楽しみのために、開発されたOSが組み込みシステム用ソフトウェアの開発者にとって興味深く有用であることを心から望みます。