• 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()调用的函数)。 启动调度程序后,只会执行任务和中断。
    启动调度程序会导致在调度程序处于“初始化”状态时创建的优先级最高的任务进入“运行”状态。
    */
  • 相关阅读:
    面向对象 (11)求交并集 判断字符形式
    软件工程 课程总结
    面向对象 (10)正则判邮箱
    面向对象 (9)计算时间差 找随机数范围内规律
    面向对象 (8)字符串出现字符个数统计 字母组成回文串判定
    面向对象 (7)中介买房 平均数异常处理
    面向对象 (6)买房付首款
    第16周作业
    第15周作业
    迟到的第14周作业
  • 原文地址:https://www.cnblogs.com/ustc-anmin/p/11323720.html
Copyright © 2020-2023  润新知