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

📄 en_xport.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** EN_XPORT.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** Transport management services for the TCPIP 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.    **
**                                                                         **
*****************************************************************************
*****************************************************************************
*/

#include "cd.h"                  /* Communications Device public interface */
#include "cm.h"                  /* Connection Manager public interfaces   */
#include "nt.h"
#ifdef CD_EN_OBJECTS
#include "string.h"
#include "cd_util.h"
#include "en_util.h"
#include "en_xport.h"            /* Ethernet transports */
#include "en.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 "ECInterface.h"

/****************************************************************************
**
** Private Globals
**
****************************************************************************
*/
extern CPFHDR   sCpfHdr;

extern cd_RadioactiveMaskType sRadioActiveMasks;

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


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

/*---------------------------------------------------------------------------
** en_cd_StartTransport( )
**---------------------------------------------------------------------------
*/

StatusType en_cd_StartTransport( cd_TransportRecordType * pTr )
{
   StatusType      eStatus;
   BOOL            fEntryFound = FALSE;
   CPFHDR         *msg;

   /*
   ** Determine TCPIP ASIC Transport Type from Forward Open
   ** Transport Class and Trigger byte.  Only support transport
   ** classes 1 and 3.
   */

   switch ( pTr->iClass )
   {
   case CM_TCT_CLASS_1:

      /*
      ** Allocate the dedicated transport buffers.
      ** Bail out if the allocation fails.
      ** Zero data size is a special case for producing heartbeats.
      */

      pTr->iBufState = INITIAL;

     /*
     ** Allocate temporary storage space for the xmit buffers
     */

     pTr->pBufA = GS_Malloc( pTr->iDataSize + sizeof( pTr->iLeSeqCount )  ); 

     pTr->xSBufAccess = GS_NewSemaphore( );
     if ( ( pTr->pBufA == NULL ) ||
         ( pTr->xSBufAccess == NULL ) )
     {
        eStatus = CD_RESOURCE_UNAVAILABLE;
        goto Bailout;
     }                              /* End if buffer allocation test */
      UC_SetMem(pTr->pBufA, 0, pTr->iDataSize + sizeof(pTr->iLeSeqCount));

      pTr->pBufB = GS_Malloc(pTr->iDataSize + sizeof(pTr->iLeSeqCount) +
                             sizeof( CPFHDR ) );
      if (pTr->pBufB == NULL)
      {
         GS_LogEvent(EN_RESOURCE,
                     0,
                     0,
                     FATAL);
         goto Bailout;
      }                                  /* End if message == NULL */
      msg = (CPFHDR *) (pTr->pBufB);

       /*
       ** Copy the static template information and then the data...
       */

      UC_CopyMem((char *) msg, (char *) &sCpfHdr, sizeof sCpfHdr);
      *((UINT32 *) msg->aiAs_cid) = ENCAP_TO_PL(*(UINT32 *) pTr->abTxTag);
      msg->iDs_length = ENCAP_TO_HS(pTr->iDataSize + 2);    /* Include 2 bytes of Transport sequence count */
       /*
       ** Invalidate buffer.
       */
      *((UINT32 *) msg->aiAs_seq) = ~ENCAP_TO_PL(pTr->iSeqCount);

     /*
     ** Fill the semaphore so we can "Get" a transport record 
     */
     GS_SetSemaphore( pTr->xSBufAccess ); 
      /* 
      ** If this is a bridged connection do not do any RPI related functions.
      */
/*jjw 8/22/00 */
      if ( pTr->fBridged )
         break;     /* break out of class 1 functions */

      if ( pTr->fServerConsumer )       /* Consumer */
      {
      }                                 /* End if consumer */
      else                              /* Producer */
      {
         /*
         ** Verify that a valid schedule request is being made
         */
/* jjw Verify the PIT and API parameters here */
         if ( pTr->lProApi < (UINT32)GS_TICKPERIOD * 1000 )      /* The producer API is less than Timer */
         {
            eStatus = CD_UNSUPPORTED_BANDWIDTH;
            goto Bailout;
         }                              /* End if API */
         /*
         ** Call the function to resend the data on an RPI basis directly.  
         ** Quicker response than using a task, and less overhead.  However
         ** it could overwhelm the system if to many low RPI connections
         ** exist
         */
          pTr->xAPITimer = GS_NewTaskletPTimer( TIMER_CONTINUOUS,
                                              ( ( pTr->lProApi / 1000 ) - GS_TICKPERIOD ) * 2, 
                                              ( pTr->lProApi / 1000 ) - GS_TICKPERIOD,
                                   (FD_pFuncPType) en_cd_ProcessAPITxList,
                                   pTr);
          GS_StartTimer( pTr->xAPITimer );
      }                                 /* End if producer */

      break;



   case CM_TCT_CLASS_3:

      break;


   default:

      /*
      ** Unsupported transport class.
      */

      eStatus = CD_UNSUPPORTED_TRANSPORT;
      goto Bailout;

   }                                    /* End of switch( pTr->iClass ) */

   /*
   ** Transport configuration complete. This starts the transport.
   */

   return ( SUCCESS );

Bailout:

   /*
   ** Some sort of problem detected during setup.
   ** Free the buffers, the transport & toss the transport record.
   ** Don't forget to log a fault.
   */

   GS_LogEvent( eStatus, pTr->iTransportId, pTr, WARNING );
   en_cd_StopTransport( pTr );
   return ( eStatus );
}                                       /* End of en_cd_StartTransport( ) */



/*---------------------------------------------------------------------------
** en_cd_StopTransport( )
**---------------------------------------------------------------------------
*/

void en_cd_StopTransport( cd_TransportRecordType * pTr )
{
   BOOL            fEntryFound = FALSE;

   /*
   ** Delete the screener / API TX list entries for this transport
   */

   switch ( pTr->iClass )
   {
   case CM_TCT_CLASS_1:

      if ( pTr->fServerConsumer )       /* Consumer */
      {
      }                                 /* End if consumer */
      else                              /* Producer */
      {
         /*
         ** Find the transport record in the SchTx List
         */

         /* 
         ** If this is a bridged connection do not do any API related functions.
         */
/*jjw 8/22/00*/
          if ( !pTr->fBridged )
          {
             /*
             ** Non task mode does not have a tribble to delete
             */
             if ( pTr->xAPITimer != NULL )
                GS_DeleteTimer( pTr->xAPITimer );
          }  
      }                                 /* End if producer */
      en_cd_FreeTransportBuffers(pTr);
      break;


   case CM_TCT_CLASS_3:

      break;

   }                                    /* End of switch( pTr->iClass ) */
}                                       /* End of en_cd_StopTransport( ) */




/*---------------------------------------------------------------------------
** en_cd_FreeTransportBuffers( )
**---------------------------------------------------------------------------
*/

StatusType en_cd_FreeTransportBuffers( cd_TransportRecordType * psTransportRecord )
{
   /*
   ** If a API Tx buffer has been allocated for this transport, return it.
   */

   if ( psTransportRecord->xSBufAccess != NULL )
   {
      GS_WaitSemaphore(  psTransportRecord->xSBufAccess  );
      GS_DeleteSemaphore( psTransportRecord->xSBufAccess );
      psTransportRecord->xSBufAccess = NULL;
   }

   if ( psTransportRecord->pBufA != NULL )
   {
      GS_Free( psTransportRecord->pBufA );
      psTransportRecord->pBufA = NULL;
   }

   if (psTransportRecord->pBufB != NULL)
   {
      GS_Free(psTransportRecord->pBufB);
      psTransportRecord->pBufB = NULL;
   }

   return ( SUCCESS );

}                                       /* end of en_cd_FreeTransportBuffers( ) */



/*---------------------------------------------------------------------------
** en_cd_ProcessAPITxList( )
**---------------------------------------------------------------------------
*/

void en_cd_ProcessAPITxList( cd_TransportRecordType *pTransport )
{
   
   UINT16          iNumBytesCopied;


   if( ( pTransport->iBufState < A_CURRENT_B_FREE ) )
      return;

   /*
   ** Time to send this message, it has met or exceeded its API
   */

   /*
   ** Get access to the buffer
   */

   if( EN_CD_GetTransportBuffer( pTransport->iTransportId ) == NULL )
      return;                /* skip the rest of the processing */

   if( pTransport->pTxCopyFunction )
   {
      /*
      ** Call producer copy function using a pointer
      **
      ** Here we request that iDataSize bytes be copied.
      ** However, the actual number of bytes transfered is returned by
      ** the function.  The returned value could be zero, indicating
      ** that no data is to be sent.  In that case, continue with the next
      ** item on the list.
      **
      ** Note that pTxBuffer->pData is a pointer to where to put the
      ** transport sequence count and pTxBuffer->pData + 2 is a pointer to where
      ** to put the data.
      */
      iNumBytesCopied = ( pTransport->pTxCopyFunction )
             ( pTransport->xTxAppHandle,           /* Parameter for copy function */
               (LeUINT16*) pTransport->pBufA,      /* Pointer to transport sequence count */
               (UINT8*)(pTransport->pBufA + 2),    /* Pointer to start of data */
               pTransport->iDataSize );            /* Data length */

      if ( iNumBytesCopied == 0xFFFF ) 
      {
         EN_CD_PutTransportBuffer( pTransport->iTransportId );
         return;                /* skip the rest of the processing */
      }

      /*
      ** Change endian of the transport sequence number 
      */

      *(UINT16*) pTransport->pBufA = ENCAP_VALUE_SHORT(*(UINT16*) pTransport->pBufA );

   }                              /* end if copy function */

   en_cd_Class1TxPacket( pTransport->pBufA, pTransport );   /* xmit data */


   /*
   ** start edits: October,13th 2005, H.F.:
   **
   ** update data after transmission
   ** (NOTE: An ad_ResyncCommAndAppBufs() call before executing
   ** en_cd_Class1TxPacket() does not work!)
   */

   GS_PutMsgQueueBits( AD_xQid, AD_BIT_MSG_SENT_PRO );

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

#endif                                  /* CD_EN_OBJECTS */



/****************************************************************************
**
** End of EN_XPORT.C
**
*****************************************************************************
*/

⌨️ 快捷键说明

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