FRDM-K64FのSDKに付属のamazon FreeRTOS のサンプルをいじって、わかったことを書き留めます。
開発環境はMCUXpressoを使用します。
frdm_k64f_freertos_hello
- タスクからHelloWorldするサンプル
- ROM/RAM は
-O0
でそれぞれ 22872 Byte / 19120 Byte -
main()
では最初にBOARD_xxx
というAPI群を呼ぶ- クロック、ペリフェラル初期化など
-
BOARD_xxx
APIはboard/board.c
にあるBSPのAPI
-
xTaskCreate()
でHello_task
のタスク登録- 引数はタスクメイン関数ポインタ、タスク名、スタックサイズ、起動引数、プライオリティ、ハンドラ格納用変数
- このAPIを呼ぶには
source/FreeRTOSConfig.h
のconfigSUPPORT_DYNAMIC_ALLOCATION
が 1 でないといけない - タスク登録に成功すると
pdPASS
が返る
-
hello_task()
は無限ループ- "Hello world." を出力してサスペンドする
-
vTaskSupend()
はvTaskResume()
待ちとなりディスパッチされなくなる - 引数はタスクのハンドラだが、NULLで呼ぶと自身をサスペンドする
- タスク登録後
vTaskStartScheduler()
でタスクスケジューラを起動して、メイン関数は無限ループに入る - ここで起動しているタスクは3つ
- Hello_task
- IDLE : アイドルタスク
- Tmr svc : タイマーデーモンタスク
- アイドルタスクとタイマーデーモンタスクは
vTaskStartScheduler()
呼び出し時に自動的に作成される
source/freertos_hello.c抜粋
int main(void)
{
/* Init board hardware. */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
if (xTaskCreate(hello_task, "Hello_task", configMINIMAL_STACK_SIZE + 100, NULL, hello_task_PRIORITY, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
vTaskStartScheduler();
for (;;)
;
}
static void hello_task(void *pvParameters)
{
for (;;)
{
PRINTF("Hello world.\r\n");
vTaskSuspend(NULL);
}
}
frdm_k64f_freertos_event
- ROM/RAM は
-O0
でそれぞれ 21736 Byte / 19096 Byte - イベントフラグを使うサンプル
- FreeRTOSではイベントフラグをイベントグループという
- グローバルでイベントグループハンドラを宣言
-
main()
ではhelloworldと同様の初期化 -
xEventGroupCreate()
でイベントグループを作成、ヒープに確保される - イベントのビット数は
source/FreeRTOSConfig.h
のconfigUSE_16_BIT_TICKS
が 0 であるため 24 ビット - イベント書き込みタスク
WRITE_TASK_1
,WRITE_TASK_2
, イベント読み出しタスクREAD_TASK
を作成- プライオリティは大きい方が高く
READ_TASK
がWRITE_TASK_1
,WRITE_TASK_2
より高くしている
- プライオリティは大きい方が高く
- 2つのイベント書き込みタスクはひたすら
xEventGroupSetBits()
で、それぞれビット0, ビット1を立てる - 読み出しタスクは
xEventGroupWaitBits()
でイベントを待っている- この関数はブロックし、戻り値でイベントビットをとれる
- 引数はイベントグループハンドル、待受けビットマスク、ビットクリア指定、ビットマスクでしたビットのAND待ち、タイムアウトチック
- 待受けビットマスクは
B0 | B1 = 0x03
で待受け - ビットクリア指定は true なので、イベントが起きた後ビットはクリアされる
- 第4引数は false なので、ビット0, 1, タイムアウトのいずれかが起きると関数は返る
- タイムアウトは
portMaxDelay = 0xffffffffUL
となっているが詳細不明
- 読み出しタスクは起きたイベントに応じてログ出力する
- 起動するタスクは同じく、作成した3つとアイドルタスク、タイマーデーモンタスク
source/freertos_event.c抜粋
static EventGroupHandle_t event_group = NULL;
int main(void)
{
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
event_group = xEventGroupCreate();
if (xTaskCreate(write_task_1, "WRITE_TASK_1", configMINIMAL_STACK_SIZE + 100, NULL, tskIDLE_PRIORITY + 1, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
if (xTaskCreate(write_task_2, "WRITE_TASK_2", configMINIMAL_STACK_SIZE + 100, NULL, tskIDLE_PRIORITY + 1, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
if (xTaskCreate(read_task, "READ_TASK", configMINIMAL_STACK_SIZE + 100, NULL, tskIDLE_PRIORITY + 2, NULL) != pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
/* Start scheduling. */
vTaskStartScheduler();
for (;;)
;
}
static void write_task_1(void *pvParameters)
{
while (1)
{
xEventGroupSetBits(event_group, B0);
}
}
static void write_task_2(void *pvParameters)
{
while (1)
{
xEventGroupSetBits(event_group, B1);
}
}
static void read_task(void *pvParameters)
{
EventBits_t event_bits;
while (1)
{
event_bits = xEventGroupWaitBits(event_group, /* The event group handle. */
B0 | B1, /* The bit pattern the event group is waiting for. */
pdTRUE, /* BIT_0 and BIT_4 will be cleared automatically. */
pdFALSE, /* Don't wait for both bits, either bit unblock task. */
portMAX_DELAY); /* Block indefinitely to wait for the condition to be met. */
if ((event_bits & (B0 | B1)) == (B0 | B1))
{
PRINTF("Both bits are set.");
}
else if ((event_bits & B0) == B0)
{
PRINTF("Bit B0 is set.\r\n");
}
else if ((event_bits & B1) == B1)
{
PRINTF("Bit B1 is set.\r\n");
}
}
}
実行ログはこのようになる
Bit B0 is set.
Bit B1 is set.
Bit B0 is set.
Bit B1 is set.
Bit B0 is set.
Bit B1 is set.
Bit B0 is set.
Bit B1 is set.
Bit B0 is set.
.
.
試しにタスクプライオリティを READ
> WRITE2
> WRITE1
にしてみる。
WRITE1
はディスパッチされなくなり READ
と WRITE2
だけで回る。
Bit B1 is set.
Bit B1 is set.
Bit B1 is set.
Bit B1 is set.
Bit B1 is set.
Bit B1 is set.
Bit B1 is set.
Bit B1 is set.
.
.
今回はここまで。