目录
-
任务状态
FreeRTOS中的任务永远处于下面几个状态中的某一个
他们之间的转化关系如下:
-
任务的挂起与恢复
API函数如下:
挂起函数:
恢复函数:
测试内容:
一共有4个任务,分别是start,key_task,task1和task2,start优先级最高,其余优先级递增,任务的工作如下:
- start:创建另外3个任务,输出所有任务的状态,然后删除自己
- key_task:负责挂起和恢复task1和task2
- task1:屏幕显示,闪烁LED,使用vTaskDelay()阻塞自己
- task2:屏幕显示,闪烁LED,使用vTaskDelay()阻塞自己
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //设置系统中断优先级分组4
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口
LED_Init(); //初始化LED端口
LCD_Init(); //初始化LCD
EXTIX_Init(); //初始化外部中断
KEY_Init(); //初始化按键
POINT_COLOR=BLACK;
LCD_ShowString(30,50,200,16,16,"@ZZP@");
//创建开始任务
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(); //进入临界区
//创建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(); //退出临界区
}
//TASK1任务函数
void key_task(void *pvParameters)
{
u8 key;
while(1)
{
key=KEY_Scan(0);
switch(key)
{
case WKUP_PRES:
vTaskSuspend(Task1Task_Handler); //挂起任务1
printf("挂起任务1的运行!\r\n");
break;
case KEY1_PRES:
vTaskResume(Task1Task_Handler); //恢复任务1
printf("恢复任务1的运行!\r\n");
break;
case KEY2_PRES:
vTaskSuspend(Task2Task_Handler); //挂起任务2
printf("挂起任务2的运行!\r\n");
break;
}
vTaskDelay(10);
}
}
//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,加到255的时候会清零
LED0=!LED0;
printf("任务1已经执行:%d次\r\n",task1_num);
LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域
LCD_ShowxNum(86,111,task1_num,3,16,0x80); //显示任务执行次数
vTaskDelay(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++; //任务执行次数加1
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);
}
}
测试结果:
Tist:
- 任务有4种状态,分别为就绪态、运行态、阻塞态、挂起态
- FreeRTOS调度器有两种调度算法,抢占式和协作式