EtherNet/IP™ Adapter3.07.03
Generic Device (Device Type: 0x2B)

Scope

The Generic Device profile according to Volume 1 Chapter 6 of the CIP NETWORKS LIBRARY does not specify any specific instances of the Assembly Object or the type of application objects necessary for device operation. This portion of the device profile must be supplied by the product developer and in this example focuses on digital I/O functionality via an LED array available on the evaluation board. The Generic Device example does not discuss CIP Sync functionality.

As such the Generic Device is commonly used for vendor-specific device implementation that do not match any of the standard profiles specify by ODVA.

The profile specific elements of this example are implemented in deviceProfiles\genericDevice\app_generic_device.c with board specific functionality located in appNV.c and below board\am64x-evm\freertos.

Create Vendor-Specific Content

In EI_APP_GENERIC_DEVICE_cipGenerateContent() the Generic Device example creates a vendor-specific object with Class ID 0x70 and Instance ID 0x01. Within instance 0x01 the creation of the following attributes with different data types is demonstrated. As Attribute IDs values from the Vendor Specific range between 0x300 - 0x4FF are used, see also Table 4-10.6 Instance Attribute ID Range in Volume 1.

Vendor-Specific Instance Attributes

::
uint64_t attribID = 0x300;
// 64 USINT (uint8_t).
for (i = 0; i < 64; i++)
{
OSAL_MEMORY_memset(&attr, 0, sizeof(attr));
attr.id = attribID;
attr.pvValue = &i;
EI_API_CIP_addInstanceAttr(cipNode, classId, instanceId, &attr);
EI_API_CIP_setInstanceAttr(cipNode, classId, instanceId, &attr);
attribID++;
}
::
Class ID 0x70, Instance 0x01, Attributes
Attribute ID Name Data Type Value
0x300 Input1 USINT Default: 0x00
Note that as the attribute value from the output parameter 0x308 is mirrored onto the input parameter 0x300 in EI_APP_GENERIC_DEVICE_run, the value that is read is actually 0x08.
0x301 Input2 USINT Default: 0x01
Note that as the attribute value from the output parameter 0x309 is mirrored onto the input parameter 0x301 in EI_APP_GENERIC_DEVICE_run, the value that is read is actually 0x09.
0x302 Input3 USINT Default: 0x02
Note that as the attribute value from the output parameter 0x30A is mirrored onto the input parameter 0x302 in EI_APP_GENERIC_DEVICE_run, the value that is read is actually 0x0A.
0x303 Input4 USINT Default: 0x03
Note that as the attribute value from the output parameter 0x30B is mirrored onto the input parameter 0x303 in EI_APP_GENERIC_DEVICE_run, the value that is read is actually 0x0B.
0x304 Input5 USINT Default: 0x04
Note that as the attribute value from the output parameter 0x30C is mirrored onto the input parameter 0x304 in EI_APP_GENERIC_DEVICE_run, the value that is read is actually 0x0C.
0x305 USINT Default: 0x05
0x308 Output1 USINT Default: 0x08
0x30C Output5 USINT Default: 0x0C
0x33F USINT Default: 0x3F
0x340 UINT Default: 0x0000
0x35F UINT Default: 0x001F
0x360 UDINT Default: 0x00000000
0x36F UDINT Default: 0x0000000F
0x370 ULINT Default: 0x0000000000000000
0x377 ULINT Default: 0x0000000000000007

Attributes are created with both Set and Get acces permission.

Assembly Object (Class Code: 0x04)

Finally assemblies are created and Attributes 0x300 - 0x304 and 0x308 - 0x30C are added to the Producing, respectively Consuming Assembly.

::
errCode = EI_API_CIP_createAssembly(pCipNode, 0xfe, EI_API_CIP_eAR_GET); // Input-only.
errCode = EI_API_CIP_createAssembly(pCipNode, 0xff, EI_API_CIP_eAR_GET); // Listen-only.
for (i = 0x300; i < 0x305; i++)
{
errCode = EI_API_CIP_addAssemblyMember(pCipNode, 0x64, classId, instanceId, i);
if (errCode != EI_API_CIP_eERR_OK)
{
OSAL_printf("Failed to add Class ID %#x, Instance ID %#x, Attribute ID %#x to Assembly Instance 0x64: Error code: 0x%08x\n", classId, instanceId, (uint16_t)i, errCode);
}
errCode = EI_API_CIP_addAssemblyMember(pCipNode, 0x65, classId, instanceId, (uint16_t)(8 + i));
if (errCode != EI_API_CIP_eERR_OK) {
OSAL_printf("Failed to add Class ID %#x, Instance ID %#x, Attribute ID %#x to Assembly Instance 0x65: Error code: 0x%08x\n", classId, instanceId, (uint16_t)(8 + i), errCode);
}
}
::

For all instances of the Assembly Object (0x64, 0x65, 0xFE, 0xFF) the following Instance Attribute is implemented:

Instance attributes
Attribute ID Name Data Type Value
3 Data ARRAY of octet

In the EDS files shipped with the example this is reflected in the fragments below:

::
[Params]
Param1 =
0, $ first field shall equal 0
7,"20 70 24 01 31 08 03", $ path size,path
0x0000, $ descriptor
0xC6, $ data type
1, $ data size in bytes
"Output1", $ name
"", $ units
"Output Byte 1", $ help string
,,0, $ min, max, default data values
,,,, $ mult, dev, base, offset scaling not used
,,,, $ mult, dev, base, offset link not used
0; $ decimal places not used
Param2 =
0, $ reserved, shall equal 0
7,"20 70 24 01 31 09 03", $ Link Path Size, Link Path
0x0000, $ Descriptor
0xC6, $ Data Type
1, $ Data Size in bytes
"Output2", $ name
"", $ units
"Output Byte 2", $ help string
,,0, $ min, max, default data values
,,,, $ mult, div, base, offset scaling
,,,, $ mult, div, base, offset links
; $ decimal places
::
[Assembly]
Object_Name = "Assembly Object";
Object_Class_Code = 0x04;
MaxInst = 2;
Number_Of_Static_Instances = 2;
Max_Number_Of_Dynamic_Instances = 0;
Assem1 =
"Producing Assembly (Input Data)",
,
5,
0x0001,
,,
8,Param11,
8,Param12,
8,Param13,
8,Param14,
8,Param15;
Assem2 =
"Consuming Assembly (Output Data)",
,
5,
0x0001,
,,
8,Param1,
8,Param2,
8,Param3,
8,Param4,
8,Param5;
::

Cyclic Run Function

In the cyclically called EI_APP_GENERIC_DEVICE_run function, the attribute values for the first five attributes used for process data out (0x308 - 0x30C) are mirrored onto the attributes used for process data in. Also, the first process data out attribute is connected to the industrial LED array implemented on the Texas Instruments evaluation boards.

void EI_APP_GENERIC_DEVICE_run(EI_API_CIP_NODE_T* pCipNode)
{
uint32_t errCode = EI_API_CIP_eERR_OK;
uint8_t attrValue = 0;
uint16_t attr;
// Mirror I/O data.
for(attr = 0; attr < 5; attr++)
{
errCode = EI_API_CIP_getAttr_usint(pCipNode, 0x0070, 0x0001, attr + 0x0308, &attrValue);
if (attr == 0 && errCode == EI_API_CIP_eERR_OK)
{
CUST_DRIVERS_LED_setIndustrialLeds(attrValue);
}
EI_API_CIP_setAttr_usint(pCipNode, 0x0070, 0x0001, attr + 0x0300, attrValue);
}
}
EI_API_CIP_SAttr::edt
EI_API_CIP_EEdt_t edt
Definition: EI_API_CIP_define.h:178
EI_API_CIP_createAssembly
ETHIP_API uint32_t EI_API_CIP_createAssembly(T *pCipNode_p, uint16_t assemblyInstanceId_p, EI_API_CIP_EAr_t accessRule_p)
Create a new assembly instance.
Definition: EI_API_CIP_stub.c:4171
EI_API_CIP_SAttr
General attribute parameter collection.
Definition: EI_API_CIP_define.h:175
EI_API_CIP_eEDT_USINT
@ EI_API_CIP_eEDT_USINT
Definition: EI_API_CIP_define.h:101
EI_API_CIP_getAttr_usint
ETHIP_API uint32_t EI_API_CIP_getAttr_usint(T *pCipNode_p, uint16_t classId_p, uint16_t instanceId_p, uint16_t attrId_p, ei_api_cip_edt_usint *pValue_p)
Get attribute of type USINT.
Definition: EI_API_CIP_stub.c:1938
EI_API_CIP_eERR_OK
@ EI_API_CIP_eERR_OK
Definition: EI_API_CIP_define.h:30
EI_API_CIP_SAttr::pvValue
void * pvValue
Definition: EI_API_CIP_define.h:184
EI_API_CIP_SAttr::accessRule
EI_API_CIP_EAr_t accessRule
Definition: EI_API_CIP_define.h:180
EI_API_CIP_SAttr::id
uint16_t id
Definition: EI_API_CIP_define.h:177
EI_API_CIP_setAttr_usint
ETHIP_API uint32_t EI_API_CIP_setAttr_usint(T *pCipNode_p, uint16_t classId_p, uint16_t instanceId_p, uint16_t attrId_p, ei_api_cip_edt_usint value_p)
Set attribute of type USINT.
Definition: EI_API_CIP_stub.c:3271
EI_API_CIP_setInstanceAttr
ETHIP_API uint32_t EI_API_CIP_setInstanceAttr(T *pCipNode_p, uint16_t classId_p, uint16_t instanceId_p, EI_API_CIP_SAttr_t *pAttr_p)
Set instance attribute value only.
Definition: EI_API_CIP_stub.c:1451
EI_API_CIP_addAssemblyMember
ETHIP_API uint32_t EI_API_CIP_addAssemblyMember(T *pCipNode_p, uint16_t assemblyInstanceId_p, uint16_t classId_p, uint16_t instanceId_p, uint16_t attributeId_p)
Add an member to an assembly member list.
Definition: EI_API_CIP_stub.c:4294
EI_API_CIP_eAR_GET_AND_SET
@ EI_API_CIP_eAR_GET_AND_SET
Definition: EI_API_def.h:120
EI_API_CIP_eAR_GET
@ EI_API_CIP_eAR_GET
Attribute is gettable.
Definition: EI_API_def.h:119
EI_API_CIP_addInstanceAttr
ETHIP_API uint32_t EI_API_CIP_addInstanceAttr(T *pCipNode_p, uint16_t classId_p, uint16_t instanceId_p, EI_API_CIP_SAttr_t *pAttr_p)
Add an attribute to an instance.
Definition: EI_API_CIP_stub.c:1042