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

📄 os.c

📁 ucos on sa1200 from ixp1200 EB
💻 C
📖 第 1 页 / 共 2 页
字号:
} /* OSTimeGet */


static void
OSEventTaskResume(OS_EVENT *pevent)
{
    unsigned int intFlagsSave;
    uint    x, y, bitx, bity, p;
    OS_TCB  *ptcb;

    intFlagsSave = ENTER_CRITICAL(); 
    /* find highest priority task pending on event */
    y = OSUnMapTbl[pevent->OSEventGrp];
    bity = OSMapTbl[y];
    x = OSUnMapTbl[pevent->OSEventTbl[y]];
    bitx = OSMapTbl[x];
    p = (y << 3) + x;
    /* remove task from waiting list */
    if ((pevent->OSEventTbl[y] &= ~bitx) == 0)
        pevent->OSEventGrp &= ~bity;
    /* pointer to new task */ 
    ptcb = OSTCBPrioTbl[p];
    /* reset timeout */
    ptcb->OSTCBDly = 0;
    /* task is ready to run */
    ptcb->OSTCBStat = OS_STAT_RDY;
    /* unlink control block */
    ptcb->OSTCBEventPtr = (OS_EVENT *)0;
    /* put task in ready to run list */
    OSRdyGrp |= bity;
    OSRdyTbl[y] |= bitx;
    EXIT_CRITICAL(intFlagsSave); 
} /* OSEventTaskResume */


/* create a semaphore */
OS_EVENT*
OSSemCreate(int value)
{
    unsigned int intFlagsSave;
    OS_EVENT    *pevent;

    if (value < 0) /* semaphore cannot start negative */
        return((OS_EVENT*)0);
    intFlagsSave = ENTER_CRITICAL();
    /* get next available event CB */
    if ((pevent = OSEventFreeList) != 0)
    {
        /* update free list */
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
        /* set semaphore values */
        pevent->OSEventCnt = value;
        pevent->OSEventGrp = 0;
        pevent->OSEventTbl[0] = 0;
        pevent->OSEventTbl[1] = 0;
        pevent->OSEventTbl[2] = 0;
        pevent->OSEventTbl[3] = 0;
        pevent->OSEventTbl[4] = 0;
        pevent->OSEventTbl[5] = 0;
        pevent->OSEventTbl[6] = 0;
        pevent->OSEventTbl[7] = 0;
    }

    EXIT_CRITICAL(intFlagsSave);
    return(pevent);
} /* OSSemCreate */


/* signal semaphore */
uint        
OSSemPost(OS_EVENT *pevent)
{
    unsigned int intFlagsSave;

    intFlagsSave = ENTER_CRITICAL();

    if (pevent->OSEventCnt >= OS_INT_MAX) {
        /* semaphore overflow */
        EXIT_CRITICAL(intFlagsSave);
        return(OS_SEM_OVF);
    }
    /* negative semaphore means tasks pending */
    if ((pevent->OSEventCnt++ < 0) && (pevent->OSEventGrp)) {
        /* resume highest priority task pending on semaphore */
        OSEventTaskResume(pevent);

        if (intFlagsSave & IRQ_INT)
        {
            /* This routine has been called within ISR */
            taskReSched = 1; /* Need to do task re-schedule later */
            EXIT_CRITICAL(intFlagsSave);
        }
        else
        {
            EXIT_CRITICAL(intFlagsSave);
            OSSched();
        }
    } else {
        EXIT_CRITICAL(intFlagsSave);
    }
    return(OS_NO_ERR);
} /* OSSemPost */


/* wait semaphore */
void        
OSSemPend(OS_EVENT *pevent, uint timeout, uint *err)
{
    unsigned int intFlagsSave;

    intFlagsSave = ENTER_CRITICAL();
    if (pevent->OSEventCnt-- > 0) {
        /* resource available */
        EXIT_CRITICAL(intFlagsSave);
        if (err != 0)
            *err = OS_NO_ERR;
        return;
    }
    /* resource not available, sleep on semaphore */
    OSTCBCur->OSTCBStat = OS_STAT_SEM;
    OSTCBCur->OSTCBDly = timeout;
    OSTCBCur->OSTCBEventPtr = pevent;
    /* suspend task */
    if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
        OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
    pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
    pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
    EXIT_CRITICAL(intFlagsSave);
    /* find next task ready to run */
    OSSched();
    intFlagsSave = ENTER_CRITICAL();
    if (OSTCBCur->OSTCBStat == OS_STAT_SEM) {
        /* still pending on semaphore: timeout */
        if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= 
                        ~OSTCBCur->OSTCBBitX) ==0)
            pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
        OSTCBCur->OSTCBStat = OS_STAT_RDY;
        /* no longer waiting for event */
        OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
        /* signal timeout */
        if (err != 0)
            *err = OS_TIMEOUT;
    }
    else {
        if (err != 0)
            *err = OS_NO_ERR;
    }
    EXIT_CRITICAL(intFlagsSave);
} /* OSSemPend */


/* create mailbox */
OS_EVENT*
OSMboxCreate(void *msg)
{
    unsigned int intFlagsSave;
    OS_EVENT    *pevent;

    intFlagsSave = ENTER_CRITICAL();
    /* get next available event CB */
    if ((pevent = OSEventFreeList) != 0)
    {
        /* update free list */
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
        /* set mailbox values */
        pevent->OSEventPtr = msg;
        pevent->OSEventGrp = 0;
        pevent->OSEventTbl[0] = 0;
        pevent->OSEventTbl[1] = 0;
        pevent->OSEventTbl[2] = 0;
        pevent->OSEventTbl[3] = 0;
        pevent->OSEventTbl[4] = 0;
        pevent->OSEventTbl[5] = 0;
        pevent->OSEventTbl[6] = 0;
        pevent->OSEventTbl[7] = 0;
    }

    EXIT_CRITICAL(intFlagsSave);
    return(pevent);
} /* OSMBoxCreate */


/* post mbox message */
uint        
OSMboxPost(OS_EVENT *pevent, void *msg)
{
    unsigned int intFlagsSave;

    intFlagsSave = ENTER_CRITICAL();
    /* make sure mailbox doesn't contain a message */
    if (pevent->OSEventPtr != (void *)0) {
        EXIT_CRITICAL(intFlagsSave);
        return(OS_MBOX_FULL);
    }
    /* place message in mailbox */
    pevent->OSEventPtr = msg;
    /* see if any task is pending on the mailbox */
    if (pevent->OSEventGrp) {
        /* resume highest priority task pending on mailbox */
        OSEventTaskResume(pevent);

        if (intFlagsSave & IRQ_INT)
        {
            /* This routine has been called within ISR */
            taskReSched = 1; /* Need to do task re-schedule later */
            EXIT_CRITICAL(intFlagsSave);
        }
        else
        {
            EXIT_CRITICAL(intFlagsSave);
            OSSched();
        }
    } else {
        EXIT_CRITICAL(intFlagsSave);
    }
    return(OS_NO_ERR);
} /* OSMboxPost */


/* pend for mbox message */
void*
OSMboxPend(OS_EVENT *pevent, uint timeout, uint *err)
{
    unsigned int intFlagsSave;
    void    *msg;

    intFlagsSave = ENTER_CRITICAL();
    /* check if the mailbox already has a message */
    if ((msg = pevent->OSEventPtr) != (void *)0) {
        /* clear the mailbox */
        pevent->OSEventPtr = (void *)0;
        EXIT_CRITICAL(intFlagsSave);
        if (err != 0)
            *err = OS_NO_ERR;
        /* return mailbox content */
        return(msg);
    }
    /* resource not available, sleep on mailbox */
    OSTCBCur->OSTCBStat = OS_STAT_MBOX;
    OSTCBCur->OSTCBDly = timeout;
    OSTCBCur->OSTCBEventPtr = pevent;
    /* suspend task */
    if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
        OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
    pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
    pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
    EXIT_CRITICAL(intFlagsSave);
    /* find next task ready to run */
    OSSched();
    intFlagsSave = ENTER_CRITICAL();
    if (OSTCBCur->OSTCBStat == OS_STAT_MBOX) {
        /* still pending on mailbox: timeout */
        if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &=
                            ~OSTCBCur->OSTCBBitX) == 0)
            pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
        OSTCBCur->OSTCBStat = OS_STAT_RDY;
        /* no longer waiting for event */
        OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
        /* set message content to null */
        msg = (void *)0;
        /* signal timeout */
        if (err != 0)
            *err = OS_TIMEOUT;
    }
    else {
        /* message received */
        msg = pevent->OSEventPtr;
        /* clear the mailbox */
        pevent->OSEventPtr = (void *)0;
        if (err != 0)
            *err = OS_NO_ERR;
    }
    EXIT_CRITICAL(intFlagsSave);
    return(msg);
} /* OSMBoxPend */


/* create a queue */
OS_EVENT*
OSQCreate(void **start, uint size)
{
    unsigned int intFlagsSave;
    OS_EVENT    *pevent;
    OS_Q        *pq;

    intFlagsSave = ENTER_CRITICAL();
    /* get next available event CB */
    if ((pevent = OSEventFreeList) == (OS_EVENT*)0) {
        /* ran out of event CB */
        EXIT_CRITICAL(intFlagsSave);
        return((OS_EVENT *)0);  
    }
    /* get next available queue CB */
    if ((pq = OSQFreeList) == (OS_Q *)0) {
        /* ran out of queue CB */
        EXIT_CRITICAL(intFlagsSave);
        return((OS_EVENT *)0);
    }
    /* update free list */
    OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
    OSQFreeList = OSQFreeList->OSQPtr;

    /* initialize the queue */
    pq->OSQStart = start;
    pq->OSQEnd = &start[size];
    pq->OSQIn = start;
    pq->OSQOut = start;
    pq->OSQSize = size;
    pq->OSQEntries = 0;
    pevent->OSEventPtr = pq;
    pevent->OSEventGrp = 0;
    pevent->OSEventTbl[0] = 0;
    pevent->OSEventTbl[1] = 0;
    pevent->OSEventTbl[2] = 0;
    pevent->OSEventTbl[3] = 0;
    pevent->OSEventTbl[4] = 0;
    pevent->OSEventTbl[5] = 0;
    pevent->OSEventTbl[6] = 0;
    pevent->OSEventTbl[7] = 0;

    EXIT_CRITICAL(intFlagsSave);
    return(pevent);
} /* OSQCreate */


/* post a message to a queue */
uint        
OSQPost(OS_EVENT *pevent, void *msg)
{
    unsigned int intFlagsSave;
    OS_Q *pq;

    intFlagsSave = ENTER_CRITICAL();
    pq = (OS_Q*)(pevent->OSEventPtr);
    /* make sure the queue is not full */
    if (pq->OSQEntries >= pq->OSQSize) {
        EXIT_CRITICAL(intFlagsSave);
        return(OS_Q_FULL);
    }
    /* insert message into queue */
    *pq->OSQIn++ = msg;
    pq->OSQEntries++;
    if (pq->OSQIn == pq->OSQEnd)
        /* wrap around In pointer if reached end */
        pq->OSQIn = pq->OSQStart;

    /* see if any task is pending on the queue */
    if (pevent->OSEventGrp) {
        /* resume highest priority task pending on queue */
        OSEventTaskResume(pevent);

        if (intFlagsSave & IRQ_INT)
        {
            /* This routine has been called within ISR */
            taskReSched = 1; /* Need to do task re-schedule later */
            EXIT_CRITICAL(intFlagsSave);
        }
        else
        {
            EXIT_CRITICAL(intFlagsSave);
            OSSched();
        }
    } else {
        EXIT_CRITICAL(intFlagsSave);
    }
    return(OS_NO_ERR);
} /* OSQPost */


/* pend for message from a queue */
void*
OSQPend(OS_EVENT *pevent, uint timeout, uint *err)
{
    unsigned int intFlagsSave;
    void *msg;
    OS_Q *pq;

    intFlagsSave = ENTER_CRITICAL();
    pq = (OS_Q *)(pevent->OSEventPtr);
    /* check if the queue already has a message */
    if (pq->OSQEntries != 0) {
        /* extract the message */
        msg = *pq->OSQOut++;
        /* update message counter */
        pq->OSQEntries--;
        /* wrap around Out pointer if reached end */
        if (pq->OSQOut == pq->OSQEnd)
            pq->OSQOut = pq->OSQStart;
        EXIT_CRITICAL(intFlagsSave);
        if (err != 0)
            *err = OS_NO_ERR;
        return(msg);
    }
    /* no messages available, sleep on the queue */
    OSTCBCur->OSTCBStat = OS_STAT_Q;
    OSTCBCur->OSTCBDly = timeout;
    /* suspend task */
    if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
        OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
    pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
    pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
    EXIT_CRITICAL(intFlagsSave);
    /* find next task ready to run */
    OSSched();
    intFlagsSave = ENTER_CRITICAL();
    if (OSTCBCur->OSTCBStat == OS_STAT_Q) {
        /* still pending on queue: timeout */
        if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &=
                                                ~OSTCBCur->OSTCBBitX) == 0)
                        pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
        OSTCBCur->OSTCBStat = OS_STAT_RDY;
        /* no longer waiting for event */
        OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
        /* set message content to null */
        msg = (void *)0;
        /* signal timeout */
        if (err != 0)
            *err = OS_TIMEOUT;
    }
    else {
        /* message received */
        msg = *pq->OSQOut++;
        /* update message counter */
        pq->OSQEntries--;
        /* wrap around Out pointer if reached end */
        if (pq->OSQOut == pq->OSQEnd)
            pq->OSQOut = pq->OSQStart;
        if (err != 0)
            *err = OS_NO_ERR;
    }
    
    EXIT_CRITICAL(intFlagsSave);
    return(msg);
} /* OSQPend */

/*******************************************************************************
*
* sysMemVirtSize - get sizes of virtual memory regions
*
* This routine returns sizes of virtual memory regions.
* 
* void sysMemVirtSize
*     (
*     unsigned int* sys,     // Size of memory mapped at zero for uC/OS 
*     unsigned int* sys_all, // Size of memory mapped at zero and usable by uC/OS 
*     unsigned int* sdram,   // Size of memory mapped at C0000000 and usable by HW
*     unsigned int* sram,    // Size of sram
*     unsigned int* flash    // Size of Flash 
*     )
*
* SYS_ALL is the actual amount of memory mapped to virtual address
* zero from the SDRAM. Some amount of the top end of this may be
* reserved by users, so the amount actually available to uC/OS
* is given by SYS. The size SDRAM which is available to the HW and 
* not used by uC/OS (mapped with virt addr == phys addr) is given
* by SDRAM.
*

*
* RETURNS: N/A
*/

void sysMemVirtSize(unsigned int* sys, unsigned int* sys_all, unsigned int* sdram,
                    unsigned int* sram, unsigned int* flash)
{
    /* Size of memory mapped at zero for UCOS */
    // 32 - 24 mBytes (24 is for MEngine communications)
    *sys_all = DRAM_SIZE; 

    /* Size of memory mapped at zero and usable by UCOS */
    *sys = DRAM_SIZE;

    /* Size of memory mapped at C0000000 and usable by HW */
    // 24 MB for MEngine communications
    *sdram = DRAMBaseForUEngSize;

    /* Size of sram **/
    // 0x200000 (2 mb)
    *sram = SRAM_SIZE;

    /* Size of Flash */
    // 0x4000
    *flash = FLASH_SIZE;
}

/* end of file */

⌨️ 快捷键说明

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