📄 msgbuf.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 + -