你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 FreeRTOS创建和删除任务示例(静态方法)

[复制链接]
STMCU小助手 发布时间:2022-6-18 17:00
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.

  1. #define configSUPPORT_STATIC_ALLOCATION 1 //静态内存
复制代码

编译报如下错误

HI%IAR`~]R9$V39@2Z~WA%V.png

使用静态的方法创建任务我们需要自己实现函数vApplicationGetTimerTaskMemory()和函数vApplicationGetIdleTaskMemory()。

  1. //空闲任务任务堆栈
  2. static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
  3. //空闲任务控制块
  4. static StaticTask_t IdleTaskTCB;

  5. //定时器服务任务堆栈
  6. static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
  7. //定时器服务任务控制块
  8. static StaticTask_t TimerTaskTCB;

  9. //ppxIdleTaskTCBBuffer:任务控制块内存
  10. //ppxIdleTaskStackBuffer:任务堆栈内存
  11. //pulIdleTaskStackSize:任务堆栈大小
  12. void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
  13.                                                                    StackType_t **ppxIdleTaskStackBuffer,
  14.                                                                    uint32_t *pulIdleTaskStackSize)
  15. {
  16.         *ppxIdleTaskTCBBuffer=&IdleTaskTCB;
  17.         *ppxIdleTaskStackBuffer=IdleTaskStack;
  18.         *pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
  19. }


  20. //获取定时器服务任务的任务堆栈和任务控制块内存
  21. //ppxTimerTaskTCBBuffer:任务控制块内存
  22. //ppxTimerTaskStackBuffer:任务堆栈内存
  23. //pulTimerTaskStackSize:任务堆栈大小
  24. void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
  25.                                                                         StackType_t **ppxTimerTaskStackBuffer,
  26.                                                                         uint32_t *pulTimerTaskStackSize)
  27. {
  28.         *ppxTimerTaskTCBBuffer=&TimerTaskTCB;
  29.         *ppxTimerTaskStackBuffer=TimerTaskStack;
  30.         *pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
  31. }
复制代码

任务优先级,堆栈大小,任务句柄和任务函数


  1. //任务优先级
  2. #define START_TASK_PRIO                1
  3. //任务堆栈大小        
  4. #define START_STK_SIZE                 128  
  5. //任务堆栈
  6. StackType_t StartTaskStack[START_STK_SIZE];
  7. //任务控制块
  8. StaticTask_t StartTaskTCB;
  9. //任务句柄
  10. TaskHandle_t StartTask_Handler;
  11. //任务函数
  12. void start_task(void *pvParameters);

  13. //任务优先级
  14. #define TASK1_TASK_PRIO                2
  15. //任务堆栈大小        
  16. #define TASK1_STK_SIZE                 50  
  17. //任务堆栈
  18. StackType_t Task1TaskStack[TASK1_STK_SIZE];
  19. //任务控制块
  20. StaticTask_t Task1TaskTCB;
  21. //任务句柄
  22. TaskHandle_t Task1Task_Handler;
  23. //任务函数
  24. void task1_task(void *pvParameters);

  25. //任务优先级
  26. #define TASK2_TASK_PRIO                3
  27. //任务堆栈大小        
  28. #define TASK2_STK_SIZE                 50  
  29. //任务堆栈
  30. StackType_t Task2TaskStack[TASK2_STK_SIZE];
  31. //任务控制块
  32. StaticTask_t Task2TaskTCB;
  33. //任务句柄
  34. TaskHandle_t Task2Task_Handler;
  35. //任务函数
  36. void task2_task(void *pvParameters);
复制代码

start_task函数

  1. //开始任务任务函数
  2. void start_task(void *pvParameters)
  3. {
  4.     taskENTER_CRITICAL();           //进入临界区
  5.     //创建TASK1任务
  6.         Task1Task_Handler=xTaskCreateStatic((TaskFunction_t        )task1_task,               
  7.                                                                                 (const char*         )"task1_task",               
  8.                                                                                 (uint32_t                 )TASK1_STK_SIZE,        
  9.                                                                                 (void*                           )NULL,                                
  10.                                                                                 (UBaseType_t         )TASK1_TASK_PRIO,         
  11.                                                                                 (StackType_t*   )Task1TaskStack,        
  12.                                                                                 (StaticTask_t*  )&Task1TaskTCB);        
  13.     //创建TASK2任务
  14.         Task2Task_Handler=xTaskCreateStatic((TaskFunction_t        )task2_task,               
  15.                                                                                 (const char*         )"task2_task",               
  16.                                                                                 (uint32_t                 )TASK2_STK_SIZE,        
  17.                                                                                 (void*                           )NULL,                                
  18.                                                                                 (UBaseType_t         )TASK2_TASK_PRIO,         
  19.                                                                                 (StackType_t*   )Task2TaskStack,        
  20.                                                                                 (StaticTask_t*  )&Task2TaskTCB);
  21.     vTaskDelete(StartTask_Handler); //删除开始任务
  22.     taskEXIT_CRITICAL();            //退出临界区
  23. }
复制代码

task1_task函数

  1. //任务1
  2. void task1_task(void *pvParameters)
  3. {
  4.         u8 task1_num = 0;
  5.         
  6.         while(1)
  7.         {
  8.                 task1_num++;
  9.                 LED0 = !LED0;
  10.                 printf("任务1已经运行%d次\r\n", task1_num);
  11.         
  12.                 if (5 == task1_num)
  13.                 {
  14.                         //任务1删除任务2
  15.                         vTaskDelete(Task2Task_Handler);
  16.                         printf("任务1删除了任务2\r\n");
  17.                 }
  18.                
  19.                 //延时1秒 1000个时钟节拍
  20.                 vTaskDelay(1000);
  21.         }
  22. }
复制代码

task2_task函数

  1. //任务2
  2. void task2_task(void *pvParameters)
  3. {
  4.         u8 task2_num = 0;
  5.         
  6.         while(1)
  7.         {
  8.                 task2_num++;
  9.                 LED1 = !LED1;
  10.                 printf("任务2已经执行了%d次\r\n", task2_num);
  11.                
  12.                 //延时1秒 1000个时钟节拍
  13.                 vTaskDelay(1000);
  14.         }
  15. }
复制代码

04. 程序设计
main.c文件

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"


  7. //空闲任务任务堆栈
  8. static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
  9. //空闲任务控制块
  10. static StaticTask_t IdleTaskTCB;

  11. //定时器服务任务堆栈
  12. static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
  13. //定时器服务任务控制块
  14. static StaticTask_t TimerTaskTCB;

  15. //任务优先级
  16. #define START_TASK_PRIO                1
  17. //任务堆栈大小        
  18. #define START_STK_SIZE                 128  
  19. //任务堆栈
  20. StackType_t StartTaskStack[START_STK_SIZE];
  21. //任务控制块
  22. StaticTask_t StartTaskTCB;
  23. //任务句柄
  24. TaskHandle_t StartTask_Handler;
  25. //任务函数
  26. void start_task(void *pvParameters);

  27. //任务优先级
  28. #define TASK1_TASK_PRIO                2
  29. //任务堆栈大小        
  30. #define TASK1_STK_SIZE                 50  
  31. //任务堆栈
  32. StackType_t Task1TaskStack[TASK1_STK_SIZE];
  33. //任务控制块
  34. StaticTask_t Task1TaskTCB;
  35. //任务句柄
  36. TaskHandle_t Task1Task_Handler;
  37. //任务函数
  38. void task1_task(void *pvParameters);

  39. //任务优先级
  40. #define TASK2_TASK_PRIO                3
  41. //任务堆栈大小        
  42. #define TASK2_STK_SIZE                 50  
  43. //任务堆栈
  44. StackType_t Task2TaskStack[TASK2_STK_SIZE];
  45. //任务控制块
  46. StaticTask_t Task2TaskTCB;
  47. //任务句柄
  48. TaskHandle_t Task2Task_Handler;
  49. //任务函数
  50. void task2_task(void *pvParameters);


  51. //ppxIdleTaskTCBBuffer:任务控制块内存
  52. //ppxIdleTaskStackBuffer:任务堆栈内存
  53. //pulIdleTaskStackSize:任务堆栈大小
  54. void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
  55.                                                                    StackType_t **ppxIdleTaskStackBuffer,
  56.                                                                    uint32_t *pulIdleTaskStackSize)
  57. {
  58.         *ppxIdleTaskTCBBuffer=&IdleTaskTCB;
  59.         *ppxIdleTaskStackBuffer=IdleTaskStack;
  60.         *pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
  61. }


  62. //获取定时器服务任务的任务堆栈和任务控制块内存
  63. //ppxTimerTaskTCBBuffer:任务控制块内存
  64. //ppxTimerTaskStackBuffer:任务堆栈内存
  65. //pulTimerTaskStackSize:任务堆栈大小
  66. void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
  67.                                                                         StackType_t **ppxTimerTaskStackBuffer,
  68.                                                                         uint32_t *pulTimerTaskStackSize)
  69. {
  70.         *ppxTimerTaskTCBBuffer=&TimerTaskTCB;
  71.         *ppxTimerTaskStackBuffer=TimerTaskStack;
  72.         *pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
  73. }

  74. //主函数
  75. int main(void)
  76. {
  77.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
  78.         delay_init(168);                //初始化延时函数
  79.         uart_init(115200);             //初始化串口
  80.         LED_Init();                        //初始化LED端口
  81.         
  82.     //创建开始任务
  83.         StartTask_Handler=xTaskCreateStatic((TaskFunction_t        )start_task,                //任务函数
  84.                                                                                 (const char*         )"start_task",                //任务名称
  85.                                                                                 (uint32_t                 )START_STK_SIZE,        //任务堆栈大小
  86.                                                                                 (void*                           )NULL,                                //传递给任务函数的参数
  87.                                                                                 (UBaseType_t         )START_TASK_PRIO,         //任务优先级
  88.                                                                                 (StackType_t*   )StartTaskStack,        //任务堆栈
  89.                                                                                 (StaticTask_t*  )&StartTaskTCB);        //任务控制块   

  90.     vTaskStartScheduler();          //开启任务调度
  91. }

  92. //开始任务任务函数
  93. void start_task(void *pvParameters)
  94. {
  95.     taskENTER_CRITICAL();           //进入临界区
  96.     //创建TASK1任务
  97.         Task1Task_Handler=xTaskCreateStatic((TaskFunction_t        )task1_task,               
  98.                                                                                 (const char*         )"task1_task",               
  99.                                                                                 (uint32_t                 )TASK1_STK_SIZE,        
  100.                                                                                 (void*                           )NULL,                                
  101.                                                                                 (UBaseType_t         )TASK1_TASK_PRIO,         
  102.                                                                                 (StackType_t*   )Task1TaskStack,        
  103.                                                                                 (StaticTask_t*  )&Task1TaskTCB);        
  104.     //创建TASK2任务
  105.         Task2Task_Handler=xTaskCreateStatic((TaskFunction_t        )task2_task,               
  106.                                                                                 (const char*         )"task2_task",               
  107.                                                                                 (uint32_t                 )TASK2_STK_SIZE,        
  108.                                                                                 (void*                           )NULL,                                
  109.                                                                                 (UBaseType_t         )TASK2_TASK_PRIO,         
  110.                                                                                 (StackType_t*   )Task2TaskStack,        
  111.                                                                                 (StaticTask_t*  )&Task2TaskTCB);
  112.     vTaskDelete(StartTask_Handler); //删除开始任务
  113.     taskEXIT_CRITICAL();            //退出临界区
  114. }

  115. //任务1
  116. void task1_task(void *pvParameters)
  117. {
  118.         u8 task1_num = 0;
  119.         
  120.         while(1)
  121.         {
  122.                 task1_num++;
  123.                 LED0 = !LED0;
  124.                 printf("任务1已经运行%d次\r\n", task1_num);
  125.         
  126.                 if (5 == task1_num)
  127.                 {
  128.                         //任务1删除任务2
  129.                         vTaskDelete(Task2Task_Handler);
  130.                         printf("任务1删除了任务2\r\n");
  131.                 }
  132.                
  133.                 //延时1秒 1000个时钟节拍
  134.                 vTaskDelay(1000);
  135.         }
  136. }

  137. //任务2
  138. void task2_task(void *pvParameters)
  139. {
  140.         u8 task2_num = 0;
  141.         
  142.         while(1)
  143.         {
  144.                 task2_num++;
  145.                 LED1 = !LED1;
  146.                 printf("任务2已经执行了%d次\r\n", task2_num);
  147.                
  148.                 //延时1秒 1000个时钟节拍
  149.                 vTaskDelay(1000);
  150.         }
  151. }
复制代码

05. 结果验证

任务1运行5秒中之后删除了任务2,任务2被删除之后就不会被运行。最后只剩下任务1运行了。


收藏 评论0 发布时间:2022-6-18 17:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版