FreeRTOSを仕事で使う機会がありましたので、使用方法・OSの振る舞いの概要をここにまとめておこうかと思います。
FreeRTOS( https://www.freertos.org/ )とは
複数のマイクロコントローラに対応した、オープンソースのRTOS。各マイクロコントローラごとにサンプルが用意されているため、導入は難しくない。
ライセンス
バージョン9までは例外条項付きGPLの下で配布されていた。 例外条項は、カーネルそのものがオープンソースである場合にはユーザのコードをクローズドソースにしておくことができるという内容である。Amazon.comに買収された後のバージョン10からはMITライセンスを採用している。
(wikipediaより引用)
FreeRTOSの振る舞いとAPI
用語
用語 | 意味 |
---|---|
アイドルタスク | アイドルタスクとは優先度が最小値で設定されている。 常時実行可能な状態のタスクのことを示す。 実行するタスクが無い場合、このタスクが動く。アイドルタスクはOSの処理で定義される |
タスクトレース | 作成されたタスク情報を出力する機能。OSの設定方法によっては使用可能 |
コルーチン | コルーチンはタスクと違い、スタックを共有する小さなタスクのことを示す。コルーチンは協調的スケジューリングを行う。主に低スペックなCPUでのマルチタスク動作がしたい場合に用いる |
OS設定
FreeRTOS設定方法
「FreeRTOSConfig.h」というファイルにて定義されているマクロの値を変更、もしくは決められたマクロを定義することによりOSの設定を変更できる。各マクロは以下を参照のこと
マクロ | 意味 |
---|---|
configUSE_PREEMPTION | スケジューラの設定。 値が1のときはプリエンプティブ、0のときは協調型 |
configUSE_TIME_SLICING | 同じ優先度のタスクに対しタイムスライスを行うかどうか。値が1の時にタイムスライスを行う |
configUSE_IDLE_HOOK | 値が1のとき、 「void vApplicationIdleHook( void )」 を定義することで、アイドルタスク内で定義したvApplicationIdleHook が呼ばれる |
configMAX_PRIORITIES | ( 設定した値-1 )がタスクの最大の優先度になる |
configUSE_TICK_HOOK | 値が1のとき、 「void vApplicationTickHook( void )」 を定義することでタイマ割込み内で「vApplicationTickHook」が呼ばれる。 割込み頻度は「configTICK_RATE_HZ」の値で設定できる |
configCPU_CLOCK_HZ | CPUの周波数を設定する |
configTICK_RATE_HZ | 1秒間に何度タイマ割込みがかかるかを示す |
configMINIMAL_STACK_SIZE | アイドルタスクのスタックサイズ(タスクのスタックの最小値)を設定 |
configTOTAL_HEAP_SIZE | 動的に確保できるメモリの総量。タスクのスタックもこの領域から確保するため、タスクのスタックが必要ならばこの値を大きくするとよい |
configMAX_TASK_NAME_LEN | タスク名(タスクを生成する際に指定するデバッグ用のタスクを示す文字 列)の最大の長さ |
configUSE_TRACE_FACILITY | タスクトレースを使用するかどうか。デバッグ用。1にした際はタスクトレースが使用可能になる |
configUSE_STATS_FORMATTING_FUNCTIONS | タスクトレースを使用するかどうか。デバッグ用。 configUSE_TRACE_FACILITYとこの値を1にした際はタスクトレースが使用可能になる |
configUSE_16_BIT_TICKS | タイマ割り込みによるtickカウンタのビット数を示す。1なら16bit、0なら32bit |
configIDLE_SHOULD_YIELD | configUSE_PREEMPTION == 1のとき、1を定義することでアイドルタスクの 処理中にタスクの切り替えを行う |
configUSE_CO_ROUTINES | コルーチンを使用するかどうか。 1を定義することでコルーチンが使用可能になる。 |
configUSE_MUTEXES | ミューテックスを使用するかどうか。 1を定義することでミューテックスを使用可能 |
configMAX_CO_ROUTINE_PRIORITIES | コルーチンの優先度の最大値を設定。 configMAX_CO_ROUTINE_PRIORITIES-1が優先度の最大値となる |
configUSE_COUNTING_SEMAPHORES | 資源獲得回数を数える機能を持ったセマフォを使うかどうか。 1にすると使用可能 |
configCHECK_FOR_STACK_OVERFLOW | stack overflow時の処理の設定。0にするとstack overflow時に何もしない。1にした場合はstack overflow時にタスクを停止する。2にした場合はstackが残り16byteを切った時に、ユーザが定義した void vApplicationStackOverflowHook(void) を呼び出す |
configUSE_RECURSIVE_MUTEXES | 再帰を使用した排他制御を使用するかどうか。1にすると使用可能 |
configQUEUE_REGISTRY_SIZE | デバッグ用。キューの名前を割り当てる際、いくつまで割り当てが可能かを設定する |
configGENERATE_RUN_TIME_STATS | タスクの実行状況を確認する機能を使うかどうか。1にするとタスクの実行状況の計測 を使用可能にする(cortex M3で使用できるかは不明。) |
INCLUDE_~ | 値が1のとき「~」に入るモジュールを使用可能にする。例えば「INCLUDE_vTaskPrioritySet」の値が1なら「vTaskPrioritySet()」関数が使用可能になる |
configKERNEL_INTERRUPT_PRIORITY | arm CortexM-3, PIC24, dsPIC, PIC32, SuperH and RX600.で使用。割込みの優先度の最大値(cortexM-3では0が最大値のため)を設定する。ここで設定された値が、そのままPendSVの優先度とSysTick の優先度に設定される |
configMAX_SYSCALL_INTERRUPT_PRIORITY | この値が割込みマスクレジスタ(BASEPRI(basepri))に反映される |
configSUPPORT_STATIC_ALLOCATION | OSで確保する以外のメモリを使用してタスク、システムコールを使用する場合に1にする。定義されていない場合は、OSのコード上で configSUPPORT_STATIC_ALLOCATION=0 と定義される |
configSUPPORT_DYNAMIC_ALLOCATION | OSで確保するメモリを使用してタスク、システムコールを使用する場合に1にする。 定義されていない場合は、OSのコード上で configSUPPORT_DYNAMIC_ALLOCATION=1 と定義される |
configTIMER_TASK_STACK_DEPTH | OS内で作成されるタイマータスクのスタックサイズ |
configTIMER_QUEUE_LENGTH | OS内で作成されるタイマータスクのキューの長さ |
configTIMER_TASK_PRIORITY | OS内で作成されるタイマータスクの優先度。低い優先度に設定しても特に影響はなし |
configUSE_TIMERS | OS内で作成されるタイマータスクを使用するかどうか。使わない場合は割込みからのシステムコールが使用できないため、値を1と定義しておく必要がある |
INCLUDE_xTimerPendFunctionCall | OS内で作成されるタイマータスクにおいて、割込みからのシステムコールの対応に必要な関数を使用するかどうか。基本的には値を1と定義しておく必要がある |
メモリ
-
OSにて使用しているメモリサイズは
376byte+タスクのスタックサイズ+queueサイズ(システムコール用に使っているもの) -
「FreeRTOSConfig.h」の「configTOTAL_HEAP_SIZE」の値で使用できるメモリの総サイズを調節できる
-
ヒープメモリの確保・解放のために使用するファイルが5つ用意されており、どれか一つを選んで使用する形
(私が使用した際は主にheap_4.cを使用。 heap_1.c、 heap_2.cはメモリが足リなくなりやすいので非推奨)
使用ファイル | メモリの処理方法 |
---|---|
heap_1.c | メモリの確保を一度行うと解放できない |
heap_2.c | メモリの再確保が可能。 ただし、フラグメンテーションを避けるための処理はなし |
heap_3.c | C言語のmalloc,freeのラッパー |
heap_4.c | メモリの再確保が可能。 フラグメンテーションを避けるため、解放されているメモリで隣接したものがあれば、一つにまとめる動作を行う。逆に小さいサイズのメモリが隣接していても一つにまとめてくれるわけではないので注意 |
heap_5.c | heap_4.cに加え、確保したメモリエリアを非隣接的に割り当てる機能あり。 vPortDefineHeapRegions()で使用するメモリを定義しなければ使用不可。定義したメモリのみを使用してタスクやシステムコールで使用するメモリを確保する。 |
参考: https://www.freertos.org/FAQMem.html
その他設定
FREERTOS_TASKS_C_ADDITIONS_INIT(型はvoid func(void))を定義することにより、vTaskStartScheduler呼び出し時に追加で初期化を行うことが可能
タスクステート
タスクの状態に関して説明する。タスクは生成された時点ではreadyステートになり、4つのステートどれかに設定されている。以下のリンクを参照のこと
参考:https://www.freertos.org/RTOS-task-states.html
Running
実行状態であることを示す。現在実行されているタスクがRunningステートとなる
Ready
実行可能状態であることを示す。現在実行されているタスクより優先度が低く、Blockedステート・SuspendedステートではないタスクがReadyステートとなる
Blocked
別タスク・もしくは割込みからのOSのシステムコール(イベントフラグ・メッセージボックス・データキュー等)を待っている際になるステート
Suspended
vTaskSuspend()を呼び出した際になるステート。Blockedステートとは厳密には違う状態として扱う
(ただし、ソースコードを見る限りではBlockedステートと同じ扱いをしている)
スケジューリング
FreeRTOSのスケジューラは「FreeRTOSConfig.h」の「configUSE_PREEMPTION」の値を1と定義するとプリエンプティブになる。「configUSE_PREEMPTION」の値を0とした際は協調的スケジューリングとなる
プリエンプティブスケジューリング
基本的なスケジューリングは、Itron系OS等と同等なスケジューリングを行う。ただし、同じ優先度のタスクにおいては「FreeRTOSConfig.h」の「configUSE_TIME_SLICING」の値を1にしていると、同じ優先度のタスク同士でタイムスライスを行い、交互にそれぞれのタスクが動く。また、タスクの切り替えのタイミングは以下の3つである
-
OS用のタイマ割込み
- タイマ割込みの頻度はFreeRTOSConfig.h内のconfigTICK_RATE_HZの値で調節可能。1秒間の間にconfigTICK_RATE_HZで指定した値の回数分だけが呼ばれる。ただし、内ではOSで使用するタイマのカウントも行うため、タスクを1ms刻みでwait,delayする際にはconfigTICK_RATE_HZの値を1000にしておく必要がある。(configTICK_RATE_HZの値は1000で固定を推奨)
-
RunningステートのタスクがBlockedステートorSuspendedステートに切り替わった時
-
OSのシステムコールにより、BlockedステートorSuspendedステートのタスクがreadyステートに切り替わった時
協調的スケジューリング
割愛(時間のある時に更新予定)
システムコール及びAPI
概ね使用頻度が高いものを重点的に説明する。「~ISR」という名前の付いた関数(xEventGroupSetBitsFromISR, xMessageBufferSendFromISR等 )は割込みのルーチンからシステムコール(セマフォ・イベントフラグ・メッセージボックス等の関数)を呼ぶ際に用いる関数である。
※ただし、この割込み用のシステムコールではシステムコールのアドレスを別の場所にストックし、割込み終了後にタイマー割り込みによって呼び出していると思われる。
スケジューラ関連
void vTaskStartScheduler( void )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | スケジューラをスタートする。(RTOSの動作開始) | |
引数 | なし | |
返り値 | なし |
void vTaskEndScheduler( void )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | スケジューラを停止する。(RTOSの動作終了) | |
引数 | なし | |
返り値 | なし |
TickType_t xTaskGetTickCount( void )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | OSのスケジューラで使用するタイマの値を取得する | |
引数 | なし | |
返り値 | OSのタイマの値 |
task関連
BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pvCreatedTask )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | タスクを生成する。 | |
引数 | pvTaskCode | タスクとなる関数 |
pcName | タスク名(デバッグ用。動作に影響なし) | |
usStackDepth | スタックサイズ | |
pvParameters | タスク起動時にタスクに渡される引数。 基本的にはNULLで設定 |
|
uxPriority | 優先度 | |
pvCreatedTask | タスクのID | |
返り値 | タスク生成が成功ならばpdTRUEを返す |
TaskHandle_t xTaskGetCurrentTaskHandle( void )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | 呼び出し先のタスクのIDを取得する | |
引数 | なし | |
返り値 | 呼び出し先のタスクID |
void vTaskDelete( TaskHandle_t xTaskToDelete )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | タスクを削除する(タスクがsuspendedステート、blockedステートの際に動作可能) | |
引数 | xTaskToDelete | 削除するタスクのID |
返り値 | なし |
wake(vTaskResume),sleep(vTaskSuspend)
wake,sleepという概念はなく、sleepはvTaskSuspend() 、wakeはvTaskResume() で代用することになる。ただし、vTaskResume()が呼ばれた後にvTaskSuspend()が呼ばれた際は、初めに呼ばれたvTaskResume()は無効になる。使用する際は必ずvTaskSuspend()を呼んだ後にvTaskResume()を呼ぶ必要がある(つまり、itronと違い、wakeリクエストはキューイングされない)
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | タスクのステートをSuspendedステートへ変更する | |
引数 | xTaskToSuspend | Suspendedステートへステートを変更する対象のタスクID |
返り値 | なし |
void vTaskResume( TaskHandle_t xTaskToResume )
void xTaskResumeFromISR( TaskHandle_t xTaskToResume )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | Suspendedステートのタスク のステートをReadyステート へ変更する。このとき、指定 したIDのタスクがSuspended ステートでない場合は何もしない |
|
引数 | xTaskToSuspend | Readyステートへステートを 変更する対象のタスクID |
返り値 | なし |
wait(vTaskDelay, vTaskDelayUntil)
「FreeRTOSConfig.h」の「configTICK_RATE_HZ」の値によって精度が変わるので注意。ms単位でwait,delayをしたい場合は、「configTICK_RATE_HZ」の値を1000にすること
void vTaskDelay( const TickType_t xTicksToDelay )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | 呼び出し先のタスクを引数で 指定した時間waitする |
|
引数 | xTicksToDelay | waitする時間 |
返り値 | なし |
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | 呼び出し先のタスクを指定した時間 (pxPreviousWakeTime + xTimeIncrement ) までwaitする。周期タスクにて使用するの がよい。vTaskDelayは、関数が呼ばれた時 点から指定した時間waitするが、この関数 はpxPreviousWakeTimeで入力された時間 から、xTimeIncrement で指定した時間waitする |
|
引数 | pxPreviousWakeTime | waitする時間の基準となる値。 初回の呼び出し時はxTaskGetTickCount() で取得した時間を入れる。 関数内でwaitが終了した時点で pxPreviousWakeTime = pxPreviousWakeTime + xTimeIncrement に更新される |
xTimeIncrement | pxPreviousWakeTimeからwaitする時間 | |
返り値 | なし |
semaphor
使用できるセマフォは以下の2種類ある
項目 | 説明 |
---|---|
バイナリセマフォ | 単発の待ち合わせ用のセマフォ。 Itron系と同じように使用できる。 「vSemaphoreCreateBinary()」 で生成 |
カウンタセマフォ | 複数回の資源獲得・解放を行う場 合に、資源獲得回数を記憶してお くことができるセマフォ。 「xSemaphoreCreateCounting()」 で生成 |
void vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | 単発の待ち合わせ用のセマフォ を作成する |
|
引数 | xSemaphore | セマフォID。 (SemaphoreHandle_tはポイン タとして定義されているので、 セマフォIDを格納したいものを 引数にする) |
返り値 | なし |
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | 資源獲得回数を数えるセマフォ を作成する |
|
引数 | uxMaxCount | 獲得回数の最大値 |
引数 | uxInitialCount | 獲得回数の初期値。この数値から カウントをスタートする |
返り値 | セマフォID。 (SemaphoreHandle_tはポイン タとして定義されているので、 セマフォIDを格納したいものを引 数にする) |
BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,
TickType_t xBlockTime )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | セマフォを獲得する (vSemaphoreCreateBinary ,xSemaphoreCreateCounting で作成されたセマフォ用) |
|
引数 | xSemaphore | 獲得するセマフォID |
xBlockTime | タイムアウト時間 | |
返り値 | 正常終了したならばpdTRUEを返す |
BaseType_t xSemaphoreGive( xSemaphore )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | セマフォを解放する (vSemaphoreCreateBinary, xSemaphoreCreateCounting で作成されたセマフォ用) |
|
引数 | xSemaphore | 解放するセマフォID |
返り値 | 正常終了したならばpdTRUEを返す |
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | セマフォを削除する (vSemaphoreCreateBinary, xSemaphoreCreateCounting で作成されたセマフォ用) |
|
引数 | xSemaphore | 削除するセマフォID |
返り値 | なし |
eventGroup(eventFlag)
名前はeventGroupだが、仕様はItronやToppers等のイベントフラグと似たような形。''イベントフラグの使用可能な数はFreeRTOSConfig.hで定義するconfigUSE_16_BIT_TICKSの値によって決まる。configUSE_16_BIT_TICKSが0なら8、configUSE_16_BIT_TICKSが1なら24まで使用することができる''
EventGroupHandle_t xEventGroupCreate( void )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | イベントフラグを作成する | |
引数 | なし | |
返り値 | 作成に成功したイベントフラグのID。失敗時はNULLが入る |
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
const TickType_t xTicksToWait );
項目1 | 項目2 | 説明 |
---|---|---|
機能 | イベントフラグを待つ | |
引数 | xEventGroup | イベントフラグID |
uxBitsToWaitFor | 待ちbitパターン | |
xClearOnExit | イベントフラグが立った際に、 フラグをクリアするかどうか |
|
xWaitForAllBits | pdTRUEならば、待っている すべてのbitが立つまで待つ。 pdFALSEなら、待っている bitのうちどれかが立つのを待つ |
|
xTicksToWait | タイムアウト時間 | |
返り値 | 待ち解除時のbitパターン |
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | イベントフラグを立てる | |
引数 | xEventGroup | イベントフラグID |
uxBitsToSet | セットするbitパターン | |
返り値 | uxBitsToSet をセットした後のbitパターン |
EventBits_t xEventGroupSetBitsISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t *pxHigherPriorityTaskWoken )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | イベントフラグを立てる | |
引数 | xEventGroup | イベントフラグID |
uxBitsToSet | セットするbitパターン | |
pxHigherPriorityTaskWoken | イベントフラグを立てた際にready ステートになるタスクが、その時 点でrunningステートのタスクよりも優先度が高い場合にpdTRUEが入る |
|
返り値 | uxBitsToSet をセットした後のbit パターン |
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear );
項目1 | 項目2 | 説明 |
---|---|---|
機能 | イベントフラグをクリアする | |
引数 | xEventGroup | イベントフラグID |
uxBitsToClear | クリアするbitパターン。 0になっているbitをクリアする |
|
返り値 | uxBitsToClear でクリアする前のbitパターン |
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | イベントフラグを削除する | |
引数 | xEventGroup | 削除するイベントフラグのID |
返り値 | なし |
スケジューラの具体的な動きとしては、タスク情報の構造体のメンバであるイベントリスト(xEventListItem)に待っているビットの値を格納し、ブロックステートに入り、タスクの切り替えを行う。仕様書ではフラグ待ち時はブロックステートとなっているが、タスクをサスペンドさせた時と同じようにpxDelayedTaskListに追加される
イベントフラグのセット時は、タスク情報からイベントリスト(xEventListItem)内にあるビットの値を参照し、待っていたビットならばステートをreadyステートに変更し、タスクの切り替えを行う。
messageBuffer(messageBox)
名前はmessageBufferだが、仕様はItronやToppers等のメッセージボックス、メールボックスと似たような形。ただし、メッセージボックスで受信するのに使うバッファはユーザ側で定義する必要がある(OS側では受信バッファを用意していない)。
また、uItronにおけるメッセージバッファ(先頭アドレスのみを渡すもの)は機能として存在しない
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | メッセージボックスを作成する | |
引数 | xBufferSizeBytes | 一度に送受信可能なメッセージサイズ。小さすぎると動作が遅くなることがあるので注意 (単位はbyte) |
返り値 | 作成に成功したメッセージボックスの ID。失敗時はNULLが入る |
size_t xMessageBufferSend(
MessageBufferHandle_t xMessageBuffer,
const void *pvTxData,
size_t xDataLengthBytes,
TickType_t xTicksToWait )
size_t xMessageBufferSendISR(
MessageBufferHandle_t xMessageBuffer,
const void *pvTxData,
size_t xDataLengthBytes,
TickType_t xTicksToWait )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | メッセージボックスへメッセージ を送る |
|
引数 | xMessageBuffer | 送信先のメッセージボックスのID |
pvTxData | 送信するメッセージの先頭ポインタ (メッセージそのものはメッセージ ボックス内でコピーされ使われる) |
|
xDataLengthBytes | 送信するメッセージの長さ(byte値) | |
xTicksToWait | タイムアウト時間 | |
返り値 | 送信が完了したデータサイズ(byte値) |
size_t xMessageBufferReceive(
MessageBufferHandle_t xMessageBuffer,
void *pvRxData,
size_t xBufferLengthBytes,
TickType_t xTicksToWait )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | メッセージボックスからメッセージを受信する | |
引数 | xMessageBuffer | 受信先のメッセージボックスのID |
pvRxData | 受信するメッセージの先頭ポインタ (メッセージそのものはpvRxDataに コピーされる) |
|
xBufferLengthBytes | 受信するメッセージの長さ(byte値) | |
xTicksToWait | タイムアウト時間 | |
返り値 | 受信が完了したデータサイズ(byte値) |
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | メッセージボックスを削除する | |
引数 | xMessageBuffer | 削除するメッセージボックスのID |
返り値 | なし |
ミューテックス
未調査。後々更新予定
メモリ関連
void *pvPortMalloc( size_t xSize )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | メモリの確保 | |
引数 | xSize | 確保するメモリサイズ |
返り値 | 確保したメモリの先頭ポインタ |
void vPortFree( void *pv )
項目1 | 項目2 | 説明 |
---|---|---|
機能 | メモリの解放 | |
引数 | pv | 解放するメモリの先頭ポインタ |
返り値 | なし |
FreeRTOSのコード例
一つ以上のタスクを生成し、「vTaskStartScheduler()」を呼び出すことによりOSのスケジューリングが開始される。
以下にFreeRTOSを使用した際のmain.cのコード例を示す。以下の例では優先度2、スタックサイズ1024のタスク(mainTask)を作成し、動作させている
コード例:
/* FreeRTOS用モジュール */
#include "FreeRTOS.h"
#include "task.h"
static void mainTask( void *pvParameters );
int main()
{
UENV_OS_TSKID testID1;
uenv_os_CreTask( mainTask, &testID1, 2, 1024 );
/* RTOSの動作開始。中で無限ループしている。エラーがかかった場合のみリターンされる */
vTaskStartScheduler();
while(1);
}
static void mainTask( void *pvParameters )
{
const TickType_t xTicksToDelay = 1000 / portTICK_PERIOD_MS;
while(1) {
vTaskDelay( xTicksToDelay );
}
}
※また、使用するすべてのタスクを定義した後に「vTaskStartScheduler()」を呼び出すことが公式では推奨されているが、特に動作に影響はないので気にしなくてもよいと思われる(動作確認済)
その他
- cortex M-3にてfreeRTOSを用いる際はcortex M-3用のMemory protection Unitはサポート