STM32 RTOS 系列教學 - 第三篇:RTOS 任務間通訊(Queue 與 Semaphore 實作)
STM32 RTOS 系列教學 - 第三篇:RTOS 任務間通訊(Queue 與 Semaphore 實作)
🎯 教學目標
- 理解 RTOS 中 Queue(佇列)的用途與特性
- 學會在任務之間安全地傳遞資料
- 使用 Queue 實作一個簡單的生產者-消費者範例
- 結合 Semaphore 控制 Queue 的存取
📦 Queue 是什麼?
Queue(佇列)是一種資料結構,可在 RTOS 中讓任務之間以 FIFO(先進先出)方式安全交換資料。每個任務可以是資料的「生產者」或「消費者」。
📌 特性
- 支援固定長度的訊息資料(byte 或結構)
- 多任務可同時傳送(Send)與接收(Receive)資料
- 有 blocking / timeout 功能,等待 Queue 可用
- 適合用於任務間資料傳輸、命令交換、感測器讀值同步等
🔒 Semaphore 是什麼?
Semaphore(信號量)是 RTOS 中的同步工具,用來控制對共享資源(如 Queue)的存取,避免資源競爭。
📌 常見類型
- Binary Semaphore:常用於同步(如中斷觸發任務)
- Counting Semaphore:常用於資源控制(如 Queue 空間或緩衝區)
🛠 STM32CubeMX 設定 Queue 與 Semaphore
Step 1:新增 Queue
- 開啟
Middleware > FreeRTOS > CMSIS RTOS v2 - 新增
Message Queue,命名為myQueue01 - 設定:
- 資料長度:
sizeof(uint16_t)或自訂 struct - Queue 長度:例如 10(最多可存放 10 筆資料)
- 資料長度:
Step 2:新增 Semaphore(可選)
- 在
FreeRTOS > CMSIS RTOS v2新增Semaphore - 命名為
myBinarySem01,選擇 Binary
Step 3:初始化
// Queue 初始化
osMessageQueueId_t myQueue01Handle;
const osMessageQueueAttr_t myQueue01_attributes = {
.name = "myQueue01"
};
myQueue01Handle = osMessageQueueNew(10, sizeof(uint16_t), &myQueue01_attributes);
// Semaphore 初始化
osSemaphoreId_t myBinarySem01Handle;
const osSemaphoreAttr_t myBinarySem01_attributes = {
.name = "myBinarySem01"
};
myBinarySem01Handle = osSemaphoreNew(1, 1, &myBinarySem01_attributes); // 初始為可用
🧪 範例:數值傳送與接收
任務 A(傳送端) - 每秒傳送一個數字:
void StartSenderTask(void *argument)
{
uint16_t value = 0;
for(;;)
{
osSemaphoreAcquire(myBinarySem01Handle, osWaitForever); // 取得信號
osMessageQueuePut(myQueue01Handle, &value, 0, 0);
osSemaphoreRelease(myBinarySem01Handle); // 釋放信號
value++;
osDelay(1000);
}
}
任務 B(接收端) - 接收後印出數值:
void StartReceiverTask(void *argument)
{
uint16_t recvVal;
for(;;)
{
osSemaphoreAcquire(myBinarySem01Handle, osWaitForever); // 取得信號
if(osMessageQueueGet(myQueue01Handle, &recvVal, NULL, osWaitForever) == osOK)
{
printf("Received: %d\n", recvVal);
}
osSemaphoreRelease(myBinarySem01Handle); // 釋放信號
}
}
🧠 應用場景
- 任務間傳送 sensor 資料
- 接收中斷服務程式的資料(需透過中斷內部觸發任務)
- 排程控制命令、狀態
- 結合 Semaphore 確保多任務對 Queue 的安全存取
✅ 成功條件檢查
- 每秒有數值被傳送與接收
- 無資料遺失(Queue 空間足夠)
- 接收順序正確(FIFO)
- Semaphore 正確同步,無競爭狀況
第 4 篇:RTOS 計時器(Software Timer)與非阻塞處理技巧