首页 > 其他分享 >FreeRTOS 任务挂起和恢复API函数使用

FreeRTOS 任务挂起和恢复API函数使用

时间:2024-04-01 21:33:06浏览次数:21  
标签:优先级 函数 FreeRTOS 中断 句柄 任务 API

FreeRTOS 任务挂起和恢复API函数使用

挂起的作用就是当我们需要暂停某任务时候,等过一段时间在运行,这个时候要是使用删除和重建的方法就会当时任务进行时候的变量保存的值。当需要将这个任务停止运行一段时间的将这个任务挂起,当重新进行运行这个任务就恢复运行。

vTaskSuspend()//挂起一个任务
vTaskResume()//恢复一个任务的运行
xTaskResumeFromISR()//中断服务函数中恢复一个任务的进行

一旦将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。除非对当前这个任务进行解挂,
1

void vTaskSuspend( TaskHandle_t xTaskToSuspend)

xTaskToSuspend: 要挂起的任务的任务句柄,创建任务的时候会为每个任务分配一个任务句柄。如果使用函数 xTaskCreate()创建任务的话那么函数的参数,pxCreatedTask 就是此任务的任务句柄,如果使用函数xTaskCreateStatic()创建任务的话那么函数的返回值就是此任务的任务句柄。也可以通过函数 xTaskGetHandle()来根据任务名字来获取某个任务的任务句柄。注意!如果参数为NULL 的话表示挂起任务自己。
2

vTaskResume()//恢复一个任务的运行,xTaskToResume: 要恢复的任务的任务句柄。

3

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume)

xTaskToResume: 要恢复的任务的任务句柄。返回值:pdTRUE:恢复运行的任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数以后必须进行一次上下文切换。pdFALSE:恢复运行的任务的任务优先级低于当前正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数的以后不需要进行上下文切换。
换句话就是当中断恢复挂起的优先级等于高于的时候,就会切换另一个任务,否则不会切换这个任务。想象一下,你在做一件非常重要的事情(比如做饭),这时候有人敲门(这就像是一个中断)。根据敲门的人是谁(中断的优先级),你会决定是否暂停做饭去开门(中断服务),还是让他们等一会儿。

pdTRUE 的情况:

如果敲门的人是你的好朋友,而且你已经约好了(这意味着“中断”很重要,优先级高或等同于你正在做的事情),你会选择停下手中的事情(做饭),去开门(处理中断)。在开完门后,你可能会决定先陪陪朋友,不立即回去做饭(这就是所谓的“上下文切换”,从一个任务切换到另一个)。

pdFALSE 的情况:

相反,如果敲门的是一个推销员(这意味着“中断”不太重要,优先级较低),你可能会决定让他等一下,继续做饭(即使你知道门外有人)。这个时候,你没有放下手中的事情去开门,也就没有发生“上下文切换”。

在实时操作系统(RTOS)中,任务(比如做饭)有不同的优先级,中断也是如此。系统需要决定在中断发生时是否暂停当前任务去处理中断,以及处理完中断后是否回到原来的任务或者转去做另一个更重要的任务。这个决定基于任务和中断的优先级:

  • 如果中断很重要(优先级高或相等),系统会处理中断,并可能转去做另一个任务(pdTRUE)。
  • 如果中断不那么重要(优先级低),系统会忽略它,继续当前的任务(pdFALSE)。
    接下来我们编写程序来使用挂起以及恢复函数:
    我们将创建三个任务:
void LED0_task(void *pvParameters)
{
	  u16 task1num = 0;
		while(1)
		{
			printf("task1num=%d\r\n",++task1num);
			LED0 = ~LED0;
			vTaskDelay(500);
		}
}
void LED1_task(void *pvParameters)
{
		u16 task2num = 0;
		while(1)
		{
			printf("task2num=%d\r\n",++task2num);
			LED1 = ~LED1;
			vTaskDelay(500);
		}
}
void KEY_task(void *pvParameters)
{
		u8 key = 0;
		while(1)
		{
			key = KEY_Scan(0);
			if(key == KEY0_PRES)
			{
				  printf("在任务中挂起任务1\r\n");
					vTaskSuspend(LED0Task_Handler);
			}
			if(key == KEY1_PRES)
			{
				  printf("在任务中恢复任务1\r\n");
					vTaskResume(LED0Task_Handler);
			}
			vTaskDelay(10);
		
		}

具体来说就是这三个,同时我们在按键任务设置了按键0按下在任务中挂起任务1也就是LED0任务,接下来我们使用中断恢复任务1,具体代码如下:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  	BaseType_t xYieldRequired;  
	  delay_ms(100);      //消抖
    switch(GPIO_Pin)
    {
        case GPIO_PIN_0:
            if(WK_UP==1) 
            {
				xYieldRequired = xTaskResumeFromISR(LED0Task_Handler);
				printf("在中断中恢复任务1\r\n");
            }
			if(xYieldRequired == pdTRUE)
			{
				portYIELD_FROM_ISR(xYieldRequired);
			}
            break;
    }
}

portYIELD_FROM_ISR(xYieldRequired) 是在许多实时操作系统(RTOS)中用于从中断服务例程(ISR)触发任务上下文切换的函数。
在这里插入图片描述
但是我们在串口中会发现出现了错误,在port.c769行中,我们进入到这个函数,可以定位这个代码:
在这里插入图片描述
该报错意思是当前中断的优先级大于系统能够管理的优先级。打开FreeRTOSConfig.h,可以找到下面管理的优先级的最大值和最小值。

在这里插入图片描述
在FreeRTOS内有一个configMAX_SYSCALL_INTERRUPT_PRIORITY的宏,它是配置FreeRTOS能够管理中断的最大优先级,FreeRTOS内中断优先级分组只能全部配置成抢占优先级,没有子优先级,FreeRTOS也没有处理子优先级的代码。在FreeRTOS内只有大于configMAX_SYSCALL_INTERRUPT_PRIORITY才能调用FreeRTOS API(中断优先级很低),小于configMAX_SYSCALL_INTERRUPT_PRIORITY不能调用FreeRTOS的API(中断优先级很高),如果调用了就会出现上述问题。
在这里插入图片描述

在这里插入图片描述
所以这里设置分组四,也就是4位全部用抢占优先级,0位响应优先级。
在这里插入图片描述
并且这里也要更改。然后编译下载烧录进去。发现这个时候就能够正常运行。串口接受的信息没有报错。
在这里插入图片描述

标签:优先级,函数,FreeRTOS,中断,句柄,任务,API
From: https://www.cnblogs.com/bathwind/p/18109407

相关文章

  • [实时流基础 flink] 窗口函数
    尚硅谷学习笔记6.5窗口函数增量聚合函数(ReduceFunction/AggregateFunction)窗口将数据收集起来,最基本的处理操作当然就是进行聚合。我们可以每来一个数据就在之前结果上聚合一次,这就是“增量聚合”。典型的增量聚合函数有两个:ReduceFunction和AggregateFunction。......
  • 数据库—单行函数
    单行函数数组函数abs(x)返回x的绝对值ceil(x)返回大于或等于x的最小整数(向上取整)selectceil(-2.1)floor(x)向下取整selectfloor(-2.1)round(x)四舍五入selectround(3.49)字符串函数concat(s1,s2…sn)将字符串s1,s2等多个字符串合并为一个字......
  • SQL SERVER 日期和时间数据类型及函数 (Transact-SQL)
    declare@time1datetime=getdate()--代码declare@time2datetime=getdate()SELECTDATEDIFF(year,@TIME1,@TIME2);SELECTDATEDIFF(quarter,@TIME1,@TIME2);SELECTDATEDIFF(month,@TIME1,@TIME2);SELECTDATEDIFF(dayofyear,@TIME1,@TIME2);SE......
  • FreeRTOS系列补充2:重点API函数的应用代码范例(特特特详细)
    目录1、任务创建和删除API函数 动态创建任务函数原型 动态创建任务函数使用范例 静态创建函数原型静态创建任务函数使用范例任务删除函数原型任务删除函数使用范例2、任务挂起和恢复函数任务挂起函数原型任务恢复函数(任务中恢复)原型任务恢复函数(中断中恢复)原型......
  • SQL SERVER 从入门到精通 第5版 第二篇 第6章 SQL函数的使用 读书笔记
     第六章SQL函数的使用按函数种类可以分为聚合函数,数学函数,字符串函数,日期和时间函数,转换函数和元数据函数6种.>.聚合函数. 聚合函数对一组值执行计算,并返回单个值.除count外,聚合函数都会忽略空值.通常与SELECT语句的GROUPBY子句一起......
  • Python的opencv库的函数合集(持续更新中)
    为自己也为别人,整合opencv的函数,欢迎纠错!目录1.imread()2.cv2.imshow()1.imread()介绍:cv2.imread()是OpenCV库中的一个函数,专门用于读取图片文件并将其转换为NumPy数组。此函数对于图像处理和计算机视觉应用非常有用,因为它提供了读取图片到程序中的基本能力。格式:参数......
  • php获取淘宝详情api接口
    要获取淘宝商品的详情信息,你可以使用淘宝开放平台的接口。具体步骤如下:在淘宝开放平台(https://open.taobao.com)注册开发者账号。创建一个应用,获取appkey和appsecret。使用API中的taobao.item.get接口,传入商品ID以及appkey,即可获取商品的详情信息。示例代码如下(使用淘宝......
  • 基于 Python + Requests + Unitest + HwTestReport的API自动化测试框架
    一、框架目录结构概览 二、框架执行流程简介 三、框架目录结构简介▹case:存放测试用例▹data:存放测试数据及测试数据的处理▹config:存放相关配置文件(Token获取、Excel测试数据读取、requests二次封装等)▹file:存放测试接口信息▹report:存放测试报告▹to......
  • EL虚拟化表格 用h函数自定义表头并且指定插槽
    第一次使用el-table-v2,需要实现点击表头弹框来展示数据,官方文档中只有tsx的写法,没有使用h函数的写法,因此记录一下先看下最终的效果以下是部分代码import{ElButton,ElRadio,ElTooltip,ElPopover }from'element-plus'; //columns是一个数组,里面的值为每一列的配置......
  • day08-函数进阶
    1.参数的补充在函数基础部分,我们掌握函数和参数基础知识,掌握这些其实完全就可以进行项目的开发。今天的补充内容属于进阶知识,包含:内存地址相关、面试题相关等,在特定情况下也可以让代码更加简洁,提升开发效率。1.1参数内存地址相关【面试题】在开始讲参数内存地址相关之前,我们......