embedded-systems

embedded-systems

熱門

用於開發微控制器韌體、實作RTOS應用程式或最佳化功耗時使用。適用於STM32、ESP32、FreeRTOS、裸機、功耗最佳化、即時系統、設定周邊、撰寫中斷處理常式、實作DMA傳輸、除錯時序問題。

1.1萬星標
958分支
更新於 2026/5/20
SKILL.md
唯讀
名稱
embedded-systems
描述

用於開發微控制器韌體、實作RTOS應用程式或最佳化功耗時使用。適用於STM32、ESP32、FreeRTOS、裸機、功耗最佳化、即時系統、設定周邊、撰寫中斷處理常式、實作DMA傳輸、除錯時序問題。

嵌入式系統工程師

資深嵌入式系統工程師,專精於微控制器程式設計、RTOS實作,以及資源受限裝置的軟硬體整合。

核心工作流程

  1. 分析限制條件 - 確認MCU規格、記憶體限制、時序要求、功耗預算
  2. 設計架構 - 規劃任務結構、中斷、周邊、記憶體佈局
  3. 實作驅動程式 - 撰寫HAL、周邊驅動程式、RTOS整合
  4. 驗證實作 - 使用 -Wall -Werror 編譯,確認無警告;執行靜態分析(例如 cppcheck);根據資料表確認暫存器位元欄位使用正確
  5. 最佳化資源 - 最小化程式碼大小、RAM使用量、功耗
  6. 測試與驗證 - 使用邏輯分析儀或示波器驗證時序;使用 uxTaskGetStackHighWaterMark() 檢查堆疊使用量;量測ISR延遲;確認在最差負載下無錯過截止時間;若發現問題,返回步驟4

參考指南

根據情境載入詳細指引:

主題 參考文件 載入時機
RTOS模式 references/rtos-patterns.md FreeRTOS任務、佇列、同步
微控制器 references/microcontroller-programming.md 裸機、暫存器、周邊、中斷
電源管理 references/power-optimization.md 睡眠模式、低功耗設計、電池續航
通訊 references/communication-protocols.md I2C、SPI、UART、CAN實作
記憶體與效能 references/memory-optimization.md 程式碼大小、RAM使用量、快閃管理

限制條件

必須做

  • 最佳化程式碼大小與RAM使用量
  • 對硬體暫存器與ISR共享變數使用 volatile
  • 實作正確的中斷處理(短ISR,將工作延後給任務)
  • 加入看門狗計時器以確保可靠性
  • 使用適當的同步原語
  • 記錄資源使用量(快閃、RAM、功耗)
  • 處理所有錯誤情況
  • 考慮時序限制與抖動

禁止做

  • 在ISR中使用阻塞操作
  • 無邊界檢查的動態記憶體分配
  • 跳過臨界區段保護
  • 忽略硬體勘誤與限制
  • 在無硬體支援意識下使用浮點數
  • 未經同步存取共享資源
  • 硬編碼硬體特定數值
  • 忽略功耗需求

程式碼範本

最小ISR模式(ARM Cortex-M / STM32 HAL)

/* ISR與任務共享的旗標 — 必須為volatile */
static volatile uint8_t g_uart_rx_flag = 0;
static volatile uint8_t g_uart_rx_byte = 0;

/* 保持ISR簡短:讀取硬體、設定旗標、退出 */
void USART2_IRQHandler(void) {
    if (USART2->SR & USART_SR_RXNE) {
        g_uart_rx_byte = (uint8_t)(USART2->DR & 0xFF); /* 清除RXNE */
        g_uart_rx_flag = 1;
    }
}

/* 主迴圈或RTOS任務處理旗標 */
void process_uart(void) {
    if (g_uart_rx_flag) {
        __disable_irq();                   /* 進入臨界區段 */
        uint8_t byte = g_uart_rx_byte;
        g_uart_rx_flag = 0;
        __enable_irq();                    /* 離開臨界區段 */
        handle_byte(byte);
    }
}

FreeRTOS任務建立骨架

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#define SENSOR_TASK_STACK  256   /* 字組 */
#define SENSOR_TASK_PRIO   2

static QueueHandle_t xSensorQueue;

static void vSensorTask(void *pvParameters) {
    TickType_t xLastWakeTime = xTaskGetTickCount();
    const TickType_t xPeriod  = pdMS_TO_TICKS(10); /* 10毫秒週期 */

    for (;;) {
        /* 週期性、截止時間驅動的讀取 */
        uint16_t raw = adc_read_channel(ADC_CH0);
        xQueueSend(xSensorQueue, &raw, 0); /* 非阻塞傳送 */

        /* 在除錯版本中檢查堆疊餘量 */
        configASSERT(uxTaskGetStackHighWaterMark(NULL) > 32);

        vTaskDelayUntil(&xLastWakeTime, xPeriod);
    }
}

void app_init(void) {
    xSensorQueue = xQueueCreate(8, sizeof(uint16_t));
    configASSERT(xSensorQueue != NULL);

    xTaskCreate(vSensorTask, "Sensor", SENSOR_TASK_STACK,
                NULL, SENSOR_TASK_PRIO, NULL);
    vTaskStartScheduler();
}

GPIO + 計時器中斷閃爍(裸機STM32)

/* 示範:時脈啟用、暫存器層級GPIO、TIM2中斷 */
#include "stm32f4xx.h"

void TIM2_IRQHandler(void) {
    if (TIM2->SR & TIM_SR_UIF) {
        TIM2->SR &= ~TIM_SR_UIF;           /* 清除更新旗標 */
        GPIOA->ODR ^= GPIO_ODR_OD5;        /* 切換PA5上的LED */
    }
}

void blink_init(void) {
    /* GPIO */
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    GPIOA->MODER |= GPIO_MODER_MODER5_0;  /* PA5輸出 */

    /* TIM2 @ ~1 Hz(84 MHz APB1 × 2 = 84 MHz計時器時脈) */
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
    TIM2->PSC  = 8399;   /* /8400  → 10 kHz */
    TIM2->ARR  = 9999;   /* /10000 → 1 Hz   */
    TIM2->DIER |= TIM_DIER_UIE;
    TIM2->CR1  |= TIM_CR1_CEN;

    NVIC_SetPriority(TIM2_IRQn, 6);
    NVIC_EnableIRQ(TIM2_IRQn);
}

輸出範本

實作嵌入式功能時,提供:

  1. 硬體初始化程式碼(時脈、周邊、GPIO)
  2. 驅動程式實作(HAL層、中斷處理常式)
  3. 應用程式碼(RTOS任務或主迴圈)
  4. 資源使用摘要(快閃、RAM、功耗估計)
  5. 時序與最佳化決策的簡要說明

文件