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

📄 en_util.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** EN_UTIL.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** Common portion of the ethernet 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.    **
**                                                                         **
*****************************************************************************
*****************************************************************************
*/


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

#include "ab.h"

#ifdef CD_EN_OBJECTS

#include "cd.h"                        /* Communications Device public interfaces*/
#include "en.h"                        /* Communications Device public interfaces*/
#include "cd_util.h"                     /* Communications Device private  interfaces*/
#include "en_util.h"                     /* Communications Device private interfaces*/
#include "en_xport.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 ) */

#include "ECInterface.h"


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

UINT32          iBadClass1Tx = 0;
cd_DataType     en_cd_s;
extern ECE      sClass1Ece;

CPFHDR          sCpfHdr = {
   ENCAP_VALUE_SHORT(2),
   ENCAP_VALUE_SHORT(CPF_TAG_ADR_SEQUENCED),
   ENCAP_VALUE_SHORT(8),
   0, 0,
   0, 0,
   ENCAP_VALUE_SHORT(CPF_TAG_PKT_CONNECTED),
   0
};


extern OE_Q_ID  sClass1TxTaskMsgQueue;
extern cd_RadioactiveMaskType sRadioActiveMasks;
extern ENCAP_OBJ_TARGET list_target_data;



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


/*---------------------------------------------------------------------------
** EN_CD_Init( )
**---------------------------------------------------------------------------
*/

StatusType EN_CD_Init( UINT16 iOptions )
{
   GS_TaskSeedType sSeed;
   UINT16          i;


   /*
   ** Allocate/Create all resources ( except for tasks ).
   */
   if( iOptions & AB_CREATE_RESOURCE )
   {
      /*
      ** Create the Config task's request queue.
      */
      CD_s[CD_ETHERNET_PORT].xConfigQid = GS_NewMsgQueue( );

      /*
      ** Create the TxUnscheduled task's request queue.
      */

      CD_s[CD_ETHERNET_PORT].xTxUnschedLoQid = GS_NewMsgQueue( );
      CD_s[CD_ETHERNET_PORT].xTxUnschedHiQid = GS_NewMsgQueue( );
   }

   /*
   ** Initialize all internal data structures.
   */

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

      CD_s[CD_ETHERNET_PORT].nLinkTimeout = EN_CD_DEFAULT_LINK_TIMEOUT;
      CD_s[CD_ETHERNET_PORT].bRetryLimit = EN_CD_RETRY_LIMIT;
      CD_s[CD_ETHERNET_PORT].bUcmmCodeOverRide = UM_REQUEST_NO_RETRY;
      CD_s[CD_ETHERNET_PORT].GetTransportBuffer = EN_CD_GetTransportBuffer;
      CD_s[CD_ETHERNET_PORT].PutTransportBuffer = EN_CD_PutTransportBuffer;
      CD_s[CD_ETHERNET_PORT].iNumTransports = EN_CD_NUM_TRANSPORTS;
      CD_s[CD_ETHERNET_PORT].StopTransport = en_cd_StopTransport;
      CD_s[CD_ETHERNET_PORT].StartTransport = en_cd_StartTransport;
      CD_s[CD_ETHERNET_PORT].papTransportRecords = &en_cd_s.apTransportRecords[0];


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

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

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

   if( iOptions & AB_CREATE_TASK )
   {
      sSeed.pRoutine = EN_CD_ConfigTask;
      sSeed.pParameter = NULL;
      sSeed.pStack = NULL;
      sSeed.iStackSize = EN_CD_CONFIG_STACK_SIZE;
      sSeed.nPrio = EN_CD_CONFIG_TASK_PRIO;
      sSeed.pTaskName = "encdCfg   ";

      GS_AssociateTaskAndQueues( GS_NewTask( &sSeed ), CD_s[CD_ETHERNET_PORT].xConfigQid, GS_NO_QUEUE );

      sSeed.pRoutine = EN_CD_TxUnscheduledTask;
      sSeed.pParameter = NULL;
      sSeed.pStack = NULL;
      sSeed.iStackSize = EN_CD_TX_UNSCHED_STACK_SIZE;
      sSeed.nPrio = EN_CD_TX_UNSCHED_TASK_PRIO;
      sSeed.pTaskName = "enTxUNSCH ";

      GS_AssociateTaskAndQueues( GS_NewTask( &sSeed ),
                                CD_s[CD_ETHERNET_PORT].xTxUnschedHiQid,
                                CD_s[CD_ETHERNET_PORT].xTxUnschedLoQid );
   }

   /*
   ** Final initialization after tasks are running.
   */

   if( iOptions & AB_INIT_TASK )
   {
   }
   return ( SUCCESS );

}  /* end of EN_CD_Init( ) */


/*---------------------------------------------------------------------------
** EN_CD_TxUnscheduledTask( )
**---------------------------------------------------------------------------
*/

TASKRETURN EN_CD_TxUnscheduledTask( TASKPARAM )
{
   cd_TransportRecordType *pTranRec;
   cd_upsTrrblType upsTrrbl;
   CB_ComBufType  *pCb;
   StatusType      eStatus;

   /*
   ** Enter task loop.  Get tribbles and transmit the attached ComBufs.
   ** Perform requested termination actions.
   */

   while ( 1 )
   {
      /*
      ** Initially, assume successful completion of the request.
      */

      eStatus = SUCCESS;

      /*
      ** Take tribbles and process each one.
      ** Extract a convenience combuf pointer.
      ** Switch on the tribble request code.
      */

      upsTrrbl.Generic = GS_TakeMsgQueuePair( CD_s[CD_ETHERNET_PORT].xTxUnschedHiQid,
                                              CD_s[CD_ETHERNET_PORT].xTxUnschedLoQid,
                                              NULL );
      pCb = upsTrrbl.Packet->pComBuf;

      switch ( upsTrrbl.Generic->eRequest )
      {

      case TREQ_TX_FIXED_TAG:

         /*
         ** All other fixed tag packets.
         */

         en_cd_TxFixedTagPacket( upsTrrbl.Packet );
         break;

      case TREQ_RX_CLASS3_PACKET:
      case TREQ_RX_UNSCHEDULED_PACKET:

         /*
         ** Class 3 packet returned from the application ( server only ).
         ** Save new data and initiate a Rx verify transmission.
         */

         pTranRec = cd_LookupTransportRecord( CD_ETHERNET_PORT, upsTrrbl.Packet->iTransport );

         if( pTranRec != NULL )
         {
            /*
            ** Toss the old freshest combuf and save the new one.
            */

            if( pTranRec->pCbFreshest )
            {
               CB_DeleteComBuf( pTranRec->pCbFreshest );
            }

            pTranRec->pCbFreshest = upsTrrbl.Packet->pComBuf;

            /*
            ** Consider this as a verification and
            ** initiate a transmission with the freshest data.
            */

            pTranRec->fVerified = TRUE;
            en_cd_TxClass3Packet( upsTrrbl.Packet, pTranRec );
         }
         else
         {
            /*
            ** If the connection timed out, toss the response.
            */

            CB_DeleteComBuf( pCb );
         }
         break;


      case TREQ_CLASS3_CLIENT_TIMEOUT:

         /*
         ** Class 3 client timed out waiting for response.
         ** Retry until the connection times out.
         */

         pTranRec = cd_LookupTransportRecord( CD_ETHERNET_PORT, upsTrrbl.Timeout->iId );

         if( pTranRec != NULL )
         {
            if( pTranRec->pCbFreshest != NULL )
            {
               /*
               ** Send the latest data if there is any available.
               ** TxClass3Packet only loads the data into the ASIC.
               ** It does nothing to the combuf or the tribble.
               */

               upsTrrbl.Packet->pComBuf = pTranRec->pCbFreshest;
               en_cd_TxClass3Packet( upsTrrbl.Packet, pTranRec );

            }

            /*
            ** Reload the timeout tribble into the timer and get
            ** the timer going again.
            */

            GS_ReloadLinkedMsgTimer( pTranRec->xRetryTimer, 0, pTranRec->pRetryTot );

            /*
            ** Skip to the end of the while( 1 ) loop. This keeps us from
            ** deleting the tribble we just pulled off the queue which
            ** has just been reattached to the retry timer.
            */

            continue;
         }
         break;


      case TREQ_TX_CLASS3_REQUEST:
      case TREQ_TX_CLASS3_RESPONSE:

         /*
         ** Initiate a transmission.
         ** Request for clients, response for servers.
         **
         ** Lookup the transport record. Bail if the transport is no longer
         ** active or there is no data to transmit.
         */

         pTranRec = cd_LookupTransportRecord( CD_ETHERNET_PORT, upsTrrbl.Packet->iTransport );

         if( ( pTranRec != NULL ) &&
             ( pTranRec->pCbFreshest != NULL ) )
         {
            if( pTranRec->fServerConsumer )
            {
               /*
               ** We're a server. Mark the request as verified.
               */

               pTranRec->fVerified = TRUE;
            }
            else
            {
               /*
               ** We're a client. Retrigger the retry timer.
               */

               GS_RetriggerTimer( pTranRec->xRetryTimer );
            }

            /*
            ** Send the latest data in any case.
            */

            upsTrrbl.Packet->pComBuf = pTranRec->pCbFreshest;
            en_cd_TxClass3Packet( upsTrrbl.Packet, pTranRec );
         }
         break;


      case TREQ_WRITE_CLASS3_TX_DATA:

         /*
         ** New class 3 transmit data for a
         ** request ( client ) or response ( server ).
         */

         pTranRec = cd_LookupTransportRecord( CD_ETHERNET_PORT, upsTrrbl.Packet->iTransport );

         if( pTranRec != NULL )
         {
            /*
            ** Toss the old freshest combuf ( if any ) and save the new one.
            */

            if( pTranRec->pCbFreshest )
            {
               CB_DeleteComBuf( pTranRec->pCbFreshest );
            }

            pTranRec->pCbFreshest = upsTrrbl.Packet->pComBuf;


⌨️ 快捷键说明

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