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

📄 jbuffer.c

📁 在Freescale16位单片机MC9s12dp256上移植了J1939源码和操作系统(ucOSII)。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*--------------------------------------------------------------------
       jBUFFER.C
  --------------------------------------------------------------------
       Copyright (C) 2004 Vector Informatik GmbH, Stuttgart

       Function: Basic routines to filter and store CAN messages
                 for the J1939 protocol stack.
  --------------------------------------------------------------------
* Comments:       
*                 
*
* Version  Date           Author           Comments
* -------  ----------     --------------   ------------------------------
*     0.1  15.05.2001     Ma               Create
*     0.2  28.01.2001     Ma               changed PDUS handling in lookup
*                                          table
*     0.3  22.05.2003     Ma               minor changes - save RX buffer access
*     0.4  10.07.2003     Ma               changed memory qualifier
*     1.0  24.06.2004     Ma               removed TX lookup handling
*     1.1  28.06.2004     Ma               changed comments and removed unused vars
*/

/*--------------------------------------------------------------------*/
/*  include files                                                     */
/*--------------------------------------------------------------------*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Includes.h"

#ifdef BENCHMARK
#ifdef _TSK_166
#  include <reg167.h>
#endif /* _TSK_166_ */
#endif /* BENCHMARK */


#include "J1939.h"
#include "PortAB.h"
#include "Types.h"
#include "JCanCntrl.h"
#include "J1939PGN.h"
#include "JBuffer.h"
#include "J1939cfg.h"


/*--------------------------------------------------------------------*/
/*  external data                                                     */
/*--------------------------------------------------------------------*/
/*! External dependencies */
extern VJ1939PGN gRxPGTable[NR_OF_RX_PG];         /*!< the PG RxTable */
extern unsigned char gDeviceAddress;              /*!< the device address for special handling */

/*--------------------------------------------------------------------*/
/*  private data                                                      */
/*--------------------------------------------------------------------*/
VJ1939PGNBuffer stPGNBuffer;      /* PG buffer structure */

/* ########################## PERFORMANCE MEASSUREMENT  ####################### */
/* ################################### BEGIN ################################## */
#if BENCHMARK == 1
#ifdef _TSK_166_
#define START_TIM 0x0040
void configBenchTimer(void)
{
  T4CON = 0x0002;
  T4 = 0x0000;
}

void startBenchTimer(void)
{
   T4CON |= START_TIM;
}

void stopBenchTimer(void)
{
   T4CON &= ~START_TIM;
}

void resetBenchTimer(void)
{
    T4 = 0x0000;
}
#endif /* _TSK_166_ */

#endif /* BENCHMARK */
/* #################################### END ################################## */
/* ########################## PERFORMANCE MEASSUREMENT  ###################### */

/*--------------------------------------------------------------------*/
/*  private functions                                                  */
/*--------------------------------------------------------------------*/
/*!
  \brief Look up for a PG in the Hash Table

  This function is called from the buffer module to look up if a PG is
  registrated in the hash table
*/
/*!
  
  \param pg   ptr to the PG for which we have to look up
  \retval     INVAL_INDEX if PG was not registrated
  \retval     A value >= 0 and < INVAL_INDEX if PG was registrated */
unsigned short lCB_LookUp(unsigned long id, unsigned char buffselect) REENTRANT
{
  unsigned char lHoldPDUS;
  unsigned char lPDUF = (id&0x00FF0000)>>16;
  unsigned char lPDUS = (id&0x0000FF00)>>8;
  unsigned char lSource = (id&0x000000FF);
  unsigned char lAddress = J1939NULLADDRESS;

# if (USE_HASHTABLE == 1)
  unsigned short traverser;
  unsigned short PGindex = ((((unsigned short)lPDUF)<<8) | lPDUS);  /* generate the index for hash table */;
#else
  unsigned short loop;
#endif /* USE_HASHTABLE */ 
  /* remember the PG's PDUS */
  lHoldPDUS = lPDUS;
  /* check the PDU format - it is neccessary for both methods */
  if(lPDUF<240)         /* slect the PDU format if it ist Format I */
  {
    lAddress = lPDUS;   /* set PDUS to "0" and remember the destination address */
    lPDUS = 0x00;
  }
  else
  {
    lAddress = J1939GLOBALADDRESS;  /* if it is Format II, Address is the global address */
  }

#if (USE_HASHTABLE == 1)

# if BENCHMARK == 1
  configBenchTimer();
  startBenchTimer();
#endif /* BENCHMARK */
  switch(buffselect)       /* in which buffer we have to look up */
  {
    /* the RX Buffer was selected */
    case RX_BUFF:
      PGindex %= RX_MODULATOR;
      if((stPGNBuffer.PDURxIndex[PGindex] != INVAL_RX_INX/*INVAL_INX*/) 
         && ((lAddress==J1939GLOBALADDRESS)||(lAddress==gDeviceAddress)))  /* is a path into the table? */
      {
        traverser = stPGNBuffer.PDURxIndex[PGindex];    /* geth the traverser root */   
        /* walking through the path */
        while(traverser != INVAL_RX_INX/*INVAL_INX*/)
        {
          /* check the PG's on this path */
          if((lPDUF == (unsigned char)((stPGNBuffer.mPDURxTable[traverser].mElement&0xFF00)>>8))
          &&(lHoldPDUS == (unsigned char) stPGNBuffer.mPDURxTable[traverser].mElement&0x00FF) 
          && (((VJ1939PGN*)stPGNBuffer.mPDURxTable[traverser].mIndex)->mSource == lSource))
          {
            return traverser;    /* bingo, we hit the PG */
          } /* if */
          traverser = stPGNBuffer.mPDURxTable[traverser].mNext;  /* PG doesn't hit - continue the path */
        } /* while */
      } /* if */
      break;
    default:
      /* do nothing */
      break;
  } /* switch */
  return INVAL_INDEX /* INVAL_INX */;
# else
# if BENCHMARK == 1
  configBenchTimer();
  startBenchTimer();
# endif /* BENCHMARK */
  switch(buffselect)       /* in which buffer we have to look up */
  {
    case RX_BUFF:
      for(loop=0; loop<stPGNBuffer.RxElms; loop++)             /* loop for all list elements */
      {
        if((stPGNBuffer.RxPGN[loop].Used)
           && (stPGNBuffer.RxPGN[loop].ptPGN->mPDUF == lPDUF   /* compare the PGN */
           && stPGNBuffer.RxPGN[loop].ptPGN->mPDUS == lHoldPDUS
           && stPGNBuffer.RxPGN[loop].ptPGN->mSource == lSource)
           && ((lAddress==J1939GLOBALADDRESS)||(lAddress==gDeviceAddress)))
           {
             return loop;                                      /* return the index of the PG */
           } /* if */
      } /* for */
      break;
    default:
      /* do nothing */
      break;
  } /* switch */
return INVAL_INDEX /*INVAL_INX*/;
#endif /* USE_HASHTABLE */
} /* lCB_LookUp */


/*!
  \brief Generates a CAN Message from a PG

  This function is called from the buffer module to generate a CAN Message
  form a PG - no fragmentation is allowed. This function is used in L2 
  level. TP is one level higher in use!
*/

/*!
  
  \param pg   ptr to the PG from which an Message shall be generated
  \param msg  ptr to the message which shall be created
  \return     the result of the function
  \retval     1 if message was generated
  \retval     0 if a problem occurs */
unsigned char lCB_GenMessage(VJ1939PGN* pg, CAN_MSG *msg)
{
  msg->qbId.dw = SetId(pg);                      /* generating the CAN identifier */
  msg->Rtr = 0;                                /* inizializing the message params */
  msg->Dlc = pg->mDataLength;
  msg->Ext = 1;
  msg->RxOk = 0;
  msg->TxOk = 0;
  if(memcpy((char*)msg->bDb,(char*)pg->mData,pg->mDataLength))  /* copy data */
    return 0;
  return 1;
} /* lCB_GenMessage */

/*!
  \brief Generates a PGN from a CAN Message

  This function is called from the buffer module to generate a PGN 
  form a CAN Message - no fragmentation is allowed. This function is used in L2 
  level. TP is one level higher in use!
*/

/*!
  \param pg   ptr to the PG which shall be created 
  \param msg  ptr to the message from which pg should be created
  \return     the result of the function
  \retval     0 if pg was generated
  \retval     1 if there was a problem */
unsigned char lCB_GenPGN(VJ1939PGN* pg, const CAN_MSG* msg)
{
  pg->mPGState = PG_RX_FULL;
  pg->mEnable = 1;
  pg->mDataLength = msg->Dlc;
  pg->mPriority = GetPrio(msg);  /*x !!!!!!!!!!!!!*/
  pg->mPDUF = GetPDUF(msg);
  pg->mPDUS = GetPDUS(msg);
  pg->mSource = GetSource(msg);
  if(memcpy((char*)pg->mData, (char*)msg->bDb,msg->Dlc))
    return 0;
  return 1;
} /* lCB_GenPGN */

/*--------------------------------------------------------------------*/
/*  public functions                                                  */
/*--------------------------------------------------------------------*/
/*!
  Checks if the current SYS PG was successful sent
  \param  -
  \retval 1 if PG was successful sent
  \retval 0 if PG could not sent
*/
unsigned char gCB_CheckSysPGSend(void)
{
# if (USE_HASHTABLE == 1)
  if((stPGNBuffer.TxPGN.Requested == 0)
     && (stPGNBuffer.TxPGN.ptPGN == NULL)
     && (stPGNBuffer.TxPGN.Used == 0))
  {
    return 1;
  }
# else
  if((stPGNBuffer.TxPGNBuff.Requested == 0)
     && (stPGNBuffer.TxPGNBuff.Used == 0))
  {
    return 1;
  }
#endif /* USE_HASHTABLE */
  return 0;
}


/*!
  \brief Dequeues a Message from 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_DequeueElm(void)
{
  /* if queue is not empty */
  if(stPGNBuffer.mRxQueueReadPtr != stPGNBuffer.mRxQueueWritePtr)
  {
    switch(stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUF)
    {
      case 0xEE:                 /* Address Claimed PGN */
        gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mPGState = PG_RX_FULL;
        gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mDataLength = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength;
        gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mPDUF = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUF;
        gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mPDUS = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUS;
        gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mSource = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mSource;
        memcpy((char*)gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mData,
               (char*)stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mData,
               stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength);
        break;
      case 0xEA:                 /* Request PGN */
        gRxPGTable[RX_PGN_REQ].mPGState = PG_RX_FULL;
        gRxPGTable[RX_PGN_REQ].mDataLength = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength;
        gRxPGTable[RX_PGN_REQ].mPDUF = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUF;
        gRxPGTable[RX_PGN_REQ].mPDUS = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mPDUS;
        gRxPGTable[RX_PGN_REQ].mSource = 
           stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mSource;
        memcpy((char*)gRxPGTable[RX_PGN_REQ].mData,
               (char*)stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mData,
               stPGNBuffer.RxSysPGNQueue[stPGNBuffer.mRxQueueReadPtr].mPGN.mDataLength);
        break;
      case 0xEC:                 /* TPCM PGN */
        gRxPGTable[RX_PGN_TPCM].mPGState = PG_RX_FULL;

⌨️ 快捷键说明

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