一、任务的挂起和恢复的API函数
| API函数 | 描述 |
|---|---|
| vTaskSuspend() | 挂起任务 |
| vTaskResume() | 恢复被挂起的任务 |
| xTaskResumeFroml() | 在中断中恢复被挂起的任务 |
挂起:类似暂停,可恢复
删除:无法恢复
“FromlSR”:带FromlSR后缀是在中断函数中专用的API函数
二、任务挂起函数介绍
1、挂起函数:void vTaskSuspend(TaskHandle_t xTaskToSuspend)
xTaskToSuspend:待挂起任务的任务句柄
此函数用于挂起任务,使用时需将宏INCLUDE_vTaskSuspend配置为1。
无论优先级如何,被挂起的任务都将不再被执行,知道任务被恢复。
当被传入NULL,则代表挂起任务自身。
2、恢复挂起函数:void vTaskResume(TaskHandle_t xTaskToResume)
xTaskToResume:恢复挂起任务的任务句柄
此函数用于恢复挂起任务,使用时需将宏INCLUDE_vTaskSuspend配置为1。
任务无论被vTaskSuspend()挂起多少次,只需在任务中调用vTaskResume()一次即可恢复,恢复的任务会进入就绪态。
3、中断中恢复挂起函数:BaseType_t xTaskResumeFromlSR(TaskHandle_t xTaskToResume)
| 返回值 | 描述 |
|---|---|
| pdTRUE | 任务恢复后需要进行任务切换 |
| pdFALSE | 任务恢复后不需要进行任务切换 |
此函数用于挂起任务,使用时需将宏INCLUDE_vTaskSuspend和INCLUDE_xTaskResumeFromISR配置为1。
该函数专用于中断服务函数中,用于解挂被挂起的任务
中断服务程序要调用FreeRTOS的API函数则中断优先级不能高于FreeRTOS所管理的最高优先级
ps.
任务优先级,数字越大优先级越高
中断优先级,数字越小优先级越高
Key.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Key.h"
#include "FreeRTOS.h"
#include "task.h"
extern TaskHandle_t task1_handler; //任务句柄
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure; //结构体变量
//配置时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//配置GPIO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//AFIO外部中断引脚选择
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);
//配置EXTI
EXTI_InitStructure.EXTI_Line = EXTI_Line13;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Falling 下降沿触发 Rising 上升沿触发
EXTI_Init(&EXTI_InitStructure);
//配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //分组
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //10-15中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断通道使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;//指定抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//指定响应优先级
NVIC_Init(&NVIC_InitStructure);
}
void EXTI15_10_IRQHandler(void)
{
BaseType_t KeyNum;
if(EXTI_GetITStatus(EXTI_Line13) == SET)
{
KeyNum = xTaskResumeFromISR(task1_handler);
if(KeyNum == pdTRUE)
{
portYIELD_FROM_ISR(KeyNum); //任务切换
}
else
{
}
EXTI_ClearITPendingBit(EXTI_Line13);
}
}
FreeRTOS_Demo.c
#include "FreeRTOS_Demo.h"
#include "FreeRTOS.h"
#include "task.h"
#define START_TASK_PRIO 1 //优先级
#define START_TASK_STACK_SIZE 128 //堆栈大小
StackType_t start_task_stack[START_TASK_STACK_SIZE]; //任务堆栈
StaticTask_t start_task_tcb; //任务控制块
TaskHandle_t start_task_handler; //任务句柄
void start_task(void * pvParameters);
#define TASK1_PRIO 2 //优先级
#define TASK1_STACK_SIZE 128 //堆栈大小
TaskHandle_t task1_handler; //任务句柄
StackType_t task1_stack[TASK1_STACK_SIZE]; //任务堆栈
StaticTask_t task1_tcb; //任务控制块
void task1(void * pvParameters);
#define TASK2_PRIO 3 //优先级
#define TASK2_STACK_SIZE 128 //堆栈大小
TaskHandle_t task2_handler; //任务句柄
StackType_t task2_stack[TASK2_STACK_SIZE]; //任务堆栈
StaticTask_t task2_tcb; //任务控制块
void task2(void * pvParameters);
//#define TASK3_PRIO 4 //优先级
//#define TASK3_STACK_SIZE 128 //堆栈大小
//TaskHandle_t task3_handler; //任务句柄
//StackType_t task3_stack[TASK3_STACK_SIZE]; //任务堆栈
//StaticTask_t task3_tcb; //任务控制块
//void task3(void * pvParameters);
uint8_t key_unkow = 0;
/*空闲任务配置*/
StaticTask_t idle_task_tcb;
StackType_t idle_task_stack[configMINIMAL_STACK_SIZE];
/*软件定时器任务配置*/
StaticTask_t timer_task_tcb;
StackType_t timer_task_stack[configTIMER_TASK_STACK_DEPTH];
/*空闲任务内存分配*/
void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer, //分配内存
StackType_t ** ppxIdleTaskStackBuffer, //空闲任务堆栈
uint32_t * pulIdleTaskStackSize ) //空闲任务的堆栈大小
{
* ppxIdleTaskTCBBuffer = &idle_task_tcb;
* ppxIdleTaskStackBuffer = idle_task_stack;
* pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize )
{
*ppxTimerTaskTCBBuffer = &timer_task_tcb;
*ppxTimerTaskStackBuffer = timer_task_stack;
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
void freertos_demo(void)
{
start_task_handler = xTaskCreateStatic ( (TaskFunction_t ) start_task, //任务指针
(const char * const ) "start_task", //任务名字
(const uint32_t ) START_TASK_STACK_SIZE, //堆栈大小
(void * const ) NULL, //入口函数
(UBaseType_t ) START_TASK_PRIO, //任务优先级
(StackType_t * const ) start_task_stack, //任务堆栈
(StaticTask_t * const ) &start_task_tcb //任务控制块
);
vTaskStartScheduler();//开启任务调度
}
void start_task(void * pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
task1_handler = xTaskCreateStatic ( (TaskFunction_t ) task1, //任务指针
(const char * const ) "task1", //任务名字
(const uint32_t ) TASK1_STACK_SIZE, //堆栈大小
(void * const ) NULL, //入口函数
(UBaseType_t ) TASK1_PRIO, //任务优先级
(StackType_t * const ) task1_stack, //任务堆栈
(StaticTask_t * const ) &task1_tcb ); //任务控制块
task2_handler = xTaskCreateStatic ( (TaskFunction_t ) task2, //任务指针
(const char * const ) "task2", //任务名字
(const uint32_t ) TASK2_STACK_SIZE, //堆栈大小
(void * const ) NULL, //入口函数
(UBaseType_t ) TASK2_PRIO, //任务优先级
(StackType_t * const ) task2_stack, //任务堆栈
(StaticTask_t * const ) &task2_tcb ); //任务控制块
// task3_handler = xTaskCreateStatic ( (TaskFunction_t ) task3, //任务指针
// (const char * const ) "task3", //任务名字
// (const uint32_t ) TASK3_STACK_SIZE, //堆栈大小
// (void * const ) NULL, //入口函数
// (UBaseType_t ) TASK3_PRIO, //任务优先级
// (StackType_t * const ) task3_stack, //任务堆栈
// (StaticTask_t * const ) &task3_tcb ); //任务控制块
//
vTaskSuspend(task1_handler);
vTaskDelete(NULL);
taskEXIT_CRITICAL(); //退出临界区
}
//任务1,蓝灯每500ms翻转一次
void task1(void * pvParameters)
{
while(1)
{
LED1_TOGGLE();
vTaskDelay(500);
}
}
//任务2,绿灯每250ms翻转一次
void task2(void * pvParameters)
{
while(1)
{
LED0_TOGGLE();
vTaskDelay(250);
}
}
//任务3,按下按键删除任务1,只让绿灯翻转
//void task3(void * pvParameters)
//{
//
// while(1)
// {
//
//
// }
//
// vTaskDelay(10);
// }








