FreeRTOS 任務管理學習筆記
引言
本文檔旨在通過在STM32微控制器上使用FreeRTOS來理解和實現任務管理。實驗的重點是創建和管理多個任務、處理任務同步以及通過簡單的硬件接口控制任務狀態。
實驗概述
實驗涉及創建三個任務:
- LED1_Task: 每300毫秒切換一次LED。
- LED2_Task: 每500毫秒切換一次另一個LED。
- Key_Task: 監控按鈕按下以暫停或恢復
LED1_Task
。
此外,創建了一個初始化任務(InitializeTasks
)來設置和管理這些任務。
關鍵概念
1. 任務創建
在FreeRTOS中,任務是通過xTaskCreate
函數創建的。該函數接受以下參數:
- 任務函數: 實現任務功能的函數。
- 任務名稱: 任務的描述性名稱。
- 堆棧大小: 分配給任務的堆棧大小。
- 參數: 傳遞給任務函數的參數。
- 優先級: 任務的優先級。
- 任務句柄: 創建的任務的句柄,用于任務管理。
示例
xTaskCreate(LED1_Task, "LED1_Task", configMINIMAL_STACK_SIZE, NULL, 1, &LED1_Task_Handle);
2. 任務延遲
任務可以使用vTaskDelay
函數進行延遲,這會使任務暫停指定的時間。延遲時間以滴答為單位指定,可以使用pdMS_TO_TICKS
將其從毫秒轉換為滴答。
示例
vTaskDelay(pdMS_TO_TICKS(300));
3. 任務同步
在本實驗中,任務同步通過任務暫停和恢復實現:
- 暫停: 使用
vTaskSuspend
暫停任務。這會停止任務的調度。 - 恢復: 使用
vTaskResume
恢復任務。這會使任務重新被調度。
示例
vTaskSuspend(LED1_Task_Handle);
vTaskResume(LED1_Task_Handle);
4. 按鈕去抖動
按鈕去抖動通過在檢測到按鈕狀態變化后引入短暫延遲并再次檢查狀態來確保準確檢測到按鈕按下。這有助于消除機械開關的抖動。
示例
if (keyState != lastKeyState)
{vTaskDelay(pdMS_TO_TICKS(50)); // 去抖動延遲keyState = (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_10) == GPIO_PIN_RESET) ? 1 : 0;if (keyState != lastKeyState){lastKeyState = keyState;if (keyState == 1){key = (key == 1) ? 0 : 1;printf("按鍵按下: %s\r\n", key == 1 ? "1" : "0");HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);if (key == 1){vTaskSuspend(LED1_Task_Handle);}else{vTaskResume(LED1_Task_Handle);}}}
}
5. 任務刪除
在初始化并創建所有必要任務后,初始化任務(InitializeTasks
)會刪除自身以釋放資源。
示例
vTaskDelete(&InitializeTasks_Handle);
代碼分析
文件: main.c
任務函數
- LED1_Task: 每300毫秒切換一次GPIOA, Pin 0上的LED。
- LED2_Task: 每500毫秒切換一次GPIOA, Pin 1上的LED。
- Key_Task: 監控GPIOA, Pin 10上的按鈕按下以暫停/恢復
LED1_Task
。
初始化函數
- InitializeTasks: 創建所有任務并在初始化后刪除自身。
主函數
- 初始化外設和FreeRTOS調度器。
- 創建初始化任務并啟動調度器。
結論
本實驗提供了對FreeRTOS中任務管理的實際理解,包括任務創建、同步和資源管理。按鈕去抖動和任務暫停/恢復的實現展示了如何有效地使用FreeRTOS功能來動態控制任務行為。