⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ucos.c

📁 ucos 在 Intel 196 单片机上的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
/*$PAGE*/
/*
******************************************************************************
*                                 ENTER ISR
******************************************************************************
*/
void OSIntEnter(void)
{
    OS_ENTER_CRITICAL();
    OSIntNesting++;                           /* Increment ISR nesting level */
    OS_EXIT_CRITICAL();
}

/*
******************************************************************************
*                                 EXIT ISR
******************************************************************************
*/
void OSIntExit(void)
{
    OS_ENTER_CRITICAL();
    if ((--OSIntNesting | OSLockNesting) == 0)
    {                  /* Reschedule only if all ISRs completed & not locked */
        OSIntExitY = OSUnMapTbl[OSRdyGrp];
        OSTCBHighRdy = OSTCBPrioTbl[(OSIntExitY << 3) + 
                                             OSUnMapTbl[OSRdyTbl[OSIntExitY]]];
        if ((OSTCBHighRdy != OSTCBCur) && OSRunning)
        {              /* No context switch if current task is highest ready */
#if USE_DEBUG
            OSCtxSwCtr++;
#endif /*USE_DEBUG*/
            OSIntCtxSw();          /* Perform interrupt level context switch */
        }
    }
    OS_EXIT_CRITICAL();
}

/*$PAGE*/
#if USE_CHG_PRIORITY
/*
******************************************************************************
*                          CHANGE PRIORITY OF A TASK
******************************************************************************
*/
BYTE OSTaskChangePrio(BYTE oldp, BYTE newp)
{
OS_TCB   *ptcb;
OS_EVENT *pevent;
BOOLEAN   rdy;


    OS_ENTER_CRITICAL();
    if (OSTCBPrioTbl[newp] != (OS_TCB *)0)
    {                                 /* New priority must not already exist */
        OS_EXIT_CRITICAL();
        return (OS_PRIO_EXIST);
    } else
    {
        if ((ptcb = OSTCBPrioTbl[oldp]) != (OS_TCB *)0)
        {                                       /* Task to change must exist */
            OSTCBPrioTbl[oldp] = (OS_TCB *)0; /* Remove TCB from old priority */
            pevent = ptcb->OSTCBEventPtr;/*Get pointer to event control block*/
            if (OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX)
            {                          /* If task is ready make it not ready */
                if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
                {
                    OSRdyGrp &= ~ptcb->OSTCBBitY;
                }
                rdy = TRUE;
            } else
            {
                rdy = FALSE;
                if (pevent != (OS_EVENT *)0)
                {                            /* Remove from event wait list */
                    if ((pevent->OSEventTbl[ptcb->OSTCBY]
                                                    &= ~ptcb->OSTCBBitX) == 0)
                    {
                        pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
                    }
                }
            }
            if (ptcb->OSTCBPrev == (OS_TCB *)0)
            {                                      /* Remove from TCB chain */
                ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
                OSTCBList = ptcb->OSTCBNext;
            } else
            {
                ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
                ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
            }
            OS_EXIT_CRITICAL();
            ptcb->OSTCBPrio = newp;              /* Setup task control block */
            ptcb->OSTCBY = newp >> 3;      /* ... other fields are unchanged */
            ptcb->OSTCBBitY = OSMapTbl[newp >> 3];
            ptcb->OSTCBX = newp & 0x07;
            ptcb->OSTCBBitX = OSMapTbl[newp & 0x07];
            OS_ENTER_CRITICAL();
            if (rdy)
            {                                       /* If task was ready ... */
                OSRdyGrp |= ptcb->OSTCBBitY;
                                      /* ... make new priority ready to run  */
                OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
            } else
            {
                if (pevent != (OS_EVENT *)0)
                {                           /* Wait for event if was waiting */
                    pevent->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
                    pevent->OSEventGrp |= ptcb->OSTCBBitY;
                }
            }
            OSTCBPrioTbl[newp] = ptcb;/* Place pointer to TCB @ new priority */
            OSTCBList->OSTCBPrev = ptcb;  /* Link OS_TCB to OS_TCB chain ... */
            OSTCBList = ptcb;          /* ... we assume idle task is present */
            OS_EXIT_CRITICAL();
            OSSched();                    /* Run highest priority task ready */
            return (OS_NO_ERR);
        } else
        {
            OS_EXIT_CRITICAL();
            return (OS_PRIO_ERR);             /* Task to change didn't exist */
        }
    }
}
#endif /*USE_CHG_PRIORITY*/

/*$PAGE*/
/*
******************************************************************************
*                               DELETE A TASK
******************************************************************************
*/
BYTE OSTaskDel(BYTE p)
{
OS_TCB   *ptcb;
OS_EVENT *pevent;

    if (p == OS_LO_PRIO)
    {                                     /* Not allowed to delete idle task */
        return (OS_TASK_DEL_IDLE);
    }
    OS_ENTER_CRITICAL();
    if ((ptcb = OSTCBPrioTbl[p]) != (OS_TCB *)0)
    {                                           /* Task to delete must exist */
        OSTCBPrioTbl[p] = (OS_TCB *)0;           /* Clear old priority entry */
        if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
        {                                             /* Make task not ready */
            OSRdyGrp &= ~ptcb->OSTCBBitY;
        }
        if (ptcb->OSTCBPrev == (OS_TCB *)0)
        {                                           /* Remove from TCB chain */
            ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
            OSTCBList = ptcb->OSTCBNext;
        } else
        {
            ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
            ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
        }
        if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0)
        {                                     /* If task is waiting on event */
            if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
            {                                        /* ... remove task from */
                pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
                                                     /* ... event ctrl block */
            }
        }
        if ((pevent = ptcb->OSTCBEvent2Ptr) != (OS_EVENT *)0)
        {                                     /* If task is waiting on event */
            if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
            {                                        /* ... remove task from */
                pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
                                                     /* ... event ctrl block */
            }
        }
        ptcb->OSTCBNext = OSTCBFreeList;      /* Return TCB to free TCB list */
        OSTCBFreeList = ptcb;
        OS_EXIT_CRITICAL();
        OSSched();                         /* Find new highest priority task */
        return (OS_NO_ERR);
    } else
    {
        OS_EXIT_CRITICAL();
        return (OS_TASK_DEL_ERR);
    }
}

/*$PAGE*/
/*
******************************************************************************
*                 DELAY TASK 'n' TICKS   (n from 1 to 65535)
******************************************************************************
*/
void OSTimeDly(WORD ticks)
{
    if (ticks > 0)
    {
        OS_ENTER_CRITICAL();
        if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
        {                                              /* Delay current task */
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
        OSTCBCur->OSTCBDly = ticks;                     /* Load ticks in TCB */
        OS_EXIT_CRITICAL();
        OSSched();
    }
}

/*
******************************************************************************
*                            PROCESS SYSTEM TICK
******************************************************************************
*/
void OSTimeTick(void)
{
OS_TCB *ptcb;

    ptcb = OSTCBList;                      /* Point at first TCB in TCB list */
    while (ptcb->OSTCBPrio != OS_LO_PRIO)
    {                                     /* Go through all TCBs in TCB list */
        OS_ENTER_CRITICAL();
        if (ptcb->OSTCBDly != 0)
        {                            /* Delayed or waiting for event with TO */
            if (--ptcb->OSTCBDly == 0)
            {                      /* Decrement nbr of ticks to end of delay */
                OSRdyGrp |= ptcb->OSTCBBitY;
                                 /* Make task ready to run (timer timed out) */
                OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
            }
        }
        OS_EXIT_CRITICAL();
        ptcb = ptcb->OSTCBNext;             /* Point at next TCB in TCB list */
    }
    OS_ENTER_CRITICAL();
    OSTime++;
    OS_EXIT_CRITICAL();
}

/*$PAGE*/
/*
******************************************************************************
*                              SET SYSTEM CLOCK
******************************************************************************
*/
void OSTimeSet(LONG ticks)
{
    OS_ENTER_CRITICAL();
    OSTime = ticks;
    OS_EXIT_CRITICAL();
}

/*
******************************************************************************
*                            GET CURRENT SYSTEM TIME
******************************************************************************
*/
LONG OSTimeGet(void)
{
LONG ticks;

    OS_ENTER_CRITICAL();
    ticks = OSTime;
    OS_EXIT_CRITICAL();
    return (ticks);
}

/*$PAGE*/
#if USE_SEMA
/*
******************************************************************************
*                          INITIALIZE SEMAPHORE
******************************************************************************
*/
OS_EVENT *OSSemCreate(SWORD cnt)
{
OS_EVENT *pevent;

    OS_ENTER_CRITICAL();
    pevent = OSEventFreeList;           /* Get next free event control block */
    if (OSEventFreeList != (OS_EVENT *)0)
    {                              /* See if pool of free ECB pool was empty */
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
    }
    OS_EXIT_CRITICAL();
    if (pevent != (OS_EVENT *)0)
    {                                          /* Get an event control block */
        if (cnt >= 0)
        {                                 /* Semaphore cannot start negative */
            pevent->OSEventCnt    = cnt;              /* Set semaphore value */
            pevent->OSEventGrp    = 0x00;
                                   /* Initialize rest of event control block */
            pevent->OSEventTbl[0] = 0x00;
            pevent->OSEventTbl[1] = 0x00;
            pevent->OSEventTbl[2] = 0x00;
            pevent->OSEventTbl[3] = 0x00;
            pevent->OSEventTbl[4] = 0x00;
            pevent->OSEventTbl[5] = 0x00;
            pevent->OSEventTbl[6] = 0x00;
            pevent->OSEventTbl[7] = 0x00;
            return (pevent);
        } else
        {
            OS_ENTER_CRITICAL();      /* Return event control block on error */
            pevent->OSEventPtr = (void *)OSEventFreeList;
            OSEventFreeList    = pevent;
            OS_EXIT_CRITICAL();
            return ((OS_EVENT *)0);
        }
    } else
    {
        return ((OS_EVENT *)0);           /* Ran out of event control blocks */
    }
}

/*
******************************************************************************
*                          Set Semaphore
******************************************************************************
*/
void OSSetSema(OS_EVENT *pevent, SWORD value)
{
   pevent->OSEventCnt = value;                        /* Set semaphore value */
}

/*
******************************************************************************
*                             POST TO A SEMAPHORE
******************************************************************************
*/
BYTE OSSemPost(OS_EVENT *pevent)
{
    OS_ENTER_CRITICAL();
    if (pevent->OSEventCnt < 32766)
    {                               /* Make sure semaphore will not overflow */
        if (pevent->OSEventCnt++ >= 0)
        {
            OS_EXIT_CRITICAL();
        } else
        {                  /* Negative semaphore value means task(s) pending */
            if (pevent->OSEventGrp)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -