📄 cd_util.c
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** CD_UTIL.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** Common portion of the ASIC independent 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. **
** **
*****************************************************************************
*****************************************************************************
*/
/****************************************************************************
*****************************************************************************
**
** Change Log
** ----------
**
**
*****************************************************************************
*****************************************************************************
*/
/*
** See if this object is to be included.
*/
#include "ab.h"
#ifdef CD_EN_OBJECTS
#include "cd.h" /* Communications Device public interfaces */
#include "cd_util.h" /* Communications Device private interfaces */
#include "en_util.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) */
#ifdef DEBUG_OBJECT
#include "db.h" /* Debug object (for rx packet pre-routing) */
#endif
/*jjw 11/1/99 */
#ifdef CD_EN_OBJECTS
#include "en.h"
#endif
#include "cm_targt.h"
#include "ECInterface.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 "ECUserDefined.h" /* October,13th 2005, H.F. */
/****************************************************************************
**
** Globals
**
*****************************************************************************
*/
volatile CD_DataType CD_s[ CD_NPORTS + 1 ];
cd_DataType cd_s;
cd_RadioactiveMaskType sRadioActiveMasks;
/****************************************************************************
**
** Public Globals
**
*****************************************************************************
*/
/*
** Fixed tag screener programming packets.
** Initially set to accept the following tags:
**
** 0x01 through 0x35
** 0x80 0x81 0x83 0x86
** 0xfe 0xff
**
** Keepers (CNA40) should also turn on 0x88.
*/
/****************************************************************************
**
** Public Services
**
*****************************************************************************
*/
/*---------------------------------------------------------------------------
** CD_Init()
**---------------------------------------------------------------------------
*/
StatusType CD_Init( UINT16 iOptions )
{
UINT16 i;
UINT16 nTransportCount;
/*
** Allocate/Create all resources (except for tasks).
*/
/*
** Initialize all internal data structures.
*/
if( iOptions & AB_INIT_RESOURCE )
{
/*
** Fill in default configuration information.
*/
cd_s.bTuiMacId = 0;
cd_s.iLeTuiFlags = 0;
cd_s.lLeTuiCrc = 0L;
cd_s.pTrrblNutTimer = NULL;
/*
** Mark all transports as unused/unallocated.
*/
for ( i = 0; i < sizeof cd_s.apTransportRecords / sizeof cd_s.apTransportRecords[0]; i++ )
{
cd_s.apTransportRecords[ i ] = NULL;
}
/*
** Copy the initial structures from the ROM image
*/
/* Try to maximize the use of the fields in the 16 bit connection ID. We need to use one part
** for the connection index. The next part will be used as a radioactive counter for
** each connection.
*/
nTransportCount = CD_NUM_TRANSPORTS < EN_CD_NUM_TRANSPORTS ? EN_CD_NUM_TRANSPORTS : CD_NUM_TRANSPORTS;
sRadioActiveMasks.nTransportMask = 0;
sRadioActiveMasks.nBitCount = 0;
sRadioActiveMasks.nRadioactiveMask = 0xffff;
do
{
sRadioActiveMasks.nTransportMask = (sRadioActiveMasks.nTransportMask << 1) | 1;
nTransportCount >>= 1;
sRadioActiveMasks.nBitCount += 1;
sRadioActiveMasks.nRadioactiveMask >>= 1;
} while ( nTransportCount != 0);
}
/*
** Create the tasks & associate it with the message queues created earlier.
*/
return( SUCCESS );
} /* end of CD_Init() */
/****************************************************************************
**
** Private Services
**
*****************************************************************************
*/
/*---------------------------------------------------------------------------
** cd_AllocateTransport()
**---------------------------------------------------------------------------
*/
StatusType cd_AllocateTransport( CD_TransportTrrblType *psTrrbl, BOOL fProducer )
{
UINT16 iLastTransport;
UINT16 iTransport;
UINT16 *piRadioActiveBits;
cd_TransportRecordType *pTr;
CM_ConnectionRecordType *psConnRecord;
/*
** start edits: October,13th 2005, H.F.
*/
t_UserDefinedAssemblyInstance *aProducerAssemblyInstance;
/*
** end edits: October,13th 2005, H.F.
*/
/*
** Allocate a transport record to hold enough info to operate the
** transport and shut it down later. Fill in enough to do a normal
** error recovery in case any error occurs.
*/
pTr = GS_Malloc( sizeof( cd_TransportRecordType ) );
if( pTr == NULL )
{
return( CD_TRANSPORT_ALLOC_FAIL );
}
UC_SetMem( pTr, 0, sizeof( cd_TransportRecordType ) );
/*
** Load the basic information into the transport record.
** Copy the connection size data size. The actual ASIC buffer size may be
** larger to meet minimum packet requirements, but this is hidden
** from the application.
*/
psConnRecord = psTrrbl->psConnRecord; /* Get pointer to connection record. */
pTr->xQid = psConnRecord->xQid;
pTr->fDupNotify = psConnRecord->fDupNotify;
if ( psConnRecord->iPort == CD_CONTROLNET_PORT)
{
pTr->bTxRate = psConnRecord->bProRate;
pTr->bTxStartNut = psConnRecord->bProStartNut;
}
else if ( psConnRecord->iPort == CD_ETHERNET_PORT)
{
/*
** jjw 03/21/01 added the consumer api
*/
pTr->lConApi = psConnRecord->lConApi;
pTr->lProApi = psConnRecord->lProApi;
pTr->lProInhib = psConnRecord->lProInhib;
pTr->bClassTrigger = psConnRecord->bClassTrigger;
}
/*
** Determine if we are bridging by testing the upper bit of the transport type.
*/
if( fProducer )
{
pTr->fBridged = ( psConnRecord->bProTransportType & CD_XPORT_BRIDGED_MASK ) ?
TRUE : FALSE;
}
else
{
pTr->fBridged = ( psConnRecord->bConTransportType & CD_XPORT_BRIDGED_MASK ) ?
TRUE : FALSE;
}
pTr->iClass = psConnRecord->bClassTrigger & CM_TCT_CLASS_MASK;
/*
** If this is a Class 4 or Class 5 bridged connection, pretend that it is a
** class 3 as far as the transports are concerned.
*/
if( ( ( pTr->iClass == CM_TCT_CLASS_4 ) || ( pTr->iClass == CM_TCT_CLASS_5 ) )
&& pTr->fBridged )
{
pTr->iClass = CM_TCT_CLASS_3;
}
/*
** Search the appropriate portion of the transport pointer table
** based on the transport type we're creating.
*/
if( psTrrbl->psConnRecord->iPort == CD_CONTROLNET_PORT )
{
if( pTr->iClass == CM_TCT_CLASS_1 )
{
if( fProducer == TRUE )
{
iTransport = CD_FIRST_C1P_TRANSPORT;
iLastTransport = CD_LAST_C1P_TRANSPORT;
piRadioActiveBits = &cd_s.iRadioActiveScheduledProdBits;
}
else
{
iTransport = CD_FIRST_C1C_TRANSPORT;
iLastTransport = CD_LAST_C1C_TRANSPORT;
piRadioActiveBits = &cd_s.iRadioActiveMultiCastConBits;
}
}
else
{
iTransport = CD_FIRST_C3_TRANSPORT;
iLastTransport = CD_LAST_C3_TRANSPORT;
piRadioActiveBits = &cd_s.iRadioActiveP2PConsumerBits;
}
}
else if( psTrrbl->psConnRecord->iPort == CD_ETHERNET_PORT )
{
if( pTr->iClass == CM_TCT_CLASS_1 )
{
if( fProducer == TRUE )
{
iTransport = EN_CD_FIRST_C1P_TRANSPORT;
iLastTransport = EN_CD_LAST_C1P_TRANSPORT;
piRadioActiveBits = &cd_s.iRadioActiveScheduledProdBits;
}
else
{
iTransport = EN_CD_FIRST_C1C_TRANSPORT;
iLastTransport = EN_CD_LAST_C1C_TRANSPORT;
piRadioActiveBits = &cd_s.iRadioActiveMultiCastConBits;
}
}
else
{
iTransport = EN_CD_FIRST_C3_TRANSPORT;
iLastTransport = EN_CD_LAST_C3_TRANSPORT;
piRadioActiveBits = &cd_s.iRadioActiveP2PConsumerBits;
}
}
else
{
GS_Free( pTr );
return( CD_TRANSPORT_ALLOC_FAIL );
}
/*
** Find a place in the transport pointer list.
** Bail if it's full.
** Stuff the pointer in the list and adjust the transport ID if it fits.
*/
while ( ( ( CD_s[ psTrrbl->psConnRecord->iPort ].papTransportRecords )[ iTransport - 1 ] != NULL ) &&
( iTransport <= iLastTransport) )
{
iTransport++;
}
if( ( iTransport > iLastTransport ) || ( iTransport == CD_TUI_TRANSPORT ) )
{
GS_Free( pTr );
return( CD_TRANSPORT_ALLOC_FAIL );
}
( CD_s[ psTrrbl->psConnRecord->iPort ].papTransportRecords )[ iTransport - 1 ] = pTr;
/*
** Assign TransportId by incrementing the RadioActive Bit and ORing in Transport number.
*/
*piRadioActiveBits += 1;
*piRadioActiveBits &= sRadioActiveMasks.nRadioactiveMask;
pTr->iTransportId = ( ( *piRadioActiveBits << sRadioActiveMasks.nBitCount ) | iTransport );
/*
** jjw changed the connection record transport ID to NOT use the radioactive bits. Using the
** radioactive bits in the connection record forces us to include connection device information
** all the way up to the AD level.
*/
if( fProducer == TRUE )
{
psTrrbl->psConnRecord->iProTransportId = iTransport;
/*
** start edits: October,13th 2005, H.F.
**
** store the Producers Application Data Area ID to the transport record
**
*/
if( aProducerAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psTrrbl->psConnRecord->iProConnPoint ) )
pTr->itsProAssemDataAreaId = aProducerAssemblyInstance->itsAppDataAreaId;
/*
** end edits: October,13th 2005, H.F.
*/
}
else
{
psTrrbl->psConnRecord->iConTransportId = iTransport;
}
return( SUCCESS );
} /* End of cd_AllocateTransport() */
/*---------------------------------------------------------------------------
** cd_CommissionTransports()
**---------------------------------------------------------------------------
*/
StatusType cd_CommissionTransports( CD_TransportTrrblType *psTrrbl )
{
StatusType eStatus;
UINT16 iClass;
INT32 iError;
UINT16 iTransport;
cd_TransportRecordType *pTr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -