STM32 RTOS 系列教學 - 第五篇:RTOS 訊號量(Semaphore)與資源同步應用
🎯 教學目標
- 理解 RTOS 中 Semaphore 的概念與分類(Binary / Counting)
- 學會在多任務間使用 Semaphore 實現資源同步
- 實作一個防止資源衝突的共享範例
🔐 Semaphore 是什麼?
Semaphore(訊號量)是 RTOS 中用來控制任務間共享資源的一種同步工具,避免同時存取導致資源衝突。
📌 種類
- Binary Semaphore:僅有 0 和 1,用於任務間同步(類似旗標)
- Counting Semaphore:允許多個資源存取計數(像計數器),適用於多個資源管理
🛠 STM32CubeMX 設定 Semaphore
Step 1:新增 Semaphore
- 開啟
Middleware > FreeRTOS > CMSIS RTOS v2 - 新增
Semaphore,命名為myBinarySem01 - 類型選擇
Binary
Step 2:取得 Handle 並初始化
- 在
main.c中取得 handle:
osSemaphoreId_t myBinarySem01Handle;
- 在初始化階段建立 semaphore:
const osSemaphoreAttr_t myBinarySem01_attributes = {
.name = "myBinarySem01"
};
myBinarySem01Handle = osSemaphoreNew(1, 0, &myBinarySem01_attributes);
✋ 任務同步範例:Button Trigger
範例說明:
- 任務 A 持續等待 semaphore(類似被 block)
- 中斷服務程式 (EXTI) 發生時觸發
osSemaphoreRelease()
EXTI 中斷觸發:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_13)
{
osSemaphoreRelease(myBinarySem01Handle);
}
}
任務中等待觸發:
void StartDefaultTask(void *argument)
{
for(;;)
{
if(osSemaphoreAcquire(myBinarySem01Handle, osWaitForever) == osOK)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}
}
}
🧠 常見應用場景
✅ 成功條件檢查
- 按下按鈕,LED 能夠閃爍一次,且不會重複觸發
- 任務能穩定接收中斷產生的 semaphore
- 無資源衝突或 crash 現象
🧩 下一篇預告
第 6 篇:RTOS Queue 任務間資料傳輸實作