引言
隨著嵌入式技術的飛速發展,STM32與FreeRTOS的融合愈發緊密。本文聚焦于STM32平臺下FreeRTOS操作系統的任務管理,旨在為開發者提供清晰的思路與實用的技巧,助力高效開發。
為什么要進行任務管理?
在嵌入式系統中,任務管理是確保系統高效、穩定運行的關鍵環節。隨著系統功能的日益復雜,多個任務需要同時運行,且每個任務都有其優先級和資源需求。任務管理通過合理分配處理器時間、優化任務調度、確保任務間通信順暢,使系統能夠高效處理多任務,避免任務沖突和資源浪費。它還能提高系統的響應速度和可靠性,確保關鍵任務優先執行,從而提升用戶體驗和系統性能。
任務的掛起與恢復
任務掛起是任務管理中的一個重要機制,其主要目的是為了更合理地分配系統資源和優化任務調度。當一個任務暫時不需要運行時,將其掛起可以釋放處理器時間,讓其他更重要的任務得以執行,從而提高系統的整體效率。
vTaskSuspend(*任務句柄)
vTaskSuspend()是FreeRTOS 中用于掛起任務的函數。它允許將一個任務置于掛起狀態,使其暫時停止執行,直到被恢復為止。其函數原型為:
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
里面需要填的參數為需要掛起的任務函數的句柄。其功能是將指定的任務置于掛起狀態,使其不再被調度器調度,同時掛起的任務也不會占用處理器的時間,直到被恢復為止。(注:如果任務已經被掛起,則再次調用vTaskSuspend()不會產生任何效果)
vTaskResume(*任務句柄)
vTaskResume()是 FreeRTOS 中用于恢復掛起任務的函數。當一個任務被掛起后,使用 ? vTaskResume()可以將其從掛起狀態恢復到就緒狀態,使其可以被調度器調度并繼續執行。參數也是跟上面的一樣,填入要恢復的任務句柄。如果該任務已經掛起,調用該函數后,該任務將被恢復到就緒運行狀態。(注:如果任務已經處于就緒狀態或運行狀態,則再次調用vTaskResume()不會產生任何效果)
任務的刪除
在FreeRTOS中,任務刪除是一個重要的機制,主要用于動態管理任務的生命周期。當用戶不再需要執行某個任務時,可以對該任務進行刪除。因為每個任務都會占用一定系統資源,刪除任務可以釋放這些資源,供其它任務使用。
vTaskDelete(*任務句柄)
其函數原型為:
void vTaskDelete( TaskHandle_t xTaskToDelete );
參數是要刪除任務的句柄。如果是在任務內調用該函數,參數也可以傳入NULL,表示刪除當前任務。同樣,如果任務已經處于刪除狀態,再次調用該函數不會產生任何效果。(注:刪除任務后任務不可恢復)
完整示例代碼
#include "myfreertos.h"
#include "FreeRTOS.h"
#include "SysTick.h"
#include "Usart.h"
#include "oled.h"
#include "Task.h"
#include "led.h"
#include "key.h"TaskHandle_t MyTaskHandler;//任務句柄TaskHandle_t MyTask1Handler;//任務1句柄TaskHandle_t MyTask2Handler;//任務2句柄TaskHandle_t MyTask3Handler;//任務3句柄void MyTask(void *pvParameters); //聲明啟動函數void MyTask1(void *pvParameters); //聲明任務1函數void MyTask2(void *pvParameters); //聲明任務2函數void MyTask3(void *pvParameters); //聲明任務3函數void Start_Task(void)
{xTaskCreate(MyTask,"MyTask",128,NULL,1,&MyTaskHandler);//動態方法創建任務vTaskStartScheduler();//啟動任務調動
}void MyTask(void *arg) //開始創建任務函數
{taskENTER_CRITICAL(); //進入臨界區xTaskCreate(MyTask1,"MyTask1",50,NULL,2,&MyTask1Handler);//動態方法創建任務1xTaskCreate(MyTask2,"MyTask2",50,NULL,3,&MyTask2Handler);//動態方法創建任務2xTaskCreate(MyTask3,"MyTask3",50,NULL,4,&MyTask3Handler);//動態方法創建任務3vTaskDelete(MyTaskHandler); //刪除開始任務taskEXIT_CRITICAL(); //退出臨界區
}void MyTask1(void *arg) //任務1函數體
{u32 cnt=0; //定義變量while(1){OLED_ShowString(1,1,"Runing Task1");OLED_ShowNum(2,1,cnt,3);GPIO_ResetBits(GPIOC,GPIO_Pin_13);vTaskDelay(300);GPIO_SetBits(GPIOC,GPIO_Pin_13);vTaskDelay(900);if(++cnt>=10) //如果超過10次{if(MyTask1Handler!=NULL) //判斷句柄是否有效{vTaskDelete(MyTask1Handler); //刪除任務1MyTask1Handler=NULL; //清空句柄}}}
}void MyTask2(void *arg) //任務2函數體
{while(1){OLED_ShowString(1,1,"Runing Task2");GPIO_ResetBits(GPIOC,GPIO_Pin_15);delay_ms(1000); //延時產生任務調度GPIO_SetBits(GPIOC,GPIO_Pin_15);vTaskDelay(300); }
}void MyTask3(void *arg) //任務3函數體
{while(1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)!=0){vTaskSuspend(MyTask2Handler);/* 掛起任務2 */OLED_ShowString(3,1,"S");}else{vTaskResume(MyTask2Handler);/* 恢復任務2*/OLED_ShowString(3,1,"R");}vTaskDelay(100);}
}
總結
本文僅僅簡單介紹了基于STM32單片機FreeRTOS操作系統中的任務管理,如有不足,歡迎指出,謝謝!
?