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

📄 msgbuf.c

📁 最近在國外網站抓到的作業系統 以Arm為基礎去開發的
💻 C
字号:
//*************************************************************************
//
//  Copyright (C) SEIKO EPSON CORP. 1997-1999
//  All Rights Reserved
//
//  Filename : msgbuf.c
//  Function : Message buffer functions
//  Revision :
//          1999/08/20  H.Matsuoka  start
//          1999/11/25  H.Matsuoka  Add isnd_mbf
//          2000/02/23  H.Matsuoka  Fix suspend status problem
//          2000/03/29  H.Matsuoka  Fix trcv_mbf problem
//          2000/11/29  Y.Taka      Replace Enter/Return_critical_section
//          2001/01/22  Y.Taka      Replace vfnAddTimer
//          2001/03/08  Y.Taka      Change critical section
//
//*************************************************************************
#include "Ros33.h"
#include "internal.h"


//********************************************************************
//  Send Message to MessageBuffer
//  [Parameters]
//      ID      mbfid   MessageBufferID
//      INT     msgsz   SendMessageSize (in bytes)
//      VP      msg     Start Address of Send Message Packet
//      TMO     tmout   Timeout
//  [Return Parameters]
//      ER      ercd    ErrorCode
//********************************************************************
ER tsnd_mbf
    (
    ID      mbfid,
    VP      msg,
    INT     msgsz,
    TMO     tmout
    )
{
    T_TSKCB*    pTskcb;
    T_MSGBUFCB* pMsgbufcb;
    
#ifndef NO_ERROR_CHECK    
    if((g_ubIntNestCnt != 0)        // issued from task-independent portions
    || (g_ubSysStat & TSS_DDSP))    // task in dispatch disabled state
    {   
        if (tmout != TMO_POL)
            return E_CTX;
    }

    if(mbfid <= 0)
    {
        return E_ID;
    }
    
    if(mbfid > MSGBUF_NUM)
    {
        return E_NOEXS;
    }
    
    if(msgsz <= 0)
    {
        return E_PAR;
    }
    
    if(tmout <= -2)
    {
        return E_PAR;
    }
#endif
    
    pMsgbufcb = &g_sMsgbufcb[mbfid-1];
    
#ifndef NO_ERROR_CHECK    
    if(pMsgbufcb->maxmsz == 0)
    {
        return E_NOEXS;
    }

    if(msgsz > pMsgbufcb->maxmsz)
        return E_PAR;
#endif

    /* check TTW_MBF task (call rcv_mbf task) */
    if(pMsgbufcb->pNxtTsk != (UW*)pMsgbufcb) {   // exist msgbuf wait task
        pTskcb = (T_TSKCB*)pMsgbufcb->pNxtTsk;

        /* set copy size to recive task info */
        *(int*)(pTskcb->msgsize) = msgsz;

        /* copy message to buffer of recive task */
        while(msgsz--){
            *((char*)(pTskcb->pMsgbuf))++ = *((char*)msg)++;
        }

        pTskcb->ubStatus &= ~TTS_WAI;  
        pTskcb->ubWaitStat &= ~TTW_MBF;

        /* set return value for wait task */
        ((T_SAVEDREG_MIN*)(pTskcb->uwSP))->r[10] = E_OK;

        /* clear time out task link */
        vfnDelInitMember((T_NODE*)&(pTskcb->pNxtTmoTsk));

        vfnDelAddMember((T_NODE*)&g_sReadyQueue[pTskcb->bPriority], 
                        (T_NODE*)pTskcb);

        int_dispatch();         // dispatch & disable interrupt
        return E_OK;

    }
    
    // copy messege to ring buffer
    if(ros_put_mbf(pMsgbufcb, msg, msgsz) == 1) 
    {
        return E_OK;
    }

    /* following buffer full case. wait until buffer is empty. */

    if (tmout == TMO_POL)
    {
        return E_TMOUT;
    }

    g_pCurTsk->ubStatus |= TTS_WAI;  
    g_pCurTsk->ubWaitStat |= TTW_SMBF;

    g_pCurTsk->pMsgbuf = msg;
    g_pCurTsk->msgsize = msgsz;

    vfnDelAddMember((T_NODE*)&(pMsgbufcb->pNxtSndTsk), 
                   (T_NODE*)g_pCurTsk);

    /* set time out */
    if(tmout != TMO_FEVR) {
        g_pCurTsk->utime = g_sSysTime.utime;
        if (g_sSysTime.ltime > g_sSysTime.ltime + tmout)
            g_pCurTsk->utime +=  1;
        g_pCurTsk->ltime = g_sSysTime.ltime + tmout;
        vfnAddTimer((T_NODE*)&(g_pCurTsk->pNxtTmoTsk));
    }
    

    int_dispatch();        // dispatch & disable interrupt
    MOV_R1TOR0;		// mov r1(from the returnvalue in the stack) to ro (in asm)
    return;         // return value is E_OK or E_RLWAI
                    // wakeup task set return value. 
}


//********************************************************************
//  Receive Message from MessageBuffer with Timeout
//  [Parameters]
//      ID      mbfid   MessageBufferID
//      VP      msg     Start Address of Receive Message Packet
//      TMO     tmout   Timeout
//  [Return Parameters]
//      ER      ercd    ErrorCode
//      INT     msgsz   ReceiveMessageSize (in bytes)
//********************************************************************
ER trcv_mbf
    (
    VP      msg, 
    INT     *p_msgsz, 
    ID      mbfid, 
    TMO     tmout 
    )
{
    T_TSKCB*    pTskcb;
    T_TSKCB*    pTskcb2;
    T_MSGBUFCB* pMsgbufcb;
    int         msgsize;
    
    
#ifndef NO_ERROR_CHECK    
    if((g_ubIntNestCnt != 0)        // issued from task-independent portions
    || (g_ubSysStat & TSS_DDSP))    // task in dispatch disabled state
    {   
        return E_CTX;
    }

    if(mbfid <= 0)
    {
        return E_ID;
    }
    
    if(mbfid > MSGBUF_NUM)
    {
        return E_NOEXS;
    }
    
    if(tmout <= -2)
    {
        return E_PAR;
    }

#endif

    pMsgbufcb = &g_sMsgbufcb[mbfid-1];

#ifndef NO_ERROR_CHECK    
    if(pMsgbufcb->maxmsz == 0)
    {
        return E_NOEXS;
    }
#endif

    /* get message from buffer */
    /* copy message to buffer of recive task */
    msgsize = ros_get_mbf(pMsgbufcb, msg);


    if(msgsize > 0) { 
        // message exist in buffer. get message !

        *p_msgsz = msgsize;

        if(pMsgbufcb->pNxtSndTsk == (UW*)&(pMsgbufcb->pNxtSndTsk)) {
            
            // buffer space wait task dose not exist 
            
            return E_OK;

        } else {

            // buffer space wait task exist (send task wait) 

            pTskcb = (T_TSKCB*)pMsgbufcb->pNxtSndTsk;

            do {
                if(ros_put_mbf(pMsgbufcb, pTskcb->pMsgbuf, pTskcb->msgsize)!=-1) {

                    /* wakeup TTW_SMBF wait task */
                    pTskcb->ubStatus &= ~TTS_WAI;  
                    pTskcb->ubWaitStat &= ~TTW_SMBF;

                    /* set return value for wait task */
                    ((T_SAVEDREG_MIN*)(pTskcb->uwSP))->r[10] = E_OK;  //GFD


                    /* save prv task */
                    pTskcb2 = (T_TSKCB*)(pTskcb->pPrvTsk);
                    
                    /* clear time out task link */
                    vfnDelInitMember((T_NODE*)&(pTskcb->pNxtTmoTsk));

                    /* add task to ready queue */
                    vfnDelAddMember((T_NODE*)&g_sReadyQueue[pTskcb->bPriority],
                                   (T_NODE*)pTskcb);

                    /* restore prv task pointer */
                    pTskcb = pTskcb2;
                }
                pTskcb = (T_TSKCB*)(pTskcb->pNxtTsk);

            } while(pTskcb != (T_TSKCB*)&(pMsgbufcb->pNxtSndTsk));

            int_dispatch();         // dispatch & disable interrupt
            return E_OK;
        }

    } else if(msgsize == -2) {
        // buffer size is 0 
        
        /* check TTW_SMBF task */
        if(pMsgbufcb->pNxtSndTsk != (UW*)&(pMsgbufcb->pNxtSndTsk)) {
            int i;
            
            pTskcb = (T_TSKCB*)pMsgbufcb->pNxtSndTsk;

            /* set message size */
            *p_msgsz = pTskcb->msgsize;
            
            /* copy message to recive task buffer */
            i = pTskcb->msgsize;
            while(i--){
                *((char*)msg)++ = *((char*)(pTskcb->pMsgbuf))++;
            }
        
            /* wakeup smbf wait task */
            pTskcb->ubStatus &= ~TTS_WAI;  
            pTskcb->ubWaitStat &= ~TTW_SMBF;

            /* set return value for wait task */
            ((T_SAVEDREG_MIN*)(pTskcb->uwSP))->r[10] = E_OK;
        
            /* clear time out task link */
            vfnDelInitMember((T_NODE*)&(pTskcb->pNxtTmoTsk));

            /* add task to ready queue */
            vfnDelAddMember((T_NODE*)&g_sReadyQueue[pTskcb->bPriority],
                           (T_NODE*)pTskcb);

            int_dispatch();         // dispatch & disable interrupt
            return E_OK;
        }
    }


    // message not exist in buffer. Wait message.

    if (tmout == TMO_POL)
    {
        return E_TMOUT;
    }

    /* set message pointer */
    g_pCurTsk->pMsgbuf = msg;
    g_pCurTsk->msgsize = (int)p_msgsz;

    /* clear wait status */
    g_pCurTsk->ubStatus |= TTS_WAI;  
    g_pCurTsk->ubWaitStat |= TTW_MBF;
    
    /* add task to msgbuf wait queue */
    vfnDelAddMember((T_NODE*)pMsgbufcb, (T_NODE*)g_pCurTsk);

    /* set time out */
    if(tmout != TMO_FEVR) {
        g_pCurTsk->utime = g_sSysTime.utime;
        if (g_sSysTime.ltime > g_sSysTime.ltime + tmout)
            g_pCurTsk->utime +=  1;
        g_pCurTsk->ltime = g_sSysTime.ltime + tmout;
        vfnAddTimer((T_NODE*)&(g_pCurTsk->pNxtTmoTsk));
    }

    int_dispatch();         // dispatch & disable interrupt
    MOV_R1TOR0;		// mov r1(from the returnvalue in the stack) to ro (in asm)    
    return;                 // return value is E_OK, E_RLWAI, E_TMOUT
                            // wakeup task set return value. 
}

⌨️ 快捷键说明

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