freertos について
FreeRTOS アプリケーションの開発とデバッグをエージェントに案内するスキルです。タスク管理、タスク間通信、設定、メモリ検査、GDB と OpenOCD によるデバッグを扱います。
主な機能
- 01タスクの作成と優先度の設定
- 02キューやセマフォによるデータ受け渡し
- 03タスクのスタックオーバーフローを検出
- 04FreeRTOSConfig.h を設定
- 05GDB と OpenOCD でタスクをデバッグ
- 06FreeRTOS+TCP と TrustZone の機能を利用
活用シーン
- 01タスクを構成し割り込み処理の優先度を設定
- 02タスクと ISR の間でデータを交換
- 03タスクのクラッシュやスタック不足を調査
- 04ネットワークまたは MPU タスク領域を設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill freertosインストール後、Claude Code で/freertosを入力して読み込まれたか確認します。
同梱ファイルreferences/freertos-config.md
詳細
FreeRTOS
目的
FreeRTOS アプリケーション開発をエージェントに案内します。タスクの作成と優先度、キューとセマフォによるタスク間通信、スタックオーバーフロー検出、configASSERT、GDB と OpenOCD を使った FreeRTOS 対応デバッグを扱います。
トリガー
- 「FreeRTOS タスクを作成するにはどうすればよいですか?」
- 「FreeRTOS タスク間でデータを渡すにはどうすればよいですか?」
- 「FreeRTOS タスクがクラッシュします。スタックオーバーフローを検出するにはどうすればよいですか?」
- 「FreeRTOS のミューテックスを使うにはどうすればよいですか?」
- 「GDB で FreeRTOS タスクをデバッグするにはどうすればよいですか?」
- 「FreeRTOSConfig.h を設定するにはどうすればよいですか?」
ワークフロー
1. タスクの作成と優先度
#include "FreeRTOS.h"
#include "task.h"
// Task function signature
void vMyTask(void *pvParameters) {
const char *name = (const char *)pvParameters;
for (;;) {
// Task body — must never return
printf("Task %s running\n", name);
vTaskDelay(pdMS_TO_TICKS(500)); // yield for 500ms
}
}
int main(void) {
// xTaskCreate(function, name, stack_depth_words, param, priority, handle)
TaskHandle_t xHandle = NULL;
xTaskCreate(vMyTask, "MyTask",
configMINIMAL_STACK_SIZE + 128, // words, not bytes!
(void *)"sensor",
tskIDLE_PRIORITY + 2, // higher = more urgent
&xHandle);
vTaskStartScheduler(); // never returns if heap is sufficient
for (;;); // should never reach here
}
優先度のガイドライン:
tskIDLE_PRIORITY(0)— アイドルタスクです。ここではブロックしないでください- ISR 処理を遅延させるタスク — 割り込みをすばやく処理できるよう、最も高い優先度にします
configMAX_PRIORITIES - 1を超える優先度は避けてください
2. キュー — タスク間のデータ受け渡し
#include "queue.h"
typedef struct { uint32_t sensor_id; float value; } SensorReading_t;
QueueHandle_t xSensorQueue;
void vProducerTask(void *pvParam) {
SensorReading_t reading;
for (;;) {
reading.sensor_id = 1;
reading.value = read_adc();
// Send; block max 10ms if queue full
xQueueSend(xSensorQueue, &reading, pdMS_TO_TICKS(10));
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void vConsumerTask(void *pvParam) {
SensorReading_t reading;
for (;;) {
// Block forever until item available
if (xQueueReceive(xSensorQueue, &reading, portMAX_DELAY) == pdTRUE) {
process(reading.value);
}
}
}
// Create before starting scheduler
xSensorQueue = xQueueCreate(10, sizeof(SensorReading_t));
ISR からは xQueueSendFromISR() を使用し、&xHigherPriorityTaskWoken を渡してください。
3. セマフォとミューテックス
#include "semphr.h"
// Binary semaphore — signaling (ISR→task)
SemaphoreHandle_t xSem = xSemaphoreCreateBinary();
void UART_ISR(void) {
BaseType_t xWoken = pdFALSE;
xSemaphoreGiveFromISR(xSem, &xWoken);
portYIELD_FROM_ISR(xWoken);
}
void vUartTask(void *p) {
for (;;) {
xSemaphoreTake(xSem, portMAX_DELAY);
// process received data
}
}
// Mutex — mutual exclusion (NOT from ISR)
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();
void vCriticalSection(void) {
if (xSemaphoreTake(xMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
// protected access
shared_resource++;
xSemaphoreGive(xMutex);
}
}
// Recursive mutex (same task can take multiple times)
SemaphoreHandle_t xRecursive = xSemaphoreCreateRecursiveMutex();
xSemaphoreTakeRecursive(xRecursive, portMAX_DELAY);
xSemaphoreGiveRecursive(xRecursive);
共有リソースには、優先度継承を利用できるよう、バイナリセマフォではなくミューテックスを使用してください。
4. スタックオーバーフロー検出
// FreeRTOSConfig.h
#define configCHECK_FOR_STACK_OVERFLOW 2 // Method 2 (pattern + watermark)
#define configUSE_MALLOC_FAILED_HOOK 1
// Implement the hook (called when overflow detected)
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
// Log the offending task name, then halt
configASSERT(0); // triggers assertion failure
}
void vApplicationMallocFailedHook(void) {
configASSERT(0);
}
実行時にウォーターマークを確認します。
// Returns minimum ever free stack words
UBaseType_t uxHighWaterMark = uxTaskGetStackHighWaterMark(xHandle);
printf("Stack headroom: %lu words\n", uxHighWaterMark);
// Rule of thumb: keep headroom > 20 words
5. 必須の FreeRTOSConfig.h 設定
// FreeRTOSConfig.h — adapt to your MCU
#define configCPU_CLOCK_HZ (SystemCoreClock)
#define configTICK_RATE_HZ 1000 // 1ms tick
#define configMAX_PRIORITIES 8
#define configMINIMAL_STACK_SIZE 128 // words
#define configTOTAL_HEAP_SIZE (16 * 1024) // bytes
#define configMAX_TASK_NAME_LEN 16
// Debug / safety
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_MALLOC_FAILED_HOOK 1
#define configASSERT(x) if((x)==0) { taskDISABLE_INTERRUPTS(); for(;;); }
// Features
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_TIMERS 1
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)
6. OpenOCD を使った GDB デバッグ
# Connect GDB with FreeRTOS thread awareness
# OpenOCD provides FreeRTOS-aware RTOS plugin
# openocd.cfg addition
# source [find rtos/FreeRTOS.cfg] # auto-loads with most targets
# GDB session
(gdb) info threads # lists all FreeRTOS tasks
(gdb) thread 3 # switch to task 3
(gdb) bt # backtrace of that task's stack
(gdb) frame 2 # inspect specific frame
# Print task list from GDB (if trace facility enabled)
(gdb) call vTaskList(buf)
(gdb) printf "%s\n", buf
7. FreeRTOS v11 API の更新
FreeRTOS v11(2024 年以降)では、タスク通知とストリームバッファーが拡張されています。
// Task notifications v2 — 32-bit values with action semantics
xTaskNotifyIndexed(xHandle, 0, ulValue, eSetValueWithOverwrite);
xTaskNotifyWaitIndexed(0, 0, ULONG_MAX, &ulNotified, portMAX_DELAY);
// Stream buffers — ISR-safe send with trigger level
xStreamBufferSend(xStream, data, len, 0);
xStreamBufferSetTriggerLevel(xStream, 1); // wake receiver on 1 byte
API が利用可能かどうかは、コンパイル時に FreeRTOS.h の tskKERNEL_VERSION_NUMBER を確認してください。
8. ARM TrustZone の統合
Cortex-M33/M55 でセキュア/非セキュア領域を分割します。
#include "secure_context.h"
// Initialize secure context management (secure side or NSC veneer)
SecureContext_Init();
// Allocate secure context for task calling secure functions
xTaskCreateSecure(vSecureTask, "SecTask", STACK, NULL, priority, &xHandle);
// MPU defines NSC (Non-Secure Callable) regions for SG veneers
TrustZone 対応 MCU、セキュアファームウェアパーティション、および NSC リンカーセクションの配置が必要です。
9. FreeRTOS+TCP の基本
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
// After network stack init (FreeRTOS_IPInit)
Socket_t xSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM,
FREERTOS_IPPROTO_TCP);
FreeRTOS_connect(xSocket, &xAddress, sizeof(xAddress));
FreeRTOS_send(xSocket, buffer, len, 0);
FreeRTOSIPConfig.h でバッファー数と TCP/IP オプション(例:ipconfigUSE_TCP、ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS)を設定します。Ethernet MAC ドライバーおよび FreeRTOS+TCP のバッファー管理と組み合わせて使用します。
10. MPU 領域の設定
// Restricted task with MPU regions (Cortex-M with MPU)
static const TaskParameters_t xRestrictedTaskParams = {
.pvTaskCode = vRestrictedTask,
.pcName = "Restricted",
.usStackDepth = configMINIMAL_STACK_SIZE,
.pvParameters = NULL,
.uxPriority = tskIDLE_PRIORITY + 1,
.puxStackBuffer = stackBuffer,
.xRegions = {
{ .pvBaseAddress = 0x20000000, .ulLength = 0x10000,
.ulParameters = tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER },
{ .pvBaseAddress = 0x00000000, .ulLength = 0, .ulParameters = 0 } // terminator
}
};
xTaskCreateRestricted(&xRestrictedTaskParams, &xHandle);
読み取り専用のコード/データ、特権付きペリフェラル、タスク専用スタック用に、個別の RAM 領域を定義します。
OpenOCD の設定の詳細については、skills/embedded/openocd-jtag を参照してください。
FreeRTOSConfig.h のリファレンスについては、references/freertos-config.md を参照してください。
関連スキル
- GDB/OpenOCD のリモートデバッグ設定には、
skills/embedded/openocd-jtagを使用します - FreeRTOS ヒープを特定の RAM 領域に配置するには、
skills/embedded/linker-scriptsを使用します - GDB セッションの一般的な管理には、
skills/debuggers/gdbを使用します - デバイス管理機能が組み込まれた代替 RTOS には、
skills/embedded/zephyrを使用します