freeRTOS学习一
阅读原文时间:2023年07月16日阅读:1

/*
* Definition of the only type of object that a list can contain. 链表中的节点
*/
struct xLIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item.
There is therefore a two way link between the object containing the list item and the list item itself.
指向该节点的拥有者 及内嵌在哪个数据结构中
*/
void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any).通常指向链表的根节点 */
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
};
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */

/*
* Definition of the type of queue used by the scheduler. 链表
*/
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
configLIST_VOLATILE UBaseType_t uxNumberOfItems; 链表节点计数器
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY ().链表节点索引指针 */
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
} List_t;

struct xMINI_LIST_ITEM 链表的最后一个节点或者说是第一个节点 一个marker
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
configLIST_VOLATILE TickType_t xItemValue;
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

对链表的插入删除操作可参见源码中的list.c。


main()函数里面顺序执行的无限循环,在这个循环中,CPU按照顺序完成各种操作。

多任务系统中,根据功能的不同,把整个系统分割成一个个独立的且无法返回的函数,这种函数就被称为任务。

多任务系统中,每个任务都是独立的、互不干扰的,所以要为每个任务分配独立的栈空间,这个栈空间通常是一个预先定义好的全局数组。也可以是动态分配的一段内存空间。

TCB任务控制块,相当于人物的身份证,里面存有任务的所有信息。以后对任务的全部操作都可以通过任务控制块来实现。

/*
* Task control block. A task control block (TCB) is allocated for each task,
* and stores task state information, including a pointer to the task's context
* (the task's run time environment, including register values)
*/
typedef struct tskTaskControlBlock
{
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. */栈顶

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. \*/  任务栈起始地址  
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. \*/

} tskTCB;

/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
below to enable the use of older kernel aware debuggers. */
typedef tskTCB TCB_t;

任务创建函数,静态创建(PCB和栈的内存需要预先定义好,任务删除时,内存不能释放),动态创建(创建任务时动态分配,任务删除,可以释放)。

TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, //函数入口
const char * const pcName, //任务名称
const uint32_t ulStackDepth, //任务栈大小
void * const pvParameters, //任务形参
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer, //任务栈起始地址
StaticTask_t * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 任务控制块地址

定义就绪列表,任务创建好,需要把任务添加到就绪列表中,表示任务已经就绪,系统随时可以调度。就绪列表实际上就是一个List_t类型的数组。数组的下标对应任务的优先级,同一优先级的任务插入就绪队列中的同一条链表中。

将任务插入就序列表,TCB里面有一个xStateListItem成员,我们将任务插入就序列表中,就是通过将TCB中的该节点插入就序列表来实现的。

实现调度器,主要功能就是实现任务的切换,即从就序列表里面找到优先级最高的任务执行,

vTaskStartScheduler()
/*
启动FreeRTOS调度程序运行。
通常,在调度程序启动之前,将执行main()(或main()调用的函数)。 启动调度程序后,只会执行任务和中断。
启动调度程序会导致在调度程序处于“初始化”状态时创建的优先级最高的任务进入“运行”状态。
*/

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章