mcpField
F
freertos

freertos

github.com/mohitmishra786開発269651 回インストール18 週間前に更新
リポジトリ

freertos について

FreeRTOS アプリケーションの開発とデバッグをエージェントに案内するスキルです。タスク管理、タスク間通信、設定、メモリ検査、GDB と OpenOCD によるデバッグを扱います。

主な機能

  1. 01タスクの作成と優先度の設定
  2. 02キューやセマフォによるデータ受け渡し
  3. 03タスクのスタックオーバーフローを検出
  4. 04FreeRTOSConfig.h を設定
  5. 05GDB と OpenOCD でタスクをデバッグ
  6. 06FreeRTOS+TCP と TrustZone の機能を利用

活用シーン

  1. 01タスクを構成し割り込み処理の優先度を設定
  2. 02タスクと ISR の間でデータを交換
  3. 03タスクのクラッシュやスタック不足を調査
  4. 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 を使用します

コメント