FreeRTOS之任务挂起和恢复

1.本文介绍FreeRTOS的任务挂起和恢复函数。任务删除后将不再存在,不能恢复,而任务挂起是暂停任务,可以通过调用函数进行恢复。FreeRTOS任务挂起和恢复的主要步骤如下:

(1)将相关的宏定义设置为1:INCLUDE_vTaskSuspend、INCLUDE_xTaskResumeFromISR

(2)调用函数任务挂起函数vTaskSuspend(),调用任务恢复函数vTaskResume()和xTaskResumeFromISR()。函数xTaskResumeFromISR()是从中断服务函数里恢复任务。

2.宏定义INCLUDE_vTaskSuspend和INCLUDE_xTaskResumeFromISR的设置:

3.调用任务挂起函数vTaskSuspend():

vTaskSuspend()没有返回值,入口参数为需要被挂起任务的句柄。

4.调用任务恢复函数vTaskResume()和xTaskResumeFromISR():

(1)vTaskResume()没有返回值,入口参数为需要被恢复的任务句柄。

(2)xTaskResumeFromISR()是从中断里恢复被挂起的任务,入口参数为需要被恢复的任务的句柄。xTaskResumeFromISR()的返回值为pdTRUE和pdFALSE。

当返回pdTRUE时,表明被恢复的任务的优先级要等于或高于当前正在执行的任务(被中断打断的任务),因此需要调用函数portYIELD_FROM_ISR()进行一次任务切换。

当返回pdFALSE时,表明被恢复的任务的优先级要小于当前正在执行的任务(被中断打断的任务),,不需要进行任务切换。

此外,使用xTaskResumeFromISR()需要注意,系统中断优先级不能高于FreeRTOS能管理的中断优先级。通常FreeRTOS可以管理的任务优先级为5-15,因此,本文将按键的中断优先级设置为5。为了方便FreeRTOS管理,建议将子优先级设置为0。

5.代码:本文只展示main函数和中断服务函数部分的代码,若需要完整的代码,可以将本文和前面的动态创建任务部分的代码进行结合。

(1)exit代码:

#include "exti.h"
#include "key.h"
#include "delay.h"
#include "FreeRTOS.h"
#include "task.h"

extern TaskHandle_t led0_handler;

void EXTIx_Init(void)
{
	/*ÍⲿÖжϵÄÅäÖ÷½·¨£º
	  1.½«IO¿ÚÓ³Éäµ½¶ÔÓ¦ÍⲿÖжÏÏßÉÏ
	  2.ÅäÖÃÍⲿÖжÏ
	  3.ÖØдÖжϷþÎñº¯Êý£¬¼´Öжϻص÷º¯Êý*/
	
	//¶¨ÒåÍⲿÖжϺÍÖжϵĽṹÌ壺
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	//ʹÄÜʱÖÓ£º
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//ÍⲿÖжÏÐèÒª¸´ÓÃʱÖÓ
	KEY_Init();			//³õʼ»¯°´¼ü
	
	//GPIOA.0µÄÖжÏÏߺÍÖжϳõʼ»¯ÅäÖãº
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);	//GPIOÓëÖжÏÏß½øÐÐÓ³Éä
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_Init(&EXTI_InitStructure);

	EXTI_Init(&EXTI_InitStructure);
	
	//ÖжϹÜÀíÅäÖãº
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	
	NVIC_Init(&NVIC_InitStructure);
}

//ÖØдÖжϷþÎñº¯Êý.
void EXTI0_IRQHandler(void)
{
	//¾²Ì¬±äÁ¿Ö»»áÔÚµÚÒ»´ÎÔËÐÐʱ±»³õʼ»¯¡£ËùÒÔ£¬¿ÉÒÔÀí½âΪÕâÌõÓï¾äÖ»Ö´ÐÐÒ»´Î
	//static u8 flag1 = 1;	
	delay_us(1000);				//Ïû¶¶
	if(KEY_2 == 1)
	{
		BaseType_t xYieldRequired;
		xYieldRequired = xTaskResumeFromISR(led0_handler);
		if(xYieldRequired == pdTRUE)
		{
			portYIELD_FROM_ISR(xYieldRequired);
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line0);
}


#ifndef __EXTI_H
#define __EXTI_H

#include "stm32f10x.h"

void EXTIx_Init(void);

#endif

(2)main代码:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "FreeRTOS.h"
#include "task.h"
#include "key.h"
#include "exti.h"
#include "sys.h"

//¶¨Òåstart_taskµÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 64
TaskHandle_t start_handler;
void start_task(void);

//¶¨ÒåÈÎÎñ1µÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define LED0_TASK_PRIO 2
#define LED0_TASK_STACK_SIZE 64
TaskHandle_t led0_handler;
void led0(void);

//¶¨ÒåÈÎÎñ2µÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define LED1_TASK_PRIO 3
#define LED1_TASK_STACK_SIZE 64
TaskHandle_t led1_handler;
void led1(void);

//¶¨ÒåÈÎÎñ2µÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define KEY_TASK_PRIO 4
#define KEY_TASK_STACK_SIZE 64
TaskHandle_t key_handler;
void key_task(void);

int flag = 0;

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);// ÉèÖÃÖжÏÓÅÏȼ¶·Ö×é4£¬¼´×ÓÓÅÏȼ¶Îª0
	LED_Init();
	KEY_Init();
	delay_init();
	EXTIx_Init();
	
	xTaskCreate((TaskFunction_t) start_task,																//ÈÎÎñº¯Êý
							(const char *)"start_task",																	//ÈÎÎñÃû³Æ
							(uint16_t)START_TASK_STACK_SIZE,											      //ÈÎÎñ¶ÑÕ»´óС
							(void *)NULL,																								//´«µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý
							(UBaseType_t)START_TASK_PRIO,																//ÈÎÎñÓÅÏȼ¶
							(TaskHandle_t *)&start_handler);														//ÈÎÎñ¾ä±ú
	
			
	vTaskStartScheduler();																								//¿ªÊ¼ÈÎÎñµ÷¶È
}

/*´´½¨¿ªÊ¼ÈÎÎñ£º*/
void start_task(void)
{
//	taskENTER_CRITICAL();	
	/*´´½¨ÈÎÎñ*/
	if(flag == 0)
	{
		xTaskCreate((TaskFunction_t) led0,																		//ÈÎÎñº¯Êý
							(const char *)"led0_task",																//ÈÎÎñÃû³Æ
							(uint16_t)LED0_TASK_STACK_SIZE,											      //ÈÎÎñ¶ÑÕ»´óС
							(void *)NULL,																							//´«µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý
							(UBaseType_t)LED0_TASK_PRIO,															//ÈÎÎñÓÅÏȼ¶
								(TaskHandle_t *)&led0_handler);														//ÈÎÎñ¾ä±ú
		xTaskCreate((TaskFunction_t) led1,
								(const char *)"led1_task",
								(uint16_t)LED1_TASK_STACK_SIZE,
								(void *)NULL,
								(UBaseType_t)LED1_TASK_PRIO,
								(TaskHandle_t *)&led1_handler);
		xTaskCreate((TaskFunction_t) key_task,
								(const char *)"key_task",
								(uint16_t)KEY_TASK_STACK_SIZE,
								(void *)NULL,
								(UBaseType_t)KEY_TASK_PRIO,
								(TaskHandle_t *)&key_handler);
	 flag = 1;
	}
	 vTaskDelay(500);
										
	 vTaskDelete(NULL);											//ɾ³ýµ±Ç°ÈÎÎñ
//	 taskEXIT_CRITICAL();
}

void led0(void)
{
	while(1)
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);			//´ò¿ªLED
		vTaskDelay(500);
		//delay_ms(500);
		GPIO_SetBits(GPIOA,GPIO_Pin_8);			//´ò¿ªLED
		vTaskDelay(500);
	}
}

void led1(void)
{
	while(1)
	{
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);			//´ò¿ªLED
		vTaskDelay(500);
		//delay_ms(500);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);			//´ò¿ªLED
		vTaskDelay(500);
	}
}

/*´´½¨°´¼üÈÎÎñ£º*/
void key_task(void)
{
	//uint8_t key = 0;
    while(1)
    {
        //printf("task3ÕýÔÚÔËÐУ¡£¡£¡\r\n");
        //key = KEY_Scan(0);
        if(KEY_0 == 0)																//°´¼ü0±»°´ÏÂʱ£¬¹ÒÆðled0ÈÎÎñ
        {
            vTaskSuspend(led0_handler);
        }
				else if(KEY_1 == 0)														//°´¼ü1±»°´ÏÂʱ£¬»Ö¸´led0ÈÎÎñ
				{
					vTaskResume(led0_handler);
				}
        vTaskDelay(10);
    }
}

6.运行结果:

当按下key0时,led0任务被挂起。当按下key1和key2时,led0任务被恢复。

7.总结:

本文中介绍了FreeRTOS的任务挂起和恢复函数,主要是通过调用函数API实现。当在中断里恢复任务时,需要判断任务的返回值,根据返回值判断是否要进行任务切换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/563518.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OPAM模型(细粒度图像分类)

OPAM模型(细粒度图像分类) 摘要Abstract1. OPAM1.1 文献摘要1.2 细粒度图像分类1.3 研究背景1.4 OPAM模型创新点1.5 OPAM模型1.5.1 补丁过滤1.5.2 显着性提取1.5.3 细粒度区域级注意模型对象-空间约束方法(Object spatial constraint&#xf…

钟薛高创始人称卖红薯也把债还上:网友,您可千万别……

网红雪糕品牌钟薛高,是真的网红属性强到让所有消费品牌羡慕。 纵使跌落神坛、纵使站在「破产」边缘,依然话题感满满,隔段时间,总能上一个热搜。 比如欠薪上热搜、产品降价上热搜、甚至官网微博微信停更,也得上个热搜&…

MLLM | InternLM-XComposer2-4KHD: 支持336 像素到 4K 高清的分辨率的大视觉语言模型

上海AI Lab,香港中文大学等 论文标题:InternLM-XComposer2-4KHD: A Pioneering Large Vision-Language Model Handling Resolutions from 336 Pixels to 4K HD 论文地址:https://arxiv.org/abs/2404.06512 Code and models are publicly available at https://gi…

.net core webapi 添加日志管理看板LogDashboard

.net core webapi 添加日志管理看板LogDashboard 添加权限管理&#xff1a; 我们用的是Nlog文件来配置 <?xml version"1.0" encoding"utf-8" ?> <nlog xmlns"http://www.nlog-project.org/schemas/NLog.xsd"xmlns:xsi"http:/…

网络基础-TCP/IP和OSI协议模型

一、OSI和TCP/IP模型 二、OSI七层模型 三、TCP/IP模型 参考&#xff1a;https://www.cnblogs.com/f-ck-need-u/p/7623252.html

Scanpy(1)数据结构和样本过滤

注&#xff1a;主要讲述scanpy处理数据的结构、数据过滤&#xff08;生信领域&#xff09;和数据预处理&#xff08;和机器学习类似&#xff0c;但是又有不同。&#xff09; 1. Scanpy简介与安装 Scanpy 是一个可扩展的工具包&#xff0c;用于分析与 AnnData&#xff08;一种…

螺纹滑牙的原因有哪些——SunTorque智能扭矩系统

螺纹滑牙的原因&#xff0c;通常是由于在旋紧或旋松过程中&#xff0c;螺纹副之间的摩擦力不足以维持所需的预紧力或工作载荷&#xff0c;导致螺纹副的相对位置发生变化。这种现象可能由多种因素引起&#xff0c;包括材料选择不当、设计不合理、制造工艺缺陷、环境因素以及使用…

欧科云链:香港虚拟资产OTC合规在即,技术监管成市场规范关键

4月12日香港OTC发牌制度公众咨询结束后&#xff0c;欧科云链研究院在星岛日报发表专栏文章&#xff0c;分享对香港OTC市场的调研情况&#xff0c;并提出“技术监管是香港OTC及Web3生态走向规范的关键”。欧科云链研究院认为&#xff0c;随着OTC监管及虚拟资产现货ETF等事件向前…

DC30V36V60V100V转9V、12V/1.5A方案 车灯驱动芯片IC H5028L ,高性价比,皮实耐抗

DC24V、30V、36V、60V、100V转9V、12V/1.5A方案&#xff0c;以及车灯驱动芯片IC&#xff0c;这通常涉及到电源转换和驱动电路的设计。这些方案的目标是将一个较高的直流电压&#xff08;如24V、30V、36V、60V或100V&#xff09;转换为较低但稳定的直流电压&#xff08;如9V或12…

Leetcode 第 394 场周赛

Leetcode 第 394 场周赛 1. [统计特殊字母的数量 I](https://leetcode.cn/problems/count-the-number-of-special-characters-i/)2. [统计特殊字母的数量 II](https://leetcode.cn/problems/count-the-number-of-special-characters-ii/)3. [使矩阵满足条件的最少操作次数](htt…

前端工程化02-复习jQuery当中的插件开发

2、jQuery插件开发 在我们开发的时候、有时候jQuery提供的方法并不能满足我们的需求&#xff0c;如果我们想给jQuery扩展一些其他的方法&#xff0c;那这种情况下&#xff0c;可能会需要写一个插件 jQurey官网&#xff1a;jquery.com 例如一些、图片懒加载插件、滚动的插件、…

BUUCTF-MISC-04大白

题目&#xff1a;让图片全面显示宽高 更改高宽一致 发现大白没有完全显示&#xff0c;优先考虑到图片高度隐写,猜测是FLAG隐藏在少掉的部分里&#xff0c;所以需要修改图片的高度与宽一致 我们借助010工具完成操作 根据内容可以看到高和宽不一样&#xff0c;这时候&#xff0…

图像处理基础知识

图像处理基础知识 图像 1、模拟图像 模拟图像&#xff0c;又称连续图像&#xff0c;是指在二维坐标系中连续变化的图像&#xff0c;即图像的像点是无限稠密的&#xff0c;同时具有灰度值&#xff08;即图像从暗到亮的变化值&#xff09;。 2、数字图像 数字图像&#xff0…

Jenkins CI/CD 持续集成专题一 Jenkins的安装和配置

一 jenkins 官方教程 安装Jenkins 二 安装 2.1 安装方式一 通过安装包的package方式安装 第一步下载链接&#xff1a; Download the latest package 第二步操作方式&#xff1a;打开包装并按照说明操作 2.2 安装方式二 brew安装 第一 安装最新版本jenkins brew install …

C语言进阶课程学习记录 - 函数的意义

C语言进阶课程学习记录 - 函数的意义 实验-声明与定义小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 实验-声明与定义 //global.c #include <stdio.h>//int g_var 10;//case1float g_var …

极客时间《SQL必知必会》学习笔记

开篇词丨SQL可能是你掌握的最有用的技能 尽管技术人员或多或少地会使用 SQL&#xff0c;但不同的人编写出来的 SQL 的效率是不同的&#xff0c;比如说一份好的 SQL 执行计划就会尽量减少 I/O 操作&#xff0c;因为 I/O 是 DBMS &#xff08;数据库管理系统&#xff0c;Database…

上位机图像处理和嵌入式模块部署(树莓派4b进行驱动的编写)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 树莓派4b上面还支持驱动代码的编写&#xff0c;这是我没有想到的。这里驱动&#xff0c;更多的是一种框架的编写&#xff0c;不一定是编写真正的驱…

提取出图像的感兴趣区域

这是我们的原图像 将图像的数值统计后进行条形图展示 import matplotlib.pyplot as plt from PIL import Image import numpy as np# 图像路径 image_path r"D:\My Data\Figure\OIP.jpg"# 打开图像 image Image.open(image_path)# 将图像转换为numpy数组 image_ar…

C#控制台相关方法

控制台相关方法 文章目录 控制台输入1、清空2、设置控制台3、设置光标位置&#xff0c;1y 2x4、设置颜色相关5、光标显隐6、关闭控制台思考 移动方块 控制台输入 //如果ReadKey(true)不会把输入的内容显示再控制台上 char c Console.ReadKey(true).KeyChar;1、清空 ​ Cons…

poll实现echo服务器的并发

poll实现echo服务器的并发 代码实现 #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <arpa/inet.h> #include <sys/time.h> #include <unistd.h> #…