依照FreeRTOS用户的操作顺序,我们一般先创建任务,分配好任务的调用栈,再去开启任务调度器进行任务调度。所以,这篇文章就从FreeRTOS的创建任务开始,细致整理一下FreeRTOS。如有错误,请大佬指正!
那么任务创建分为动态创建和静态创建两种,这里就以动态创建(因为使用最多)为例,分析一下FreeRTOS的源码,看看这里面都在做什么事情。
首先进入xTaskCreate(...)API内部,第一步,会去使用pvPortMalloc
(类似malloc一样的申请内存函数)申请到一片名为pxStack
的内存部分,这部分就作为这个任务的调用栈,用来保存任务内部函数的局部变量、函数调用信息、任务的上下文切换等。
pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) );
第二步,申请一块内存为pxNexTCB
,用来存储任务信息(比如这个任务的调用栈地址、当前任务在什么列表中等)。
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
具体TCB存储着什么任务信息,需要去TCB_这个结构体中去详细看,这里简单列在下面:
typedef struct tskTaskControlBlock
{
volatile StackType_t *pxTopOfStack; //任务栈栈顶,必须为TCB第一个成员
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings;
#endif
ListItem_t xStateListItem; //任务状态列表项
ListItem_t xEventListItem; //任务时间列表项
UBaseType_t uxPriority; //任务优先级
StackType_t *pxS