再学FreeRTOS---(任务的挂起与恢复)

ops/2024/11/2 19:55:52/

目录

一.FreeRTOS任务挂起与恢复的API函数

二.任务挂起和恢复的基本操作

 1.任务挂起:

2.任务恢复:

三.任务挂起与恢复的实现步骤

任务挂起的实现

任务恢复的实现


在实时操作系统FreeRTOS中,任务的挂起与恢复是一项重要的控制功能。任务挂起相当于暂停任务的执行,直到条件满足才恢复继续运行。这种机制在任务的调度和系统资源管理上起到了关键作用。本篇文章将通过FreeRTOS提供的任务挂起和恢复API函数及相关实验来深入理解这一机制。

一.FreeRTOS任务挂起与恢复的API函数

在FreeRTOS中,以下几个API函数用于实现任务的挂起和恢复:

vTaskSuspend(TaskHandle_txTaskToSuspend):挂起指定任务。
vTaskResume(TaskHandle_txTaskToResume):恢复指定任务。
xTaskResumeFromISR(TaskHandle_txTaskToResume):在中断服务例程(ISR)中恢复任务。

特别注意:如果API函数名称中包含"FromISR"后缀,它只能用于中断服务中调用。例如,xTaskResumeFromISR用于在中断中恢复被挂起的任务。挂起任务时需要将宏INCLUDE_vTaskSuspend配置为1,表示启用该功能。

二.任务挂起和恢复的基本操作

 1.任务挂起:


使用vTaskSuspend()函数来挂起任务。无论任务的优先级高低,被挂起后便停止执行,直到通过恢复函数vTaskResume()使其继续执行。
当传入的任务句柄参数为NULL时,表示挂起当前运行的任务自身。

void task3( void * pvParameters )
{uint8_t key = 0;while(1){key = key_scan(0);if(key == KEY0_PRES){printf("挂起task1\r\n");vTaskSuspend(task1_handler);}	else if(key == KEY_UP){printf("挂起task3\r\n");vTaskSuspend(task1_handler);}vTaskDelay(10);}
}

2.任务恢复:


调用vTaskResume()函数恢复被挂起的任务。值得注意的是,无论任务被vTaskSuspend()挂起多少次,vTaskResume()只需调用一次便可恢复该任务继续运行。
xTaskResumeFromISR()用于在中断服务中恢复被挂起的任务。在任务恢复时,需要检查任务的优先级以判断是否需要进行任务切换。

void task3( void * pvParameters )
{uint8_t key = 0;while(1){key = key_scan(0);if(key == KEY1_PRES){printf("在任务中恢复task1\r\n");vTaskResume(task1_handler);}vTaskDelay(10);}
}

三.任务挂起与恢复的实现步骤

任务挂起的实现

1.确保INCLUDE_vTaskSuspend宏定义为1

-功能选择性启用:如果INCLUDE_vTaskSuspend未定义或定义为0,则编译时FreeRTOS不会包含与任务挂起和恢复相关的代码逻辑。这种选择性的编译配置可以减少代码体积,节省内存资源。这对于嵌入式系统尤其重要,因为这些系统的存储和内存通常有限。

-API功能可用性:如果未定义为1,那么vTaskSuspend()和vTaskResume()函数将不会被包含,任何试图调用这些函数的代码都会在编译时报错。定义宏为1才能确保这些API函数能够被正常调用。

-系统效率优化:通过使用宏开关,FreeRTOS可以根据不同项目需求来裁剪无关的功能模块,从而优化系统运行效率。这样可以减轻调度器的负担,使任务切换和资源管理更加高效。

2.通过任务句柄获取任务控制块(TCB)

任务控制块(TCB)是FreeRTOS中存储任务状态的核心数据结构。通过任务句柄可以直接访问到任务的TCB,从而执行挂起操作。具体步骤如下:

-获取TCB:任务句柄在创建任务时生成,指向该任务的TCB结构。调用vTaskSuspend()时,如果传入的句柄为某个任务的句柄,则会对该任务执行挂起操作。

-挂起当前任务:如果传入的句柄为NULL,则表示挂起当前运行的任务。此时FreeRTOS会自动找到当前任务的TCB,并执行后续的挂起操作。

3.将待挂起的任务从状态列表和事件列表中移除,并插入挂起任务列表

挂起任务涉及将任务从调度器的管理列表中移出并转入挂起列表,以防其继续参与系统的任务调度。具体操作如下:

-移出状态列表:在FreeRTOS中,所有任务根据状态(就绪、阻塞、延时等)被组织在不同的状态列表中。当任务被挂起时,需要将它从这些状态列表中移除,以避免调度器将其视为可调度任务。

-移出事件列表:任务可能因等待事件(如信号量、消息队列等)而被阻塞。挂起操作需要将任务从任何事件等待列表中移出,以确保它不再响应这些事件。

-插入挂起列表:将任务添加到挂起列表中,以便在任务恢复时能够方便地从该列表中移回到就绪列表。

4.若挂起的是当前任务且调度器正在运行,则需要一次任务切换

挂起当前任务时,如果调度器处于运行状态,则需要立即进行任务切换,以确保系统有其他任务可以运行:

-判断调度器状态:首先,FreeRTOS会检查调度器是否正在运行。如果调度器暂停,则挂起当前任务不会触发任务切换;若调度器正在运行,则系统必须在挂起当前任务后立即切换到优先级最高的可运行任务。

-任务切换:一旦确认需要切换任务,FreeRTOS会查找下一个优先级最高的就绪任务,并将其切换到执行状态。这确保了系统不会因为挂起当前任务而停滞,保证实时性。

这一任务切换机制在FreeRTOS中称为“上下文切换”,它确保调度器始终运行优先级最高的任务。
 

任务恢复的实现

1.确保宏INCLUDE_vTaskSuspend定义为1,恢复的任务不能是当前运行任务

在执行任务恢复时,首先需要确认以下两点:

-启用挂起和恢复功能:INCLUDE_vTaskSuspend宏必须定义为1。它决定了FreeRTOS是否包含和启用任务挂起和恢复功能。如果该宏未定义,编译时将不包含与恢复功能相关的代码,导致恢复API不可用。

-不能恢复当前运行任务:如果试图恢复当前运行的任务,会导致任务行为异常,因为当前任务本身已经处于就绪状态且正在执行。恢复操作应仅作用于挂起状态的任务,因此调用恢复函数时需确保目标任务并非当前任务。

2.检查恢复的任务是否在挂起列表中,若是,则将其移除并添加到就绪列表

任务恢复时,首先需要验证该任务是否确实处于挂起状态:

-挂起列表检查:FreeRTOS将所有挂起任务保存在挂起列表中。当调用恢复函数时,系统会先查找目标任务是否在该列表中,以确保仅对实际被挂起的任务执行恢复操作。

-从挂起列表移除:如果目标任务确实在挂起列表中,则将其移出挂起列表,表示该任务将重新进入调度器的管理,能够再次参与任务调度。

-添加到就绪列表:被移出挂起列表后,目标任务会被添加到就绪列表。就绪列表中包含所有可以立即调度的任务。此时,恢复的任务可以根据其优先级重新参与任务调度。

3.比较恢复任务的优先级与当前任务的优先级,若高于当前任务则触发任务切换

任务恢复后,需要判断是否立即切换到该任务:

-优先级比较:FreeRTOS在恢复任务后会将其优先级与当前任务进行比较。如果恢复的任务优先级高于当前运行的任务,则系统会触发任务切换,以立即执行优先级更高的任务。

-任务切换:如果优先级比较结果需要切换,则系统会触发上下文切换,将CPU控制权交给恢复的高优先级任务。这种任务切换确保了系统始终执行优先级最高的任务,以满足实时性的要求。

通过这些步骤,FreeRTOS实现了对任务恢复的完整操作,确保任务能有效地从挂起状态回到正常调度,且不会影响当前任务的执行逻辑。
 

通过上述的API解析和实验步骤,相信大家对FreeRTOS任务的挂起与恢复有了更深入的理解。这些操作在嵌入式系统中灵活地管理任务的执行,为实时调度提供了强有力的支持。
 


http://www.ppmy.cn/ops/130505.html

相关文章

如何使用python完成数据统计分析及预测?

在当今数据驱动的时代,数据分析和预测已成为各行各业的重要组成部分。 Python作为一种强大的编程语言,因其简洁的语法和丰富的库而广泛应用于数据科学领域。 本文将深入探讨如何使用Python进行数据统计分析和数据预测,并提供相关的代码示例。 第一部分:数据统计分析 1.…

vscode摸鱼学习插件开发

不知道大家在摸鱼的时候,会不会想要学习? 或者有没有考公人,下班要学习的? 上班时间摸鱼,下班时间不够学习? 为此,我决定开发一个vscode插件,来刷粉笔题 粉笔插件名称:…

启纬科技发布6色无源电子纸手机壳InkaceE6

杭州启纬科技有限公司投稿:无源NFC技术的开创者和领导者,杭州启纬科技有限公司于北京时间2024年10月28号正式发布了面向iOS系统和安卓/鸿蒙系统的6色无源电子纸手机壳---InkaceE6系列产品及配套方案。 图1:手机壳高清图 图2:6色与3色、4色效果对比图,海边美女 启纬…

OpenCV图像预处理1

目录 图像翻转 图像仿射变换 仿射变换函数 图像旋转 图像平移 图像缩放 图像倾斜 图像色彩空间转换 RGB 转 Gray RGB 转 HSV 图像二值化处理 图像掩模 图像位与操作 图像检测轮廓 绘制轮廓 图像翻转 cv2.flip(src, flipCode[, dst]) -> dst 用于翻转图像。翻…

PySpark 本地开发环境搭建与实践

目录 一、PySpark 本地开发环境搭建 (一)Windows 本地 JDK 和 Hadoop 的安装 (二)Windows 安装 Anaconda (三)Anaconda 中安装 PySpark (四)Pycharm 中创建工程 二、编写代码 …

交易所开发:开启数字金融新时代

当今数字化高速发展的时代,交易所作为金融市场的核心枢纽,发挥着至关重要的作用。而随着区块链技术的兴起,数字货币交易所的开发更是为金融领域带来了全新的变革与机遇。 一、数字货币交易所的重要性 数字货币交易所是连接数字货币世界与传统…

微服务基础-Ribbon

客户端负载均衡器 1.1 Ribbon介绍: 1.2 Ribbon--默认负载均衡策略: @loadBalanced就是调用loadBalance服务:获取注册过的服务列表:

GPT-Sovits-1-数据处理

1.1 切割音频 将音频切割为多个10s内的片段 1.2 降噪 这一步用的是modelscope的pipeline 如果要去除背景音,可以用傅立叶转为为频谱,去除低频部分后再转回来 1.3 提取音频特征 这里用到了 funasr 库 这一步目的是输出音频样本的《文本标签文件》&am…