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

📄 db_obj.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** DB_OBJ.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** Debug Object.
**
** This source module implements an object which allows interrogation and
** inspection of "internals" of the example code and application code.
**
** The Debug Object (DB) can accept tribbles generated locally within its
** own device or remotely from a client using unconnected fixed tag messages.
** The DB may communicate either using UCMM, or alternatively, by using two
** special (reserved) fixed tags specifically for this purpose.
**
*****************************************************************************
*****************************************************************************
**
** Source Change Indices
** ---------------------
**
** Porting: <none>0----<major>         Customization: <none>----4<major>
**
**    *  Application developers may wish to provide their own application
**       specific debug support.
**
*****************************************************************************
*****************************************************************************
**                                                                         **
** 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 DEBUG_OBJECT


#include "cd.h"         /* communications device public interfaces         */
#include "cd_util.h"    /* communications device private interfaces        */

#include "cm.h"         /* Connection Manager public interfaces            */

#include "gs_util.h"    /* general services component private interfaces   */

#include "um.h"         /* UCMM services public interfaces                 */
#include "um_util.h"    /* UCMM services private interfaces                */

#include "mr.h"         /* message router public interfaces                */

#include "db.h"         /* global definitions                              */
#include "db_obj.h"     /* local scope definitions for this module         */



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

GS_MsgQueueType DB_xQid;



/****************************************************************************
**
** Private Globals
**
*****************************************************************************
*/

db_DataType db_s;



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

/*---------------------------------------------------------------------------
** DB_Init()
**---------------------------------------------------------------------------
*/

StatusType DB_Init( UINT16 iOptions )
{
   GS_TaskSeedType            sSeed;
   MR_RegistrationTrrblType  *pMrTrrbl;


   /*
   ** Allocate/Create all resources (except for tasks).
   */

   if( iOptions & AB_CREATE_RESOURCE )
   {
      /*
      ** Create the task's request queue & watchdog timer.
      */

      DB_xQid = GS_NewMsgQueue( );
      db_s.xTimer = GS_NewBitMsgTimer( TIMER_ONE_SHOT, 250L, 250L, DB_xQid, 0x0001 );
   }

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

   if( iOptions & AB_INIT_RESOURCE )
   {
      db_s.pRqTrrbl  = NULL;
      db_s.iSeqCount = 0;
   }

   /*
   ** Create the task & associate it with the message queue created earlier.
   */

   if( iOptions & AB_CREATE_TASK )
   {
      sSeed.pRoutine   = db_ObjectTask;
      sSeed.pParameter = NULL;
      sSeed.pStack     = NULL;
      sSeed.iStackSize = DB_STACK_SIZE;
      sSeed.nPrio      = DB_TASK_PRIO;
      sSeed.pTaskName  = "DB  ";

      GS_AssociateTaskAndQueues( GS_NewTask( &sSeed ), DB_xQid, GS_NO_QUEUE );
   }

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

   if( iOptions & AB_INIT_TASK )
   {
      /*
      ** Register ourselves with the message router.
      */

      pMrTrrbl = GS_NewTrrbl( MR_RegistrationTrrblType );
      pMrTrrbl->eRequest  = TREQ_REGISTER_OBJECT;
      pMrTrrbl->iClass    = DB_CLASS_NUMBER;
      pMrTrrbl->iInstance = MR_CLASS_AND_INSTANCE_1;
      pMrTrrbl->iPort     = MR_ALL_PORTS;
      pMrTrrbl->xQ        = DB_xQid;
      GS_PutTrrbl( MR_xQid, pMrTrrbl );
   }

   return( SUCCESS );

} /* end of DB_Init() */



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

/*---------------------------------------------------------------------------
** db_ObjectTask()
**---------------------------------------------------------------------------
*/

TASKRETURN db_ObjectTask( TASKPARAM )
{
   UINT8                  bService;
   CB_ComBufType         *pComBuf;
   DB_upsHeaderType       upsHeader;
   db_upsTrrblType        upsTrrbl;


   GS_UseCritical( );

   /*
   ** Process requests forever.
   */

   while( 1 )
   {
      upsTrrbl.Generic = GS_TakeTrrbl( DB_xQid );

      switch( upsTrrbl.Generic->eRequest )
      {
      case TREQ_BIT_MSG:

         /*
         ** Watchdog timed out on a remote request.
         ** Check for timeout and completion that crossed in the mail.
         */

         if( db_s.pRqTrrbl == NULL )
         {
            break;
         }

         /*
         ** There is a request pending that timed out.
         ** Send an error response back to the requestor.
         ** Start by pulling the interesting stuff out of the request packet.
         */

         pComBuf = db_s.pRqTrrbl->pComBuf;
         CB_ShrinkComBuf( pComBuf, sizeof( DB_LeDirectHeaderType ) );
         upsHeader.Generic = CB_GetDataPtrComBuf( pComBuf );
         bService = upsHeader.Generic->bService;

         /*
         ** Now build a matching error reply packet.
         */

         CB_ClearComBuf( pComBuf );
         CI_PrependReplyHeader( pComBuf, bService, CI_GRC_FAILURE, 0 );

         /*
         ** Return the original request tribble (with error reply attached).
         ** Clear the request parking spot.
         */

         GS_ReturnTrrbl( db_s.pRqTrrbl )
         db_s.pRqTrrbl = NULL;
         break;


      case TREQ_PROCESS_REQUEST:

         /*
         ** Internal request.  Is it a local or remote request?
         */

         if( upsTrrbl.Debug->bMacId == 0 )
         {
            /*
            ** Local request.  Process the packet
            ** and hook the response to the request tribble.
            */

            upsTrrbl.Debug->pComBuf = db_ProcessPacket( upsTrrbl.Debug->pComBuf );
         }
         else
         {
            /*
            ** Remote request.
            ** If there's one in progress, bail out.
            */

            if( db_s.pRqTrrbl != NULL )
            {
               upsTrrbl.Debug->eStatus = FAILURE;
               GS_ReturnTrrbl( upsTrrbl.Debug );
               break;
            }

            /*
            ** Park this tribble and forward the packet
            ** on to the other node via the debug request fixed tag.
            ** The response will come back via the debug response fixed tag.
            */

            db_s.pRqTrrbl = upsTrrbl.Debug;
            upsTrrbl.Packet = GS_NewTrrbl( CD_PacketTrrblType );
            upsTrrbl.Packet->eRequest     = TREQ_TX_FIXED_TAG;
            upsTrrbl.Packet->pComBuf      = db_s.pRqTrrbl->pComBuf;
            db_s.iSeqCount++;
            CB_PrependComBuf( upsTrrbl.Packet->pComBuf, &db_s.iSeqCount, sizeof( DB_LeDirectHeaderType ) );
            CB_AttachComBuf( upsTrrbl.Packet->pComBuf );
            GS_PutTrrbl( CD_s[ CD_CONTROLNET_PORT ].xTxUnschedLoQid, upsTrrbl.Packet );

            /*
            ** Start up the watchdog timer.
            */

            GS_RestartTimer( db_s.xTimer, 0 );
            continue;
         }
         break;

      case TREQ_RX_UNSCHEDULED_PACKET:

         /*
         ** Packet received via UCMM or a class 3 connection.
         ** No debug protocol header to strip, so just process the packet.
         */

         upsTrrbl.Packet->pComBuf = db_ProcessPacket( upsTrrbl.Packet->pComBuf );
         break;
      }

      /*
      ** Return the tribble/packet.
      */

      GS_ReturnTrrbl( upsTrrbl.Packet );
   }

} /* end of db_ObjectTask() */


/*---------------------------------------------------------------------------
** db_ProcessPacket()
**---------------------------------------------------------------------------
*/

CB_ComBufType* db_ProcessPacket( CB_ComBufType *pComBuf )
{
   UINT8                     bCommand;
   UINT8                     bGRC;
   UINT8                     bNumTasks;
   UINT8                     bParameters;
   UINT8                     bService;
   UINT16                    i;
   UINT16                    iTask;
   UINT32                    lAddress;
   UINT32                    lSize;
   UINT32                    lHeapStart;
   UINT32                    lHeapStaticStart;
   UINT32                    lHeapStaticCurrent;
   StatusType                    eStatus;
   DB_CnetConnectionUcmmCountsType  *psConnCounts;
   DB_LeCnetNetworkStatusType   *psNetStatus;
   DB_LeCnetTransportStatusType *psTransStatus;
   DB_LeEventLogEntryType       *psLeEventLogEntry;
   DB_LeHeapInfoType        *psLeHeapInfo;
   DB_LeHeapStatusType      *psLeHeapStatus;
   DB_LeLogCountType        *psLeLogCounts;
   DB_LeNodeTimeType        *psLeNodeTime;
   DB_LeRevisionType        *psLeRevision;
   DB_LeStaticHeapStatusType   *psLeStaticHeapStatus;
   DB_LeTaskInfoType        *psLeTaskInfo;
   DB_LeTaskStatusType          *psLeTaskStatus;
   DB_LeVersionsType           *psLeVersions;
   cd_TransportRecordType      *pTranRec;
   DB_upsHeaderType             upsHeader;
   GS_EventRecordType            sEventRecord;
   GS_SysTimeType            sTime;
   gs_TaskDataType              *psTaskData;
#ifdef DEBUG_HEAP_BUCKET_DEMAND
   UINT32                    l;
#endif

   /*
   ** Grab the header & save the service code for the return trip.
   */

   upsHeader.Generic = CB_GetDataPtrComBuf( pComBuf );
   bService    = upsHeader.Generic->bService;
   bCommand    = upsHeader.Generic->bCommand;
   bParameters = upsHeader.Generic->bParameters;
   bGRC     = CI_GRC_SUCCESS;
   CB_ClearComBuf( pComBuf );

   /*
   ** Process per the service code
   */

   switch( bService )
   {
   case DB_SC_EXECUTE_COMMAND:

      /*
      ** Process per the command code.
      */

      switch( bCommand )
      {
      case DB_CMD_GET_CNET_CON_UCMM_COUNTS:

         /*
         ** Get the current connection counts.
         */

         if( db_TradeComBuf( &pComBuf, sizeof( DB_CnetConnectionUcmmCountsType ), bService ) != SUCCESS )
         {
            goto BailOut;
         }

         psConnCounts = CB_GetDataPtrComBuf( pComBuf );
         psConnCounts->bClass1Config = 0;
         psConnCounts->bClass1Active = 0;
         psConnCounts->bClass3Server = 0;
         psConnCounts->bClass3Client = 0;

         for( i = 0; i < CD_NUM_CLASS_3 ; i++ )
         {
            pTranRec = cd_s.apTransportRecords[ CD_FIRST_C3_TRANSPORT - 1 + i ];

            if( pTranRec != NULL )
            {
               pTranRec->fServerConsumer ? psConnCounts->bClass3Server++ : psConnCounts->bClass3Client++;
            }
         }

         psConnCounts->bUcmmClientMax     = UM_UCMM_MAX_CLIENT_TRANS_RECS;
         psConnCounts->bUcmmClientHiWater = um_s.iMaxActiveClientRecords;
         psConnCounts->bUcmmClientCurrent = um_s.iActiveClientRecords;
         psConnCounts->bUcmmServerMax     = UM_UCMM_MAX_SERVER_TRANS_RECS;
         psConnCounts->bUcmmServerHiWater = um_s.iMaxActiveServerRecords;
         psConnCounts->bUcmmServerCurrent = um_s.iActiveServerRecords;

         break;


      case DB_CMD_GET_CNET_NETWORK_STATUS:

         /*
         **= Get various portions of general network operational status.
         */

         if( db_TradeComBuf( &pComBuf, sizeof( DB_LeCnetNetworkStatusType ), bService ) != SUCCESS )
         {
            goto BailOut;
         }

         psNetStatus = CB_GetDataPtrComBuf( pComBuf );
         psNetStatus->iLeIdObjStatus  = 0; /* UC_iTOiLe( ID_GetObjectStatus() ); */
         psNetStatus->iLeDeviceStatus = 0; /* UC_iTOiLe( ID_GetStatus() );		 */

         psNetStatus->bKeeperMacId  = 0;
         psNetStatus->bTuiFlags     = 0;

         break;


      case DB_CMD_GET_CNET_TRANSPORT_STATUS:

         /*
         **= Get various portions of general network operational status.
         */

⌨️ 快捷键说明

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