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

📄 jbuffer.c

📁 在Freescale16位单片机MC9s12dp256上移植了J1939源码和操作系统(ucOSII)。
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -