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);
vTaskDelay(NULL);
}
こんな感じでタスク一個作って5秒間隔でタスクのスタック残量を出力するプログラムを作ったんですが。
出力された内容はこんな感じになりました。
I (317) TestRTOS: MINIMAL_STACK_SIZE: 1536
I (317) main_task: Returned from app_main()
I (327) TestRTOS: task01 stack: 2772
I (5337) TestRTOS: task01 stack: 1332
I (10347) TestRTOS: task01 stack: 1332
I (15357) TestRTOS: task01 stack: 1332
I (20367) TestRTOS: task01 stack: 1332
I (25377) TestRTOS: task01 stack: 1332
I (30387) TestRTOS: task01 stack: 1332
I (35397) TestRTOS: task01 stack: 1332
I (40407) TestRTOS: task01 stack: 1332
I (45417) TestRTOS: task01 stack: 1332
I (50427) TestRTOS: task01 stack: 1332
I (55437) TestRTOS: task01 stack: 1332
configMINIMAL_STACK_SIZE が1536です。
これmenuConfigでデフォルト値として使用している値です。
FreeRTOSのサイトではxTaskCreateの第三引数に渡す値はバイトではなくワードですよ~って書いてあるんですけど、ESP-IDFの場合はワードじゃなくてバイトですよ~って書いてある。
ここはESP-IDFの話なんだからバイトだとして最小値は1536バイトになるんですかね。1.5kバイト。
タスク実行するとそれだけで1.5kバイトのほぼ全量使ってしまうというのはなんなんだろう。
スタックって関数呼び出しの時のパラメータや戻り先アドレスなんかを一時保管するためのものじゃないのかな。FreeRTOSだと違うのかしら。
とにかくデフォルトの1536だと暴走しまくるので倍の2772を設定したら暴走しなくなりました。
でも、このスタックってESP-IDFというかFreeRTOSだと何に使われてるんだろ。
ソフトウェア開発では「とりあえず動けばよし」という割り切りもありだと思うんですけど、まったく原因が掴めないのは気持ち悪いんですよね。
この辺誰か自分のようなバカにも分かるくらい噛み砕いて説明してくれないかなぁ。
補足なんですが、スタックサイズを2772にしてタスク1000個作っても普通に動く。メモリとかどうやって管理してるんだろ。
頭がグチャグチャして全然進みません。困る。
コメント
コメントを投稿