STM32 RTOS 系列教學 - 第三篇:RTOS 任務間通訊(Queue 與 Semaphore 實作)

STM32 RTOS 系列教學 - 第三篇:RTOS 任務間通訊(Queue 與 Semaphore 實作)

🎯 教學目標

📦 Queue 是什麼?

Queue(佇列)是一種資料結構,可在 RTOS 中讓任務之間以 FIFO(先進先出)方式安全交換資料。每個任務可以是資料的「生產者」或「消費者」。

📌 特性


🔒 Semaphore 是什麼?

Semaphore(信號量)是 RTOS 中的同步工具,用來控制對共享資源(如 Queue)的存取,避免資源競爭。

📌 常見類型


🛠 STM32CubeMX 設定 Queue 與 Semaphore

Step 1:新增 Queue

Step 2:新增 Semaphore(可選)

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);  // 釋放信號
  }
}

🧠 應用場景


✅ 成功條件檢查


第 4 篇:RTOS 計時器(Software Timer)與非阻塞處理技巧


Revision #1
Created 2026-04-01 02:06:35 UTC by TaipeiTechRacing
Updated 2026-04-01 02:12:53 UTC by TaipeiTechRacing