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）與非阻塞處理技巧