FreeRTOS任务挂起和恢复

任务挂起:暂停某个任务的执行
任务恢复:让暂停的任务继续执行
通过任务挂起和恢复,可以达到让任务停止一段时间后重新运行。
相关API函数:
在这里插入图片描述

vTaskSuspend

void vTaskSuspend( TaskHandle_t xTaskToSuspend );
  • xTaskToSuspend :要挂起任务的任务句柄,如果使用函数xTaskCreate创建任务的话,xTaskCreate的参数pxCreatedTask就是此任务的任务句柄,如果使用xTaskCreateStatic创建任务,那么函数的返回值就是此任务的任务句柄。

vTaskResume

void vTaskResume( TaskHandle_t xTaskToResume ) ;
  • xTaskToResume :要恢复的任务的任务句柄

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

xTaskResumeFromISR

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) ;

此函数是vTaskResume的中断版本,用于在中断服务函数中恢复一个任务
返回值:

  • pdTRUE:恢复运行的任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务)
  • pdFALSE:恢复运行的任务的任务优先级低于当前运行的任务(被中断打断的任务)

实验程序设计

  • start_task:用来创建其他三个任务
  • key_task:按键服务函数,检测按键的按下结果,根据不同的按键结果执行不同的操作
  • task1_task:应用任务1
  • task2_task:应用任务2

具体代码:
start_task:

void start_task(void *pvParameters)
{taskENTER_CRITICAL();		//进入临界区xTaskCreate(key_task,"key_task",KEY_STK_SIZE,NULL,KEY_TASK_PRIO,&KeyTask_Handler);xTaskCreate(task1_task,"task1_task",TASK1_STK_SIZE,NULL,TASK1_TASK_PRIO,&Task1Task_Handler);xTaskCreate(task2_task,"task2_task",TASK2_STK_SIZE,NULL,TASK2_TASK_PRIO,&Task2Task_Handler);taskEXIT_CRITICAL();		//退出临界区vTaskDelete(StartTask_Handler);	//删除任务
}

key_task:

void key_task(void *pvParameters)
{u8 key;while(1){key=KEY_Scan(0);switch(key){case WKUP_PRES:vTaskSuspend(Task1Task_Handler);	//挂起任务1break;case KEY0_PRES:vTaskResume(Task1Task_Handler);	//恢复任务1break;case KEY1_PRES:vTaskSuspend(Task2Task_Handler);break;case KEY2_PRES:vTaskResume(Task2Task_Handler);break;		}vTaskDelay(10);	//延迟10ms}}

task1_task:

//task1任务函数
void task1_task(void *pvParameters)
{u8 task1_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	LCD_DrawLine(5,130,115,130);		//画线POINT_COLOR = BLUE;LCD_ShowString(6,111,110,16,16,"Task1 Run:000");while(1){task1_num++;	//任务执1行次数加1 注意task1_num1加到255的时候会清零!!LED0=!LED0;LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//显示任务执行次数vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	}
}

task2_task

//task2任务函数
void task2_task(void *pvParameters)
{u8 task2_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(125,110,234,314); //画一个矩形	LCD_DrawLine(125,130,234,130);		//画线POINT_COLOR = BLUE;LCD_ShowString(126,111,110,16,16,"Task2 Run:000");while(1){task2_num++;	//任务2执行次数加1 注意task1_num2加到255的时候会清零!!LED1=!LED1;//printf("任务2已经执行:%d次\r\n",task2_num);LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //显示任务执行次数LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	}
}

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "sdram.h"
#include "key.h"
#include "exti.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 KEY_TASK_PRIO		2
//任务堆栈大小	
#define KEY_STK_SIZE 		128  
//任务句柄
TaskHandle_t KeyTask_Handler;
//任务函数
void key_task(void *pvParameters);//任务优先级
#define TASK1_TASK_PRIO		3
//任务堆栈大小	
#define TASK1_STK_SIZE 		128  
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);//任务优先级
#define TASK2_TASK_PRIO		4
//任务堆栈大小	
#define TASK2_STK_SIZE 		128  
//任务句柄
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);//LCD刷屏时使用的颜色
int lcd_discolor[14]={	WHITE, BLACK, BLUE,  BRED,      GRED,  GBLUE, RED,   MAGENTA,       	 GREEN, CYAN,  YELLOW,BROWN, 			BRRED, GRAY };int main(void)
{HAL_Init();                     //初始化HAL库   Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhzdelay_init(180);                //初始化延时函数uart_init(115200);              //初始化串口LED_Init();                     //初始化LED KEY_Init();						//初始化按键SDRAM_Init();					//初始化SDRAMLCD_Init();						//初始化LCDPOINT_COLOR = RED;LCD_ShowString(30,10,200,16,16,"Apollo STM32F4/F7");	LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 6-3");LCD_ShowString(30,50,200,16,16,"Task Susp and Resum");//LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,90,200,16,16,"2021/11/21");xTaskCreate(start_task,"start_task",START_STK_SIZE,NULL,START_TASK_PRIO,&StartTask_Handler);vTaskStartScheduler();	//开启粪污调度}void start_task(void *pvParameters)
{taskENTER_CRITICAL();		//进入临界区xTaskCreate(key_task,"key_task",KEY_STK_SIZE,NULL,KEY_TASK_PRIO,&KeyTask_Handler);xTaskCreate(task1_task,"task1_task",TASK1_STK_SIZE,NULL,TASK1_TASK_PRIO,&Task1Task_Handler);xTaskCreate(task2_task,"task2_task",TASK2_STK_SIZE,NULL,TASK2_TASK_PRIO,&Task2Task_Handler);taskEXIT_CRITICAL();		//退出临界区vTaskDelete(StartTask_Handler);	//删除任务
}void key_task(void *pvParameters)
{u8 key;while(1){key=KEY_Scan(0);switch(key){case WKUP_PRES:vTaskSuspend(Task1Task_Handler);	//挂起任务1break;case KEY0_PRES:vTaskResume(Task1Task_Handler);	//恢复任务1break;case KEY1_PRES:vTaskSuspend(Task2Task_Handler);break;case KEY2_PRES:vTaskResume(Task2Task_Handler);break;		}vTaskDelay(10);	//延迟10ms}}//task1任务函数
void task1_task(void *pvParameters)
{u8 task1_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	LCD_DrawLine(5,130,115,130);		//画线POINT_COLOR = BLUE;LCD_ShowString(6,111,110,16,16,"Task1 Run:000");while(1){task1_num++;	//任务执1行次数加1 注意task1_num1加到255的时候会清零!!LED0=!LED0;LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//显示任务执行次数vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	}
}//task2任务函数
void task2_task(void *pvParameters)
{u8 task2_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(125,110,234,314); //画一个矩形	LCD_DrawLine(125,130,234,130);		//画线POINT_COLOR = BLUE;LCD_ShowString(126,111,110,16,16,"Task2 Run:000");while(1){task2_num++;	//任务2执行次数加1 注意task1_num2加到255的时候会清零!!LED1=!LED1;//printf("任务2已经执行:%d次\r\n",task2_num);LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //显示任务执行次数LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	}
}

编译即可

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

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

相关文章

FreeRTOS中断配置与临界段

Cortex-M中断 中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序(中断服务程序),处理完毕后又返回原被暂停的程序继续运行。Cortex-M内核的MCU提供了一个用…

FreeRTOS的列表和列表项

列表和列表项 列表 列表是FreeRTOS中的一个数据结构,概念上和链表有点类型,是一个循环双向链表,列表被用来跟踪FreeRTOS中的任务。列表的类型是List_T,具体定义如下: typedef struct xLIST {listFIRST_LIST_INTEGRI…

FreeRTOS队列

在实际应用中,我们会遇到一个任务或者中断服务需要和另一个任务进行消息传递,FreeRTOS提供了队列的机制来完成任务与任务、任务与中断之间的消息传递。 0x01 队列简介 队列是为了任务与任务、任务与中断之间的通信而准备的,可以在任务与任务…

剧情介绍:“阿甘正传”

阿甘是个智商只有75的低能儿。在学校里为了躲避别的孩子的欺侮,听从一个朋友珍妮的话而开始“跑”。他跑着躲避别人的捉弄。在中学时,他为了躲避别人而跑进了一所学校的橄榄球场,就这样跑进了大学。阿甘被破格录取,并成了橄榄球巨…

FreeRTOS信号量---二值信号量

信号量可以用来进行资源管理和任务同步,FreeRTOS中信号量又分为二值信号量、计算型信号量、互斥信号量和递归互斥信号量。 0x01 二值信号量 二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的,任…

FreeRTOS软件定时器

软件定时器允许设置一段时间,当设置的时间达到后就执行指定的功能函数,被软件定时器调用的功能函数叫做定时器的回调函数。软件定时器的回调函数是在定时器服务任务中执行的,所以一定不能在回调函数中调用任何阻塞任务的API函数,比…

WP7之Application Bar控件

Microsoft.Phone.Shell命名空间中定义了ApplicationBar及其相关类(ApplicationBarIconButton和ApplicationBarMenuItem),这些类派生自Object,并完全独立于常规Silverlight编程中的DependencyObject,UIElement和FrameworkElement类层次结构。A…

TomCat使用以及端口号被占用的处理方法

一.HTTP协议 什么是HTTP协议 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。 HTTP请求 HTTP响应 2.如何处理端口被占用 方法一&#xff…

FreeRTOS事件标志组

使用信号量来同步的话,任务只能与单个事务或任务进行同步,有时候某个任务可能会需要与多个事件或任务进行同步,此时信号量就无能为力了,FreeRTOS为此提供了一个可选的解决方法,那就是事件标志组。 0x01 事件标志组 事…

FusionCharts等产品简介

以前做柱状图、饼形图等图表都是根据数据绘制出来的静态图,偶然看到别人的一套系统,居然可以让柱状图的柱子动画般的逐个出现,效果还是很不错的。不要跟我抬杠说不就是展现数据嘛,静态图表有什么不好,要知道用户一般可…

Eclipse和Tomcat绑定并且将上传资源到Tomcat上

步骤如下: 创建一个Dynamic Web Project(图一) Target runtime 选择Apache Tomcat v7.0版本(图二) 切记要选择 v7.0 和2.5 (若没有图二选项见图三) 然后,点击window --> Prefer…

FreeRTOS任务通知

从v8.2.0版本开始,FreeRTOS新增了任务通知这个功能,可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西,使用任务通知的话效率会更高。 任务通知在FreeRTOS是一个可选的选项,要使用任务通知的话就需要将宏configUSE_T…

kinect在openni下也能玩抠出人物换背景

之前想了个很拉风的名字《用kinect玩穿越》,但是现在功能还不是很完善,细节处理也不是很好,脸皮没有足够的厚,所以呢还是叫换背景吧。 这里面包含两个技术要点: 一、抠出活动人物 在微软的SDK里深度图像的前3位即0-2位…

Emit学习-基础篇-基本概念介绍

之前的Hello World例子应该已经让我们对Emit有了一个模糊的了解,那么Emit到底是什么样一个东西,他又能实现些什么功能呢?昨天查了点资料,大致总结了下,由于才开始学习肯定有不完善的地方,希望大家能够批评指…

The FreeRTOS Distribution(介绍、移植、类型定义)

1 Understand the FreeRTOS Distribution 1.1 Definition :FreeRTOS Port FreeRTOS目前可以在20种不同的编译器构建,并且可以在30多种不同的处理器架构上运行,每个受支持的编译器和处理器组合被认为是一个单独的FreeRTOS Port。 1.2 Build…

Eclipse项目左上角出现大红色感叹号怎么办?

出现大红色感叹号是因为环境不匹配 解决方法: 右击出现大红色感叹号的项目 点击 Libraries,将有叉号的给Remove掉 然后再点击 Add Library —> JRE System Library —> Next 勾选第二个即可 之后,就不会出现大红色感叹号了。

PCB---STM32最小系统制作过程

PCB 制作过程STM32核心模块连接外部电源晶振OSC_IN(8MHz)OSC32_IN(32.768MHz)复位下载口BOOT模式电源模块添加功能UARTWKUPSTM32核心模块 这里我们以STM32F103C8T6为列,先将芯片的原理图放到原理图中 对于STM32,有几个模块是核心&#xff0…

FreeRTOS---堆内存管理(一)

FreeRTOS的堆内存管理简介动态内存分配及其与 FreeRTOS 的相关性动态内存分配选项内存分配方案Heap_1heap_2Heap_3Heap_4设置heap_4的起始地址Heap_5vPortDefineHeapRegions()堆相关的函数xPortGetFreeHeapSizexPortGetMinimumEverFreeHeapSizeMalloc调用失败的Hook函数这篇文章…

FreeRTOS--堆内存管理(二)

堆内存管理代码具体实现heap_1内存申请函数内存释放函数heap_2内存块内存堆初始化函数内存块插入函数内存申请函数判断是不是第一次申请内存开始分配内存内存释放函数heap_3heap_4内存堆初始化函数内存块插入函数heap_5上一篇文章说了FreeRTOS实现堆内存的原理,这一…

css中的node.js_在Node App中使用基本HTML,CSS和JavaScript

css中的node.jsYou may think this is not important, but it is!. As a beginner in node.js, most coding exercises are always server sided. 您可能认为这并不重要,但确实如此! 作为node.js的初学者,大多数编码练习始终都是服务器端的。…