📄 jbuffer.c
字号:
gRxPGTable[RX_PGN_TPCM].mDataLength =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength;
gRxPGTable[RX_PGN_TPCM].mPDUF =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUF;
gRxPGTable[RX_PGN_TPCM].mPDUS =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUS;
gRxPGTable[RX_PGN_TPCM].mSource =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mSource;
memcpy((char*)gRxPGTable[RX_PGN_TPCM].mData,
(char*)stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mData,
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength);
break;
case 0xEB: /* TPDT PGN */
gRxPGTable[RX_PGN_TPDT].mPGState = PG_RX_FULL;
gRxPGTable[RX_PGN_TPDT].mDataLength =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength;
gRxPGTable[RX_PGN_TPDT].mPDUF =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUF;
gRxPGTable[RX_PGN_TPDT].mPDUS =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUS;
gRxPGTable[RX_PGN_TPDT].mSource =
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mSource;
memcpy((char*)gRxPGTable[RX_PGN_TPDT].mData,
(char*)stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mData,
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength);
break;
case 0xE8: /* ACK PGN */
/* not handled here */
break;
default:
break;
} /* switch */
/* now release the Queueu element */
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].Used = 0;
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPGState = PG_RX_FREE;
/* resetting read pointer - wrap around */
if((++stPGNBuffer.mRxQueueReadPtr) >= MAX_RX_QUEUESIZE)
stPGNBuffer.mRxQueueReadPtr = 0;
return 1;
} /* if */
return 0;
} /* gCB_DequeueElm() */
/*!
\brief Enqueues a Message to the RX System PG Queue
This function is called from the buffer module to generate a PG from the
a Message.
*/
/*!
\param msg ptr to a message from which the PG has to be generated
\retval 1 if PG was generated an Enqueued
\retval 0 if PG could't genearted or Queue was full */
unsigned char gCB_EnqueueElm(const CAN_MSG* msg)
{
if(((stPGNBuffer.mRxQueueWritePtr+1) == stPGNBuffer.mRxQueueReadPtr)
|| ((stPGNBuffer.mRxQueueReadPtr+MAX_RX_QUEUESIZE-1) == stPGNBuffer.mRxQueueWritePtr))
{
return 0; /* queue full!! */
} /* if */
else
{
lCB_GenPGN(&stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueWritePtr].mPGN,msg);
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueWritePtr].Used = 1;
stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueWritePtr].Overrun = 0;
/* resetting write pointer - wrap around */
if(((++stPGNBuffer.mRxQueueWritePtr) >= MAX_RX_QUEUESIZE) && (stPGNBuffer.mRxQueueReadPtr != 0))
stPGNBuffer.mRxQueueWritePtr = 0;
return 1;
} /* else */
} /* gCB_EnqueueElm() */
/*!
\brief Signals the stack the successful transmission of a PG
This function will be called from the CAN interrupt service routine,
if a transmit interrupt occured. The control data structure will
be reseted
*/
void gCB_SignalTx(void)
{
# if (USE_HASHTABLE == 1)
if(stPGNBuffer.TxPGN.Requested)
{
stPGNBuffer.TxPGN.Requested = 0; /* resetting the TX flags */
stPGNBuffer.TxPGN.ptPGN->mPGState = PG_TX_TX;
stPGNBuffer.TxPGN.ptPGN = NULL;
stPGNBuffer.TxPGN.Used = 0;
} /* if */
# else
if(stPGNBuffer.TxPGNBuff.Requested)
{
stPGNBuffer.TxPGNBuff.ptPGN->mPGState = PG_TX_TX;
stPGNBuffer.TxPGNBuff.Requested = 0;
stPGNBuffer.TxPGNBuff.Used = 0;
stPGNBuffer.reqPGN = INVAL_INDEX;
stPGNBuffer.PGType = INVAL_BUFFER;
}
#endif /* USE_HASHTABLE */
} /* gCB_SignalTx */
/*!
\brief Transmit a System PG to the CAN bus
This function is called from the protocol stack to send a PGN over the
CAN bus.
*/
/*!
Allocate a PGN into the buffer
\param pg is a PG ptr to transmit
\retval 0 if message was successful tranmitted
\retval 1 if message could not transmit
*/
unsigned char gCB_SendSysPG(VJ1939PGN* pg)
{
CAN_MSG msg;
unsigned char retVal;
# if (USE_HASHTABLE == 1)
/* if buffer is not used */
if((!stPGNBuffer.TxPGN.Used) && (!stPGNBuffer.TxPGN.Requested))
{
lCB_GenMessage(pg,&msg); /* make a CAN message from the PG */
stPGNBuffer.PGType = TX_SYS_BUFF;
stPGNBuffer.TxPGN.ptPGN = pg; /* hold the message in the buffer */
stPGNBuffer.TxPGN.Used = 1;
stPGNBuffer.TxPGN.Overrun = 0;
stPGNBuffer.TxPGN.ptPGN->mPGState = PG_TX_XMT;
stPGNBuffer.TxPGN.Requested = 1;
retVal = gCan_SendMsg(&msg); /* send CAN message */
if(!retVal)
{
/* successful send */
return 1;
}
stPGNBuffer.TxPGN.Requested = 0;
stPGNBuffer.TxPGN.Used = 0;
stPGNBuffer.TxPGN.ptPGN->mPGState = PG_TX_REQ;
stPGNBuffer.PGType = INVAL_BUFFER;
stPGNBuffer.TxPGN.ptPGN = NULL;
stPGNBuffer.TxPGN.Overrun = 1;
}
# else
if((!stPGNBuffer.TxPGNBuff.Used) && (!stPGNBuffer.TxPGNBuff.Requested)
&& (stPGNBuffer.PGType == INVAL_BUFFER))
{
lCB_GenMessage(pg,&msg); /* make a CAN message from the PG */
stPGNBuffer.PGType = TX_SYS_BUFF;
stPGNBuffer.TxPGNBuff.ptPGN = pg;
stPGNBuffer.TxPGNBuff.Used = 1;
stPGNBuffer.TxPGNBuff.Overrun = 0;
stPGNBuffer.TxPGNBuff.Requested = 1;
stPGNBuffer.TxPGNBuff.ptPGN->mPGState = PG_TX_XMT;
retVal = gCan_SendMsg(&msg); /* send message */
if(!retVal)
{
/* successful send */
return 1;
}
stPGNBuffer.TxPGNBuff.Overrun = 1;
stPGNBuffer.TxPGNBuff.Used = 0;
stPGNBuffer.TxPGNBuff.ptPGN->mPGState = PG_TX_REQ;
stPGNBuffer.TxPGNBuff.Requested = 0;
stPGNBuffer.PGType = INVAL_BUFFER;
stPGNBuffer.TxPGNBuff.ptPGN = NULL;
} /* if */
# endif /* USE_HASHTABLE */
return 0;
}
/*!
\brief Transmit a User PG to the CAN bus
This function is called from the protocol stack to send a PGN over the
CAN bus.
*/
/*!
Allocate a PGN into the buffer
\param pg is a PG ptr to transmit
\retval 0 if transmission is activated
\retval 1 if message could not transmit
*/
unsigned char gCB_SendUserPG(VJ1939PGN* pg)
{
CAN_MSG msg;
unsigned char retVal = 0;
unsigned long id = 0;
unsigned short tblIndex = INVAL_INDEX;
#if (USE_HASHTABLE == 1)
if(((!stPGNBuffer.TxPGN.Used) && (!stPGNBuffer.TxPGN.Requested))) /* if it is registrated */
{
lCB_GenMessage(pg,&msg); /* genereate a CAN message */
stPGNBuffer.PGType = TX_BUFF;
stPGNBuffer.TxPGN.Used = 1;
stPGNBuffer.TxPGN.ptPGN = pg; /* hold the PG in buffer */
stPGNBuffer.TxPGN.ptPGN->mPGState = PG_TX_XMT;
stPGNBuffer.TxPGN.Requested = 1;
if(!gCan_SendMsg(&msg)) /* activate the controler */
{
return 1;
}
stPGNBuffer.TxPGN.Requested = 0;
stPGNBuffer.TxPGN.Used = 0;
stPGNBuffer.TxPGN.ptPGN->mPGState = PG_TX_REQ;
stPGNBuffer.TxPGN.Overrun = 1;
stPGNBuffer.PGType = INVAL_BUFFER;
stPGNBuffer.TxPGN.ptPGN = NULL;
}
/* overrun */
#else
if((!stPGNBuffer.TxPGNBuff.Used) && (!stPGNBuffer.TxPGNBuff.Requested)
&& (stPGNBuffer.PGType == INVAL_BUFFER))
{
lCB_GenMessage(pg,&msg); /* make a CAN message from the PG */
stPGNBuffer.PGType = TX_SYS_BUFF;
stPGNBuffer.TxPGNBuff.ptPGN = pg;
stPGNBuffer.TxPGNBuff.Used = 1;
stPGNBuffer.TxPGNBuff.Overrun = 0;
stPGNBuffer.TxPGNBuff.Requested = 1;
stPGNBuffer.TxPGNBuff.ptPGN->mPGState = PG_TX_XMT;
retVal = gCan_SendMsg(&msg); /* send message */
if(!retVal)
{
/* successful send */
return 1;
}
stPGNBuffer.TxPGNBuff.Overrun = 1;
stPGNBuffer.TxPGNBuff.Used = 0;
stPGNBuffer.TxPGNBuff.ptPGN->mPGState = PG_TX_REQ;
stPGNBuffer.TxPGNBuff.Requested = 0;
stPGNBuffer.PGType = INVAL_BUFFER;
stPGNBuffer.TxPGNBuff.ptPGN = NULL;
} /* if */
#endif /* USE_HASHTABLE */
return 0;
} /* gCB_SendUserPG() */
/*!
\brief free an occupied buffer and return the buffer state
This function is called from the protocol stack to free a
Rx or a Tx PGN in the buffer. Only registrered PGN in the buffer will
executed
*/
/*!
Allocate a PGN into the buffer
\param pg is the PG to free from the Buffer
\param buff is the select flag in which buffer the PG shall be freed RX|TX
\return a handler to the buffer
\retval 0...MAX_{RX|TX}_BUFF the PGN was freed
\retval 0xFF buffer empty, nothing done
*/
unsigned char gCB_ReleaseBuffer(VJ1939PGN* pg, unsigned char buffselect)
{
#if (USE_HASHTABLE == 1)
unsigned short PGNindex; /* index for table entry */
unsigned short traverser; /* traverser of table path */
unsigned short stepback; /* marker of the element before */
if(!IsSysPG(pg))
{
/* in which buffer shall the PG register */
switch(buffselect)
{
case RX_BUFF:
if(stPGNBuffer.RxElms > 0) /* is there anything in buffer */
{
PGNindex = ((((unsigned short)pg->mPDUF)<<8) | pg->mPDUS); /* generate the table index */
PGNindex %= RX_MODULATOR;
if(stPGNBuffer.PDURxIndex[PGNindex] != INVAL_RX_INX/*INVAL_INX*/) /* is index used */
{
traverser = stPGNBuffer.PDURxIndex[PGNindex]; /* gereate a traverser */
while(traverser != INVAL_RX_INX/*INVAL_INX*/) /* max for the whole tree */
{ /* if we found the PGN */
if((pg->mPDUF == (unsigned char)((stPGNBuffer.mPDURxTable[traverser].mElement&0xFF00)>>8))
&&(pg->mPDUS == (unsigned char) stPGNBuffer.mPDURxTable[traverser].mElement&0x00FF)
&& (((VJ1939PGN*)stPGNBuffer.mPDURxTable[traverser].mIndex)->mSource == pg->mSource))
{
stPGNBuffer.mPDURxTable[traverser].mElement = 0xFFFF; /* release the value */
stPGNBuffer.mPDURxTable[traverser].mIndex = NULL; /* release the pointer to PG */
if(traverser == stPGNBuffer.PDURxIndex[PGNindex]) /* is it the first in tree? */
{
if(stPGNBuffer.mPDURxTable[traverser].mNext == INVAL_RX_INX/*INVAL_INX*/) /* is it the first & last in tree */
stPGNBuffer.PDURxIndex[PGNindex] = INVAL_RX_INX/*INVAL_INX*/; /* release PDU index */
else
/* set PG index to next Table element */
stPGNBuffer.PDURxIndex[traverser] = stPGNBuffer.mPDURxTable[traverser].mNext;
} /* if */
else
{
if(stPGNBuffer.mPDURxTable[traverser].mNext != INVAL_RX_INX/*INVAL_INX*/) /* is it in middle of the tree */
/* put pointer from elm before to next elm */
stPGNBuffer.mPDURxTable[stepback].mNext = stPGNBuffer.mPDURxTable[traverser].mNext;
else
/* if it is the last elm in tree - set next pointer to INVALID */
stPGNBuffer.mPDURxTable[stepback].mNext = INVAL_RX_INX/*INVAL_INX*/;
}
/* insert element in free list */
stPGNBuffer.mPDURxTable[traverser].mNext = stPGNBuffer.mPDURxFree;
stPGNBuffer.mPDURxFree = traverser; /* mark element as free */
stPGNBuffer.RxElms--; /* reduce element counter */
return stPGNBuffer.RxElms;
break;
} /* if */
stepback = traverser; /* remember the last element */
traverser = stPGNBuffer.mPDURxTable[traverser].mNext; /* increment traverser */
} /* while */
} /* if */
} /* if */
break;
default:
/* do nothing */
break;
} /* switch */
} /* if */
#else
unsigned short loop;
unsigned short loop2;
if(!IsSysPG(pg))
{
/* in which buffer shall the PG register */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -