UC/OS II 基础函数的分析

一、UC/OS II代码:
①与硬件无关的内核代码
②与处理器有关的代码移植
③用户配置文件
在这里插入图片描述
二、主要函数
(1)OSInit()
在这里插入图片描述
(2)OSStart
在这里插入图片描述
(3)OSTaskCreate
在这里插入图片描述
(4)OSTimeDly
在这里插入图片描述
(5)OSTimeTick
在这里插入图片描述
(6)OSTaskDel
在这里插入图片描述
(7)OSIntEnter
在这里插入图片描述
(8)OSIntExit
在这里插入图片描述
(9)OS_ENTER_CRITICAL和OS_EXIT_CRITICAL
在这里插入图片描述
(10)OSSemCreate
在这里插入图片描述
(11)OSSemPend
在这里插入图片描述
(12)OSSemPost
在这里插入图片描述
(13)OSSemDel
在这里插入图片描述
三、最小内核
1.任务
①任务之间不能直接调用,也不能进行数据交换,需要通过内核进行任务调度和数据交换。
②任务状态:睡眠状态、就绪状态、运行状态、等待状态、被中断状态
在这里插入图片描述
2.OS初始化:调用OS-InitMisc()、OS-InitRdyList()[创建空闲任务]、OS-InitTCBList()、OS-InitTaskldle()四个函数。
3.获取并初始化TCB
在这里插入图片描述
4.启动OS

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;  //更变TCB指针
        OSStartHighRdy();                            /* Execute target specific code to start task     */
    }
}

5.中断初始化
μC/OS-Ⅱ要求在多任务环境启动之前不允许产生中断,所以通常会在第一个执行的任务中调用函数TargetInit()初始化中断系统和能够产生中断的外设。

void TargetInit(void)
{
    OS_ENTER_CRITICAL();
    VICInit(); //中断优先级初始化
    Timer0Init(); //定时器初始化,用于时钟节拍中断,检测任务超时
    OS_EXIT_CRITICAL();
}

6.延时任务切换
①延时函数

void  OSTimeDly (INT16U ticks) 
{
    if (ticks > 0) 
    {
        OS_ENTER_CRITICAL();
        if ((OSRdyTbl[OSTCBCur->OSTCBY] &= 
            ~OSTCBCur->OSTCBBitX) == 0)   /任务脱离就绪状态/
        {
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY; 
        } 
        OSTCBCur->OSTCBDly = ticks;   //设置延时的时间
        OS_EXIT_CRITICAL();
        OS_Sched(); //任务切换
    }
}

②任务切换

void  OS_Sched (void)
{
    INT8U      y;
    OS_ENTER_CRITICAL();  // 关闭中断
    if (OSIntNesting == 0) {  //判断是否处于中断状态
        y             = OSUnMapTbl[OSRdyGrp]; 
        OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);  //获取就绪态任务的最高优先级
        if (OSPrioHighRdy != OSPrioCur) {                 //判断当前任务是否为最高优先级 
            OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; // 就绪态优先级最高,获取TCB
            OS_TASK_SW(); //任务切换
        }
    }
    OS_EXIT_CRITICAL();
}

③OS_TASK_SW(); //

TASK_SW
    MRS     R3, SPSR 
    MOV     R2, LR     //获取软中断产生时的状态和返回地址
    MSR     CPSR_c, #(NoInt | SYS32Mode)  //状态切换
    STMFD   SP!, {R2}
    STMFD   SP!, {R0-R12, LR} //保护现场,寄存器入栈
    B       OSIntCtxSw_0 //调用子函数
    LDR     R4, =OSPrioCur
    LDR     R5, =OSPrioHighRdy
    LDRB   R6, [R5]
    STRB   R6, [R4]  //修改OSPrioCur
    LDR     R6, =OSTCBHighRdy
    LDR     R6, [R6]
    LDR     R4, =OSTCBCur
    STR     R6, [R4] //修改OSTCBCur
 

7.时钟节拍

void  OSTimeTick (void) 
{
    OS_TCB    *ptcb; 
    if (OSRunning == TRUE) ;  // 是否系统运行
    {
        ptcb = OSTCBList;      //获取TCB列表表头指针
        while (ptcb->OSTCBPrio != OS_IDLE_PRIO) {  //判断是否处于表尾
        OS_ENTER_CRITICAL();
            if (ptcb->OSTCBDly != 0);   //任务在等待时间事件
            {
                if (--ptcb->OSTCBDly  == 0);  //减少等待时间
                {
                    OSRdyGrp |= ptcb->OSTCBBitY;
                    OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; //使任务进入就绪态
                }
            }
            ptcb = ptcb->OSTCBNext; //处理下一个任务
            OS_EXIT_CRITICAL();	
        }
    }
}

8.删除任务

INT8U  OSTaskDel (INT8U prio)  //uc/os ii 没有时间轮转片,一个优先级对应一个任务,删除优先级就是删除任务
{
    OS_TCB       *ptcb;
    if (OSIntNesting > 0) {
        return (OS_TASK_DEL_ISR);
    }
    if (prio == OS_IDLE_PRIO) {   // 是否删除空闲任务
        return (OS_TASK_DEL_IDLE);
    }
    if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {  // 是否删除自身
        return (OS_PRIO_INVALID);
    }
    OS_ENTER_CRITICAL();
    if (prio == OS_PRIO_SELF) {
        prio = OSTCBCur->OSTCBPrio;
    }
    ptcb = OSTCBPrioTbl[prio];
    if (ptcb != (OS_TCB *)0) {
    if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {  //任务从就绪表中删除
            OSRdyGrp &= ~ptcb->OSTCBBitY;
        }
        ptcb->OSTCBDly	= 0;
        ptcb->OSTCBStat	= OS_STAT_RDY;
        OSTCBPrioTbl[prio] = (OS_TCB *)0;
        if (ptcb->OSTCBPrev == (OS_TCB *)0) { //任务从优先级列表中删除,tcb从tcb列表中删除
            ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
            OSTCBList                  = ptcb->OSTCBNext;
        } else {
            ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
            ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
        }
        ptcb->OSTCBNext = OSTCBFreeList;
        OSTCBFreeList   = ptcb;
        OS_EXIT_CRITICAL();
        OS_Sched();
        return (OS_NO_ERR);
    }
    OS_EXIT_CRITICAL();
    return (OS_TASK_DEL_ERR);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值