【复习笔记】FreeRTOS(三)任务挂起和恢复

news2024/11/24 16:26:41

本文是FreeRTOS复习笔记的第三节,任务挂起和恢复,使用的开发板是stm32f407VET6,创建两个任务,task1负责闪烁LED,task2负责按键控制,当按键按下时控制任务挂起,按键再次按下恢复任务,并通过串口打印任务状态。

上一篇文章: 【复习笔记】FreeRTOS(二)创建和删除任务

文章目录

  • 一、实验目的
  • 二、测试例程
  • 三、实验效果


一、实验目的

首先回顾一下FreeRTOS的四个任务状态:就绪态、运行态、挂起态和阻塞态。他们之间的关系如下:
在这里插入图片描述

图1 任务状态之间的转换
本篇内容复习的是FreeRTOS中的任务恢复与挂起。 有时候我们需要将暂停某个任务的运行,过一段时间以后在重新运行,如果使用任务删除和重建的方法,那么任务中变量保存的值肯定丢了.FreeRTOS给我们提供了解决这种问题的方法,那就是任务的恢复与挂起,当莫个任务要停止运行一段时间的话就将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。FreeRTOS的主要用到3个API函数:
函数作用
vTaskSuspend()挂起一个任务,进入挂起态的任务永远都不会进入运行态
vTaskResume()恢复一个任务,恢复运行被挂起的任务
xTaskResumeFromISR()中断服务函数中恢复一个任务

1.任务挂起函数:

vTaskSuspend()

此函数用于将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。退出挂起态的唯一方法就是调用任务恢复函数vTaskResume()xTaskResumeFromISR()。

2.任务恢复函数:

vTaskResume()

将一个任务从挂起态恢复到就绪态,只有通过函数 vTaskSuspend()设置为挂起态的任务才可以使用 vTaskRexume()恢复。

3.中断服务函数中使用的任务恢复函数:

BaseType_t xTaskResumeFromISR()

此函数是 vTaskResume()的中断版本,用于在中断服务函数中恢复一个任务
返回值:
pdTrue:恢复运行的任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务),在退出中断服务函数以后必须进行一次上下文切换。
pdFALSE: 恢复运行的任务的任务优先级低于当前正在运行的任务(被中断打断的任务),在退出中断服务函数的以后不需要进行上下文切换。

本次实验就是使用一个按键控制任务的挂起和恢复。

二、测试例程

主函数 main.c代码如下:


/**
  * @file    main.c
  * @author  HuiTanglang
  * @version V1.0
  * @date    2023.05
  * @brief   This file provides firmware functions to manage the following 
  *          functionalities of HuiTanglang;
 */
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "FreeRTOS.h"
#include "task.h"

#define START_TASK_PRIO		1 //任务优先级	
#define START_STK_SIZE 		128  //任务堆栈大小
TaskHandle_t StartTask_Handler; //任务句柄
void start_task(void *pvParameters); //任务函数

#define TASK1_TASK_PRIO		2 //任务优先级
#define TASK1_STK_SIZE 		128  //任务堆栈大小	
TaskHandle_t TASK1Task_Handler; //任务句柄
void task1_task(void *p_arg); //任务函数

#define TASK2_TASK_PRIO		3 //任务优先级
#define TASK2_STK_SIZE 		128  //任务堆栈大小	
TaskHandle_t TASK2Task_Handler; //任务句柄
void task2_task(void *p_arg); //任务函数

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	delay_init(168);		//初始化延时函数
	uart_init(115200);     	//初始化串口
//	EXTIX_Init();
	LED_Init();		        //初始化LED端口
	KEY_Init();
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}
 

/**
  * @brief  开始任务任务函数
  * @param  None
  * @retval None  
  */
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区

    xTaskCreate((TaskFunction_t )task1_task,     
                (const char*    )"task1_task",   
                (uint16_t       )TASK1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )TASK1_TASK_PRIO,
                (TaskHandle_t*  )&TASK1Task_Handler);  

	xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&TASK2Task_Handler);  
				
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}


/**
  * @brief  显示任务1运行,而且LED 0.5s闪烁
  * @param  None
  * @retval None  
  */
void task1_task(void *pvParameters)
{

	u8 task_num=0;
	while(1)
	{
		task_num++;
		LED0=~LED0;
		printf("任务1运行次数%d\r\n",task_num);
        vTaskDelay(1000);
    }
	
}
	

/**
  * @brief  按键按下就删除任务1的执行程序,按一下挂起,再按一下恢复
  * @param  None
  * @retval None  
  */
void task2_task(void *pvParameters)
{

	u8 key1;
	u8 key_num=0;

	while(1)
	{
		   key1=KEY_Scan(0);
		if(key1==WKUP_PRES)
		{
			key_num++;

		}
		
		if(key_num%2==0 && key_num!=0)
		{  
	       vTaskResume(TASK1Task_Handler);	//恢复任务1

	       printf("恢复任务1的运行!\r\n");
		}
		if(key_num%2==1)
		{  
	        vTaskSuspend(TASK1Task_Handler);//挂起任务1

	       printf("挂起任务1的运行!\r\n");
		}

		vTaskDelay(1000);    
    }
}

按键驱动函数,key.c

#include "key.h"
#include "delay.h" 

/**
  * @brief  按键初始化函数,设置PA0为按键接口,按下就通过电阻接3.3上拉
  * @param  None
  * @retval None  
  */
void KEY_Init(void)
{
	
	GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA,时钟 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//WK_UP对应引脚PA0--K1按键
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;//下拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA0
 
} 

/**
  * @brief  按键处理函数,返回按键值
  * @param  mode:0,不支持连续按;1,支持连续按;
  * @retval 0,没有任何按键按下
  * @retval 1,WKUP按下 --对应K1按键
  */
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		  
	if(key_up&&(WK_UP==1))
	{
		delay_ms(10);//去抖动 
		key_up=0;
		if(WK_UP==1) return WKUP_PRES;
	}
	else if(WK_UP==0)key_up=1; 	    
 	return 0;// 无按键按下
}

三、实验效果

本实验使用的开发板是stm32f407VET6最小系统板。在这里插入图片描述
实验效果如下:

在这里插入图片描述
可以看到led在闪烁,接上串口,通过串口工具可以看到打印的任务1运行次数,每过1秒次数加1。当第一次按下按键时,LED停止闪烁,串口显示挂起任务1状态。当再次按下按键时,LED恢复闪烁,通过串口可以看到打印的任务1运行次数,运行次数是从挂起之前的次数开始计数,起到了一个恢复计数的功能。

本节主要是通过一个小实验,学习和掌握FreeRTOS任务挂起和恢复相关API函数使用。
完整程序放在gitee上:程序下载地址

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】经典排序法

欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析2 目录 👉🏻 直接插入排序👉🏻 选择排序&…

微信支付(小程序)-java

微信支付开发者文档微信支付是腾讯公司的支付业务品牌,微信支付提供公众号支付、APP支付、扫码支付、刷卡支付等支付方式。微信支付结合微信公众账号,全面打通O2O生活消费领域,提供专业的互联网行业解决方案,微信支付支持微信红包…

访问github网络问题解决

查看wsl可用镜像列表时产生如下访问github的网络问题 C:\Users\jiangcheng> wsl --list --online 无法从“https://raw.githubusercontent.com/microsoft/WSL/master/distributions/DistributionInfo.json”中提取列表分发。无法与服务器建立连接 Error code: Wsl/WININET_…

hive任务reduce步骤卡在99%原因及解决

我们在写sql的时候经常发现读取数据不多,但是代码运行时间异常长的情况,这通常是发生了数据倾斜现象。数据倾斜现象本质上是因为数据中的key分布不均匀,大量的数据集中到了一台或者几台机器上计算,这些数据的计算速度远远低于平均…

Vulkan Tutorial 9 模型加载Mipmaps

目录 28 加载模型 Sample mesh 加载顶点和索引 ​编辑 顶点去重 28 加载模型 我们将使用tinyobjloader库来从OBJ文件中加载顶点和面。它的速度很快,而且很容易集成,因为它是一个像stb_image一样的单文件库。将包含tiny_obj_loader.h的目录添加到Add…

ChatGPT国内镜像站

免费国内镜像推荐(超稳定) 下面为大家收集了目前国内最稳定流畅的ChatGPT镜像网站 目录 机器人 博弈ai 泰cool辣 道合顺 二狗问答 核桃 WOChat GPT中文站 TomChat 利用ChatGPTMindShow三分钟生成PPT ChatGPT国内镜像是啥 ChatGPT 镜像是指…

Xpdf 阅读器源码编译后查看文件中文乱码问题解决

经查阅,是由于缺少中文字体包: 第一步:下载所需要的字体包 下载https://dl.xpdfreader.com/xpdf-t1fonts.tar.gz 包含下载中文字体包(非嵌入字体) http://ftp.gnu.org/gnu/non-gnu/chinese-fonts-truetype/gkai00mp…

pytorch-简单回归问题-手写数字识别

pytorch-简单回归问题-手写数字识别 线性回归添加噪声简单例子分类问题引入-手写数字识别数据集 训练推导手写数字识别1加载数据集编写网络训练网络计算正确率 线性回归添加噪声 使用均方差损失函数来衡量损失 简单例子 通过最小化损失函数,求解出参数w b 下图表示…

封装的函数停发/启动CAN报文,以及报文接收检测,高可用

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe,博客目录大全,点击跳转👉 📘前言 🍅 在测试过程中,我们可能需要可控的停/发某些报文,今天博主给…

chatgpt赋能python:Python主页面的SEO分析及优化建议

Python主页面的SEO分析及优化建议 Python是一种高级编程语言,广泛应用于人工智能、数据分析、Web开发等领域。Python官方网站是Python社区的一个重要门户,为全球学习Python的开发者提供了全面、权威、可靠的信息。在这篇文章中,我们将分析Py…

Text to image论文精读SeedSelect: 使用SeedSelect微调扩散模型It’s all about where you start

随着文本到图像扩散模型的发展,很多模型已经可以合成各种新的概念和场景。然而,它们仍然难以生成结构化、不常见的概念、组合图像。今年4月巴伊兰大学和OriginAI发表《It’s all about where you start: Text-to-image generation with seed selection》…

软件外包开发项目原型图工具

项目原型图工具有非常重要的作用,尤其是在APP项目开发中,对于整体需求的表达是必不可少的工具。相比于传统的文档需求,图形文字的表达可以更清楚的表达需求,让客户清楚的明白软件功能有哪些,最后的界面是怎样的&#x…

微信海量数据查询如何从1000ms降到100ms?

👉腾小云导读 微信的多维指标监控平台,具备自定义维度、指标的监控能力,主要服务于用户自定义监控。作为框架级监控的补充,它承载着聚合前 45亿/min、4万亿/天的数据量。当前,针对数据层的查询请求也达到了峰值 40万/m…

RL - 强化学习 上置信界算法 (UCB) 和 汤普森采样算法 (TS)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/130983835 上置信界算法和汤普森采样算法是两种解决多臂老虎机问题的经典方法。多臂老虎机问题是一种探索与利用的平衡问题,…

Java easypoi 导出excel 并合并相关列

在项目开发中经常会使用到合并列&#xff0c;格式如下&#xff1a; 1.引入easypoi <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId></dependency><dependency><groupId>cn.aftertur…

设计模式详解之策略模式

作者&#xff1a;刘文慧 策略模式是一种应用广泛的行为型模式&#xff0c;核心思想是对算法进行封装&#xff0c;委派给不同对象来管理&#xff0c;本文将着眼于策略模式进行分享。 一、概述 我们在进行软件开发时要想实现可维护、可扩展&#xff0c;就需要尽量复用代码&#x…

chatgpt赋能python:Python什么情况下用类

Python什么情况下用类 在Python编程中&#xff0c;类是一种重要的数据结构&#xff0c;它是面向对象编程的核心。类可定义数据类型&#xff0c;并把数据与操作数据的函数组合在一起。因此&#xff0c;通过使用类&#xff0c;我们可以将数据、函数和其他方法组合在一起&#xf…

OLAP系列:四、clickhouse分布式表使用指南

一、背景 ClickHouse中最强大的表引擎当属MergeTree&#xff08;合并树&#xff09;引擎及该系列&#xff08;*MergeTree&#xff09;中的其他引擎&#xff0c;支持索引和分区&#xff0c;地位可以相当于innodb之于Mysql。 而且基于MergeTree&#xff0c;还衍生出了很多小弟&a…

【量化分析】绘制指标线EWM和MACD(1)

目录 一、说明 二、使用mplfinance的前提 2.1 mplfinance生态圈 2.1 安装mplfinance 三、mplfinance绘图 3.1 单变量图 3.2 将用户自己生成的曲线添加到 mplfinance plot() 四、显示EWM和MACD 一、说明 在做量化分析的时候&#xff0c;需要有能力计算种种曲线&#xff…

ShowMeBug 持续升级,提供高信效度支撑的技术招聘方案

去年年底&#xff0c;全新升级版的 ShowMeBug ——一款支持实战编程的技术能力评估平台&#xff0c;首次揭开了它神秘的面纱。 而近日&#xff0c;ShowMeBug 再次迎来一系列产品更新&#xff0c;它将以全新的面貌&#xff0c;提供高信效度支撑的技术招聘方案&#xff0c;持续助…