FreeRTOS源码学习_02-创建任务
一、写在前面
- FreeRTOS版本:V10.4.5
- 内存分配方式:动态分配
- Port.c版本:GCC/ARM_CM4F_V10.4.5
我自己最近在学习FreeRTOS操作系统,在使用中发现,虽然官方的英文注释十分的详尽,但是很多地方不是特别好理解,初学者看了注释后还是一头雾水。因此决定将自己的使用理解以及注释写在这里,方便大家参考。
注意:因为加了注释符后,注释会变成斜体,看着很别扭,因此文中注释统一采用 “ ** … ** ” 的方式
第一阶段为基础篇 分为四篇:
01-任务调度器:分析开启任务调度函数
02-创建任务:分析任务是如何被创建的
03-链表操作:系统中的任务、消息、信号量等都与链表息息相关,分析FreeRTOS中的链表操作(待更新)
04-汇编指令解析:分析FreeRTOS中的汇编代码(待更新)
注释写的十分详细,直接写在源码中,篇幅较长,希望耐心看完!
如果这篇文章帮助到了您,作者甚是欣慰。若文中有不正确或不恰当的地方,也请大家及时指正!
二、源码分析
任务的一个核心的东西是任务控制快,这个东西保存了任务的一切信息,通过任务控制块,可以知道该任务的优先级、任务状态、任务事件等等。因此首先来分析任务控制块这个结构信息,然后再看任务创建源码就会一目了然。
1、tskTCB结构分析
typedef struct tskTaskControlBlock
{
**
这是一个 32位的指针,用来保存该任务TCB(任务控制块)的栈首地址,就是我们在创建任务时,为这个任务分配的内存首地址
**
volatile StackType_t * pxTopOfStack;
**
下面的条件编译是针对有MPU功能的芯片的操作,文章不予考虑
**
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
#endif
**
存放任务状态的链表
**
ListItem_t xStateListItem;
**
存放任务事件的链表(事件是FreeRTOS的一项功能,后面会有专门的章节来介绍)
**
ListItem_t xEventListItem;
**
存放当前任务优先级
**
UBaseType_t uxPriority;
**
指向当前任务的任务堆栈,就是为这个任务运行所分配的内存
**
StackType_t * pxStack;
**
任务的名字
**
char pcTaskName[ configMAX_TASK_NAME_LEN ];
**
堆栈的栈底
**
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t * pxEndOfStack;
#endif
**
嵌套临界区的深度(临界区是为了保护临界段代码所设置的,FreeRTOS中保护方式就是关闭中断)FreeRTOS支持临界区嵌套,即调用了n次保护,就必须n次释放保护,才会打开中断
**
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting;
#endif
**
这两个变量主要是调试的时候使用的,用来记录创建的TCB数量和任务数量
**
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated