FreeRTOS-タスクの作成
9503 ワード
FreeRTOSの設計はコンパクトで簡単で、コアコード全体が3~4個のCファイルしかなく、コードを読みやすく、移植し、維持するために、大部分のコードはC言語で作成され、いくつかの関数(多くはアーキテクチャ特定のクラス分けサブルーチン)だけがアセンブリ言語で作成されている.
FreeRTOSは、マルチスレッド(threads)、マルチジョブ(task)、反発ロック(mutex)、信号量(semaphore)、ソフトウェアタイマ(software timer)を実現するための多くの方法を提供し、低消費電力アプリケーションのために提供されるクリックレスモードがあり、スレッドの優先権管理もサポートされている.
FreeRTOSのすべての作業はタスクで完了しているので、タスクがどのように作成されているかを見てみましょう.
タスクAPI関数の作成
タスクの作成xTaskCreate関数の使用
パラメータ名
説明
pvTaskCode
タスクは決して終了しないC関数にすぎず、実装は通常デッドサイクルである.パラメータpvTaskCodeは、タスクの実装関数を指すポインタ(効果的には関数名のみ)のみを指す.
pcName
記述的なタスク名.このパラメータはFreeRTOSでは使用されません.単純にデバッグを支援するために使用されます.可読性のある名前を識別することは、ハンドルで識別するよりもずっと簡単です.アプリケーションは定数config_を定義できます.MAX_TASK_NAME_LENは、タスク名の最大長を定義します.'0'終了子が含まれます.入力された文字列の長さがこの最大値を超えると、文字列は自動的に切断されます.
usStackDepth
タスクが作成されると、カーネルは各タスクに割り当てられてタスク独自の一意のステータスになります.USStackDepth値は、カーネルにどれだけのスタックスペースが割り当てられているかを示すために使用されます.この値は、スタックスペースが何バイト(byte)ではなく、何ワード(word)を保存できるかを指定します.たとえば、32ビット幅のスタックスペースで、入力されたusStackDepth値が100の場合、400バイトのスタックスペース(100*4 bytes)が割り当てられます.スタックの深さにスタックの幅を乗じた結果、sizeを超えてはいけません.t型変数が表現できる最大値.アプリケーションは定数configMINIMAL_を定義します.STACK_SIZEは,空きタスクが任用するスタック空間の大きさを決定する.
pvParameters
タスク関数はvoidを指すポインタ(void*)を受け入れます.pvParametersの値は、タスクに渡される値です.このドキュメントのいくつかのサンプルプログラムでは、このパラメータがどのように使用できるかを示します.
uxPriority
タスクの実行の優先度を指定します.優先度の値の範囲は、最低優先度0から最高優先度(configmaX_PRIORITIES–1)までです.configMAX_PRIORITIESは、ユーザによって定義される定数です.優先度番号には上限はありません(使用するデータ型とシステムの有効なメモリ領域に制限されている場合を除きます).ただし、メモリの無駄を回避するために、実際に必要な最小値を使用することが望ましいです.uxPriorityの値が(configmaX_PRIORITIES–1)を超えると、実際に割り当てられたタスクの優先度が最大正当値に自動的にカプセル化されます.
pxCreatedTask
pxCreatedTaskは、タスクをエクスポートするハンドルに使用されます.このハンドルは、作成されたタスクをAPI呼び出しで参照します.たとえば、タスクの優先度を変更したり、タスクを削除したりします.アプリケーションでこのタスクのハンドルが使用されない場合は、pxCreatedTaskをNULLに設定できます.
戻り値
1. pdTRUE
タスクの作成に成功したことを示します.
2. errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
メモリスタック容量が不足しているため、FreeRTOSはタスク構造データとタスクスタックを保存するのに十分なスペースを割り当てることができず、タスクを作成できません.
例
1.タスク1の作成
1.タスク2の作成
3、main()関数はこの2つのタスクを簡単に作成し、スケジューラを起動するだけです.
これで2つの簡単なタスクの作成が完了しました
FreeRTOSは、マルチスレッド(threads)、マルチジョブ(task)、反発ロック(mutex)、信号量(semaphore)、ソフトウェアタイマ(software timer)を実現するための多くの方法を提供し、低消費電力アプリケーションのために提供されるクリックレスモードがあり、スレッドの優先権管理もサポートされている.
FreeRTOSのすべての作業はタスクで完了しているので、タスクがどのように作成されているかを見てみましょう.
タスクAPI関数の作成
タスクの作成xTaskCreate関数の使用
portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,
const signed portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pxCreatedTask );
パラメータ名
説明
pvTaskCode
タスクは決して終了しないC関数にすぎず、実装は通常デッドサイクルである.パラメータpvTaskCodeは、タスクの実装関数を指すポインタ(効果的には関数名のみ)のみを指す.
pcName
記述的なタスク名.このパラメータはFreeRTOSでは使用されません.単純にデバッグを支援するために使用されます.可読性のある名前を識別することは、ハンドルで識別するよりもずっと簡単です.アプリケーションは定数config_を定義できます.MAX_TASK_NAME_LENは、タスク名の最大長を定義します.'0'終了子が含まれます.入力された文字列の長さがこの最大値を超えると、文字列は自動的に切断されます.
usStackDepth
タスクが作成されると、カーネルは各タスクに割り当てられてタスク独自の一意のステータスになります.USStackDepth値は、カーネルにどれだけのスタックスペースが割り当てられているかを示すために使用されます.この値は、スタックスペースが何バイト(byte)ではなく、何ワード(word)を保存できるかを指定します.たとえば、32ビット幅のスタックスペースで、入力されたusStackDepth値が100の場合、400バイトのスタックスペース(100*4 bytes)が割り当てられます.スタックの深さにスタックの幅を乗じた結果、sizeを超えてはいけません.t型変数が表現できる最大値.アプリケーションは定数configMINIMAL_を定義します.STACK_SIZEは,空きタスクが任用するスタック空間の大きさを決定する.
pvParameters
タスク関数はvoidを指すポインタ(void*)を受け入れます.pvParametersの値は、タスクに渡される値です.このドキュメントのいくつかのサンプルプログラムでは、このパラメータがどのように使用できるかを示します.
uxPriority
タスクの実行の優先度を指定します.優先度の値の範囲は、最低優先度0から最高優先度(configmaX_PRIORITIES–1)までです.configMAX_PRIORITIESは、ユーザによって定義される定数です.優先度番号には上限はありません(使用するデータ型とシステムの有効なメモリ領域に制限されている場合を除きます).ただし、メモリの無駄を回避するために、実際に必要な最小値を使用することが望ましいです.uxPriorityの値が(configmaX_PRIORITIES–1)を超えると、実際に割り当てられたタスクの優先度が最大正当値に自動的にカプセル化されます.
pxCreatedTask
pxCreatedTaskは、タスクをエクスポートするハンドルに使用されます.このハンドルは、作成されたタスクをAPI呼び出しで参照します.たとえば、タスクの優先度を変更したり、タスクを削除したりします.アプリケーションでこのタスクのハンドルが使用されない場合は、pxCreatedTaskをNULLに設定できます.
戻り値
1. pdTRUE
タスクの作成に成功したことを示します.
2. errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
メモリスタック容量が不足しているため、FreeRTOSはタスク構造データとタスクスタックを保存するのに十分なスペースを割り当てることができず、タスクを作成できません.
例
1.タスク1の作成
void Task1( void *pvParameters )
{
const char *pcTaskName = "Task1 output ........";
volatile unsigned long ul;
/* 。 */
while(1)
{
/* , */
vPrintString( pcTaskName );
/* , */
for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
{
/* 。 */
}
}
}
1.タスク2の作成
void Task2( void *pvParameters )
{
const char *pcTaskName = "Task2 output ........";
volatile unsigned long ul;
/* 。 */
while(1)
{
/* , */
vPrintString( pcTaskName );
/* , */
for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
{
/* 。 */
}
}
}
3、main()関数はこの2つのタスクを簡単に作成し、スケジューラを起動するだけです.
int main( void )
{
/* 。 xTaskCreate() ,
。 */
xTaskCreate( Task1, /* */
"Task 1", /* , */
1000, /* – */
NULL, /* */
1, /* 1 . */
NULL ); /* */
/* Create the other task in exactly the same way and at the same priority. */
xTaskCreate( Task2, "Task 2", 1000, NULL, 1, NULL );
/* , */
vTaskStartScheduler();
/* ,main() 。 ,
。 */
while(1);
}
これで2つの簡単なタスクの作成が完了しました