STM32 RTOS 系列教學 - 第六篇:RTOS Queue 任務間資料傳輸實作
STM32 RTOS 系列教學 - 第六篇:RTOS Queue 任務間資料傳輸實作
🎯 教學目標
- 理解 RTOS 中 Queue(佇列)的用途與特性
- 學會在任務之間安全地傳遞資料
- 使用 Queue 實作一個簡單的生產者-消費者範例
📦 Queue 是什麼?
Queue(佇列)是一種資料結構,可在 RTOS 中讓任務之間以 FIFO(先進先出)方式安全交換資料。每個任務可以是資料的「生產者」或「消費者」。
📌 特性
- 支援固定長度的訊息資料(byte 或結構)
- 多任務可同時傳送(Send)與接收(Receive)資料
- 有 blocking / timeout 功能,等待 Queue 可用
🛠 STM32CubeMX 設定 Queue
Step 1:新增 Queue
- 開啟
Middleware > FreeRTOS > CMSIS RTOS v2 - 新增
Message Queue,命名為myQueue01 - 設定:
- 資料長度:
sizeof(uint16_t)或自訂 struct - Queue 長度:例如 10(最多可存放 10 筆資料)
- 資料長度:
Step 2:取得 Handle 並初始化
osMessageQueueId_t myQueue01Handle;
const osMessageQueueAttr_t myQueue01_attributes = {
.name = "myQueue01"
};
myQueue01Handle = osMessageQueueNew(10, sizeof(uint16_t), &myQueue01_attributes);
🧪 範例:數值傳送與接收
任務 A(傳送端) - 每秒傳送一個數字:
void StartSenderTask(void *argument)
{
uint16_t value = 0;
for(;;)
{
osMessageQueuePut(myQueue01Handle, &value, 0, 0);
value++;
osDelay(1000);
}
}
任務 B(接收端) - 接收後印出數值:
void StartReceiverTask(void *argument)
{
uint16_t recvVal;
for(;;)
{
if(osMessageQueueGet(myQueue01Handle, &recvVal, NULL, osWaitForever) == osOK)
{
printf("Received: %d\n", recvVal);
}
}
}
🧠 應用場景
- 任務間傳送 sensor 資料
- 接收中斷服務程式的資料(需透過中斷內部觸發任務)
- 排程控制命令、狀態
✅ 成功條件檢查
- 每秒有數值被傳送與接收
- 無資料遺失(Queue 空間足夠)
- 接收順序正確(FIFO)
🧩 下一篇預告
第 7 篇:RTOS Timer 與軟體定時器應用