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

📄 j1939.c

📁 在Freescale16位单片机MC9s12dp256上移植了J1939源码和操作系统(ucOSII)。
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*
* File Name:      j1939.c
*
* Description:    Main part of the J1939 protocol stack 
*                 
*
* Comments:       
*                 
*
* Version  Date         Author           Comments
* -------  ----------   --------------   ------------------------------
*     0.9    18.12.98   Ft               Create
*     1.0    29.04.99   Ft               C167CR and Tasking compiler
*     1.1    24.08.00   Ft               Ack handling
*     1.2    31.05.2001 Ma               merge Stack with CANopen Driver
*     1.3    11.06.2001 Ma               add new statemachine  fpr TX PG's
*     2.0    18.06.2001 Ma               Version 2.0 new buffer concept and
*                                        documented for doxygen  
*     2.1    31.02.2002 Ma               get CAN controller status at end of fct.
*     2.2    03.06.2002 Ma               changed ADC handling in offline state
*     2.4    08.06.2004 For              Bugfix 1350
*
* Copyright (c) 1998 - 2004 Vector Informatik GmbH
*****************************************************************************/
#include "Includes.h"

#include "PortAB.h"
#include "Types.h"
#include "J1939.h"
#include "J1939CFG.h"
#include "J1939PGN.h"
#include "J1939TRA.h"
#define NOEXTERNALS
#include "J1939EXT.h"
#undef NOEXTERNALS
#include "JCanCntrl.h"


/*!
  \brief This Function is the main loop of the J1939 protocol stack

  Function should be called as often as possible from the application.
  This function is the main function for the J1939 protocol stack.
  The function processes all receiving and transmitting PGs, the
  Address claiming, BAM and CMDT protocols, the request and the CmdAddress
  PGs
  
  \param      -
  \retval     -
*/
void J1939Stack(void)
{
  unsigned char i; /* Counter variable */
  unsigned char retVal;

  gCB_DequeueElm();

  /* Check for transport protocoll PGs */
  if (gRxPGTable[RX_PGN_TPCM].mPGState == PG_RX_FULL) /* Transport protocoll command */
  {
    HandleRxTransportCmdPG();
    gRxPGTable[RX_PGN_TPCM].mPGState = PG_RX_FREE; /* free buffer */
  }
  else if (gRxPGTable[RX_PGN_TPDT].mPGState == PG_RX_FULL) /* Transport protocoll */
  {
    HandleRxTransportDataPG();
    gRxPGTable[RX_PGN_TPDT].mPGState = PG_RX_FREE; /* free buffer */
  }

  /* Check for address claiming PG */
  else if (gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mPGState == PG_RX_FULL)
  {
    CheckRxAddressClaimed(); /* Address claimed received */
    gRxPGTable[RX_PGN_ADDRESS_CLAIMED].mPGState = PG_RX_FREE; /* Free buffer */
  }

  /* Commanded address PGN */
  else if (gRxPGTable[RX_PGN_COMMAND_ADDRESS].mPGState == PG_RX_FULL)
  {
    if (CompareJ1939Name(&((struct VJ1939PGN_DATA_FED8*)gRxPGTable[RX_PGN_COMMAND_ADDRESS].mData)->mName) < 0)  /* compare names, must be equal */
    {
      /* handle commanded address */
      gAddressClaimed = 0; /* remove address */
      J1939AppCmdAddrIndication(&gRxPGTable[RX_PGN_COMMAND_ADDRESS]); /* Inform Application */
    }
    gRxPGTable[RX_PGN_COMMAND_ADDRESS].mPGState = PG_RX_FREE; /* Free buffer */
  }

  /* First check special system PGs (not user/profile defined) */
  /* Request PG */
  if ((gRxPGTable[RX_PGN_REQ].mPGState == PG_RX_FULL) && 
      (gRxPGTable[RX_PGN_REQ].mPDUS == J1939GLOBALADDRESS) &&
      (((((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNlsb)==0x00) &&
      ((((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGN)==0xEE)) &&
      (gOnlineMarker == 1))
  {
    if(!gAddressClaimed)
    { 
      SendCannotClaimAddress(); 
      gRxPGTable[RX_PGN_REQ].mPGState = PG_RX_FREE;
    }
  }

  /* Now handle the user and some system PGs */
  if (gAddressClaimed) /* Check if device has an address */
  {
    /* First check special system PGs (not user/profile defined) */
    /* Request PG */
    if (gRxPGTable[RX_PGN_REQ].mPGState == PG_RX_FULL) 
    {
      /* handle this request PG */
      if ((gRxPGTable[RX_PGN_REQ].mPDUS == gDeviceAddress) ||   /* specific or */
          (gRxPGTable[RX_PGN_REQ].mPDUS == J1939GLOBALADDRESS)) /* global request */
      {
        /* search if PGN is available */
        for (i=TX_PGN_USER; i<NR_OF_TX_PG; i++)
        {
          if (gTxPGTable[i].mPDUF == ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGN)
          {
            if (((gTxPGTable[i].mPDUF > 239) && 
                (((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNlsb)==gTxPGTable[i].mPDUS) ||
                (gTxPGTable[i].mPDUF < 240))
            {
              retVal = J1939AppRequestIndication(&gTxPGTable[i]); 
              switch (retVal)
              {
                case REQ_SENDPGN:
                  gTxPGTable[i].mPGState = PG_TX_REQ; /* send requested pgn */
                  break;
                case REQ_SENDNOTHING:
                  gTxPGTable[i].mPGState = PG_TX_FREE; /* do not send requested pgn */
                  break; 
                case REQ_SENDNACK:
                  /* send negative acknowledgment */
                  if (gTxPGTable[TX_PGN_ACK].mPGState == PG_TX_FREE)
                  {
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mAcknowledge = 1; /* set negative ACK */
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGNlsb = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNlsb;
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGN = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGN;
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGNmsb = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNmsb;
                    gTxPGTable[TX_PGN_ACK].mSource = gDeviceAddress; /* source addr. */
                    gTxPGTable[TX_PGN_ACK].mPGState = PG_TX_REQ; /* send Acknowledge */
                  }
                  else
                  {
                    gCANOverrun = TRUE;
                  }
                  gTxPGTable[i].mPGState = PG_TX_FREE; /* do not send requested pgn */     
                  break;
                case REQ_SENDPACK:
                  /* send positive acknowledgment */
                  if (gTxPGTable[TX_PGN_ACK].mPGState == PG_TX_FREE)
                  {
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mAcknowledge = 0; /* set positive ACK */
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGNlsb = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNlsb;
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGN = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGN;
                    ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGNmsb = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNmsb;
                    gTxPGTable[TX_PGN_ACK].mSource = gDeviceAddress; /* source addr. */
                    gTxPGTable[TX_PGN_ACK].mPGState = PG_TX_REQ; /* send Acknowledge */
                  }
                  else
                  {
                    gCANOverrun = TRUE;
                  }
                  gTxPGTable[i].mPGState = PG_TX_FREE; /* do not send requested pgn */
                  break; 
              } /* switch */
              break; /* leave for loop */
            } /* if */
          } /* if */
        } /* for */
        if (((gRxPGTable[RX_PGN_REQ].mPDUS == gDeviceAddress)||(gRxPGTable[RX_PGN_REQ].mPDUS == J1939GLOBALADDRESS)) && /* check if this request is for this device */
            (i == NR_OF_TX_PG))                                  /* and the PGN is not available. Then send NACK. */
        {
          if (((((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNlsb) == 0x00) &&
             ((((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGN == 0xEE)))
             {
              if(gAddressClaimed)
                SendAddressClaimed();
              else
                SendCannotClaimAddress();
             }
          else if (gTxPGTable[TX_PGN_ACK].mPGState == PG_TX_FREE)
          {
            ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mAcknowledge = 1; /* set negative ACK */
            ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGNlsb = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNlsb;
            ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGN = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGN;
            ((struct VJ1939PGN_DATA_E800*)gTxPGTable[TX_PGN_ACK].mData)->mPGNmsb = ((struct VJ1939PGN_DATA_EA00*)gRxPGTable[RX_PGN_REQ].mData)->mPGNmsb;
            gTxPGTable[TX_PGN_ACK].mSource = gDeviceAddress; /* source addr. */
            gTxPGTable[TX_PGN_ACK].mPGState = PG_TX_REQ; /* send Acknowledge */
          }
          else
          {
            gCANOverrun = TRUE;
          }
        } /* if */
      } /* if */
      gRxPGTable[RX_PGN_REQ].mPGState = PG_RX_FREE; /* Free buffer */
    } /* Request PG */

    /* Check if data is to be send by a BAM or CMDT connection */
    if (gTxPGTable[TX_PGN_TPDT].mPGState == PG_TX_FREE)
    {
      if (gTPTxCnxn.mState==CMDT_TX_STATE_DATA) 
      {
        gTxPGTable[TX_PGN_TPDT].mPGState = PG_TX_REQ;
        gTxPGTable[TX_PGN_TPDT].mPDUS = gTPTxCnxn.mSource;
        gTxPGTable[TX_PGN_TPDT].mSource = gDeviceAddress;
        ((struct VJ1939PGN_DATA_EB00*)gTxPGTable[TX_PGN_TPDT].mData)->mSequence = gTPTxCnxn.mSequence; /* sequence number */

        for (i=0;i<7;i++)
        {
          ((struct VJ1939PGN_DATA_EB00*)gTxPGTable[TX_PGN_TPDT].mData)->mData[i] = 
              *((unsigned char*)gTxPGTable[gTPTxCnxn.mRxPGTable].mData+i+(7*(gTPTxCnxn.mSequence-1)));         
        }
        
        if (gTPTxCnxn.mSequence==gTPTxCnxn.mPackets) /* last packet */
        {
          for (i=(gTPTxCnxn.mBytes%7);(i<7)&&(i>0);i++)
          {
            ((struct VJ1939PGN_DATA_EB00*)gTxPGTable[TX_PGN_TPDT].mData)->mData[i] = 0xFF; /* fill reserved */
          }
        }
        gTPTxCnxn.mPToSend--;
        if (gTPTxCnxn.mPToSend) /* more packets in this sequence */
        {
          gTPTxCnxn.mSequence++;
        }
        else
        {
          gTPTxCnxn.mState = CMDT_TX_STATE_OPEN;
        }
        gTPTxCnxn.mTimer = Tim_GetCurrentTime();
      }
      else if (gTPTxCnxn.mState==BAM_TX_STATE_DATA)
      {
        gTxPGTable[TX_PGN_TPDT].mPGState = PG_TX_REQ;
        gTxPGTable[TX_PGN_TPDT].mPDUS = gTPTxCnxn.mSource;
        gTxPGTable[TX_PGN_TPDT].mSource = gDeviceAddress;
        ((struct VJ1939PGN_DATA_EB00*)gTxPGTable[TX_PGN_TPDT].mData)->mSequence = gTPTxCnxn.mSequence; /* sequence number */

        for (i=0;i<7;i++)
        {
          ((struct VJ1939PGN_DATA_EB00*)gTxPGTable[TX_PGN_TPDT].mData)->mData[i] = 

⌨️ 快捷键说明

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