FreeRtos是之前的一些聰明的工程師寫的免費且開源的嵌入式實時操作系統代碼,由于我們實際工作中不需要再去寫rtos,我們只需要用就行了,所以博主這里只分享項目工程實戰相關的內容,具體rtos源碼,可以無需理會,除非你要自己寫一個rtos。
另外rtos的移植的話,博主會放在最后一章,因為也沒什么用(畢竟cubemx或者類似S32DS等軟件已經可以一鍵生成帶freertos的工程了)。
廢話說完了,干貨走起。
———————————————————————————————————————————
1.以rtos的形式開發時,首先是在main函數中進行相關外設的初始化,之后創建個start_task任務,start_task用于創建實際項目應用所需要的各個執行任務,創建完start任務之后,開始任務調度器的任務調度。
外設的初始化代碼如下:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4 delay_init(); //延時函數初始化 uart_init(115200); //初始化串口LED_Init(); //初始化LEDLCD_Init(); //初始化LCDPOINT_COLOR = RED;LCD_ShowString(30,10,200,16,16,"ATK STM32F103/F407"); LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 6-1");LCD_ShowString(30,50,200,16,16,"Task Creat and Del");LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,90,200,16,16,"2016/11/25");
2.創建任務:
之后main函數中要先創建開始任務,創建完成之后開始任務調度,代碼如下:
//創建開始任務xTaskCreate((TaskFunction_t )start_task, //任務函數(const char* )"start_task", //任務名稱(uint16_t )START_STK_SIZE, //任務堆棧大小(void* )NULL, //傳遞給任務函數的參數(UBaseType_t )START_TASK_PRIO, //任務優先級(TaskHandle_t* )&StartTask_Handler); //任務句柄 vTaskStartScheduler(); //開啟任務調度
這個地方我們展開說一下創建任務的接口及所需變量定義:
創建任務接口:
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,const char * const pcName,const uint16_t usStackDepth,void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
①其中pxTaskCode為實際的任務接口名稱,具體實現見下:
//開始任務任務函數
void start_task(void *pvParameters)
{taskENTER_CRITICAL(); //進入臨界區//創建TASK1任務xTaskCreate((TaskFunction_t )task1_task, (const char* )"task1_task", (uint16_t )TASK1_STK_SIZE, (void* )NULL, (UBaseType_t )TASK1_TASK_PRIO, (TaskHandle_t* )&Task1Task_Handler); //創建TASK2任務xTaskCreate((TaskFunction_t )task2_task, (const char* )"task2_task", (uint16_t )TASK2_STK_SIZE,(void* )NULL,(UBaseType_t )TASK2_TASK_PRIO,(TaskHandle_t* )&Task2Task_Handler); vTaskDelete(StartTask_Handler); //刪除開始任務taskEXIT_CRITICAL(); //退出臨界區
}
注意:start任務的主要功能為創建項目工程實際需要使用的具體任務,需要在創建完其他任務之后,刪除掉start任務,所謂的“事了拂衣去,深藏功與名”
②pcName:即任務字符串名稱,跟上一個任務名稱保持一致即可;
③usStackDepth:即任務堆棧大小;
④pvParameters:傳遞給任務函數的參數,這里我們一般為NULL即可;
⑤uxPriority:任務優先級,注意freertos的任務優先級不同于中斷優先級,freertos的任務優先級是值越大,優先級越高;
⑥pxCreatedTask:任務句柄,用來存放任務的相關信息;
任務相關參數的定義示例如下:
//任務優先級
#define START_TASK_PRIO 1
//任務堆棧大小
#define START_STK_SIZE 128
//任務句柄
TaskHandle_t StartTask_Handler;
//任務函數
void start_task(void *pvParameters);
3.刪除任務:
vTaskDelete(StartTask_Handler); //刪除開始任務
調用接口示例如上,vTaskDelate(NULL);時為刪除當前任務;
3.集成示例:
之后我們創建task1和task2,在task1和task2的任務函數中的相關代碼結構如下:
void task1_task(void *pvParameters)
{//init codewhile(1){//action code}
}
我們這里實現的task1和task2的任務邏輯為,task1按照1s為周期切換LCD屏幕區域的填充顏色,且在任務執行五次之后刪除任務2;
task2的任務執行邏輯為按照1s為周期切換LCD屏幕的填充顏色;
實際效果見下:(后續會上傳視頻,視頻正在審核中)
freertos的任務創建及刪除演示視頻