# FreeRTOS操作系统学习
# 前言
功能:有时候我们需要暂停某个任务的运行,过一段时间以后在重新运行。这个时候要是使用任
务删除和重建的方法的话那么任务中变量保存的值肯定丢失了!FreeRTOS 给我们提供了解决
这种问题的方法,那就是任务挂起和恢复,当某个任务要停止运行一段时间的话就将这个任务
挂起,当要重新运行这个任务的话就恢复这个任务的运行。
# 一、任务挂起与恢复
API函数:
vTaskSuspend():
挂起一个任务。
此函数用于将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。退出挂
起态的唯一方法就是调用任务恢复函数 vTaskResume()或 xTaskResumeFromISR()。函数原型
```c
void vTaskSuspend( 任务句柄)
```
vTaskResume() 恢复一个任务的运行。
xTaskResumeFromISR() 中断服务函数中恢复一个任务的运行。
挂起后处于挂起态。
# 二、任务挂起与恢复
## 1.代码实战
代码如下,注释在图片里
```c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.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);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é4
delay_init(); //ÑÓʱº¯Êý³õʼ»¯
uart_init(115200); //³õʼ»¯´®¿Ú
LED_Init(); //³õʼ»¯LED
KEY_Init(); //³õʼ»¯°´¼ü
EXTIX_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(); //½øÈëÁÙ½çÇø(²»ÄܽøÈëSysTickÖжÏ)
//´´½¨KEYÈÎÎñ
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);
//´´½¨TASK1ÈÎÎñ
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);
//´´½¨TASK2ÈÎÎñ
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(); //Í˳öÁÙ½çÇø
}
//keyÈÎÎñº¯Êý
void key_task(void *pvParameters)
{
u8 key,statflag=0;
while(1)
{
key=KEY_Scan(0);//»ñÈ¡°´¼üÖµ
vTaskDelay(10);
switch(key)
{
case WKUP_PRES:
statflag=!statflag;
if(statflag==1)
{
vTaskSuspend(Task1Task_Handler);//¹ÒÆðÈÎÎñ1,º¯Êý(¾ä±ú)
printf("¹ÒÆðÈÎÎñ1µÄÔËÐÐ!\r\n");
}
else if(statflag==0)
{
vTaskResume(Task1Task_Handler); //»Ö¸´ÈÎÎñ1£¬º¯Êý(¾ä±ú)
printf("»Ö¸´ÈÎÎñ1µÄÔËÐÐ!\r\n");
}
break;
case KEY1_PRES:
vTaskSuspend(Task2Task_Handler);//¹ÒÆðÈÎÎñ2
printf("¹ÒÆðÈÎÎñ2µÄÔËÐÐ!\r\n");
break;
case KEY0_PRES:
vTaskResume(Task2Task_Handler);//»Ö¸´ÈÎÎñ2
printf("»Ö¸´ÈÎÎñ2µÄÔËÐÐ!\r\n");
break;
}
vTaskDelay(10); //ÑÓʱ10ms
}
}
//task1ÈÎÎñº¯Êý
void task1_task(void *pvParameters)
{
u8 task1_num=0;
while(1)
{
task1_num++; //ÈÎÎñÖ´1ÐдÎÊý¼Ó1 ×¢Òâtask1_num1¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
LED0=!LED0;
printf("ÈÎÎñ1ÒѾִÐУº%d´Î\r\n",task1_num);
vTaskDelay(500);
}
}
//task2ÈÎÎñº¯Êý
void task2_task(void *pvParameters)
{
u8 task2_num=0;
while(1)
{
task2_num++; //ÈÎÎñ2Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num2¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
LED1=!LED1;
printf("ÈÎÎñ2ÒѾִÐУº%d´Î\r\n",task2_num);
vTaskDelay(500);
}
}
```
# 总结
在FreeRTOS中任务的挂起与恢复,掌握挂起函数与恢复函数的使用。
来源:freertos——任务的挂起与恢复(二) - 嵌入式论坛-人气最火爆嵌入式学习开发论坛 - 21ic电子技术开发论坛