【STM32】FreeRTOS创建和删除任务示例(静态方法)(了解)
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 功能描述
- 03. 任務設計
- 04. 程序設計
- 05. 結果驗證
- 06. 附錄
- 07. 參考
01. 概述
FreeRTOS中創建和刪除任務API函數的應用。使用靜態方法創建任務,任務的堆棧、任務控制塊就需要有用戶來指定。
02. 功能描述
設計三個任務:start_task、task1_task和task2_task,這三個任務的功能分別如下:
start_task: 用來創建其它兩個任務。
task1_task: 當此任務運行5秒以后就會調用函數vTaskDelete()刪除任務task2_task,該任務控制LED0的閃爍,并且周期性的輸出信息到串口中。
task2_task:普通的應用任務,此任務控制LED1的閃爍,并且周期性的輸出信息到串口中。
03. 任務設計
系統設置
在FreeRTOSConfig.h文件中需要將宏configSUPPORT_STATIC_ALLOCATION設置為1.
#define configSUPPORT_STATIC_ALLOCATION 1 //靜態內存編譯報如下錯誤
使用靜態的方法創建任務我們需要自己實現函數vApplicationGetTimerTaskMemory()和函數vApplicationGetIdleTaskMemory()。
//空閑任務任務堆棧 static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE]; //空閑任務控制塊 static StaticTask_t IdleTaskTCB;//定時器服務任務堆棧 static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH]; //定時器服務任務控制塊 static StaticTask_t TimerTaskTCB;//ppxIdleTaskTCBBuffer:任務控制塊內存 //ppxIdleTaskStackBuffer:任務堆棧內存 //pulIdleTaskStackSize:任務堆棧大小 void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {*ppxIdleTaskTCBBuffer=&IdleTaskTCB;*ppxIdleTaskStackBuffer=IdleTaskStack;*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE; }//獲取定時器服務任務的任務堆棧和任務控制塊內存 //ppxTimerTaskTCBBuffer:任務控制塊內存 //ppxTimerTaskStackBuffer:任務堆棧內存 //pulTimerTaskStackSize:任務堆棧大小 void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {*ppxTimerTaskTCBBuffer=&TimerTaskTCB;*ppxTimerTaskStackBuffer=TimerTaskStack;*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH; }任務優先級,堆棧大小,任務句柄和任務函數
//任務優先級 #define START_TASK_PRIO 1 //任務堆棧大小 #define START_STK_SIZE 128 //任務堆棧 StackType_t StartTaskStack[START_STK_SIZE]; //任務控制塊 StaticTask_t StartTaskTCB; //任務句柄 TaskHandle_t StartTask_Handler; //任務函數 void start_task(void *pvParameters);//任務優先級 #define TASK1_TASK_PRIO 2 //任務堆棧大小 #define TASK1_STK_SIZE 50 //任務堆棧 StackType_t Task1TaskStack[TASK1_STK_SIZE]; //任務控制塊 StaticTask_t Task1TaskTCB; //任務句柄 TaskHandle_t Task1Task_Handler; //任務函數 void task1_task(void *pvParameters);//任務優先級 #define TASK2_TASK_PRIO 3 //任務堆棧大小 #define TASK2_STK_SIZE 50 //任務堆棧 StackType_t Task2TaskStack[TASK2_STK_SIZE]; //任務控制塊 StaticTask_t Task2TaskTCB; //任務句柄 TaskHandle_t Task2Task_Handler; //任務函數 void task2_task(void *pvParameters);start_task函數
//開始任務任務函數 void start_task(void *pvParameters) {taskENTER_CRITICAL(); //進入臨界區//創建TASK1任務Task1Task_Handler=xTaskCreateStatic((TaskFunction_t )task1_task, (const char* )"task1_task", (uint32_t )TASK1_STK_SIZE, (void* )NULL, (UBaseType_t )TASK1_TASK_PRIO, (StackType_t* )Task1TaskStack, (StaticTask_t* )&Task1TaskTCB); //創建TASK2任務Task2Task_Handler=xTaskCreateStatic((TaskFunction_t )task2_task, (const char* )"task2_task", (uint32_t )TASK2_STK_SIZE, (void* )NULL, (UBaseType_t )TASK2_TASK_PRIO, (StackType_t* )Task2TaskStack, (StaticTask_t* )&Task2TaskTCB);vTaskDelete(StartTask_Handler); //刪除開始任務taskEXIT_CRITICAL(); //退出臨界區 }task1_task函數
//任務1 void task1_task(void *pvParameters) {u8 task1_num = 0;while(1){task1_num++;LED0 = !LED0;printf("任務1已經運行%d次\r\n", task1_num);if (5 == task1_num){//任務1刪除任務2vTaskDelete(Task2Task_Handler);printf("任務1刪除了任務2\r\n");}//延時1秒 1000個時鐘節拍vTaskDelay(1000);} }task2_task函數
//任務2 void task2_task(void *pvParameters) {u8 task2_num = 0;while(1){task2_num++;LED1 = !LED1;printf("任務2已經執行了%d次\r\n", task2_num);//延時1秒 1000個時鐘節拍vTaskDelay(1000);} }04. 程序設計
main.c文件
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "FreeRTOS.h" #include "task.h"//空閑任務任務堆棧 static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE]; //空閑任務控制塊 static StaticTask_t IdleTaskTCB;//定時器服務任務堆棧 static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH]; //定時器服務任務控制塊 static StaticTask_t TimerTaskTCB;//任務優先級 #define START_TASK_PRIO 1 //任務堆棧大小 #define START_STK_SIZE 128 //任務堆棧 StackType_t StartTaskStack[START_STK_SIZE]; //任務控制塊 StaticTask_t StartTaskTCB; //任務句柄 TaskHandle_t StartTask_Handler; //任務函數 void start_task(void *pvParameters);//任務優先級 #define TASK1_TASK_PRIO 2 //任務堆棧大小 #define TASK1_STK_SIZE 50 //任務堆棧 StackType_t Task1TaskStack[TASK1_STK_SIZE]; //任務控制塊 StaticTask_t Task1TaskTCB; //任務句柄 TaskHandle_t Task1Task_Handler; //任務函數 void task1_task(void *pvParameters);//任務優先級 #define TASK2_TASK_PRIO 3 //任務堆棧大小 #define TASK2_STK_SIZE 50 //任務堆棧 StackType_t Task2TaskStack[TASK2_STK_SIZE]; //任務控制塊 StaticTask_t Task2TaskTCB; //任務句柄 TaskHandle_t Task2Task_Handler; //任務函數 void task2_task(void *pvParameters);//ppxIdleTaskTCBBuffer:任務控制塊內存 //ppxIdleTaskStackBuffer:任務堆棧內存 //pulIdleTaskStackSize:任務堆棧大小 void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {*ppxIdleTaskTCBBuffer=&IdleTaskTCB;*ppxIdleTaskStackBuffer=IdleTaskStack;*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE; }//獲取定時器服務任務的任務堆棧和任務控制塊內存 //ppxTimerTaskTCBBuffer:任務控制塊內存 //ppxTimerTaskStackBuffer:任務堆棧內存 //pulTimerTaskStackSize:任務堆棧大小 void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {*ppxTimerTaskTCBBuffer=&TimerTaskTCB;*ppxTimerTaskStackBuffer=TimerTaskStack;*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH; }//主函數 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4delay_init(168); //初始化延時函數uart_init(115200); //初始化串口LED_Init(); //初始化LED端口//創建開始任務StartTask_Handler=xTaskCreateStatic((TaskFunction_t )start_task, //任務函數(const char* )"start_task", //任務名稱(uint32_t )START_STK_SIZE, //任務堆棧大小(void* )NULL, //傳遞給任務函數的參數(UBaseType_t )START_TASK_PRIO, //任務優先級(StackType_t* )StartTaskStack, //任務堆棧(StaticTask_t* )&StartTaskTCB); //任務控制塊 vTaskStartScheduler(); //開啟任務調度 }//開始任務任務函數 void start_task(void *pvParameters) {taskENTER_CRITICAL(); //進入臨界區//創建TASK1任務Task1Task_Handler=xTaskCreateStatic((TaskFunction_t )task1_task, (const char* )"task1_task", (uint32_t )TASK1_STK_SIZE, (void* )NULL, (UBaseType_t )TASK1_TASK_PRIO, (StackType_t* )Task1TaskStack, (StaticTask_t* )&Task1TaskTCB); //創建TASK2任務Task2Task_Handler=xTaskCreateStatic((TaskFunction_t )task2_task, (const char* )"task2_task", (uint32_t )TASK2_STK_SIZE, (void* )NULL, (UBaseType_t )TASK2_TASK_PRIO, (StackType_t* )Task2TaskStack, (StaticTask_t* )&Task2TaskTCB);vTaskDelete(StartTask_Handler); //刪除開始任務taskEXIT_CRITICAL(); //退出臨界區 }//任務1 void task1_task(void *pvParameters) {u8 task1_num = 0;while(1){task1_num++;LED0 = !LED0;printf("任務1已經運行%d次\r\n", task1_num);if (5 == task1_num){//任務1刪除任務2vTaskDelete(Task2Task_Handler);printf("任務1刪除了任務2\r\n");}//延時1秒 1000個時鐘節拍vTaskDelay(1000);} }//任務2 void task2_task(void *pvParameters) {u8 task2_num = 0;while(1){task2_num++;LED1 = !LED1;printf("任務2已經執行了%d次\r\n", task2_num);//延時1秒 1000個時鐘節拍vTaskDelay(1000);} }05. 結果驗證
任務1運行5秒中之后刪除了任務2,任務2被刪除之后就不會被運行。最后只剩下任務1運行了。
06. 附錄
6.1 【STM32】STM32系列教程匯總
網址:【STM32】STM32系列教程匯總
6.2 示例下載
下載:25FreeRTOS靜態創建任務.rar
07. 參考
《FreeRTOS Reference Manual》
《Using the FreeRTOS Real Time Kernel -A Practical Guide》
《The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors,3rd Edition》
總結
以上是生活随笔為你收集整理的【STM32】FreeRTOS创建和删除任务示例(静态方法)(了解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【STM32】FreeRTOS创建和删除
- 下一篇: 【STM32】FreeRTOS任务挂起和