IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【FreeRtos任务恢复与挂起】 -> 正文阅读

[嵌入式]【FreeRtos任务恢复与挂起】

FreeRtos任务恢复与挂起

本篇内容分享的是FreeRtos中的任务恢复与挂起。
有时候我们需要将暂停某个任务的运行,过一段时间以后在重新运行。这个时候是要适应任务删除和重建的方法的话那么任务中变量保存的值肯定丢了!FreeRtos给我们提供了解决这种问题的方法,那就是任务的恢复与挂起,当莫个任务要停止运行一段时间的话就将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行,FreeRtos的任务挂起与恢复API函数如下:

在这里插入图片描述

在这里插入图片描述

vTaskSuspend()函数

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

/*-----------------------函数原型-------------------*/
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
//参数为任务句柄

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

vTaskResume()

/*--------------------函数原型------------------*/
void vTaskResume( TaskHandle_t xTaskToResume )
//参数为任务句柄

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

xTaskResumeFromISR()

/*-------------------函数原型------------------*/
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume) 

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

实验需求

通过两个按键来控制LED0的挂起与恢复

key.h

#ifndef _KEY_H_
#define _KEY_H_
#include "stm32f10x.h"
#include "delay.h"

//#define KEY0 GPIO_Pin_5
//#define KEY1 GPIO_Pin_6
//#define KEY2 GPIO_Pin_7
//#define KEY3 GPIO_Pin_8
//#define KEY4 GPIO_Pin_9

#define GPIO_PORT GPIOB
#define GPIO_PIN GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9
#define KEY0	GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_9)   //读GPIO端口的输入,输入等于0返回1
#define KEY1	GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_8)   //读GPIO端口的输入,输入等于0返回2
#define KEY2 	GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_7)	  //读GPIO端口的输入,输入等于0返回3
#define KEY3 	GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_6)  	//读GPIO端口的输入,输入等于0返回4
#define KEY4 	GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_4)  	//读GPIO端口的输入,输入等于0返回4


#define KEY_ON 0  //按键按下为0
#define KEY_OFF -1 //按键没有按下为-1
#define KEY0_Value 1 //按键1的返回值
#define KEY1_Value 2 //按键1的返回值
#define KEY2_Value 3 //按键2的返回值
#define KEY3_Value 4 //按键3的返回值
#define KEY4_Value 5 //按键4的返回值
#define Error -2 //错误值返回

void KEY_GPIO_INIT(void);
unsigned char KEY_Scan(void);

#endif

key.c





void KEY_GPIO_INIT(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitStructure.GPIO_Mode  =  GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin   = GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);		
}


//独立键盘扫描函数 
unsigned char KEY_Scan(void)
{ 
//	KEY_GPIO_INIT();
		//keyvalue = 0;
	if(KEY0==0||KEY1==0||KEY2==0||KEY3==0)
	{
		delay_ms(20);//去抖动 
		if(KEY0==0)   //按键0按下
		{
			while(KEY0 == 0);
			return KEY0_Value;
		}
		else if(KEY1==0)  //按键1按下
		{		
				while(KEY1 == 0);
			return KEY1_Value;
		}
		else if(KEY2==0)   //按键2按下
		{		
			//delay_ms(10);
				while(KEY2 == 0);
			return KEY2_Value;
		}
		else if(KEY3==0) //按键3按下
		{		
			//delay_ms(10);
				while(KEY3 == 0);
			return KEY3_Value;
		}
		else if(KEY4==0)
		{
				while(KEY4 == 0);
			return KEY4_Value;
		}
	}
		return 0;// 无按键按下
}

主函数

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "key.h"


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

//任务优先级
#define LED0_TASK_PRIO		4
//任务堆栈大小	
#define LED0_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		3
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);


//按键任务

#define KEY_TASK_PRIO		2
//任务堆栈大小	
#define KEY_STK_SIZE 		50  
//任务句柄
TaskHandle_t KEYTask_Handler;
//任务函数
void key_task(void *pvParameters);



int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	delay_init();	    				//延时函数初始化	  
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	KEY_GPIO_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();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    xTaskCreate((TaskFunction_t )led0_task,     	
                (const char*    )"led0_task",   	
                (uint16_t       )LED0_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )LED0_TASK_PRIO,	
                (TaskHandle_t*  )&LED0Task_Handler);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);    

		//创建按键任务
		xTaskCreate((TaskFunction_t )key_task,     
                (const char*    )"key_task",   
                (uint16_t       )KEY_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )KEY_TASK_PRIO,
                (TaskHandle_t*  )&KEYTask_Handler);    
	
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//LED0任务函数 
void led0_task(void *pvParameters)
{
    while(1)
    {
        LED0=~LED0;
        vTaskDelay(500);
			  printf("led1 is running\r\n");
    }
}   

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
				printf("led2 is running\r\n");
    }
}



//按键任务函数
void key_task(void *pvParameters)
{
    while(1)
    {
			//功能代码
			//使用两个震动传感器 一个用于挂起 一个用于解挂
			if(GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_9) == 0)
			{
				delay_ms(20); //消抖
				while(GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_9) == 0); //等待按键抬起
				vTaskDelay(100);
				//挂起
				vTaskSuspend(LED0Task_Handler);
				printf("Task0 is Suspend\r\n");
			}
			
			if(GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_8) == 0)
			{
					delay_ms(20); //消抖
				while(GPIO_ReadInputDataBit(GPIO_PORT,GPIO_Pin_8) == 0); //等待按键抬起
				vTaskDelay(100);
				//挂起
				vTaskResume(LED0Task_Handler);
				printf("Task0 is Resume\r\n");
			}
        
    }
}

实验结果

在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:49:03  更:2022-05-18 17:49:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:28:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码