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

📄 jbuffer.c

📁 在Freescale16位单片机MC9s12dp256上移植了J1939源码和操作系统(ucOSII)。
💻 C
📖 第 1 页 / 共 3 页
字号:
    switch(buffselect)
    {
    case RX_BUFF:
      for(loop=0; loop<stPGNBuffer.RxElms; loop++)     /* for all elements in the buffer */
      {
        if((stPGNBuffer.RxPGN[loop].Used)
           && pg->mPDUF == stPGNBuffer.RxPGN[loop].ptPGN->mPDUF
           && pg->mPDUS == stPGNBuffer.RxPGN[loop].ptPGN->mPDUS
           && pg->mSource == stPGNBuffer.RxPGN[loop].ptPGN->mSource)
        {
          stPGNBuffer.RxPGN[loop].ptPGN = NULL;        /* release the indexed PG */
          stPGNBuffer.RxPGN[loop].Used = 0;
          /* order the list to prevent spaces */
          for(loop2=loop; loop2<stPGNBuffer.RxElms-1 && stPGNBuffer.RxElms>1;loop2++)
          {
            stPGNBuffer.RxPGN[loop2].ptPGN = stPGNBuffer.RxPGN[loop2+1].ptPGN;
            stPGNBuffer.RxPGN[loop2].Used = stPGNBuffer.RxPGN[loop2+1].Used;
            stPGNBuffer.RxPGN[loop2].Overrun = stPGNBuffer.RxPGN[loop2+1].Overrun;
            stPGNBuffer.RxPGN[loop2].Requested = stPGNBuffer.RxPGN[loop2+1].Requested;
          } /* for */
          if(loop2>loop)  /* clear last element */
          {
            stPGNBuffer.RxPGN[loop2].ptPGN = NULL;
            stPGNBuffer.RxPGN[loop2].Used = 0;
            stPGNBuffer.RxPGN[loop2].Overrun = 0;
            stPGNBuffer.RxPGN[loop2].Requested = 0;
          }
          stPGNBuffer.RxElms--;
          return stPGNBuffer.RxElms;
        } /* if */
      } /* for */
      break;
    default:
      /* do nothing */
      break;
    } /* switch */
  } /* if */
#endif /* USE_HASHTABLE */
  return INVAL_BUFFER;
} /* gCB_ReleaseBuffer() */

/*!
  \brief occupy a free buffer and return the buffer handler

  This function is called from the protocol stack to allocate an
  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 store into the Buffer
  \param buff is the select flag in which buffer the PG shall be stored RX|TX
  \return a handler to the buffer
  \retval 0...MAX_{RX|TX}_BUFF the PGN was allocated
  \retval 0xFF buffer full, no registration
*/


unsigned char gCB_AllocBuffer(VJ1939PGN* pg, unsigned char buffselect)
{
#if (USE_HASHTABLE == 1)
  unsigned short PDUindex;
  unsigned short traverser;

  /* we don't register System PG's */
  if(!IsSysPG(pg))
  {
    /* in which buffer shall the PG register */
    switch(buffselect)
    {
      case RX_BUFF:
        if(stPGNBuffer.RxElms<MAX_RX_ELMS)                /* is the free space in table? */
        {
          PDUindex = ((((unsigned short)pg->mPDUF)<<8) | pg->mPDUS);        /* generate the Table index */
          PDUindex %= RX_MODULATOR;
          if(stPGNBuffer.PDURxIndex[PDUindex] == INVAL_RX_INX/*INVAL_INX*/) /* is elm the first element */
          {
            stPGNBuffer.PDURxIndex[PDUindex] = stPGNBuffer.mPDURxFree;  /* get the next free element */
            /* set PGN into table */
            stPGNBuffer.mPDURxTable[stPGNBuffer.PDURxIndex[PDUindex]].mElement = (unsigned short)((((unsigned short)pg->mPDUF)<<8) | pg->mPDUS);
            stPGNBuffer.mPDURxTable[stPGNBuffer.PDURxIndex[PDUindex]].mIndex = (VJ1939PGN*) pg;
            /* set pointers of the new element */
            stPGNBuffer.mPDURxFree = stPGNBuffer.mPDURxTable[stPGNBuffer.PDURxIndex[PDUindex]].mNext;
            stPGNBuffer.mPDURxTable[stPGNBuffer.PDURxIndex[PDUindex]].mNext = INVAL_RX_INX/*INVAL_INX*/;
          }
          else
          {
            traverser = stPGNBuffer.PDURxIndex[PDUindex];
            while(stPGNBuffer.mPDURxTable[traverser].mNext != INVAL_RX_INX/*INVAL_INX*/)
            {
              traverser = stPGNBuffer.mPDURxTable[traverser].mNext; /* search for the last element */ 
            } /* while */
            /* set free pointer ans set PGN to table */
            stPGNBuffer.mPDURxTable[traverser].mNext = stPGNBuffer.mPDURxFree; 
            stPGNBuffer.mPDURxTable[stPGNBuffer.mPDURxTable[traverser].mNext].mElement = (unsigned short)((((unsigned short)pg->mPDUF)<<8) | pg->mPDUS);
            stPGNBuffer.mPDURxTable[stPGNBuffer.mPDURxTable[traverser].mNext].mIndex = (VJ1939PGN*) pg;
            /* set pointer of the new element */
            stPGNBuffer.mPDURxFree = stPGNBuffer.mPDURxTable[stPGNBuffer.mPDURxFree].mNext; 
            stPGNBuffer.mPDURxTable[stPGNBuffer.mPDURxTable[traverser].mNext].mNext = INVAL_RX_INX/*INVAL_INX*/;
          } /* else */
          stPGNBuffer.RxElms++;      /* increment element counter */
          return stPGNBuffer.RxElms;
        } /* if */
        break;
      default:
        /* do nothing */
        break;
    }/* switch */
  }
#else
  if(!IsSysPG(pg))
  {
    switch(buffselect)   /* select a buffer */
    {
      case RX_BUFF:
        /* if the buffer ist free */
        if(!stPGNBuffer.RxPGN[stPGNBuffer.RxElms].Used && stPGNBuffer.RxElms < MAX_RX_ELMS)
        {
          /* register the element */
          stPGNBuffer.RxPGN[stPGNBuffer.RxElms].ptPGN = pg;
          stPGNBuffer.RxPGN[stPGNBuffer.RxElms].Requested = 0;
          stPGNBuffer.RxPGN[stPGNBuffer.RxElms].Used = 1;
          stPGNBuffer.RxElms++;
          return (stPGNBuffer.RxElms);
        }
        break;
      default:
        /* do nothing */
        break;
    }/* switch */
  } /* if */
#endif /* USE_HASHTABLE */
  return INVAL_BUFFER;               /* return a default value */
}/* gCB_AllocBuffer() */

/*!
  \brief Reset the buffer structure

   This function must be called on each startup routine 
*/

void gCB_Init(void)
{
  unsigned short loop;
  unsigned char i;

  stPGNBuffer.RxElms = 0;
  stPGNBuffer.mCurrRxPG = INVAL_INDEX/*INVAL_INX*/;

  /* resetting the queue pointers */
  stPGNBuffer.mRxQueueReadPtr =  0;
  stPGNBuffer.mRxQueueWritePtr = 0;

  /* reseting the RX Sys PGN Queue */
  for(loop=0; loop<MAX_RX_QUEUESIZE; loop++)
  {
    stPGNBuffer.RxSysPGNQueue[loop].mPGN.mEnable = 0;
    stPGNBuffer.RxSysPGNQueue[loop].mPGN.mPGState = PG_RX_FREE;
    stPGNBuffer.RxSysPGNQueue[loop].mPGN.mDataLength = 0;
    stPGNBuffer.RxSysPGNQueue[loop].Used = 0;
    stPGNBuffer.RxSysPGNQueue[loop].Overrun = 0;
    for(i=0; i<8; i++)
    {
      stPGNBuffer.RxSysPGNQueue[loop].mPGNData[i] = 0;  
    }
    stPGNBuffer.RxSysPGNQueue[loop].mPGN.mData =                   /* QUEUE PGN shall point to a data field */
        (unsigned char*)stPGNBuffer.RxSysPGNQueue[loop].mPGNData; 
  }/* for */

#if (USE_HASHTABLE == 1)
  stPGNBuffer.mPDURxFree = 0;
  stPGNBuffer.mPDUTxFree = 0;

  /* reseting the TX Sys PGN structure */
  stPGNBuffer.TxPGN.Overrun = 0;
  stPGNBuffer.TxPGN.ptPGN = NULL;
  stPGNBuffer.TxPGN.Requested = 0;
  stPGNBuffer.TxPGN.Used = 0;

  /* resetting the RX PGN buffer */
  for(loop=0; loop<MAX_RX_ELMS; loop++)
  {
    stPGNBuffer.PDURxIndex[loop] = INVAL_RX_INX/*INVAL_INX*/;
    stPGNBuffer.mPDURxTable[loop].mElement = 0xFFFF;
    stPGNBuffer.mPDURxTable[loop].mIndex = NULL;
    if(loop == (MAX_RX_ELMS-1))
      stPGNBuffer.mPDURxTable[loop].mNext = 0;
    else
      stPGNBuffer.mPDURxTable[loop].mNext = loop+1;      
  }/* for */

#else
  stPGNBuffer.PGType = INVAL_BUFFER;
  stPGNBuffer.reqPGN = INVAL_INDEX;

  /* resetting the tx sys pgn structure */
  stPGNBuffer.TxPGNBuff.Overrun = 0;
  stPGNBuffer.TxPGNBuff.ptPGN = NULL;
  stPGNBuffer.TxPGNBuff.Requested = 0;
  stPGNBuffer.TxPGNBuff.Used = 0;

  /* resetting the Rx buffer */  
  for(loop=0; loop<MAX_RX_ELMS; loop++)
  {
    stPGNBuffer.RxPGN[loop].Overrun = 0;
    stPGNBuffer.RxPGN[loop].ptPGN = NULL;
    stPGNBuffer.RxPGN[loop].Requested = 0;
    stPGNBuffer.RxPGN[loop].Used = 0;
  } /* for */
    
#endif /* USE_HASTABLE */
} /* gCB_Init */


void gCB_ClearIdFilter(BYTE bManager)
{
  /* TBD */
} /* gCB_ClearIdFilter */

/*!
  \brief Quick extended identifier checking.

  Check if an identifier has an assigned manager.
  \param wId any CAN identifier
  \retval TRUE - manager exist
  \retval FALSE - manager does not exist
*/
BYTE gCB_PreCheckXtdId(DWORD wId)
{
  unsigned short tblIndex;
  if((((wId&0x00FF0000)>>16)==0xEE)||(((wId&0x00FF0000)>>16)==0xEA)||(((wId&0x00FF0000)>>16)==0xEC)
                                      ||(((wId&0x00FF0000)>>16)==0xEB)||(((wId&0x00FF0000)>>16)==0xE8))
  {
    stPGNBuffer.PGType = RX_SYS_BUFF;
    return 1;
  }

  tblIndex = lCB_LookUp(wId,RX_BUFF);   /* look if PG is registrated in table */
  if((tblIndex != INVAL_INDEX/*INVAL_INX*/) && (stPGNBuffer.mCurrRxPG == INVAL_INDEX/*INVAL_INX*/))
  {
    stPGNBuffer.PGType = RX_BUFF;
    stPGNBuffer.mCurrRxPG = tblIndex;
    return TRUE;
  }
  return FALSE;
} /* gCB_PreCheckXtdId */

/*!
  \brief Quick standard identifier checking.

  Check if an identifier has an assigned manager.
  \param wId any CAN identifier
  \retval TRUE - manager exist
  \retval FALSE - manager does not exist
*/
BYTE gCB_PreCheckStdId(WORD wId)
{
  return 0; /* TBD in next Version we don't use standard CAN frames at J1939 yet*/
} /* gCB_PreCheckStdId */

/*!
  If a message was received correctly, it will be put into a related
  buffer or queue.
  This function will be called from the CAN interrupt service routine.
  \param ptMsg - Pointer to message (is invalid after routine execution).
  \retval TRUE - message could be written to buffer.
  \retval FALSE - message not buffered.
*/
BYTE gCB_CanBufferMsg(const CAN_MSG *ptMsg)  
{
  /* system PG shall be buffered in a Queue */
  if(stPGNBuffer.PGType == RX_SYS_BUFF)
  {
    /* Queue Handling !! */
    stPGNBuffer.mCurrRxPG = INVAL_INDEX/*INVAL_INX*/;
    stPGNBuffer.PGType = INVAL_BUFFER;
    if(gCB_EnqueueElm(ptMsg))
      return 1;
  }
  else if(stPGNBuffer.PGType == RX_BUFF)
  {
#   if (USE_HASHTABLE == 1)
    /* check the reception of a PG */
    if(stPGNBuffer.mCurrRxPG != INVAL_INDEX 
       && ((VJ1939PGN*)stPGNBuffer.mPDURxTable[stPGNBuffer.mCurrRxPG].mIndex)->mPGState != PG_RX_FULL)
    {
      /* sign the stack the receiption of a PG */
      ((VJ1939PGN*)stPGNBuffer.mPDURxTable[stPGNBuffer.mCurrRxPG].mIndex)->mPGState = PG_RX_FULL;
      /* refresh the elements in goal buffer */
      memcpy((char*)(((VJ1939PGN*)stPGNBuffer.mPDURxTable[stPGNBuffer.mCurrRxPG].mIndex)->mData),
             (char*)ptMsg->bDb,
             ptMsg->Dlc);
      /* clear handler */
      stPGNBuffer.mCurrRxPG = INVAL_INDEX/*INVAL_INX*/;
      stPGNBuffer.PGType = INVAL_BUFFER;
      return 1;
    } /* if */
#   else
    if(stPGNBuffer.mCurrRxPG != INVAL_INDEX 
       && stPGNBuffer.RxPGN[stPGNBuffer.mCurrRxPG].ptPGN->mPGState != PG_RX_FULL)
    {
      /* sign the stack the receiption of a PG */
      stPGNBuffer.RxPGN[stPGNBuffer.mCurrRxPG].ptPGN->mPGState = PG_RX_FULL;
       /* refresh the elements in goal buffer */
      memcpy((char*)stPGNBuffer.RxPGN[stPGNBuffer.mCurrRxPG].ptPGN->mData,
             (char*)ptMsg->bDb,
             ptMsg->Dlc);
      /* clear handler */
      stPGNBuffer.mCurrRxPG = INVAL_INDEX/*INVAL_INX*/;
      stPGNBuffer.PGType = INVAL_BUFFER;
      return 1;
    }  
#   endif /* USE_HASHTABLE */
  }
  return 0;
}

/*--------------------------------------------------------------------*/
/*  documentation                                                     */
/*--------------------------------------------------------------------*/

/*!
  \file
  \brief Basic routines to filter and store CAN messages
         for the J1939 protocol stack.
*/

⌨️ 快捷键说明

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