freeRTOS学习一

freeRTOS中的链表结构:

/*
 * 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()调用的函数)。 启动调度程序后,只会执行任务和中断。
启动调度程序会导致在调度程序处于“初始化”状态时创建的优先级最高的任务进入“运行”状态。
*/

 

posted @ 2019-08-08 20:43  Practical  阅读(290)  评论(0编辑  收藏  举报