PNS SimpleConfig Example exercise
- Stefan Neumann
- Enis Hassad
The SimpleConfig example can be found in the Knowledge Base on the following website:
netX 90: https://hilscher.atlassian.net/wiki/display/NXLFWHST/netX+90+-+PROFINET+IO+Device+-+Examples
netX 51: https://hilscher.atlassian.net/wiki/display/NXLFWHST/netX+51+-+PROFINET+IO+Device+-+Examples
This can alternatively be found under:
kb.hilscher.com → Software → LFW Host Examples → Profinet IO-Device → netX 90 APP / netX 51 → PROFINET IO Device - simpleConfig Vx.x.x.x
The SimpleConfig project can be opened by double-clicking the ".solproject" file. This requires the latest version of netXStudio (https://hilscher.atlassian.net/wiki/display/NDT/).
1. Vendor ID
The vendor ID is the identification number of the manufacturer, which the PROFIBUS & PROFINET International organization has assigned to the vendor. Hilscher products use the value 286 / 0x011E.
Although the parameter vendor ID has a defined value range, the protocol stack will not verify the value received from the application. All values are accepted, even those outside the defined value range. The device vendor has the responsibility to use correct numbers. The vendor ID is assigned by PROFIBUS & PROFINET International organization.
For your device you need to use your own vendor ID. The first task is to change the Hilscher vendor ID to your own.
Please change the vendor ID and vendor name.
The vendor ID has to be changed in the GSDML file and also in the application (SimpleConfig example).
The PacketHandler describes the acyclic packages and can be found in the Project Explorer under:
netXxx_PNSVx_simpleConfig → Components → cifXApplicationDemoPNS → Sources → AppPNS_DemoApplicationFunctions.c
long SetConfigParams(void* pvPck, uint16_t usDeviceClass) { ... ptSetConfig->ulVendorId = 0x011E; /* Vendor ID */ }
A GSDML file is required for this example. The GSDML file can be found in the netXStudio project in Project Explorer at:
netXxx_PNSVx_simpleConfig → Components → cifXApplicationDemoPNS → DeviceDescription → GSDML-V2.3x-HILSCHER-NETX xx-RE PNS-20xxxxxx.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<DeviceIdentity DeviceID="0x1003" VendorID="0x011E">
<InfoText TextId="DeviceDescription_InfoText"/>
<VendorName Value="Hilscher Gesellschaft für Systemautomation mbH"/>
</DeviceIdentity>
</ProfileBody>
</ISO15745Profile>
2. Device ID
This is the identification number of the device. The device vendor can assign a device ID and has the responsibility to use a fix and unique number for each device type.
Although the parameter device ID has a defined value range, the protocol stack will not verify the value received from the application.
For your device you need to use your own Device ID. The second task is to change the Hilscher device ID to your own.
Please change the device ID.
The Device ID has to be changed in the GSDML file and also in the application (SimpleConfig example).
The PacketHandler describes the acyclic packages and can be found in the Project Explorer under:
netXxx_PNSVx_simpleConfig → Components → cifXApplicationDemoPNS → Sources → AppPNS_DemoApplicationFunctions.c
long SetConfigParams(void* pvPck, uint16_t usDeviceClass) { ... ptSetConfig->ulDeviceId = 0x1003; /* Device ID */ }
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<DeviceIdentity DeviceID="0x1003" VendorID="0x011E">
<InfoText TextId="DeviceDescription_InfoText"/>
<VendorName Value="Hilscher Gesellschaft für Systemautomation mbH"/>
</DeviceIdentity>
</ProfileBody>
</ISO15745Profile>
3. Software Version
In the software version you can assign unique version numbers to unique states of the software. Within a given version number category (major, minor), these numbers are assigned in increasing order and correspond to new developments in the software.
This is the software version of the whole item including the PROFINET Protocol implementation and the Application. This version is managed by the manufacturer of the item. It must be changed whenever a part of the software within the item (including the PROFINET Protocol implementation if it is part of the item) changes.
This is not the version number of the PROFINET Protocol implementation. Do not use the Hilscher Version of the PROFINET Protocol implementation. The third task is to change the software version.
Please change the software version.
The software version has to be changed in the GSDML file and also in the application (SimpleConfig example).
The PacketHandler describes the acyclic packages and can be found in the Project Explorer under:
netXxx_PNSVx_simpleConfig → Components → cifXApplicationDemoPNS → Sources → AppPNS_DemoApplicationFunctions.c
long SetConfigParams(void* pvPck, uint16_t usDeviceClass) { ... ptSetConfig->usSwRevision1 = 1; /* Software Revision 1, default: 0 */ ptSetConfig->usSwRevision2 = 0; /* Software Revision 2, default: 0 */ ptSetConfig->usSwRevision3 = 0; /* Software Revision 3, default: 0 */ ptSetConfig->bSwRevisionPrefix = 'V'; /* Software Revision Prefix, default: 0 */ }
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<ApplicationProcess>
<DeviceAccessPointList>
<DeviceAccessPointItem CheckDeviceID_Allowed="true" DNS_CompatibleName="netxv5repns" DeviceAccessSupported="true" FixedInSlots="0" ID="DIM 32" ImplementationType="netX" LLDP_NoD_Supported="true" MinDeviceInterval="8"
ModuleIdentNumber="0x00003021" MultipleWriteSupported="true" NameOfStationNotTransferable="true" NumberOfDeviceAccessAR="1" ObjectUUID_LocalIndex="1" PNIO_Version="V2.35" PhysicalSlots="0..32"
PowerOnToCommReady="10000" PrmBeginPrmEndSequenceSupported="false" ResetToFactoryModes="2" SharedDeviceSupported="true" SharedInputSupported="false">
<ModuleInfo>
<Name TextId="NETX RE/PNS V5.3.0 Host Example Use Case A"/>
<InfoText TextId="DIM 32_InfoText"/>
<VendorName Value="Hilscher Gesellschaft für Systemautomation mbH"/>
<OrderNumber Value="1234.567"/>
<HardwareRelease Value="3"/>
<SoftwareRelease Value="V1.0.0"/>
</ModuleInfo>
</DeviceAccessPointItem>
</DeviceAccessPointList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>
4. Hardware Version
In the hardware version you can assign unique version numbers to unique states of the hardware. Within a given version number, this number are assigned in increasing order and correspond to new developments in the hardware.
This value must be equal to any hardware revision markings on the item itself.
For your device you need to use your own hardware number. The fourth task is to change the Hilscher hardware number to your own.
Please change the hardware number.
The hardware version has to be changed in the GSDML file and also in the application (SimpleConfig example).
HIL_DDP_SERVICE_SET_REQ_T *ptReq; ptReq->tHead.ulCmd = HIL_DDP_SERVICE_SET_REQ; /* set OEM HardwareRevision to 1 as string */ ptReq->tHead.ulLen = ptReq->tData.ulDataType = ptReq->tData.uDataType.szString[0] = ptReq->tData.uDataType.szString[1] = /* termination */ /* send packet to SystemChannel, wait for confirmation, check packet status */ /* set OEM option flags, indicate that HardwareRevision is valid */ ptReq->tHead.ulLen = ptReq->tData.ulDataType = ptReq->tData.uDataType.ulValue = /* send packet to SystemChannel, wait for confirmation, check packet status */ /* last step - set DDP Mode to active */ ptReq->tHead.ulLen = ptReq->tData.ulDataType = ptReq->tData.uDataType.ulValue = /* send packet to SystemChannel, wait for confirmation, check packet status */
The following code snippet shows the principle for creating the DDP Service Set Requests packets. The code snippet does not show packet handling. For details, check the current API Protocol manual. This can be downloaded from the Knowledge Base at the following website:
https://kb.hilscher.com/display/DL/PROFINET+IO-Device+V5
HIL_DDP_SERVICE_SET_REQ_T *ptReq; ptReq->tHead.ulCmd = HIL_DDP_SERVICE_SET_REQ; /* set OEM HardwareRevision to 1 as string */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + 2; ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_OEM_HARDWAREREVISION; ptReq->tData.uDataType.szString[0] = '1'; ptReq->tData.uDataType.szString[1] = 0; /* termination */ /* send packet to SystemChannel, wait for confirmation, check packet status */ /* set OEM option flags, indicate that HardwareRevision is valid */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + sizeof(ptReq->tData.uDataType.ulValue); ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_OEM_OPTIONS; ptReq->tData.uDataType.ulValue = HIL_PRODUCT_DATA_OEM_IDENTIFICATION_FLAG_HARDWAREREVISION_VALID; /* send packet to SystemChannel, wait for confirmation, check packet status */ /* last step - set DDP Mode to active */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + sizeof(ptReq->tData.uDataType.ulValue); ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_STATE; ptReq->tData.uDataType.ulValue = HIL_DDP_SERVICE_STATE_ACTIVE; /* send packet to SystemChannel, wait for confirmation, check packet status */
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<ApplicationProcess>
<DeviceAccessPointList>
<DeviceAccessPointItem CheckDeviceID_Allowed="true" DNS_CompatibleName="netxv5repns" DeviceAccessSupported="true" FixedInSlots="0" ID="DIM 32" ImplementationType="netX" LLDP_NoD_Supported="true" MinDeviceInterval="8"
ModuleIdentNumber="0x00003021" MultipleWriteSupported="true" NameOfStationNotTransferable="true" NumberOfDeviceAccessAR="1" ObjectUUID_LocalIndex="1" PNIO_Version="V2.35" PhysicalSlots="0..32"
PowerOnToCommReady="10000" PrmBeginPrmEndSequenceSupported="false" ResetToFactoryModes="2" SharedDeviceSupported="true" SharedInputSupported="false">
<ModuleInfo>
<Name TextId="NETX RE/PNS V5.3.0 Host Example Use Case A"/>
<InfoText TextId="DIM 32_InfoText"/>
<VendorName Value="Hilscher Gesellschaft für Systemautomation mbH"/>
<OrderNumber Value="1234.567"/>
<HardwareRelease Value="1"/>
<SoftwareRelease Value="V1.0.0"/>
</ModuleInfo>
</DeviceAccessPointItem>
</DeviceAccessPointList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>
The hardware version has to be changed in the GSDML file and also in the application (SimpleConfig example).
The PacketHandler describes the acyclic packages and can be found in the Project Explorer under:
netXxx_PNSVx_simpleConfig → Components → cifXApplicationDemoPNS → Sources → AppPNS_DemoApplicationFunctions.c
long SetConfigParams(void* pvPck, uint16_t usDeviceClass) { ... ptSetConfig->usHwRevision = 0; /* Hardware Revision, default: 0 */ }
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<ApplicationProcess>
<DeviceAccessPointList>
<DeviceAccessPointItem CheckDeviceID_Allowed="true" DNS_CompatibleName="netxv5repns" DeviceAccessSupported="true" FixedInSlots="0" ID="DIM 32" ImplementationType="netX" LLDP_NoD_Supported="true" MinDeviceInterval="8"
ModuleIdentNumber="0x00003021" MultipleWriteSupported="true" NameOfStationNotTransferable="true" NumberOfDeviceAccessAR="1" ObjectUUID_LocalIndex="1" PNIO_Version="V2.35" PhysicalSlots="0..32"
PowerOnToCommReady="10000" PrmBeginPrmEndSequenceSupported="false" ResetToFactoryModes="2" SharedDeviceSupported="true" SharedInputSupported="false">
<ModuleInfo>
<Name TextId="NETX RE/PNS V5.3.0 Host Example Use Case A"/>
<InfoText TextId="DIM 32_InfoText"/>
<VendorName Value="Hilscher Gesellschaft für Systemautomation mbH"/>
<OrderNumber Value="1234.567"/>
<HardwareRelease Value="1"/>
<SoftwareRelease Value="V1.0.0"/>
</ModuleInfo>
</DeviceAccessPointItem>
</DeviceAccessPointList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>
5. Order Number
This is the Order ID, model number or SKU number of the device. It is assigned by the vendor and should be equal to customer readable markings on the device.
Starting with PROFINET IO-Device V5.3.0.0, it is no longer possible to use PROFINET IO-Device specific API services to set / change these generic parameters.
Instead, the generic DeviceDataProvider (DDP) is the only source of PROFINET IO-Device firmware for these parameters.
By default, the DDP will use the values stored in the FlashDeviceLabel (FDL) of the netX chip the firmware is running on and provide these values to the PROFINET IO-Device firmware. If these defaults shall not be used, the following steps are required:
Set the Order ID to 7833.000
- modify firmware taglist to start in DDP mode "passive" and flash it into netX chip
- after firmware is started, open the SystemChannel and
- Use "DDP Service Set Request" to set the individual OEM parameters
- Use "DDP Service Set Request" to set the DDP OEM Options field
- Use "DDP Service Set Request" to set DDP mode to active
- Now the PROFINET IO-Device communication channel can be configured and it will use the parameters just written to DDPs OEM section.
HIL_DDP_SERVICE_SET_REQ_T *ptReq; ptReq->tHead.ulCmd = HIL_DDP_SERVICE_SET_REQ; /* set OEM OrderID to OID 2 as string */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + 6; ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_OEM_ORDERNUMBER; ptReq->tData.uDataType.szString[0] = 'O'; ptReq->tData.uDataType.szString[1] = 'I'; ptReq->tData.uDataType.szString[2] = 'D'; ptReq->tData.uDataType.szString[3] = ' '; ptReq->tData.uDataType.szString[4] = '2'; ptReq->tData.uDataType.szString[5] = 0; /* termination */ /* send packet to SystemChannel, wait for confirmation, check packet status */
- Open the Tag List Editor:
- Load the firmware.
- modify firmware taglist to start in DDP mode "passive" and flash it into netX chip
HIL_DDP_SERVICE_SET_REQ_T *ptReq; ptReq->tHead.ulCmd = HIL_DDP_SERVICE_SET_REQ; /* set OEM OrderID to 7833.000 as string */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + 9; ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_OEM_ORDERNUMBER; ptReq->tData.uDataType.szString[0] = '7'; ptReq->tData.uDataType.szString[1] = '8'; ptReq->tData.uDataType.szString[2] = '3'; ptReq->tData.uDataType.szString[3] = '3'; ptReq->tData.uDataType.szString[4] = '.'; ptReq->tData.uDataType.szString[5] = '0'; ptReq->tData.uDataType.szString[6] = '0'; ptReq->tData.uDataType.szString[7] = '0'; ptReq->tData.uDataType.szString[8] = 0; /* termination */ /* send packet to SystemChannel, wait for confirmation, check packet status */ /* set OEM option flags, indicate that HardwareRevision and OrderID are valid */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + sizeof(ptReq->tData.uDataType.ulValue); ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_OEM_OPTIONS; ptReq->tData.uDataType.ulValue = HIL_PRODUCT_DATA_OEM_IDENTIFICATION_FLAG_ORDERNUMBER_VALID | HIL_PRODUCT_DATA_OEM_IDENTIFICATION_FLAG_HARDWAREREVISION_VALID; /* send packet to SystemChannel, wait for confirmation, check packet status */ /* last step - set DDP Mode to active */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + sizeof(ptReq->tData.uDataType.ulValue); ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_STATE; ptReq->tData.uDataType.ulValue = HIL_DDP_SERVICE_STATE_ACTIVE; /* send packet to SystemChannel, wait for confirmation, check packet status */
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<ApplicationProcess>
<DeviceAccessPointList>
<DeviceAccessPointItem CheckDeviceID_Allowed="true" DNS_CompatibleName="netxv5repns" DeviceAccessSupported="true" FixedInSlots="0" ID="DIM 32" ImplementationType="netX" LLDP_NoD_Supported="true" MinDeviceInterval="8"
ModuleIdentNumber="0x00003021" MultipleWriteSupported="true" NameOfStationNotTransferable="true" NumberOfDeviceAccessAR="1" ObjectUUID_LocalIndex="1" PNIO_Version="V2.35" PhysicalSlots="0..32"
PowerOnToCommReady="10000" PrmBeginPrmEndSequenceSupported="false" ResetToFactoryModes="2" SharedDeviceSupported="true" SharedInputSupported="false">
<ModuleInfo>
<Name TextId="NETX RE/PNS V5.3.0 Host Example Use Case A"/>
<InfoText TextId="DIM 32_InfoText"/>
<VendorName Value="Hilscher Gesellschaft für Systemautomation mbH"/>
<OrderNumber Value="7833.000"/>
<HardwareRelease Value="1"/>
<SoftwareRelease Value="V1.0.0"/>
</ModuleInfo>
</DeviceAccessPointItem>
</DeviceAccessPointList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>
The order ID version has to be changed in the GSDML file and also in the application (SimpleConfig example).
The PacketHandler describes the acyclic packages and can be found in the Project Explorer under:
netXxx_PNSVx_simpleConfig → Components → cifXApplicationDemoPNS → Sources → AppPNS_DemoApplicationFunctions.c
long SetConfigParams(void* pvPck, uint16_t usDeviceClass) { PNS_IF_DEVICE_PARAMETER_T FAR* ptSetConfig = pvPck; memset( ptSetConfig->abOrderId, 0x00, 20); /* The OrderId as ASCII char-array */ (...) memcpy( ptSetConfig->abOrderId, "7833.000", sizeof( "7833.000" ) - 1 ); /* The OrderId as ASCII char-array */ }
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<ApplicationProcess>
<DeviceAccessPointList>
<DeviceAccessPointItem CheckDeviceID_Allowed="true" DNS_CompatibleName="netxv5repns" DeviceAccessSupported="true" FixedInSlots="0" ID="DIM 32" ImplementationType="netX" LLDP_NoD_Supported="true" MinDeviceInterval="8"
ModuleIdentNumber="0x00003021" MultipleWriteSupported="true" NameOfStationNotTransferable="true" NumberOfDeviceAccessAR="1" ObjectUUID_LocalIndex="1" PNIO_Version="V2.35" PhysicalSlots="0..32"
PowerOnToCommReady="10000" PrmBeginPrmEndSequenceSupported="false" ResetToFactoryModes="2" SharedDeviceSupported="true" SharedInputSupported="false">
<ModuleInfo>
<Name TextId="NETX RE/PNS V5.3.0 Host Example Use Case A"/>
<InfoText TextId="DIM 32_InfoText"/>
<VendorName Value="Hilscher Gesellschaft für Systemautomation mbH"/>
<OrderNumber Value="7833.000"/>
<HardwareRelease Value="1"/>
<SoftwareRelease Value="V1.0.0"/>
</ModuleInfo>
</DeviceAccessPointItem>
</DeviceAccessPointList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>
6. Serial Number
This must be a unique serial number associated with the item. It must be equal to any serial number markings on the item itself.
For your device you need to use your own serial number. The sixth task is to change the Hilscher serial number to your own.
Please change the serial number.
HIL_DDP_SERVICE_SET_REQ_T *ptReq; ptReq->tHead.ulCmd = HIL_DDP_SERVICE_SET_REQ; /* set OEM SerialNumber to 4711 as string */ {...} /* send packet to SystemChannel, wait for confirmation, check packet status */ /* set OEM option flags, indicate that SerialNumber, HardwareRevision and OrderID are valid */ ptReq->tHead.ulLen = ptReq->tData.ulDataType = ptReq->tData.uDataType.ulValue = /* send packet to SystemChannel, wait for confirmation, check packet status */ /* last step - set DDP Mode to active */ ptReq->tHead.ulLen = ptReq->tData.ulDataType = ptReq->tData.uDataType.ulValue = /* send packet to SystemChannel, wait for confirmation, check packet status */
HIL_DDP_SERVICE_SET_REQ_T *ptReq; ptReq->tHead.ulCmd = HIL_DDP_SERVICE_SET_REQ; /* set OEM SerialNumber to 4711 as string */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + 5; ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_OEM_SERIALNUMBER; ptReq->tData.uDataType.szString[0] = '4'; ptReq->tData.uDataType.szString[1] = '7'; ptReq->tData.uDataType.szString[2] = '1'; ptReq->tData.uDataType.szString[3] = '1'; ptReq->tData.uDataType.szString[4] = 0; /* termination */ /* send packet to SystemChannel, wait for confirmation, check packet status */ /* set OEM option flags, indicate that SerialNumber, HardwareRevision and OrderID are valid */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + sizeof(ptReq->tData.uDataType.ulValue); ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_OEM_OPTIONS; ptReq->tData.uDataType.ulValue = HIL_PRODUCT_DATA_OEM_IDENTIFICATION_FLAG_SERIALNUMBER_VALID | HIL_PRODUCT_DATA_OEM_IDENTIFICATION_FLAG_ORDERNUMBER_VALID | HIL_PRODUCT_DATA_OEM_IDENTIFICATION_FLAG_HARDWAREREVISION_VALID; /* send packet to SystemChannel, wait for confirmation, check packet status */ /* last step - set DDP Mode to active */ ptReq->tHead.ulLen = sizeof(ptReq->tData.ulDataType) + sizeof(ptReq->tData.uDataType.ulValue); ptReq->tData.ulDataType = HIL_DDP_SERVICE_DATATYPE_STATE; ptReq->tData.uDataType.ulValue = HIL_DDP_SERVICE_STATE_ACTIVE; /* send packet to SystemChannel, wait for confirmation, check packet status */
7. Manufacturer Name
Change in the Flash Device Label (FDL) the Manufacturer ID.
The Flash Device Label stores the device specific hardware data and can be found in the Project Explorer under:
netXxx_PNSVx_simpleConfig → FDL → FDL_NXHX90-JTAG_783000r3_20000_ProductionTemplate_UseCaseA.fdl → Basic Device Data → Manufacturer ID
8. Process Data
The PROFINET IO protocol uses a cyclic process data model to exchange process data between the PROFINET IO Controller and Device.
In PROFINET, process data is organized at the level of submodules. Each submodule can be assigned input and/or output process data. Submodules without any data are assigned to the input process data block with a zero length. Each process data block is associated with a provider data status (IOPS) and a consumer data status (IOCS). The producer of the data generates the provider data status. Thus, the provider data status is exchanged in the same direction as the process data itself.
From the PROFINET IO Device viewpoint, the Provider process data image is the data sent from the PROFINET IO Device to the PROFINET IO Controller. This is usually called Input process data (Inputs). The application has to place this data in the Provider process data image.
For this example, the process data should be changed to 12 byte input- and 10 byte output data.
Note: Meaningful and comprehensible texts should be used for a good programming.
Please change the process data.
Please adjust the Provider- and the Consumer Data Length in the GSDML file and also in the application (SimpleConfig example).
/************************************************************************************** function: SetModulConfig description: Fills all necessary information about module configuration. global: none input: PNS_IF_MODULE_CFG_REQ_DATA_T FAR* ptModule - pointer to the packet output: none return: long (Pointer to the packet) **************************************************************************************/ long SetModulConfig( void* pvPck ) { PNS_IF_MODULE_CFG_REQ_DATA_T *ptModule = pvPck; PNS_IF_API_STRUCT_T *ptApi = NULL; PNS_IF_SUBMODULE_STRUCT_T *ptSubmod = NULL; ptModule->ulNumApi = 0x01; /* Number of API elements to follow */ ptApi = ( PNS_IF_API_STRUCT_T * ) ( ptModule + 1 ); /* Pointer to Module configuration */ ptApi->ulApi = 0x00; /* Number of the API profile to be configured */ ptApi->ulNumSubmodItems = 0x06; /* Number of submodule-items this API contains */ ptSubmod = ( PNS_IF_SUBMODULE_STRUCT_T * ) ( ptApi + 1 ); /* Pointer to Submodule configuration */ ... /* Configure 12 Byte Input module (Device to PLC) */ ptSubmod->usSlot = 0x0001; /* Slot this submodule belongs to */ ptSubmod->usSubslot = 0x0001; /* Subslot of this submodule */ /* PNS SET CONFIG*/ ptSubmod->ulModuleId = 0x00000001; /* Module ID to which this submodule belongs */ ptSubmod->ulSubmodId = 0x00000001; /* Submodule ID */ ptSubmod->ulProvDataLen = 0x0000000C; /* Length of provider data (sent by IO-Device, received by IO-Controller) */ ptSubmod->ulConsDataLen = 0x00000000; /* Length of consumer data (sent by IO-Controller, received by IO-Device) */ ptSubmod->ulDPMOffsetOut = 0x00000000; /* Offset in DPM OutputArea or in Output-image, where provided data of the*/ /* submodule shall be taken from */ ptSubmod->ulDPMOffsetIn = 0x00000000; /* Offset in DPM InputArea or in Input-image, where consumed data for the */ /* submodule shall be copied to */ ptSubmod->usOffsetIOPSProvider = 0x0000; /* Offset where the stack shall take the IOPS provider state for this */ /* submodule relative to beginning of IOPS block in DPM output area from */ ptSubmod->usOffsetIOPSConsumer = 0x0000; /* Offset where the stack shall put the IOPS consumer state of this */ /* submodule relative to beginning of IOPS block in DPM input area to */ ptSubmod->usOffsetIOCSProvider = 0x0000; /* Offset where the stack shall take the IOCS provider state for this */ /* submodule relative to beginning of IOCS block in DPM output area from */ ptSubmod->usOffsetIOCSConsumer = 0x0000; /* Offset where the stack shall put the IOCS consumer state for this */ /* submodule relative to beginning of IOCS block in DPM input area to */ ptSubmod->ulReserved = 0x00000000; /* Reserved for future usage */ ptSubmod++; /* Increment submodule */ /* Configure 10 Byte Output module (PLC to Device) */ ptSubmod->usSlot = 0x0002; /* Slot this submodule belongs to */ ptSubmod->usSubslot = 0x0001; /* Subslot of this submodule */ /* PNS SET CONFIG*/ ptSubmod->ulModuleId = 0x00000002; /* Module ID to which this submodule belongs */ ptSubmod->ulSubmodId = 0x00000001; /* Submodule ID */ ptSubmod->ulProvDataLen = 0x00000000; /* Length of provider data (sent by IO-Device, received by IO-Controller) */ ptSubmod->ulConsDataLen = 0x0000000A; /* Length of consumer data (sent by IO-Controller, received by IO-Device) */ ptSubmod->ulDPMOffsetOut = 0x00000000; /* Offset in DPM OutputArea or in Output-image, where provided data of the*/ /* submodule shall be taken from */ ptSubmod->ulDPMOffsetIn = 0x00000000; /* Offset in DPM InputArea or in Input-image, where consumed data for the */ /* submodule shall be copied to */ ptSubmod->usOffsetIOPSProvider = 0x0000; /* Offset where the stack shall take the IOPS provider state for this */ /* submodule relative to beginning of IOPS block in DPM output area from */ ptSubmod->usOffsetIOPSConsumer = 0x0000; /* Offset where the stack shall put the IOPS consumer state of this */ /* submodule relative to beginning of IOPS block in DPM input area to */ ptSubmod->usOffsetIOCSProvider = 0x0000; /* Offset where the stack shall take the IOCS provider state for this */ /* submodule relative to beginning of IOCS block in DPM output area from */ ptSubmod->usOffsetIOCSConsumer = 0x0000; /* Offset where the stack shall put the IOCS consumer state for this */ /* submodule relative to beginning of IOCS block in DPM input area to */ ptSubmod->ulReserved = 0x00000000; /* Reserved for future usage */ ptSubmod++; /* Increment submodule */ return ( long ) ptSubmod - ( long ) ptModule; } /* SetModulConfig */
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<ApplicationProcess>
<ModuleList>
<ModuleItem ID="12byteinput" ModuleIdentNumber="0x00000001">
<ModuleInfo CategoryRef="Input Module">
<Name TextId="Module_12byteinput_Name"/>
<InfoText TextId="Module_12byteinput_InfoText"/>
</ModuleInfo>
<VirtualSubmoduleList>
<VirtualSubmoduleItem ID="12byteinput" MayIssueProcessAlarm="false" SubmoduleIdentNumber="0x00000001">
<IOData>
<Input>
<DataItem DataType="OctetString" Length="12" TextId="DataItem_12byteinput_inputdata_0_Name"/>
</Input>
</IOData>
<ModuleInfo>
<Name TextId="Submodule_12byteinput_Name"/>
<InfoText TextId="Submodule_12byteinput_InfoText"/>
</ModuleInfo>
</VirtualSubmoduleItem>
</VirtualSubmoduleList>
</ModuleItem>
<ModuleItem ID="10byteoutput" ModuleIdentNumber="0x00000002">
<ModuleInfo CategoryRef="Output Module">
<Name TextId="Module_10byteoutput_Name"/>
<InfoText TextId="Module_10byteoutput_InfoText"/>
</ModuleInfo>
<VirtualSubmoduleList>
<VirtualSubmoduleItem ID="10byteoutput" MayIssueProcessAlarm="false" SubmoduleIdentNumber="0x00000001">
<IOData>
<Output>
<DataItem DataType="OctetString" Length="10" TextId="DataItem_10byteoutput_outputdata_0_Name"/>
</Output>
</IOData>
<ModuleInfo>
<Name TextId="Submodule_10byteoutput_Name"/>
<InfoText TextId="Submodule_10byteoutput_InfoText"/>
</ModuleInfo>
</VirtualSubmoduleItem>
</VirtualSubmoduleList>
</ModuleItem>
</ModuleList>
<ExternalTextList>
<PrimaryLanguage>
<Text TextId="DAP Module_CategoryName" Value="Device Access Point Modules"/>
<Text TextId="DIM 31_InfoText" Value="Firmware version V5.3.0 Identification & Maintenance 1-3, Shared Device, RT and IRT Communication."/>
<Text TextId="DataItem_12byteinput_inputdata_0_Name" Value="Inputs"/>
<Text TextId="DataItem_10byteoutput_outputdata_0_Name" Value="Outputs"/>
<Text TextId="DeviceDescription_InfoText" Value="PROFINET IO-Device"/>
<Text TextId="Input Module_CategoryName" Value="Input Modules"/>
<Text TextId="Module_12byteinput_InfoText" Value="12 Bytes Input Module"/>
<Text TextId="Module_12byteinput_Name" Value="12 Bytes Input"/>
<Text TextId="Module_10byteoutput_InfoText" Value="10 Bytes Output Module"/>
<Text TextId="Module_10byteoutput_Name" Value="10 Bytes Output"/>
<Text TextId="NETX RE/PNS V5.3.0 Host Example" Value="NETX RE/PNS V5.3.0 Host Example"/>
<Text TextId="Output Module_CategoryName" Value="Output Modules"/>
<Text TextId="PN-IO" Value="PN-IO"/>
<Text TextId="Port1" Value="Port 1"/>
<Text TextId="Port2" Value="Port 2"/>
<Text TextId="Submodule_12byteinput_InfoText" Value="12 Bytes Input Submodule"/>
<Text TextId="Submodule_12byteinput_Name" Value="12 Bytes Input"/>
<Text TextId="Submodule_10byteoutput_InfoText" Value="10 Byte Output Submodule"/>
<Text TextId="Submodule_10byteoutput_Name" Value="10 Bytes Output"/>
<Text TextId="X1" Value="X1"/>
<Text TextId="X1P1" Value="X1 P1"/>
<Text TextId="X1P2" Value="X1 P2"/>
</PrimaryLanguage>
<Language xml:lang="de">
<Text TextId="DAP Module_CategoryName" Value="Device Access Point Module"/>
<Text TextId="DIM 31_InfoText" Value="Firmware version V5.3.0 Identification & Maintenance 1-3, Shared Device, RT und IRT Betrieb."/>
<Text TextId="DataItem_12byteinput_inputdata_0_Name" Value="Eingänge"/>
<Text TextId="DataItem_10byteoutput_outputdata_0_Name" Value="Ausgänge"/>
<Text TextId="DeviceDescription_InfoText" Value="PROFINET IO-Device"/>
<Text TextId="Input Module_CategoryName" Value="Eingangsmodule"/>
<Text TextId="Module_12byteinput_InfoText" Value="12 Byte Eingangsmodul"/>
<Text TextId="Module_12byteinput_Name" Value="12 Byte Eingang"/>
<Text TextId="Module_10byteoutput_InfoText" Value="10 Byte Ausgangsmodul"/>
<Text TextId="Module_10byteoutput_Name" Value="10 Byte Ausgang"/>
<Text TextId="NETX RE/PNS V5.3.0 Host Example" Value="NETX RE/PNS V5.3.0 Host Example"/>
<Text TextId="Output Module_CategoryName" Value="Ausgangsmodule"/>
<Text TextId="PN-IO" Value="PN-IO"/>
<Text TextId="Port1" Value="Port 1"/>
<Text TextId="Port2" Value="Port 2"/>
<Text TextId="Submodule_12byteinput_InfoText" Value="12 Byte Eingangssubmodul"/>
<Text TextId="Submodule_12byteinput_Name" Value="12 Byte Eingang"/>
<Text TextId="Submodule_10byteoutput_InfoText" Value="10 Byte Ausgangssubmodul"/>
<Text TextId="Submodule_10byteoutput_Name" Value="10 Byte Ausgang"/>
<Text TextId="X1" Value="X1"/>
<Text TextId="X1P1" Value="X1 P1"/>
<Text TextId="X1P2" Value="X1 P2"/>
</Language>
</ExternalTextList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>
9. Modules/Submodules
Modules are user defined components that plug into slots. Modules can be real or virtual.
Submodules are components of a module that is plugged into a subslot. A submodule can be real or virtual.
For this example, another module should be created with a submodule. The module should be of type Input Output and with a size of 2 bytes. The module IDs should have as small values as possible and be created with ascending values.
Please add an Input Output module with the Provider- and the Consumer Data Length in the GSDML file and also in the application (SimpleConfig example).
Do not forget to add in the ModuleIdentNumber the offsets.
/************************************************************************************** function: SetModulConfig description: Fills all necessary information about module configuration. global: none input: PNS_IF_MODULE_CFG_REQ_DATA_T FAR* ptModule - pointer to the packet output: none return: long (Pointer to the packet) ************************************************************************************** / long SetModulConfig( void* pvPck ) { /* Configure 2 Byte Input Output module (Device to PLC and PLC to Device) */ ptSubmod->usSlot = 0x0003; /* Slot this submodule belongs to */ ptSubmod->usSubslot = 0x0001; /* Subslot of this submodule */ /* PNS SET CONFIG*/ ptSubmod->ulModuleId = 0x00000003; /* Module ID to which this submodule belongs */ ptSubmod->ulSubmodId = 0x00000001; /* Submodule ID */ ptSubmod->ulProvDataLen = 0x00000002; /* Length of provider data (sent by IO-Device, received by IO-Controller) */ ptSubmod->ulConsDataLen = 0x00000002; /* Length of consumer data (sent by IO-Controller, received by IO-Device) */ ptSubmod->ulDPMOffsetOut = 0x0000000E; /* 12 Bytes Input + 2 Bytes Input Output Offset in DPM OutputArea or in */ /* Output-image, where provided data of thesubmodule shall be taken from */ ptSubmod->ulDPMOffsetIn = 0x0000000C; /* 10 Bytes Input + 2 Bytes Input Output Offset in DPM InputArea or in */ /* Input-image, where consumed data for the submodule shall be copied to */ ptSubmod->usOffsetIOPSProvider = 0x0000; /* Offset where the stack shall take the IOPS provider state for this */ /* submodule relative to beginning of IOPS block in DPM output area from */ ptSubmod->usOffsetIOPSConsumer = 0x0000; /* Offset where the stack shall put the IOPS consumer state of this */ /* submodule relative to beginning of IOPS block in DPM input area to */ ptSubmod->usOffsetIOCSProvider = 0x0000; /* Offset where the stack shall take the IOCS provider state for this */ /* submodule relative to beginning of IOCS block in DPM output area from */ ptSubmod->usOffsetIOCSConsumer = 0x0000; /* Offset where the stack shall put the IOCS consumer state for this */ /* submodule relative to beginning of IOCS block in DPM input area to */ ptSubmod->ulReserved = 0x00000000; /* Reserved for future usage */ ptSubmod++; /* Increment submodule */ }
<?xml version="1.0" encoding="iso-8859-1"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.35.xsd">
<ProfileBody>
<ApplicationProcess>
<ModuleList>
<ModuleItem ID="2byteinputoutput" ModuleIdentNumber="0x00000003">
<ModuleInfo CategoryRef="Input Output Module">
<Name TextId="Module_2byteinputoutput_Name"/>
<InfoText TextId="Module_2byteinputoutput_InfoText"/>
</ModuleInfo>
<VirtualSubmoduleList>
<VirtualSubmoduleItem ID="2byteinputoutput" MayIssueProcessAlarm="false" SubmoduleIdentNumber="0x00000001">
<IOData>
<Output>
<DataItem DataType="OctetString" Length="2" TextId="DataItem_2byteinput_output_inputoutputdata_0_Name"/>
</Output>
</IOData>
<ModuleInfo>
<Name TextId="Submodule_2byteinputoutput_Name"/>
<InfoText TextId="Submodule_2byteinputoutput_InfoText"/>
</ModuleInfo>
</VirtualSubmoduleItem>
</VirtualSubmoduleList>
</ModuleItem>
</ModuleList>
<CategoryList>
<CategoryItem ID="DAP Module" TextId="DAP Module_CategoryName"/>
<CategoryItem ID="Input Module" TextId="Input Module_CategoryName"/>
<CategoryItem ID="Output Module" TextId="Output Module_CategoryName"/>
<CategoryItem ID="Input Output Module" TextId="Input Output Module_CategoryName"/>
</CategoryList>
<ExternalTextList>
<PrimaryLanguage>
<Text TextId="DAP Module_CategoryName" Value="Device Access Point Modules"/>
<Text TextId="DIM 32_InfoText" Value="Firmware version V5.3.0 Identification & Maintenance 1-3, Shared Device, RT and IRT Communication."/>
<Text TextId="DataItem_12byteinput_inputdata_0_Name" Value="Inputs"/>
<Text TextId="DataItem_10byteoutput_outputdata_0_Name" Value="Outputs"/>
<Text TextId="DataItem_2byteinput_output_inputoutputdata_0_Name" Value="InputsOutputs"/>
<Text TextId="DeviceDescription_InfoText" Value="PROFINET IO-Device"/>
<Text TextId="Input Module_CategoryName" Value="Input Modules"/>
<Text TextId="Module_12byteinput_InfoText" Value="12 Bytes Input Module"/>
<Text TextId="Module_12byteinput_Name" Value="12 Bytes Input"/>
<Text TextId="Module_10byteoutput_InfoText" Value="10 Bytes Output Module"/>
<Text TextId="Module_10byteoutput_Name" Value="10 Bytes Output"/>
<Text TextId="Module_2byteinputoutput_InfoText" Value="2 Bytes InputsOutputs Module"/>
<Text TextId="Module_2byteinputoutput_Name" Value="2 Bytes InputsOutputs"/>
<Text TextId="NETX RE/PNS V5.3.0 Host Example Use Case A" Value="NETX RE/PNS V5.3.0 Host Example"/>
<Text TextId="Output Module_CategoryName" Value="Output Modules"/>
<Text TextId="Input Output Module_CategoryName" Value="Input Output Modules"/>
<Text TextId="PN-IO" Value="PN-IO"/>
<Text TextId="Port1" Value="Port 1"/>
<Text TextId="Port2" Value="Port 2"/>
<Text TextId="Submodule_12byteinput_InfoText" Value="12 Bytes Input Submodule"/>
<Text TextId="Submodule_12byteinput_Name" Value="12 Bytes Input"/>
<Text TextId="Submodule_10byteoutput_InfoText" Value="10 Byte Output Submodule"/>
<Text TextId="Submodule_10byteoutput_Name" Value="10 Bytes Output"/>
<Text TextId="Submodule_2byteinputoutput_InfoText" Value="2 Byte InputsOutputs Submodule"/>
<Text TextId="Submodule_2byteinputoutput_Name" Value="2 Bytes InputsOutputs"/>
<Text TextId="X1" Value="X1"/>
<Text TextId="X1P1" Value="X1 P1"/>
<Text TextId="X1P2" Value="X1 P2"/>
</PrimaryLanguage>
<Language xml:lang="de">
<Text TextId="DAP Module_CategoryName" Value="Device Access Point Module"/>
<Text TextId="DIM 32_InfoText" Value="Firmware version V5.3.0 Identification & Maintenance 1-3, Shared Device, RT und IRT Betrieb."/>
<Text TextId="DataItem_12byteinput_inputdata_0_Name" Value="Eingänge"/>
<Text TextId="DataItem_10byteoutput_outputdata_0_Name" Value="Ausgänge"/>
<Text TextId="DataItem_2byteinput_output_inputoutputdata_0_Name" Value="EingängeAusgänge"/>
<Text TextId="DeviceDescription_InfoText" Value="PROFINET IO-Device"/>
<Text TextId="Input Module_CategoryName" Value="Eingangsmodule"/>
<Text TextId="Module_12byteinput_InfoText" Value="12 Byte Eingangsmodul"/>
<Text TextId="Module_12byteinput_Name" Value="12 Byte Eingang"/>
<Text TextId="Module_10byteoutput_InfoText" Value="10 Byte Ausgangsmodul"/>
<Text TextId="Module_10byteoutput_Name" Value="10 Byte Ausgang"/>
<Text TextId="Module_2byteinputoutput_InfoText" Value="2 Byte EingangsAusgangsmodul"/>
<Text TextId="Module_2byteinputoutput_Name" Value="2 Byte EingangAusgang"/>
<Text TextId="NETX RE/PNS V5.3.0 Host Example Use Case A" Value="NETX RE/PNS V5.3.0 Host Example"/>
<Text TextId="Output Module_CategoryName" Value="Ausgangsmodule"/>
<Text TextId="Input Output Module_CategoryName" Value="EingangsAusgangsmodule"/>
<Text TextId="PN-IO" Value="PN-IO"/>
<Text TextId="Port1" Value="Port 1"/>
<Text TextId="Port2" Value="Port 2"/>
<Text TextId="Submodule_12byteinput_InfoText" Value="12 Byte Eingangssubmodul"/>
<Text TextId="Submodule_12byteinput_Name" Value="12 Byte Eingang"/>
<Text TextId="Submodule_10byteoutput_InfoText" Value="10 Byte Ausgangssubmodul"/>
<Text TextId="Submodule_10byteoutput_Name" Value="10 Byte Ausgang"/>
<Text TextId="Submodule_2byteinputoutput_InfoText" Value="2 Byte EingangsAusgangssubmodul"/>
<Text TextId="Submodule_2byteinputoutput_Name" Value="2 Bytes EingangsAusgangssubmodul/>
<Text TextId="X1" Value="X1"/>
<Text TextId="X1P1" Value="X1 P1"/>
<Text TextId="X1P2" Value="X1 P2"/>
</Language>
</ExternalTextList>
</ApplicationProcess>
</ProfileBody>
</ISO15745Profile>