文章目录
0 前言
@ Author :Dargon
@ Record Date :2021/07/12
@ Reference Book : `FreeRTOS源码详解与应用开发`,`ARM Cortex-M3与Cortex-M4权威指南`,`B站正点原子FreeRTOS讲解视频`
@ Purpose :学习正点原子的miniFly,该飞控基于FreeRTOS系统开发的,所以学习一下记录下关于RTOS系统的一些基本操作,大概了解系统的工作原理,如何创建,运行,切换任务等等基本操作流程。在此进行学习的记录。
1 任务基础知识
1.1 任务优先级
- 与中断优先级不是同一回事的,中断优先级是数值越小对应的优先级就越高。
- 任务的优先级,对应的是0~
configMAX_PRIORITIES =32
,在任务调度的时候,会根据这个优先级的大小进行选择要运行的任务,即是处于就绪态的最高优先级的任务才会被运行。 - 当任务进入就绪列表的排列的时候,列表的排列是按照优先级从小到大进行排列的,例如当前优先级为4 5 ,对应的列表项的值为(32-4)和(32-5)进行入就绪态的队列操作,相应的优先级为5 的就在优先级为4 的前面。
1.2 任务控制块TCB_t
- 一个任务所包含的信息 多对应的结构体
// --任务块的结构体
typedef struct tskTaskControlBlock
{
// --volatile 表示每次都是直接从 内存地址去读取,而不是通过cache或者register读取,告诉编译器这个变量不需要优化
// --任务控制块结构体 第一项就是对应的 任务堆栈指针
volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
// --xStateListItem 和链表有关的 根据该任务的状态,将此列表项添加到对应的状态列表中,
// --xEventListItem 任务的事件列表项添加到 某个事件列表中。
ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
ListItem_t xEventListItem; /*< Used to reference a task from an event list. */
// --对应任务优先级
UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */
StackType_t *pxStack; /*< Points to the start of the stack. */
// --申请内存 都已经是16个char了
char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
// 省略一堆的条件编译(后面用到的再说)
// --关于互斥信号量 在初始化任务控制块结构体的时候 需要初始化这里的内容
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
UBaseType_t uxMutexesHeld;
#endif
} tskTCB;
typedef tskTCB TCB_t;
-
详细的解释一下各项的作用,以及后面所发挥的作用
-
volatile StackType_t *pxTopOfStack
指向任务的堆栈的最后一个位置,为什么这样说,因为在申请任务堆栈的时候,通过malloc函数,返回的内存指针,指向的是这块新内存的首地址。我们若是需要发生一次任务切换的话,就需要返回堆栈的作用,来保存现场,需要把当前的这些寄存器东西存入堆栈中,以便下次回来继续执行。但是对于STM32来说,堆栈是向下生长的,所以就需要一个,栈顶的位置pxTopOfStack
,来向下进行遍历,进行–操作,一次次的存入堆栈中。 -
ListItem_t xStateListItem
根据该任务的现在所处的状态,将此列表项添加到对应的状态列表中,例如该任务现在处于就绪态,就会根据其优先级 挂到 就绪list中。 -
ListItem_t xEventListItem
当该任务在等待某个消息或者信号量的时候,一直没有等到而进入阻塞态的任务就会将该任务的这个列表项,挂到对应的队列的xTasksWaitingToSend
list上,(在queue进行初始化的时候,会初始化相应的两个列表xTasksWaitingToSend
和xTasksWaitingToReceive
) -
UBaseType_t uxPriority
对应的任务初始化的时候,设定的该任务的优先级 -
StackType_t *pxStack
申请的任务堆栈,算作栈底吧!在初始化的时候会有这样一句话;pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t )
-
char pcTaskName[ configMAX_TASK_NAME_LEN ]
一个char字符串,保存任务的名字,configMAX_TASK_NAME_LEN =16
,最多是15个char 其中需要\0
来结尾的,
不管怎样,你申请这个结构体内存之后,即使你用不完这个名字内存,它也是占用16个char 的位置。 -
最后一个关于 如果使用了互斥信号量的时候,所进行的条件编译。
1.3 任务的状态
- <