投稿

ラベル(FreeRTOS)が付いた投稿を表示しています

ESP-IDFのFreeRTOSについて

ESP-IDFのFreeRTOSについて ESP-IDFのFreeRTOSについて FreeRTOS 本家の説明とESP-IDFのFreeRTOSに色々食い違いがあって「なんでだぁっ?」って思ってたんですが、当たり前の話でESP-IDFにはカスタマイズされたFreeRTOSがデフォルトで使用されていて違ってて当たり前だったんですね。 ESP-IDFのFreeRTOS の説明を読んでみれば一目瞭然でした。 例えばノーマルなFreeRTOSでは vTaskStartScheduler() を呼び出すのは必須ですが、ESP-IDFの場合は既に実行されていて、呼び出すなと書いてあります。 タスク一覧を取得するvTaskListを実行してみると以下のように返ってきます。 タスク名 状態 スタック空き main X 1 1764 4 0 IDLE R 0 1036 6 1 IDLE R 0 1232 5 0 esp_timer S 22 3576 3 0 ipc1 S 24 480 2 1 ipc0 S 24 480 1 0 R=準備完了, S=一時停止, B=ブロック, D=削除済, X=説明なし 既に幾つもタスクが実行されてますね。 ちなみに app_main() もタスクのようです上記のmainがapp_main()なのだと思われます。 vTaskListの実行方法 vTaskListも最初ビルドできなくてオロオロしましたが、menuConfigで以下をチェックすれば使えるようになります。 configGENERATE_RUN_TIME_STATS Enable display of xCoreID in vTaskList 上記の順番でチェックしないとvTaskListの方が出てきません。

FreeRTOSのスタック

イメージ
FreeRTOSのスタック FreeRTOSのスタック が、よくわからなくて困りました。 タスクを二つ作ったり、タスクの中の処理を弄ったりするとすぐにstack overflowで暴走しちゃうんです。 FreeRTOSのスタックって何をすると積まれていくのだろう。 # include <stdio.h> # include "freertos/FreeRTOS.h" # include "freertos/task.h" # include "esp_log.h" # define APP "TestRTOS" portTASK_FUNCTION ( task01 , pvParam ) { while ( 1 ) { // スタック使用量 UBaseType_t stackHighWaterMark = uxTaskGetStackHighWaterMark ( NULL ) ; ESP_LOGI ( APP , "task01 stack: %u" , stackHighWaterMark ) ; vTaskDelay ( 5000 / portTICK_PERIOD_MS ) ; // 5秒待機 } } void app_main ( void ) { uint32_t stack_size = configMINIMAL_STACK_SIZE ; ESP_LOGI ( APP , "MINIMAL_STACK_SIZE: %lu" , stack_size ) ; // スタックサイズ TaskHandle_t handle ; xTaskCreate ( task01 , "TestTask01" , configMINIMAL_STACK_SIZE * 2 , NULL , tskIDLE_PRIORITY , & handle ) ; ...

ボタンとタイマー

イメージ
ボタンとタイマー ボタンとタイマー ボタン押したら何かするとか、タイマーで一定時間経ったらLED点灯するとか、そういうのやったことないのでやってみます。 ボタンはDevKitCに一つついてます。二つついてますけど一つはリセットボタンなので自由に使えるのは一つだけ。GPIO0に接続されています。 GPIO0のボタンが押されたら10秒間だけLEDを点滅させる。 これだけです。 プログラム こんな感じになりました。 # include <stdio.h> # include "freertos/FreeRTOS.h" # include "freertos/task.h" # include "driver/gpio.h" # define BTN_GPIO 0 // オンボードSW (ONでLOW、OFFでHI) # define LED_GPIO 5 // LED // GPIOの入力ハンドラ void IRAM_ATTR gpio_isr_handler ( void * arg ) { TaskHandle_t xHandle = * ( TaskHandle_t * ) arg ; eTaskState state = eTaskGetState ( xHandle ) ; if ( state == eRunning ) { // 既に実行中の場合は終了 return ; } vTaskResume ( xHandle ) ; // 10秒間LED点滅タスクを再開する } // 10秒間LED点滅タスク portTASK_FUNCTION ( led_10sec_blinking , pvParam ) { while ( 1 ) { // 500ms間隔でLED点滅 int ledState = 1 ; for ( int i = 0 ; i < 20 ; i ++ ...