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

📄 ecuserdefined_obj.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** USERDEFINED_OBJ.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** This source module implements the Identity Object.
**
** This implementation of the object has been made as option parameter driven
** as possible.  By changing the defined "device profile" in AB_ENV.h and
** AB_CFG.h, the application developer can modify the behavior of the
** Device Object.
** It should NOT be necessary to directly modify the code in this module.
**
*****************************************************************************
*****************************************************************************
**
** 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
** ----------
**
**
*****************************************************************************
*****************************************************************************
*/

#include "ab.h"
#include "cd.h"         /* Communications Device public interfaces         */
#include "mr.h"         /* Message Router public interfaces                */
#include "cd_util.h"

#include "ECInterface.h"

#include "ECUserDefined_obj.h"


/***************************************************************************/

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

GS_MsgQueueType   USERDEFINED_xQid;



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


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



/*---------------------------------------------------------------------------
** USERDEFINED_Init()
**---------------------------------------------------------------------------
*/

StatusType UserDefined_Init( UINT16 iOptions )
{
   GS_TaskSeedType            sSeed;
   MR_RegistrationTrrblType  *pMrTrrbl;
   unsigned int cc;

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

   if( iOptions & AB_CREATE_RESOURCE )
   {
      /*
      ** Create the task's request queue.
      */
      USERDEFINED_xQid = GS_NewMsgQueue();
   }

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

   if( iOptions & AB_INIT_RESOURCE )
   {

      /*
      ** Initialize the instance attributes to the default values.
      */
   }

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

   if( iOptions & AB_CREATE_TASK )
   {
      sSeed.pRoutine   = UserDefined_ObjectTask;
      sSeed.pParameter = NULL;
      sSeed.pStack     = NULL;
      sSeed.iStackSize = USERDEFINED_STACK_SIZE;
      sSeed.nPrio      = USERDEFINED_TASK_PRIO;
      sSeed.pTaskName  = "USRD";

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

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

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

		/* ! register user defined classes */
		for( cc=0; cc<gUserDefined->itsClassesCount; cc++ ){

			/* ! register class */
			pMrTrrbl = GS_NewTrrbl( MR_RegistrationTrrblType );
			pMrTrrbl->eRequest  = TREQ_REGISTER_OBJECT;
			pMrTrrbl->iClass    = gUserDefined->itsClasses[cc].itsClassCode;
			pMrTrrbl->iInstance = MR_CLASS_AND_INSTANCES;
			pMrTrrbl->iPort     = MR_ALL_PORTS;
			pMrTrrbl->xQ        = USERDEFINED_xQid;

			GS_PutTrrbl( MR_xQid, pMrTrrbl );
		}
   }

   return( SUCCESS );

} /* end of USERDEFINED_Init() */


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



/*---------------------------------------------------------------------------
** UserDefined_ObjectTask()
**---------------------------------------------------------------------------
*/

TASKRETURN UserDefined_ObjectTask( TASKPARAM )
{
   CB_ComBufType            *pComBuf;
   CI_IoiType               *pIOI;
   UINT8                     bService;
   UserDefined_upsTrrblType  upsTrrbl;
   unsigned int              i;
   t_Class                   *aClass;

   /*
   ** Process request tribbles one at a time (in an endless task loop).
   */

   while ( 1 )
   {

		/*
		** Process tribbles one at a time.
		** Make sure we've gotten an expected tribble.
		*/

		upsTrrbl.Generic = GS_TakeTrrbl( USERDEFINED_xQid );

		/* ! find Class */
		aClass = NULL;
		for( i=0; i<gUserDefined->itsClassesCount; i++ ){
			if( gUserDefined->itsClasses[i].itsClassCode==upsTrrbl.Packet->iClass ){
				aClass = &gUserDefined->itsClasses[i];
				break;
			}
		}
		if( aClass==NULL ){

			/* ! */
			GS_LogEvent( UNKNOWN_TRRBL_REQUEST, upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL );

			/* ! */
			continue;
		}


		/* ! */
		switch ( upsTrrbl.Generic->eRequest )
		{

		   case TREQ_APP_OPEN:

		      /*
		      ** App open (initial connection request notification).
		      */

		      UserDefined_ProcessAppOpen( upsTrrbl.AppOpenClose );
		      continue;

		   case TREQ_RX_UNSCHEDULED_PACKET:

		      /*
		      ** Unscheduled packet received. Just fall through to the
		      ** packet processing code.
		      */

		      break ;

		   case TREQ_APP_CLOSE:

		      /*
		      ** Received an orphaned or null close, so just return the trrbl,
		      ** let the CM take care of it.
		      */

		      GS_ReturnTrrbl( upsTrrbl.Generic );
		      continue;

		   default:

		      GS_LogEvent( UNKNOWN_TRRBL_REQUEST, upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL );
		      continue;

		} /* end of switch( pTrrbl->eRequest ) */

		/*
		** We've received a request packet.
		** Is this a class or instance request, or something invalid.
		*/

		switch ( upsTrrbl.Packet->iInstance )
		{
		   case 0:

		      UserDefined_ProcessClassRequest( aClass, upsTrrbl.Packet );
		      GS_ReturnTrrbl( upsTrrbl.Packet );
		      break;

		   default:

				/* ! find instance */
				for( i=0; i<aClass->itsInstancesCount; i++ )
					if( aClass->itsInstances[i].itsInstanceCode==upsTrrbl.Packet->iInstance )
						break; /* ! for */

				/* ! */
				if( i<aClass->itsInstancesCount )
					if( !UserDefined_ProcessInstanceRequest( &aClass->itsInstances[i], upsTrrbl.Packet ) ){
						GS_ReturnTrrbl( upsTrrbl.Packet );
						continue;
					}

				/* ! */
				pComBuf  = upsTrrbl.Packet->pComBuf;
				pIOI     = CB_GetDataPtrComBuf( pComBuf );
				bService = pIOI->bService;
				CB_ClearComBuf( pComBuf );
				CI_PrependReplyHeader( pComBuf, bService, CI_GRC_BAD_CLASS_INSTANCE, 0 );
				GS_ReturnTrrbl( upsTrrbl.Packet );

				/* ! */
				break;
		}

   } /* end of while( 1 ) */

} /* end of UserDefined_ObjectTask() */

/*---------------------------------------------------------------------------
** UserDefined_ProcessAppOpen()
**---------------------------------------------------------------------------
*/

void UserDefined_ProcessAppOpen( CM_AppOpenCloseTrrblType *psTrrbl )
{
   CM_ConnectionRecordType *psConnRecord;

   /*
   ** Grab all of the interesting information from the tribble.
   */

   psConnRecord = psTrrbl->psConnRecord;

   if( CM_IsConnectionTypeNull( psConnRecord ) )
   {
      /*
      ** Just say YES, if Connection Type is NULL!
      */

      psTrrbl->eStatus = SUCCESS;
   }
   else
   {
      /*
      ** Somebody's trying to connect to us. Just say NO,
      ** if Connection Type is not NULL!
      */

      psTrrbl->eStatus = CM_UNCONNECTABLE_OBJECT;
   }

   GS_ReturnTrrbl( psTrrbl );

} /* end of UserDefined_ProcessAppOpen() */



/*---------------------------------------------------------------------------
** UserDefined_ProcessClassRequest()
**---------------------------------------------------------------------------
*/

void UserDefined_ProcessClassRequest( t_Class *theClass, CD_PacketTrrblType  *pTrrbl )
{
   CB_ComBufType              *pComBuf;
   CB_ComBufType              *pComBufNew;
   CI_IoiType                 *pIOI;
   UINT8                       bIOIsize;
   UINT8                       bService;
   int                         aClassAttributeSize;
   int                         aClassAttributesByteSize;
   UINT8                      *aClassAttributesBuf;
   t_Attribute                *aAttribute;
   UINT8               bSegType;
   UINT16              iAttribute,i;  /* i: index in for-loop; H.F. 05-12-2002 */
   UINT16				  iERCAttributeID; /* H.F. 05-12-2002 */

#define ERROR_RET(code){ CB_ClearComBuf( pComBuf ); CI_PrependReplyHeader( pComBuf, bService, code, 0 ); return; }

/* error code with extended status; H.F. 05-12-2002 */
#define ERROR_RET_EXT(code){ CB_ClearComBuf( pComBuf ); CI_PrependReplyHeaderWithExtendedERC( pComBuf, bService, code, 1, &iERCAttributeID ); return; }

   /*
   ** Valid tribble/combuf. Pull out the essential information.
   */

   pComBuf   = pTrrbl->pComBuf;
   pIOI      = CB_GetDataPtrComBuf( pComBuf );
   bService  = pIOI->bService;
   bIOIsize  = pIOI->bIoiSize;

   /*
   ** Class request. Get attribute all is the only thing supported.
   */

	/*
	** If there is anything remaining in the IOI, we have a problem.
	*/

   switch ( bService ){

		case CI_SC_GET_ATTR_ALL:

			/* ! */
			if( 0!=bIOIsize )
				ERROR_RET( CI_GRC_BAD_PATH );

			/*

⌨️ 快捷键说明

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