FREERTOS笔记(一)
一、freertos任务状态
共分为四种状态
1.运行态
2.就绪态
3.阻塞态
4.挂起态
二、freertos任务优先级
1.freertos优先级数字越高,优先级越高,和stm32NVIC中断优先级大小不一样,NVIC是数字越小优先级越高
2.freertos的优先级范围为0~configMAX_PRIORITIES-1,其中configMAX_PRIORITIES在FreeRTOS.h中用宏定义,默认定义的是5,可以修改定义,此时优先级范围就是0-4
3.不同任务可以采用同一优先级
4.优先级高的任务会抢占优先级低的任务的cpu使用权
5.IDLE空闲任务默认优先级为0
6.不建议用户任务优先级选择0和configMAX_PRIORITIES-1,建议1到configMAX_PRIORITIES-2
三、创建一个最简单的任务
动态任务创建
#define START_TASK_PRIO 1 //设置任务优先级,越大优先级越高
#define START_STK_SIZE 128 //任务堆栈大小设置,注意单位是4字节,即128*4个字节
TaskHandle_t StartTask_Handler; //任务句柄,用于保存任务信息
void start_task(void *pvParameters);
int main()
{
...
...
BaseType_t TaskCreateStatus;
TaskCreateStatus= xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",//任务名字,最大16个字符
(uint16_t )START_STK_SIZE,//任务堆栈大小设置,注意单位是4字节
(void* )NULL,//一般不用,设置成NULL简单
(UBaseType_t )START_TASK_PRIO,//设置任务优先级,越大优先级越高
(TaskHandle_t* )&StartTask_Handler);//任务句柄,创建成功后返回此任务的任务句柄
vTaskStartScheduler();//开始任务
while(1);
...
...
}
void start_task(void *pvParameters)//一般start_task用于创建其它任务,这里写简单点让led闪烁
{
while(1)
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
vTaskDelay(500);
}
vTaskDelete(StartTask_Handler);//养成每个任务最后都写上删除此任务的好习惯
//vTaskDelete(NULL);//也可以写成NULL
}
静态任务创建
静态任务用的比较少,后面有机会再补充
四、其它常见基础任务api使用(持续更新中)
一些常用的api函数,简单就仅仅列出来,略微有难度的会在下面讲解
vTaskDelay(1000);//延时1000ms
vTaskDelete(NULL);//删除当前任务
vTaskStartScheduler(void);//开始任务-无参数
vTaskSuspend( TaskHandle_t xTaskToSuspend );//挂起任务-参数为任务句柄
vTaskResume( TaskHandle_t xTaskToResume );//恢复任务,和挂起相对应-参数为任务句柄
xTaskResumeAll(void);//恢复所有任务
xTaskResumeFromISR( TaskHandle_t xTaskToResume );//在中断中需要回复任务时使用,使用后需要调用切换任务
对于一些较难的api函数会配合源码略微讲解
/*第一个 xTaskResumeFromISR 111111111111111111111111111111111111111111111111111111111111*/
xTaskResumeFromISR( TaskHandle_t xTaskToResume );//在中断中需要回复任务时使用,使用后需要调用切换任务
使用方法:
BaseType_t yield_re;//在中断中
yield_re=xTaskResumeFromISR(要恢复任务句柄);
if(yield_re==pdTRUE) portYIELD_FROM_ISR(yield_re);//切换任务为适配优先级
相应api源码:
#define portYIELD_FROM_ISR( x )portEND_SWITCHING_ISR( x )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
解释:如果传进来的参数为pdTRUE,就会调用portYIELD();进行切换任务
/*1111111111111111111111111111111111111111111111111111111111111111*/
所有api函数可以前往官网,freertos-API调用页面查看,讲的很详细