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

📄 ucos.c

📁 ucos在摩托罗拉16位微控制器68hc16上的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
*                                               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) {          /* No context switch if current task is highest ready */
            OSCtxSwCtr++;
            OSIntCtxSw();                        /* Perform interrupt level context switch             */
        }
    }
    OS_EXIT_CRITICAL();
}
/*
*********************************************************************************************************
*                                       CHANGE PRIORITY OF A TASK
*********************************************************************************************************
*/

UBYTE OSTaskChangePrio(UBYTE oldp, UBYTE newp)
{
    register OS_TCB   *ptcb;
    register 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         */
        }
    }
}
/*
*********************************************************************************************************
*                                            DELETE A TASK
*********************************************************************************************************
*/

UBYTE OSTaskDel(UBYTE p)
{
    register OS_TCB   *ptcb;
    register 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 */
            }
        }
        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);
    }
}
/*
*********************************************************************************************************
*                             DELAY TASK 'n' TICKS   (n from 1 to 65535)
*********************************************************************************************************
*/

void OSTimeDly(UWORD 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)
{
    register 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();
}

/*
*********************************************************************************************************
*                                           SET SYSTEM CLOCK
*********************************************************************************************************
*/

void OSTimeSet(ULONG ticks)
{
    OS_ENTER_CRITICAL();
    OSTime = ticks;
    OS_EXIT_CRITICAL();
}
/*
*********************************************************************************************************
*                                        GET CURRENT SYSTEM TIME
*********************************************************************************************************
*/

ULONG OSTimeGet(void)
{
    ULONG ticks;


    OS_ENTER_CRITICAL();
    ticks = OSTime;
    OS_EXIT_CRITICAL();
    return (ticks);
}
/*
*********************************************************************************************************
*                                         INITIALIZE SEMAPHORE
*********************************************************************************************************
*/

OS_EVENT *OSSemCreate(WORD cnt)
{
    register 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          */
    }
}
/*
*********************************************************************************************************
*                                           PEND ON SEMAPHORE
*********************************************************************************************************
*/

void OSSemPend(OS_EVENT *pevent, UWORD timeout, UBYTE *err)
{
    OS_ENTER_CRITICAL();
    if (pevent->OSEventCnt-- > 0) {              /* If semaphore is positive, resource available       */
        OS_EXIT_CRITICAL();
        *err = OS_NO_ERR;
    } else {                                     /* Otherwise, must wait until event occurs            */
        OSTCBCur->OSTCBStat     = OS_STAT_SEM;   /* Resource not available, pend on semaphore          */
        OSTCBCur->OSTCBDly      = timeout;       /* Store pend timeout in TCB                          */
        OSTCBCur->OSTCBEventPtr = pevent;        /* Store pointer to event control block in TCB        */
        if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {  /* Task no longer ready      */
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
        pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;      /* Put task in waiting list  */
        pevent->OSEventGrp                   |= OSTCBCur->OSTCBBitY;
        OS_EXIT_CRITICAL();
        OSSched();                               /* Find next highest priority task ready to run       */
        OS_ENTER_CRITICAL();
        if (OSTCBCur->OSTCBStat == OS_STAT_SEM) {     /* Must have timed out if still waiting for event*/
            if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {
                pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
            }
            OSTCBCur->OSTCBStat     = OS_STAT_RDY;    /* Set status to ready                           */
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;  /* Task is no longer waiting for the event       */
            OS_EXIT_CRITICAL();
            *err = OS_TIMEOUT;                   /* Indicate to caller that didn't get event within TO */
        } else {
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
            OS_EXIT_CRITICAL();
            *err = OS_NO_ERR;
        }
    }
}

/*
*********************************************************************************************************
*                                         POST TO A SEMAPHORE
*********************************************************************************************************
*/

⌨️ 快捷键说明

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