📄 db_obj.c
字号:
/****************************************************************************
*****************************************************************************
**
** 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 + -