Ucos源码分析------OS启动

Ucos源码分析

1.Ucos源码分析------任务控制块与任务调度
2.Ucos源码分析------事件控制块与事件控制
3.Ucos源码分析------信号量
4.Ucos源码分析------邮箱与队列
5.Ucos源码分析------事件标志组
6.Ucos源码分析------内存管理
7.Ucos源码分析------临界区与中断管理
8.Ucos源码分析------OS启动
9.Ucos总结



必须在调用OSStart()函数之前调用OSInit(),而只有在调用OSStart()函数之后,UCOS才真正开始运行多任务。

int main(void)
{
	//系统初始化
    OSInit(); 
    //创建主任务
    OSTaskCreate(MainTask, (void *)0, &MainTask_Stk[MainTask_StkSize-1], MainTask_Prio);
    // 开始任务调度
    OSStart(); 
    return 0;
}

1.OS初始化

1.1 OSInt()

void  OSInit (void)
{
//钩子函数,初始化开始前的
#if OS_VERSION >= 204
    OSInitHookBegin();                                           /* Call port specific initialization code   */
#endif
    //初始化一些全局变量
    OS_InitMisc();                                               /* Initialize miscellaneous variables       */
    //就绪表初始化
    OS_InitRdyList();                                            /* Initialize the Ready List                */  
    //初始化 空任务控制块链表
    OS_InitTCBList();                                            /* Initialize the free list of OS_TCBs      */  
    //初始化 空事件控制块链表
    OS_InitEventList();                                          /* Initialize the free list of OS_EVENTs    */


//OS_MAX_FLAGS 最大任务事件标注组事件数目
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
    OS_FlagInit();                                               /* Initialize the event flag structures     */
#endif
//OS_MAX_MEM_PART 最大内存控制块数目
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
    OS_MemInit();                                                /* Initialize the memory manager            */
#endif
//OS_MAX_QS 最大队列事件数目
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
    OS_QInit();                                                  /* Initialize the message queue structures  */
#endif

    //初始化空闲任务
    OS_InitTaskIdle();                                           /* Create the Idle Task                     */
#if OS_TASK_STAT_EN > 0
    OS_InitTaskStat();                                           /* Create the Statistic Task                */
#endif

//钩子函数,初始化结束后的
#if OS_VERSION >= 204
    OSInitHookEnd();                                             /* Call port specific init. code            */
#endif
}

1.2系统中全局变量的初始化

因为Ucos是不允许创建相同的任务优先级的,所以在系统调度中OS_Sched(),获取了当前就绪表OSRdyGrp[]中最高优先级任务的优先级,通过任务优先级表OSTCBPrioTbl[ ]能很快获得任务控制块。

在这里插入图片描述

1.3系统中空闲控制链表的初始化

在这里插入图片描述

2.任务的创建

INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
参数
  task:任务函数指针
  pdata:向任务传递参数
  ptos:指向任务栈顶的指针,OS_STK_GROWTH设置为1,栈被认为是向下增长
  prio:任务优先级

INT8U  OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                  /* Allocate storage for CPU status register               */
    OS_CPU_SR  cpu_sr;
#endif
    OS_STK    *psp;
    INT8U      err;


#if OS_ARG_CHK_EN > 0
    if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
        return (OS_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    //防止其他任务创建相同优先级的任务
    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */  
        OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* Reserve the priority to prevent others from doing ...  */
                                             /* ... the same thing until task is created.              */
        OS_EXIT_CRITICAL();
        //任务堆栈初始化
        // R0-R12的初始化  指定LR返回地址为Task
        psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0);    /* Initialize the task's stack         */
        // 任务控制块的初始化
        err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
        //如果成功创建任务控制块
        if (err == OS_NO_ERR) {
            OS_ENTER_CRITICAL();
            // 创建的任务数目+1
            OSTaskCtr++;                                        /* Increment the #tasks counter        */
            OS_EXIT_CRITICAL();
            // 系统是否允许状态
            if (OSRunning == TRUE) {         /* Find highest priority task if multitasking has started */
                // 任务调度
                OS_Sched();
            }
        } else {
            OS_ENTER_CRITICAL();
            // 允许其它该优先级的任务可以创建
            OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others                 */
            OS_EXIT_CRITICAL();
        }
        return (err);
    }
    OS_EXIT_CRITICAL();
    return (OS_PRIO_EXIST);
}

INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U )
用户不能调用

INT8U  OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
{
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr;
#endif    
    OS_TCB    *ptcb;


    OS_ENTER_CRITICAL();
    // 获取空闲任务控制块链表 表头指针对应的任务控制块
    ptcb = OSTCBFreeList;                                  /* Get a free TCB from the free TCB list    */
    //是否成功获取任务控制块(空闲任务控制块链表 是否是最后一个)
    if (ptcb != (OS_TCB *)0) {
       // 空闲任务控制块链表 表头指针 后移
        OSTCBFreeList        = ptcb->OSTCBNext;            /* Update pointer to free TCB list          */
        OS_EXIT_CRITICAL();
        // 任务控制块初始话
        ptcb->OSTCBStkPtr    = ptos;                       /* Load Stack pointer in TCB                */
        ptcb->OSTCBPrio      = (INT8U)prio;                /* Load task priority into TCB              */
        ptcb->OSTCBStat      = OS_STAT_RDY;                /* Task is ready to run                     */
        ptcb->OSTCBDly       = 0;                          /* Task is not delayed                      */

#if OS_TASK_CREATE_EXT_EN > 0
        ptcb->OSTCBExtPtr    = pext;                       /* Store pointer to TCB extension           */
        ptcb->OSTCBStkSize   = stk_size;                   /* Store stack size                         */
        ptcb->OSTCBStkBottom = pbos;                       /* Store pointer to bottom of stack         */
        ptcb->OSTCBOpt       = opt;                        /* Store task options                       */
        ptcb->OSTCBId        = id;                         /* Store task ID                            */
#else
        pext                 = pext;                       /* Prevent compiler warning if not used     */
        stk_size             = stk_size;
        pbos                 = pbos;
        opt                  = opt;
        id                   = id;
#endif

#if OS_TASK_DEL_EN > 0
        ptcb->OSTCBDelReq    = OS_NO_ERR;
#endif
        // 任务优先级初始化 在这初始化方便后面获取任务优先级
        ptcb->OSTCBY         = prio >> 3;                  /* Pre-compute X, Y, BitX and BitY          */
        ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];
        ptcb->OSTCBX         = prio & 0x07;
        ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];

#if OS_EVENT_EN > 0
        ptcb->OSTCBEventPtr  = (OS_EVENT *)0;              /* Task is not pending on an event          */
#endif

#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0)
        ptcb->OSTCBFlagNode  = (OS_FLAG_NODE *)0;          /* Task is not pending on an event flag     */
#endif

#if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0))
        ptcb->OSTCBMsg       = (void *)0;                  /* No message received                      */
#endif

#if OS_VERSION >= 204
        // 创建TCB钩子函数
        OSTCBInitHook(ptcb);
#endif
        // 新建任务钩子函数
        OSTaskCreateHook(ptcb);                            /* Call user defined hook                   */

        OS_ENTER_CRITICAL();
        OSTCBPrioTbl[prio] = ptcb;
        // 将当前任务控制块指针 加入任务优先级表
        ptcb->OSTCBNext    = OSTCBList;                    /* Link into TCB chain                      */
        ptcb->OSTCBPrev    = (OS_TCB *)0;
        // 将已用任务控制块 连接成双向表
        if (OSTCBList != (OS_TCB *)0) {
            OSTCBList->OSTCBPrev = ptcb;
        }
        // 已用任务控制块链表 表头指向当前新加入的任务
        OSTCBList               = ptcb;
        // 任务就绪组 加入当前新加入的任务
        OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run                   */
       // 任务就绪表 加入当前新加入的任务
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);
    }
    OS_EXIT_CRITICAL();
    return (OS_NO_MORE_TCB);
}

创建一个任务后
在这里插入图片描述

3.系统启动 OSStart ()

void  OSStart (void)
{
    INT8U y;
    INT8U x;

    // 系统运行状态判断
    if (OSRunning == FALSE) {
        // 获取任务优先级最高的任务
        y             = OSUnMapTbl[OSRdyGrp];        /* Find highest priority's task priority number   */
        x             = OSUnMapTbl[OSRdyTbl[y]];
        OSPrioHighRdy = (INT8U)((y << 3) + x);
        // 因为系统刚启动,所以任务优先级最高的任务优先级 就是现在运行的任务优先级
        OSPrioCur     = OSPrioHighRdy;
        // 从任务优先级表 获取任务优先级最高的任务
        OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */
        //  因为系统刚启动,所以任务优先级最高的任务 就是现在运行的任务
        OSTCBCur      = OSTCBHighRdy;
        // 用户的钩子函数
        OSStartHighRdy();                            /* Execute target specific code to start task     */
    }
}
  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值