FreeRTOS系列|任务挂起和恢复

2023-05-16

任务挂起和恢复

1. 任务挂起和恢复API函数

  • vTaskSuspend()函数:将任务置于挂起状态
void vTaskSuspend(TaskHandle_t xTaskToSuspend)
参    数:xTaskToSuspend 要挂起的任务的任务句柄
返 回 值:无
  • vTaskResume()函数:将任务从挂起状态恢复到就绪态
void vTaskResume(TaskHandle_t xTaskToResume)
参    数:xTaskToResume 要恢复的任务的任务句柄
返 回 值:无

2. 任务挂起和恢复函数源码分析

  • 任务挂起函数源码分析
void vTaskSuspend(TaskHandle_t xTaskToSuspend){
	TCB_t *pxTCB;
	/* 进入临界段 */
	taskENTER_CRITICAL();
	{
		/* 获取任务控制块,若为NULL则挂起自身 */
		pxTCB = prvGetTCBFromHandle(xTaskToSuspend);
		/* 将任务从就绪列表中移除 */
		if(uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0){
			taskRESET_READY_PRIORITY(pxTCB->uxPriority);
		}
		else{
			mtCOVERAGE_TEST_MARKER();
		}
		/* 查看任务是否在等待某个事件,如是则将其从事件列表中移除 */
		if(listLIST_ITEM_CONTAINER(&(pxTCB->xEventListItem))!=NULL){
			(void) uxListRemove(&(pxTCB->xEventListItem));
		}
		else{
			mtCOVERAGE_TEST_MARKER();
		}
		/* 将任务添加到挂起任务列表表尾 */
		vListInsertEnd(&xSuspendedTaskList, &(pxTCB->xStateListItem));
	}
	/* 退出临界段 */
	taskEXIT_CRITICAL();
	
	if(xSchedulerRunning != pdFALSE){	//判断调度器是否开启
		/* 重新计算还要多长时间执行下一个任务 */
		taskENTER_CRITICAL();
		{
			prvResetNextTaskUnblockTime();
		}
		taskEXIT_CRITICAL();
	}
	else{
		mtCOVERAGE_TEST_MARKER();
	}

	if(pxTCB == pxCurrentTCB){
		if(xSchedulerRunning != pdFALSE){
			/* 若刚挂起的是正在运行的任务,且任务调度器运行正常,则强制进行一次任务切换 */
			configASSERT( uxSchedulerSuspended == 0 );
			portYIELD_WITHIN_API();
		}
		else{
			/* 若任务调度器没有开启,则读取当前任务挂起列表的长度,判断所有任务是否都被挂起*/
			if(listCURRENT_LIST_LENGTH(&xSuspendedTaskList) == uxCurrentNumberOfTasks){
				/* 若所有任务都被挂起,把当前的任务控制块赋值为NULL	*/
				pxCurrentTCB = NULL;
			}
			else{
				/* 若还有没被挂起的任务,则获取下一个要运行的任务 */
				vTaskSwitchContext();
			}
		}
	}
	else{
		mtCOVERAGE_TEST_MARKER();
	}
}
  • 任务恢复函数源码分析
void vTaskResume(TaskHandle_t xTaskToResume){
	/* 获取要恢复的任务控制块 */
	TCB_t * const pxTCB = (TCB_t *) xTaskToResume;
	configASSERT( xTaskToResume );

	/* 任务控制块不能为NULL和当前任务	*/
	if(( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB )){
		/* 进入临界段 */
		taskENTER_CRITICAL();
		{
			/* 判断任务是否被挂起 */
			if(prvTaskIsTaskSuspended(pxTCB) != pdFALSE){
				/* 从挂起列表中移除 */
				(void) uxListRemove(&( pxTCB->xStateListItem));
				/* 添加到就绪列表中 */
				prvAddTaskToReadyList( pxTCB );
				/* 要恢复的任务优先级高于当前正在运行的任务优先级 */
				if(pxTCB->uxPriority >= pxCurrentTCB->uxPriority){
					/* 完成一次任务切换 */
					taskYIELD_IF_USING_PREEMPTION();
				}
				else{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		/* 退出临界段 */
		taskEXIT_CRITICAL();
	}
	else{
		mtCOVERAGE_TEST_MARKER();
	}
}

3. 任务挂起和恢复函数实例

使用STM32CubeMX可以非常方便的将FreeRTOS移植到工程中。本实验就是利用STM32CubeMX移植FreeRTOS,并创建三个任务:

Led_Task:D2指示灯闪烁
Usart_Task:每隔1s向串口输出字符串
Key_Task:按下K_UP,挂起Led_Task任务;按下K_DOWN,恢复Led_Task任务

3.1 STM32CubeMX设置
  • RCC设置外接HSE,时钟设置为72M
  • PC1设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
  • PA0设置为GPIO输入模式、下拉模式;PE2/PE3/PE4设置为GPIO输入模式、上拉模式
  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
  • 激活FreeRTOS,添加任务,设置任务名称、优先级、堆栈大小、函数名称等参数
    在这里插入图片描述在这里插入图片描述
  • 使用FreeRTOS操作系统,一定要将HAL库的Timebase Source从SysTick改为其他定时器,选好定时器后,系统会自动配置TIM
    在这里插入图片描述
  • 输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
3.2 MDK-ARM软件编程
  • 创建按键驱动文件key.c和key.h,参考按键输入例程
  • 添加Led_Task、Usart_Task和Key_Task任务函数代码
void Led_Task(void const * argument){
  /* USER CODE BEGIN Led_Task */
  /* Infinite loop */
  for(;;){
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET);
    osDelay(500);  //1ms时基
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);
    osDelay(500);  //1ms时基
  }
  /* USER CODE END Led_Task */
}

void Usart_Task(void const * argument){
  /* USER CODE BEGIN Usart_Task */
  /* Infinite loop */
  for(;;){
	printf("UsartTask is Runing!\r\n");
    osDelay(1000);
  }
  /* USER CODE END Usart_Task */
}

void KeyTask(void const * argument){
  /* USER CODE BEGIN KeyTask */
	uint8_t key = 0;	
  /* Infinite loop */
  for(;;){
    key = KEY_Scan(0);	
	switch(key){
		case KEY_UP_PRES:
			vTaskSuspend(Led_TaskHandle);
			printf("Led_Task被挂起!\r\n");
			key = 0;
			break;
		case KEY_DOWN_PRES:
			vTaskResume(Led_TaskHandle);
			printf("Led_Task被恢复!\r\n");
			key = 0;
			break;
	}
	osDelay(10);
  }
  /* USER CODE END KeyTask */
}
3.3 下载验证

编译无误下载到开发板后,D2指示灯闪烁表示程序正常运行。打开串口调试助手,可以看到串口每隔1s输出相应字符;按下K_UP按键,Led_Task被挂起,D2指示灯停止闪烁,按下K_DOWN按键,Led_Task任务恢复,D2指示灯开始闪烁
在这里插入图片描述

关注我的公众号,在公众号里发如下消息,即可获取相应的工程源代码:

FreeRTOS任务挂起和恢复实例

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS系列|任务挂起和恢复 的相关文章

  • 基于HAL库的FREERTOS----------二.任务API函数

    任务API函数览概 CUBEMX对 做了API的封装 很多 的函数没有封装到位 可以用原函数调用 任务API函数分别介绍 1 uxTaskPriorityGet 此函数用来获取指定任务的优先级 要使用此函数的话宏 INCLUDE uxTas
  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • FreeRTOS config开始的宏

    FreeRTOSConfig h系统配置文件中可以自定义 FreeRTOS h中定义默认值 configAPPLICATION ALLOCATED HEAP 默认情况下FreeRTOS的堆内存是由编译器来分配的 将宏configAPPLIC
  • 【FreeRTOS 信号量】互斥信号量

    互斥信号量与二值信号量类似 但是互斥信号量可以解决二值信号量出现的优先级翻转问题 解决办法就是优先级继承 普通互斥信号量创建及运行 参阅安富莱电子demo 互斥信号量句柄 static SemaphoreHandle t xMutex NU
  • FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列 但是在FreeRTOS中任务间的通讯还有信号量 邮箱 事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 增加邮箱部分 任务通知发送消息 Demo 202
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • FreeRTOS学习笔记(3、信号量、互斥量的使用)

    FreeRTOS学习笔记 3 信号量 互斥量的使用 前言 往期学习笔记链接 学习工程 信号量 semaphore 两种信号量的对比 信号量的使用 1 创建信号量 2 give 3 take 4 删除信号量 使用计数型信号量实现同步功能 使用
  • 【FreeRTOS开发问题】FreeRTOS内存溢出

    FreeRTOS内存溢出 如下图所示 FreeRTOS编译完成后可以看到 系统提示无法分配内存到堆 Objects Template axf Error L6406E No space in execution regions with A
  • STM32移植FreeRTOS的Tips

    转自 http bbs armfly com read php tid 7140 1 在FreeRTOS的demo文件夹中拷贝对应的FreeRTOSConfig h文件后 需要加入一行 define configUSE MUTEXES 1
  • FreeRTOS临界区

    FreeRTOS临界区是指那些必须完整运行 不能被打断的代码段 比如有的外设的初始化需要严格的时序 初始化过程中不能被打断 FreeRTOS 在进入临界区代码的时候需要关闭中断 当处理完临界区代码以后再打开中断 FreeRTOS 系统本身就
  • FreeRTOS基础五:软件定时器

    软件定时器简介 软件定时器的作用 在指定的时间到来时执行指定的函数 或者以某个频率周期性地执行某个函数 被执行的函数叫做软件定时器回调函数 软件定时器由FreeRTOS内核实现 不需要硬件支持 软件定时器只有在软件定时器回调函数被调用时才需
  • FreeRTOS之事件

    FreeRTOS之事件 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 一 事件定义 事件 事件集 与高数上的集合意义差不多 事件啊 其实是实现任务间通信的机制 主要用于实现多任务间的同步 但是事件类型
  • FreeRTOS学习笔记(8)---- 软件定时器

    使用FreeRTOS软件定时器需要在文件FreeRTOSConfig h先做如下配置 1 configUSE TIMERS 使能软件定时器 2 configTIMER TASK PRIORITY 定时器任务优先级 3 configTIMER
  • FreeRTOS死机原因

    1 中断回调函数中没有使用中断级API xxFromISR 函数 xSemaphoreGiveFromISR uart busy HighterTask 正确 xSemaphoreGive uart busy 错误 2 比configMAX
  • 13-FreeRTOS任务创建与删除

    任务创建和删除API函数位于文件task c中 需要包含task h头文件 task h里面包函数任务的类型函数 例如 对xTaskCreate的调用 通过指针方式 返回一个TaskHandle t 变量 然后可将该变量用vTaskDele
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐

  • 使用C++实现学生管理系统

    我在前面的博客中分别使用C语言的动态数组和链表实现了学生成绩管理系统 xff0c 最近正好在学习C 43 43 xff0c 于是我便使用C 43 43 实现了学生成绩管理系统 xff0c 算法和前面的C语言的动态数组实现的学生成绩管理系统差
  • 制作一个简单的Android版的音乐播放器

    音乐播放器是一个非常常见的应用 xff0c 这篇博客就是介绍如何制作一个简单的音乐播放器 xff0c 这款音乐播放器具有以下的功能 xff1a 播放歌曲 暂停播放歌曲 显示歌曲的总时长 显示歌曲的当前播放时长 调节滑块可以将歌曲调节到任何时
  • 使用Less

    为什么要使用预处理CSS 在使用CSS过程中会遇到一个非常头疼的问题 xff0c 因为CSS中没有像java C 43 43 或者PHP等程序语言一样有有自己的变量 常量 条件语句以及一些编程语法 xff0c 只是一行行单纯的属性描述 xf
  • 使用Gulp

    为什么要使用Gulp 在前端开发中通常需要做 xff0c 预处理语言的编译 js文件的压缩 css文件的压缩 图片的压缩等一系列工作 xff0c 而使用Gulp可以自动化的完成这些工作 xff0c 从而提高网站的开发效率 xff0c 在我的
  • 欢迎使用CSDN-markdown编辑器

    欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来 xff0c 用它写博客 xff0c 将会带来全新的体验哦 xff1a Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传
  • CMakeList的基本写法

    最近需要自己写CMakaList xff0c 所以简要写一下一些基本的操作 为图实用 xff0c 只写了常用的简单操作 1 确定cmake最低版本需求 span class hljs function span class hljs tit
  • SLAM的一点认识

    SLAM的一点认识 本人邮箱 xff1a sylvester0510 64 163 com xff0c 欢迎交流讨论 xff0c 欢迎转载 xff0c 转载请注明网址http blog csdn net u010128736 一 我与SLA
  • ORB-SLAM2详解(六)闭环检测

    ORB SLAM2详解 xff08 六 xff09 闭环检测 本人邮箱 xff1a sylvester0510 64 163 com xff0c 欢迎交流讨论 xff0c 欢迎转载 xff0c 转载请注明网址http blog csdn n
  • FreeRTOS系列|任务创建和删除

    任务创建和删除 1 任务创建和删除API函数 xTaskCreate 函数 xff1a 动态创建一个新的任务 xff0c 每个任务都需要RAM来保存任务状态 任务控制块 43 任务栈 xff0c 此接口采用动态分配内存资源 BaseType
  • 深度学习如何做特征工程?

    深度能自动获取特征 只是对某些领域而言的 实际上深度学习只是能自动对输入的低阶特征进行组合 变换 xff0c 得到高阶特征 对于图像处理之类的领域来说 xff0c 像素点就可以作为低阶特征输入 xff0c 组合 变换得到的高阶特征也有比较好
  • Git:《Git学习视频》学习笔记

    视频地址 xff1a 黑马程序员 Git学习视频 目录 xff1a 一Git介绍二Git与SVN的区别 速度结构其他 三Git基本命令的使用掌握 如何学习git指令常见命令单人开发配置帐号信息一般只需配置一次全局帐号即可查看日志起别名版本回
  • 海康云台摄像机 ISAPI 的签名机制与语音传输

    由于海康HikVision Hik 平台摄像机的SDK不支持Arm Linux平台 xff0c 为了跨平台的兼容性 xff0c 只能使用ISAPI作为控制或接收相机数据的方式 xff0c ISAPI是Hik的一套HTTP通信协议 xff0c
  • 无人机中的坐标系与相机姿态计算

    球坐标系 球坐标系是三维坐标系中的一种 xff0c 在无人机中一般使用球坐标系来表示相机姿态 xff0c 相机姿态的坐标是相对于无人机的 xff0c 而无人机的飞行姿态则是相对于大地坐标系的 这里我们使用的相机是2自由度的相机 xff0c
  • 【Ubuntu】安装中文输入法、终端不支持中文的解决方法

    一 中文输入法安装 1 安装汉语语言包 sudo apt install fcitx sudo apt install language pack zh hans 2 安装google拼音输入法 sudo apt install fcitx
  • 【Qt】QtCreator中配置clang-format

    1 安装clang format sudo apt install clang format 2 添加插件Beautifier 在QtCreator gt Help gt About Plugins 中添加插件Beautifer 添加后要重
  • 【TX2】TX2开发板系统默认串口有ttyS0(调试口)、ttyTHS1、ttyTHS2、ttyTHS3,通过修改设备树文件,可以新增三个串口

    1 简述 TX2开发板系统默认串口有ttyS0 调试口 ttyTHS1 ttyTHS2 ttyTHS3 通过修改设备树文件 可以新增三个串口 2 设备树 设备树中关于串口部分的描述 2 1 基础配置 注意 在这里状态都配置成禁止 statu
  • 【STM32】入门(六):I2C协议

    STM32 STM32单片机总目录 1 常见I2C设备 EEPROM 温湿度传感器 xff0c 例如 xff1a AHT10 电量计 xff0c 例如 xff1a TI的BQ34Z100 日历时钟 模数或数模转换器 2 I2C总线结构 I2
  • 【STM32】入门(九):HAL库学习

    STM32 STM32单片机总目录 1 简述 STD xff08 Standard Peripheral Libraries xff09 标准库 xff1a 面向过程 xff0c 仅仅是在寄存器上的一层封装操作 HAL xff08 Hard
  • 【STM32】入门(十一):初识uCOS-III

    STM32 STM32单片机总目录 1 轮询 中断 多任务对比 2 什么是任务 如果您学过linux xff0c 那么任务可以理解为线程 在代码中的体现就是线程函数 xff0c 一个函数中有个无限循环函数 xff0c 并且永不返回 例如 x
  • FreeRTOS系列|任务挂起和恢复

    任务挂起和恢复 1 任务挂起和恢复API函数 vTaskSuspend 函数 xff1a 将任务置于挂起状态 span class token keyword void span span class token function vTas