1.FreeRTOS系统的核心就是任务管理。
2.多任务系统
(1)裸机程序,又叫单任务系统,也称前后台系统,其中中断服务函数为前台程序,大循环while(1)为后台程序。
(2)相对于单任务系统,衍生出多任务系统,多任务系统就是把一个大问题划分成很多个小问题,然后把小问题解决掉,大问题也就随之解决了。
3.任务状态
在FreeRTOS中,任务的状态只有4种:运行态、就绪态、阻塞态、挂起态。
注:在uC/OS-III中任务的运行状态比FreeRTOS中任务的状态要复杂很多。
4.任务优先级
与任务优先级相关的宏定义由两个:configMAX_PRIORITIES和configUSE_TIME_SLICING
configMAX_PRIORITIES:任务的优先级数量,任务可以分配一个从0~configMAX_PRIORITY之间的优先级。
configUSE_TIME_SLICING:默认为1,可以分配相同优先级的任务,处于相同优先级的就绪任务会使用时间片轮转调度器获取运行时间。
优先级的数字越低表示任务的优先级越低,0的优先级最低,configMAX_PRIORITIES-1的优先级最高。空闲任务的优先级最低,为0。
5.任务控制块
在FreeRTOS中的任务控制块叫TCB_t,定义如下:
typedef struct tskTaskControlBlock
{
volatile StackType_t *pxTopOfStack; // 任务栈栈顶,指向任务栈上的最后一项,它必须是TCB结构体的第一个成员
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings; // MPU相关设置,MPU的设置被定义为接口层的一部分,它必须是TCB结构体的第二成员
#endif
ListItem_t xStateListItem; // 状态列表项
ListItem_t xEventListItem; // 事件列表项,用于从事件列表应用任务
UBaseType_t uxPriority; // 任务优先级,最小的优先级为0
StackType_t *pxStack; // 任务栈起始地址,指向任务的起始地址
char pcTaskName[ configMAX_TASK_NAME_LEN ]; // 任务名字
#if ( portSTACK_GROWTH > 0 )
StackType_t *pxEndOfStack; // 任务栈栈底:当栈是从低地址向高地址增长时,它指向栈结构的最末端
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting; // 临界区嵌套深度
#endif
#if ( configUSE_TRACE_FACILITY == 1 ) // trace到debug的时候调用
UBaseType_t uxTCBNumber;
UBaseType_t uxTaskNumber;
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; // 任务的基础优先级,优先级反转的时候使用:最后分配给任务的优先级-优先级继承机制中使用
UBaseType_t uxMutexesHeld; // 任务获取到的互斥信号量个数
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
TaskHookFunction_t pxTaskTag;
#endif
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) // 与本地存储有关
void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
#if( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulRunTimeCounter; // 用来记录任务运行的总时间
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
struct _reent xNewLib_reent; // 定义一个newlib的结构体
#endif
#if( configUSE_TASK_NOTIFICATIONS == 1 ) // 任务通知相关变量
volatile uint32_t ulNotifiedValue; // 任务通知值
volatile uint8_t ucNotifyState; // 任务通知状态
#endif
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
// 用来标记任务是动态创建的还是静态创建的,如果是静态创建的此变量为pdTRUE,如果是动态创建的就为pdFALSE
uint8_t ucStaticallyAllocated; // 若任务是动态创建的,则设置为pdTRUE,以确保没有试图释放内存
#endif
#if( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDelayAborted;
#endif
} tskTCB;
// 新版本的FreeRTOS任务控制块命名为TCB_t,但是本质上还是tskTCB,主要是为了兼容旧版本应用
typedef tskTCB TCB_t;