当前位置: 首页 > news >正文

【FreeRTOS#5】任务挂起与恢复实例

问题纠正

        在上一节中讲述了关于任务创建和删除的例程,在代码中有一个任务优先级的问题没有解决

        我们给启动任务的优先级是最低的,其实这样有一定风险

#define START_TASK_STACK 128
#define STACK_TASK_PRIORITY 1
void start_task(void * pvParameters);
TaskHandle_t start_task_handle;

        潜在风险:如果其他高优先级任务给的阻塞时间不够,可能任务创建后启动任务根本来不及删除自己的任务控制块,导致内存泄漏。

        这里给出两个解决方案:

        1. 在创建完其他任务后,临时把自己的优先级拉到最高(不一定能解决)

        2. 初始化配置时就把启动任务优先级配置为最高

        

一、API函数

        任务挂起与恢复功能实现的API有:

                vTaskSuspend(); 挂起任务

                vTaskResume();  恢复任务

                xTaskResumeFromISR; 中断中恢复被挂起的任务

        (1)  任务挂起函数

        原型:

void xTaskSuspend(TaskHandle_t xTasktoSuspend)

         xTaskToSuspend: 待挂起任务的任务句柄,为NULL表示挂起正在运行的任务自身

        使用此函数需要改变config.h中的宏

#define INCLUDE_vTaskSuspend 1

        (2)任务恢复函数

void vTaskResume(TaskHandle_t xTasktoResume);

        xTasktoResume:  无论任务被重复挂起多少次,Resume一次就能恢复就绪态

        使用此函数需要改变config中的宏

#define INCLUDE_vTaskSuspend 1

        (3)   中断中任务恢复

BaseType_t xTaskResumeFromISR(TaskHandle_t xTasktoResume)

        返回值为:pdTRUE: 任务恢复后需要进行任务切换

                         pdFALSE: 任务恢复后不需要进行任务切换

        在嵌入式系统中,低优先级中断不能打断高优先级,所以,在使用ISR任务恢复时,ISR本身的中断优先级不能高于FreeRTOS的最高中断优先级。

        此外,以下两个配置宏需要置为1

#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xTaskResumeFromISR 1

      (4) 任务挂起与恢复

        vTaskSuspendALL():挂起任务调度器,调度器停止任务切换,当前任务一直运行下去

        xTaskResumeALL    ()  : 恢复任务调度器,调度器继续任务切换

      (5)查看任务状态

        需要提前使能task跟踪

#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1

        预先开辟一个内存足够的字符串,并将首地址赋给函数

void vTaskList( uint8_t * pcWriteBuffer )

        输出结果一般为

名称			状态    优先级   堆栈使用 任务编号
'X'(运行) 'B'(阻塞)、'R'(就绪)、'S'(暂停)或 'D'(删除)。

        我们可以使用静态预估法计算需要的内存长度

总长度 = 表头长度 + (每行长度 × 任务数) + 安全余量

        任务总数可以通过uxTaskGetNumberOfTasks()获取

二、挂起恢复实验

start_task:用来创建其他的三个任务。
task1:实现LED1每500ms闪烁一次。
task2:实现LED2每500ms闪烁一次。
task3:判断按键按下逻辑,KEY1按下,挂起task1,按下KEY2在任务中恢复task1,KEY3按下,挂起调度器,KEY4按下,恢复调度器,并打印任务的状态。

        我们直接从上一节的例程修改,任务1和2没有区别,只要修改3就可以

        1. 使能相关配置宏

#define configUSE_PREEMPTION		1
#define configUSE_IDLE_HOOK			0
#define configUSE_TICK_HOOK			0
#define configCPU_CLOCK_HZ			( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES		( 5 )
#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN		( 16 )
#define configUSE_TRACE_FACILITY	1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configUSE_16_BIT_TICKS		0
#define configIDLE_SHOULD_YIELD		1/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */#define INCLUDE_vTaskPrioritySet		1
#define INCLUDE_uxTaskPriorityGet		1
#define INCLUDE_vTaskDelete				1
#define INCLUDE_vTaskCleanUpResources	0
#define INCLUDE_vTaskSuspend			1
#define INCLUDE_xResumeFromISR 1
#define INCLUDE_vTaskDelayUntil			1
#define INCLUDE_vTaskDelay				1/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY 		255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	191 /* equivalent to 0xb0, or priority 11. *//* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY	15#define xPortPendSVHandler  PendSV_Handler
#define vPortSVCHandler     SVC_Handler
#define INCLUDE_xTaskGetSchedulerState   1#endif /* FREERTOS_CONFIG_H */

     2. 修改任务3内容

void task3(void * pvParameters){while(1){printf("Task 3 Running \r\n");if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0){HAL_Delay(40);if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0){switch(status_key1){case 0: vTaskSuspend(start_task1_handle);status_key1 = 1;break;case 1: vTaskResume(start_task1_handle);status_key1 = 0;break;}
//									vTaskDelete(start_task1_handle);
//									start_task1_handle=NULL;}}if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==0){HAL_Delay(40);if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==0){switch(status_key0){case 0: vTaskSuspend(start_task2_handle);status_key0 = 1;break;case 1: vTaskResume(start_task2_handle);status_key0 = 0;break;}
//									vTaskDelete(start_task1_handle);
//									start_task1_handle=NULL;}}vTaskList(pcBuffer);printf("%s\r\n",pcBuffer);vTaskDelay(200);}
}

现象

(1)任务2挂起

 

(2)任务1挂起

http://www.dtcms.com/a/283430.html

相关文章:

  • 信息收集知识总结
  • Git分支管理完全指南:从创建到合并与冲突解决
  • Java的Gradle项目,使用SLF4J+Log4j2+log4j2.xml
  • 深度隐匿源IP:高防+群联AI云防护防绕过实战
  • C++-linux系统编程 10.内核原理基础
  • 用python程序通过指纹识别开关车门
  • 开源 python 应用 开发(六)网络爬虫
  • 健康生活,从细节开始
  • 线程学习day1---基础知识+pthread_create、self、exit、cancle、join
  • pymongo库:简易方式存取数据
  • Android 15 Settings 搜索框增加暗码功能实现
  • Windows10系统上Node.js的安装及环境配置
  • lua(xlua)基础知识点记录一
  • gem install报错解析
  • 小程序中状态管理Redux
  • ROCK Robotic R3 Pro -替代L2,适配多款无人机,支持机载、手持、车载以及船载
  • DrissionPage:一款让网页自动化更简单的 Python 库
  • 使用defineExpose暴露子组件的属性和方法、页面生命周期onLoad和onReady的使用
  • 【AI论文】可追溯证据增强的视觉基础推理:评估与方法论
  • OSS文件上传解析失败,错误:文件下载失败的排查与解决
  • 61.第二阶段x64游戏实战-抓取Lua分析本地和跨图寻路
  • Harbor 和 Helm
  • 陆面、生态、水文模拟与多源遥感数据同化的实践技术应用
  • ACL实验(思科设备)
  • 游戏开发中防止“范围蔓延”
  • Oracle 数据库常见等待事件参数详解
  • YOLO算法原理
  • 2025年中国品牌全球化发展分析:中国品牌在社交渠道、电商平台及官网流量方面显著增长
  • 测试开发工作日常用的提示词分享
  • 探秘京东外卖幕后:地图轨迹技术探寻