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

📄 jtransp.c

📁 在Freescale16位单片机MC9s12dp256上移植了J1939源码和操作系统(ucOSII)。
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*
* File Name:      JTransp.c
*
* Description:    Transport protocols for the J1939 protocol stack
*                 
*
* Comments:       Includes BAM and CMDT
*                 
*
* Version  Date         Author           Comments
* -------  ----------   --------------   ------------------------------
*     0.9    18.12.98   Ft               Create
*     1.0    24.04.99   Ft               C167CR and Tasking compiler
*     1.1    27.03.2001 Ma               Bugfixing remainder problem at 
*                                        fragmented PG of the last fragment
*     1.2    31.05.2001 Ma               merge Stack with CANopen driver
*     2.0    18.06.2001 Ma               Version 2.0 new buffer concept and
*                                        documented for doxygen  
*     2.1    01.02.2002 Ma               changed PDUS handling in CMDT send CTS
*     2.2    06.06.2003 Ma               changed CMDT cnxn handling 
*     2.3    15.07.2003 Ma               added MAX_TP_DATA_LENGTH limitation check
*     2.4    24.06.2004 Ma               changed handling of TP_CM state handling during
*                                        data receiption in CMDT protocol
*     2.5    28.06.2004 Ma               changed comments
*
* Copyright (c) 1998 - 2004 Vector Informatik GmbH
*****************************************************************************/
#include "Includes.h"

#include "Types.h"
#include "J1939.h"
#include "J1939CFG.h"
#include "J1939PGN.h"
#include "J1939TRA.h"
#include "J1939EXT.h"

/*!
  \brief Fill the TX PG structure with corresponding values
*/

/*!
  \param   dest - the destination address of the PG
  \param   pduf - PDU Format field of the PG
  \param   pdus - PDU Specific field of the PG 
*/
void FillTPCMAbort(unsigned char dest, unsigned char pduf, unsigned char pdus)
{
  if (gTxPGTable[TX_PGN_TPCM].mPGState == PG_TX_FREE)
  {
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mControl = TPCM_ABORT;
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesLsb = 0xFF; 
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesMsb = 0xFF; 
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPackets = 0xFF; 
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mReserved = 0xFF;
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNlsb = pdus;
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGN = pduf;
   ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNmsb = 0;
   gTxPGTable[TX_PGN_TPCM].mSource = gDeviceAddress; /* source addr. */
   gTxPGTable[TX_PGN_TPCM].mPDUS = dest; /* dest. addr. */
   gTxPGTable[TX_PGN_TPCM].mPGState = PG_TX_REQ; /* ready to transmit */
  }
}

/*!
  \brief Handler of the RX transport protocol for CMDT PGs

  The function handle the CMDT PGs within a fragmented PG.
*/
void HandleRxTransportCmdPG(void)
{
  unsigned char pduf, pdus, i, j;
  unsigned short tempBytes = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesLsb + (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesMsb << 8);

  if ((((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_RTS) 
      && (tempBytes <= MAX_TP_DATA_LENGTH)) /* RTS (open cnxn) */
  {
    /* Check if a transport channel is free */
    for (j=0;j<NR_OF_TP_CH; j++)
    {
      if (gTPRxCnxn[j].mState == CMDT_STATE_CLOSE)
      {
        pduf = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN;
        pdus = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb;

        for (i=0; i<NR_OF_RX_PG; i++)
        {    
          /* are we interested in this PGN */
          if ((gRxPGTable[i].mPDUF==pduf) && 
             (((gRxPGTable[i].mPDUF>239) && (gRxPGTable[i].mPDUS==pdus)) ||
             ((gRxPGTable[i].mPDUF<240) && (gRxPGTable[RX_PGN_TPCM].mPDUS == gDeviceAddress))))
          {
            /* initialize transport structure */
            /* gTPRxCnxn[j].mState = CMDT_RX_STATE_OPEN;*/
            gTPRxCnxn[j].mSource = gRxPGTable[RX_PGN_TPCM].mSource;
            gTPRxCnxn[j].mBytes = tempBytes;
            gTPRxCnxn[j].mPackets = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPackets;
            gTPRxCnxn[j].mSequence = 1;
            gTPRxCnxn[j].mRxPGTable = i;

            /* Prepare CTS to signal the producer to send data */
            if (gTxPGTable[TX_PGN_TPCM].mPGState == PG_TX_FREE)
            {
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mControl = TPCM_CTS;
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesMsb = 1; /* start with first packet */
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesLsb = 1; /* packets to send*/
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPackets = 0xFF; /* reserved */
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mReserved = 0xFF;
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNlsb = pdus;
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGN = pduf;
              ((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNmsb = 0;
              gTxPGTable[TX_PGN_TPCM].mSource = gDeviceAddress; /* source addr. */
              gTxPGTable[TX_PGN_TPCM].mPDUS = gTPRxCnxn[j].mSource; /* dest. addr. */
              gTxPGTable[TX_PGN_TPCM].mPGState = PG_TX_REQ; /* ready to transmit */
              gTPRxCnxn[j].mTimer = Tim_GetCurrentTime();
              gTPRxCnxn[j].mState = CMDT_RX_STATE_DATA;
            }
#if 0
            else
            {
              /* Should not occure, do not establish connection. */
              /* Send Abort is not possible, too. The send object */
              /* is used by another connection */
            }
#endif
            break;
          }
        }
        break;
      }
    }
  }
  else if (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_CTS) /* CTS */
  {
    if (gTPTxCnxn.mState == CMDT_TX_STATE_OPEN)
    {
      gTPTxCnxn.mSequence = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesMsb;
      gTPTxCnxn.mPToSend = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesLsb;
      if (gTPTxCnxn.mPToSend>0) /* no packets to send */
      {
        gTPTxCnxn.mState = CMDT_TX_STATE_DATA;
      }
      else
      {
        gTPTxCnxn.mTimer = Tim_GetCurrentTime();
      }
    }
  } /* elif CTS */
  else if (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_EndOfMsgAck) /* EndOfMsgAck */
  {
    if (gTPTxCnxn.mState == CMDT_TX_STATE_OPEN)
    {
      gTPTxCnxn.mState = CMDT_STATE_CLOSE;
      gTxPGTable[gTPTxCnxn.mRxPGTable].mPGState = PG_TX_FREE; /* Free buffer */
      /* inform application */
    }
  } /* elif EndOfMsgAck */
  else if (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_ABORT) /* Abort */
  {
    /* Search connection for this abort message */
    if ((gTPTxCnxn.mState == CMDT_STATE_CLOSE) &&
        (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb == gTxPGTable[gTPTxCnxn.mRxPGTable].mPDUS) &&
        (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN == gTxPGTable[gTPTxCnxn.mRxPGTable].mPDUF))
    {
      gTxPGTable[gTPTxCnxn.mRxPGTable].mPGState = PG_TX_FREE; /* free buffer */
      gTPTxCnxn.mState = CMDT_STATE_CLOSE; /* close cnxn */
    }
    else
    {
      for (j=0;j<NR_OF_TP_CH; j++)
      {
        if ((gTPRxCnxn[j].mState == CMDT_STATE_CLOSE) &&
            (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb == gRxPGTable[gTPRxCnxn[j].mRxPGTable].mPDUS) &&
            (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN == gRxPGTable[gTPRxCnxn[j].mRxPGTable].mPDUF))
        {
          gRxPGTable[gTPRxCnxn[j].mRxPGTable].mPGState = PG_RX_FREE; /* free buffer */
          gTPRxCnxn[j].mState = CMDT_STATE_CLOSE; /* close cnxn */
          break;
        }
      }
    }
  } /* elif Abort */
  else if ((((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_BAM) 
           && (tempBytes <= MAX_TP_DATA_LENGTH)) /* BAM */
  {
    /* Check if BAM channel is free */
    for (j=0;j<NR_OF_TP_CH; j++)
    {
      if (gTPRxCnxn[j].mState == BAM_STATE_CLOSE 
          && (gAddressClaimed || (!gAddressClaimed && ((((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN == 0xFE)
              &&(((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb == 0xD8)))))
      {
        pduf = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN;
        pdus = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb;

        for (i=0;i<NR_OF_RX_PG;i++)
        {    
          /* are we interested in this PGN */
          if ((gRxPGTable[i].mPDUF==pduf) && 
              (((gRxPGTable[i].mPDUF>239) && (gRxPGTable[i].mPDUS==pdus)) ||
              (gRxPGTable[i].mPDUF<240)))
          {
            /* initialize transport structure */
            gTPRxCnxn[j].mState = BAM_RX_STATE_DATA;
            gTPRxCnxn[j].mSource = gRxPGTable[RX_PGN_TPCM].mSource;
            gTPRxCnxn[j].mBytes = tempBytes;
            gTPRxCnxn[j].mPackets = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPackets;
            gTPRxCnxn[j].mSequence = 1;
            gTPRxCnxn[j].mRxPGTable = i;
            /* start timer for timeout */
            gTPRxCnxn[j].mTimer = Tim_GetCurrentTime(); /* set timer to 250ms timeout */
            break;
          }
        }
        break;
      }
    }
  } /* elif BAM */
}

/*!
  \brief Handler of the RX transport protocol for Data PGs

  The function handle the Data PGs within a fragmented PG.

⌨️ 快捷键说明

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