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

📄 cd_util.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** CD_UTIL.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** Common portion of the ASIC independent communications device interface.
**
*****************************************************************************
*****************************************************************************
**
** Source Change Indices
** ---------------------
**
** Porting: <none>0----<major>         Customization: <none>0----<major>
**
*****************************************************************************
*****************************************************************************
**                                                                         **
** ETHERNET/IP EXAMPLE CODE                                                **
** COPYRIGHT (c) 2000-2005 ODVA (Open DeviceNet Vendor Association)		   **
**						   & ControlNet International Ltd.                 **
**                                                                         **
** All rights reserved, except as specifically licensed in writing.        **
** Use of the Ethernet/IP Example Protocol Software is subject to          **
** ODVA's and ControlNet International's Terms of Use Agreement.           **
** The following work constitutes example program code and is intended     **
** merely to illustrate useful programming techniques.  The user is        **
** responsible for applying the code correctly.  The code is provided      **
** AS IS without warranty and is in no way guaranteed to be error-free.    **
**                                                                         **
*****************************************************************************
*****************************************************************************
*/

/****************************************************************************
*****************************************************************************
**
** Change Log
** ----------
**
**
*****************************************************************************
*****************************************************************************
*/

/*
** See if this object is to be included.
*/

#include "ab.h"
#ifdef CD_EN_OBJECTS

#include "cd.h"         /* Communications Device public interfaces         */
#include "cd_util.h"    /* Communications Device private interfaces        */
#include "en_util.h"    /* Communications Device private interfaces        */

#include "um.h"         /* UCMM interfaces (for rx packet pre-routing)     */
#include "cm.h"         /* Connection Manager (for rx packet pre-routing)  */

#ifdef DEBUG_OBJECT
#include "db.h"         /* Debug object (for rx packet pre-routing)        */
#endif

/*jjw 11/1/99 */
#ifdef CD_EN_OBJECTS
#include "en.h"
#endif

#include "cm_targt.h"
#include "ECInterface.h"

/*
** start edits: October,13th 2005, H.F.
*/
#include "ad.h"         /* Application Data Area manager public interfaces */
#include "bf.h"         /* Buffer Fragment mapper public interfaces        */
#include "ad_util.h"
/*
** end edits: October,13th 2005, H.F.
*/

#include "ECUserDefined.h"	/* October,13th 2005, H.F. */


/****************************************************************************
**
** Globals
**
*****************************************************************************
*/

volatile CD_DataType CD_s[ CD_NPORTS + 1 ];
cd_DataType          cd_s;
cd_RadioactiveMaskType sRadioActiveMasks;

/****************************************************************************
**
** Public Globals
**
*****************************************************************************
*/

/*
** Fixed tag screener programming packets.
** Initially set to accept the following tags:
**
**    0x01 through 0x35
**    0x80 0x81 0x83 0x86
**    0xfe 0xff
**
** Keepers (CNA40) should also turn on 0x88.
*/


/****************************************************************************
**
** Public Services
**
*****************************************************************************
*/



/*---------------------------------------------------------------------------
** CD_Init()
**---------------------------------------------------------------------------
*/

StatusType CD_Init( UINT16 iOptions )
{
   UINT16            i;
   UINT16	         nTransportCount;



   /*
   ** Allocate/Create all resources (except for tasks).
   */
   /*
   ** Initialize all internal data structures.
   */

   if( iOptions & AB_INIT_RESOURCE )
   {
      /*
      ** Fill in default configuration information.
      */

      cd_s.bTuiMacId      = 0;
      cd_s.iLeTuiFlags    = 0;
      cd_s.lLeTuiCrc      = 0L;
      cd_s.pTrrblNutTimer = NULL;

      /*
      ** Mark all transports as unused/unallocated.
      */

      for ( i = 0; i < sizeof cd_s.apTransportRecords / sizeof cd_s.apTransportRecords[0]; i++ )
      {
         cd_s.apTransportRecords[ i ] = NULL;
      }

      /*
      ** Copy the initial structures from the ROM image
      */


/* Try to maximize the use of the fields in the 16 bit connection ID.  We need to use one part
** for the connection index.  The next part will be used as a radioactive counter for
** each connection.
*/

      nTransportCount = CD_NUM_TRANSPORTS < EN_CD_NUM_TRANSPORTS ? EN_CD_NUM_TRANSPORTS : CD_NUM_TRANSPORTS;
      sRadioActiveMasks.nTransportMask = 0;
      sRadioActiveMasks.nBitCount = 0;

      sRadioActiveMasks.nRadioactiveMask = 0xffff;
      do
      {
         sRadioActiveMasks.nTransportMask = (sRadioActiveMasks.nTransportMask << 1) | 1;
         nTransportCount >>= 1;
      	sRadioActiveMasks.nBitCount += 1;
      	sRadioActiveMasks.nRadioactiveMask >>= 1;
      }  while ( nTransportCount != 0);

   }

   /*
   ** Create the tasks & associate it with the message queues created earlier.
   */

   return( SUCCESS );

} /* end of CD_Init() */


/****************************************************************************
**
** Private Services
**
*****************************************************************************
*/

/*---------------------------------------------------------------------------
** cd_AllocateTransport()
**---------------------------------------------------------------------------
*/
StatusType cd_AllocateTransport( CD_TransportTrrblType *psTrrbl, BOOL fProducer )
{
   UINT16                  iLastTransport;
   UINT16                  iTransport;
   UINT16                  *piRadioActiveBits;
   cd_TransportRecordType *pTr;
   CM_ConnectionRecordType *psConnRecord;

   /*
   ** start edits: October,13th 2005, H.F.
   */

   t_UserDefinedAssemblyInstance *aProducerAssemblyInstance;

   /*
   ** end edits: October,13th 2005, H.F.
   */


   /*
   ** Allocate a transport record to hold enough info to operate the
   ** transport and shut it down later. Fill in enough to do a normal
   ** error recovery in case any error occurs.
   */

   pTr = GS_Malloc( sizeof( cd_TransportRecordType ) );

   if( pTr == NULL )
   {
      return( CD_TRANSPORT_ALLOC_FAIL );
   }

   UC_SetMem( pTr, 0, sizeof( cd_TransportRecordType ) );

   /*
   ** Load the basic information into the transport record.
   ** Copy the connection size data size. The actual ASIC buffer size may be
   ** larger to meet minimum packet requirements, but this is hidden
   ** from the application.
   */

   psConnRecord = psTrrbl->psConnRecord; /* Get pointer to connection record. */

   pTr->xQid            = psConnRecord->xQid;
   pTr->fDupNotify      = psConnRecord->fDupNotify;
   if ( psConnRecord->iPort == CD_CONTROLNET_PORT)
   {
      pTr->bTxRate         = psConnRecord->bProRate;
      pTr->bTxStartNut     = psConnRecord->bProStartNut;
   }
   else if ( psConnRecord->iPort == CD_ETHERNET_PORT)
   {
/*
** jjw 03/21/01 added the consumer api
*/
      pTr->lConApi         = psConnRecord->lConApi;
      pTr->lProApi         = psConnRecord->lProApi;
      pTr->lProInhib       = psConnRecord->lProInhib;
      pTr->bClassTrigger   = psConnRecord->bClassTrigger;
   }

   /*
   ** Determine if we are bridging by testing the upper bit of the transport type.
   */

   if( fProducer )
   {
   pTr->fBridged = ( psConnRecord->bProTransportType & CD_XPORT_BRIDGED_MASK )  ?
      TRUE : FALSE;
   }
   else
   {
   pTr->fBridged = ( psConnRecord->bConTransportType & CD_XPORT_BRIDGED_MASK )  ?
      TRUE : FALSE;
   }

   pTr->iClass          = psConnRecord->bClassTrigger & CM_TCT_CLASS_MASK;


   /*
   ** If this is a Class 4 or Class 5 bridged connection, pretend that it is a
   ** class 3 as far as the transports are concerned.
   */

   if( ( ( pTr->iClass == CM_TCT_CLASS_4 ) || ( pTr->iClass == CM_TCT_CLASS_5 ) )
      && pTr->fBridged )
   {
      pTr->iClass = CM_TCT_CLASS_3;
   }


   /*
   ** Search the appropriate portion of the transport pointer table
   ** based on the transport type we're creating.
   */

   if( psTrrbl->psConnRecord->iPort == CD_CONTROLNET_PORT )
   {
      if( pTr->iClass == CM_TCT_CLASS_1 )
      {
         if( fProducer == TRUE )
         {
            iTransport = CD_FIRST_C1P_TRANSPORT;
            iLastTransport = CD_LAST_C1P_TRANSPORT;
            piRadioActiveBits = &cd_s.iRadioActiveScheduledProdBits;
         }
         else
         {
            iTransport = CD_FIRST_C1C_TRANSPORT;
            iLastTransport = CD_LAST_C1C_TRANSPORT;
            piRadioActiveBits = &cd_s.iRadioActiveMultiCastConBits;
         }
      }
      else
      {
         iTransport = CD_FIRST_C3_TRANSPORT;
         iLastTransport = CD_LAST_C3_TRANSPORT;
         piRadioActiveBits = &cd_s.iRadioActiveP2PConsumerBits;
      }
   }
   else if( psTrrbl->psConnRecord->iPort == CD_ETHERNET_PORT )
   {
      if( pTr->iClass == CM_TCT_CLASS_1 )
      {
         if( fProducer == TRUE )
         {
            iTransport = EN_CD_FIRST_C1P_TRANSPORT;
            iLastTransport = EN_CD_LAST_C1P_TRANSPORT;
            piRadioActiveBits = &cd_s.iRadioActiveScheduledProdBits;
         }
         else
         {
            iTransport = EN_CD_FIRST_C1C_TRANSPORT;
            iLastTransport = EN_CD_LAST_C1C_TRANSPORT;
            piRadioActiveBits = &cd_s.iRadioActiveMultiCastConBits;
         }
      }
      else
      {
         iTransport = EN_CD_FIRST_C3_TRANSPORT;
         iLastTransport = EN_CD_LAST_C3_TRANSPORT;
         piRadioActiveBits = &cd_s.iRadioActiveP2PConsumerBits;
      }
   }
   else
   {
      GS_Free( pTr );
      return( CD_TRANSPORT_ALLOC_FAIL );
   }


   /*
   ** Find a place in the transport pointer list.
   ** Bail if it's full.
   ** Stuff the pointer in the list and adjust the transport ID if it fits.
   */

   while ( (  ( CD_s[ psTrrbl->psConnRecord->iPort ].papTransportRecords )[ iTransport - 1 ]  != NULL ) &&
      ( iTransport <= iLastTransport) )
   {
      iTransport++;
   }

   if( ( iTransport > iLastTransport ) || ( iTransport == CD_TUI_TRANSPORT ) )
   {
      GS_Free( pTr );
      return( CD_TRANSPORT_ALLOC_FAIL );
   }

   ( CD_s[ psTrrbl->psConnRecord->iPort ].papTransportRecords )[ iTransport - 1 ]  = pTr;

   /*
   ** Assign TransportId by incrementing the RadioActive Bit and ORing in Transport number.
   */

   *piRadioActiveBits += 1;
   *piRadioActiveBits &= sRadioActiveMasks.nRadioactiveMask;
    pTr->iTransportId = ( ( *piRadioActiveBits << sRadioActiveMasks.nBitCount ) | iTransport );

   /*
   ** jjw changed the connection record transport ID to NOT use the radioactive bits.  Using the
   ** radioactive bits in the connection record forces us to include connection device information
   ** all the way up to the AD level.
   */

   if( fProducer == TRUE )
   {
      psTrrbl->psConnRecord->iProTransportId = iTransport;


	  /*
	  ** start edits: October,13th 2005, H.F.
	  **
	  ** store the Producers Application Data Area ID to the transport record
	  ** 
	  */

	  if( aProducerAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psTrrbl->psConnRecord->iProConnPoint ) )
		  pTr->itsProAssemDataAreaId = aProducerAssemblyInstance->itsAppDataAreaId;

	  /*
	  ** end edits: October,13th 2005, H.F.
	  */
   }
   else
   {
      psTrrbl->psConnRecord->iConTransportId = iTransport;
   }
   return( SUCCESS );

} /* End of cd_AllocateTransport() */


/*---------------------------------------------------------------------------
** cd_CommissionTransports()
**---------------------------------------------------------------------------
*/

StatusType cd_CommissionTransports( CD_TransportTrrblType *psTrrbl )
{
   StatusType               eStatus;
   UINT16                   iClass;
   INT32                    iError;
   UINT16                   iTransport;
   cd_TransportRecordType  *pTr;

⌨️ 快捷键说明

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