Decoding of Profinet Diagnosis Records
- Andreas Messer
- Marcel S
- Benjamin Meyer
How to read and decode Profinet Diagnosis from a connected Profinet IO Device?
In order to read out the current Profinet Diagnosis from an IO Device the ReadRecord service of Profinet IO Controller needs to be used. The response needs to be decoded. This FAQ will give a hint how this can be done.
Background
Every Profinet Device maintains a Diagnosis Database. This database contains records of every pending diagnosis in the device. The database content can be read through Record Objects. These record objects are accessible through AR based Read Records and Read Implicit Records. The latter may be performed from every IP based network device.
Diagnosis Types
Profinet defines Diagnosis Types of different detail to cover different use case. The type of a diagnosis is associated with a 16 bit unsigned integer called User Struct Identifier:
- User Struct Identifier values from 0 to 0x7FFF are reserved for the application and can be freely assigned by the device vendor. The format of the diagnosis data must be described in the GSDML file of the device.
- User Struct Identifier 0x8000 represents a ChannelDiagnosis. A Channel Diagnosis is made of a single 16 Bit Error Code. The values of this Error Code are partly predefined and partly free for use by the application. The later case requires corresponding definitions in the GSDML file.
- User Struct Identifier 0x8002 represents a ExtendedChannelDiagnosis. It extends the Channel Diagnosis by an additional 16 Bit Error Code and a 32 Bit Value. The 32 Bit Value can be included by the engineering software in Diagnosis messages if defined in GSDML
Record Objects for Reading Diagnoses
The following table lists all record objects through which the Diagnosis database is accessible. They differ mainly in terms of filters applied to the diagnosis database. The Api, Slot and Subslot parameters are taken from the Read Record Request, the AR is the AR which performs the Read Record or the Target AR in an Implicit Read Record.
Record Index | Record Object Name | Diagnosis entries filtered by |
---|---|---|
0x800A | Diagnosis in channel coding for one subslot | Api; Slot; Subslot; Type must be Channel or ExtendedChannel |
0x800B | Diagnosis in all codings for one subslot | Api; Slot; Subslot |
0x800C | Diagnosis, Maintenance, Qualified and Status for one subslot | Api; Slot; Subslot; Severity one of Diagnosis, Maintenance, Qualified or Status |
0x8010 | Maintenance required in channel coding for one subslot | Api; Slot; Subslot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required |
0x8011 | Maintenance demanded in channel coding for one subslot | Api; Slot; Subslot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded |
0x8012 | Maintenance required in all codings for one subslot | Api; Slot; Subslot; Severity must be Maintenance Required |
0x8013 | Maintenance demanded in all codings for one subslot | Api; Slot; subslot; Severity must be Maintenance Demanded |
0xC00A | Diagnosis in channel codings for one slot | Api; Slot; Type must be Channel or ExtendedChannel |
0xC00B | Diagnosis in all codings for one slot | Api; Slot |
0xC00C | Diagnosis, Maintenance, Qualified and Status for one slot | Api; Slot; Severity one of Diagnosis, Maintenance, Qualified or Status |
0xC010 | Maintenance required in channel coding for one slot | Api; Slot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required |
0xC011 | Maintenance demanded in channel coding for one slot | Api; Slot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded |
0xC012 | Maintenance required in all codings for one slot | Api; Slot; Severity must be Maintenance Required |
0xC013 | Maintenance demanded in all codings for one slot | Api; Slot; Severity must be Maintenance Demanded |
0xE00A | Diagnosis in channel codings for one AR | AR; Type must be Channel or ExtendedChannel |
0xE00B | Diagnosis in all codings for one AR | AR; |
0xE00C | Diagnosis, Maintenance, Qualified and Status for one AR | AR; Severity one of Diagnosis, Maintenance, Qualified or Status |
0xE010 | Maintenance required in channel coding for one AR | AR; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required |
0xE011 | Maintenance demanded in channel coding for one AR | AR; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded |
0xE012 | Maintenance required in all codings for one AR | AR; Severity must be Maintenance Required |
0xE013 | Maintenance demanded in all codings for one AR | AR; Severity must be Maintenance Demanded |
0xF00A | Diagnosis in channel codings for one API | Api; Type must be Channel or ExtendedChannel |
0xF00B | Diagnosis in all codings for one API | Api; |
0xF00C | Diagnosis, Maintenance, Qualified and Status for one API | Api; Severity one of Diagnosis, Maintenance, Qualified or Status |
0xF010 | Maintenance required in channel coding for one API | Api; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required |
0xF011 | Maintenance demanded in channel coding for one API | Api; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded |
0xF012 | Maintenance required in all codings for one API | Api; Severity must be Maintenance Required |
0xF013 | Maintenance demanded in all codings for one API | Api; Severity must be Maintenance Demanded |
0xF80C | Diagnosis, Maintenance, Qualified and Status for one Device | Severity one of Diagnosis, Maintenance, Qualified or Status |
Record Data Encoding
Reading one of the Record Objects above delivers the diagnosis entries encoded in Profinet RPC PDU format. Diagnoses of the same type are pooled together and encoded in one RPC Diagnosis PDU. Multiple RPC Diagnosis PDUs are concatenated together without padding and yield the Data of the Record Object. All PDU fields are encoded in Big Endian (Network) Byte Order.
PROFINET PDU Format
Profinet PDUs have a 6 byte header which describes the type and length of the PDU. Multiple PDUs might be concatenated together. Depending on the context two PDUs might be seperated by additional padding to achive 4-byte alignment. A PDU might contain sub-PDUs in its data part. This structure is illustrated in the following image
This can be encoded in C as follows
#pragma pack(push,1) typedef struct PN_PDU_HEAD_Ttag PN_PDU_HEAD_T; struct PN_PDU_HEAD_Ttag { uint16_t usType; uint16_t usLen; uint8_t bVersionMajor; uint8_t bVersionMinor; }; #pragma pack(pop)
PROFINET Diagnosis PDU Format
An PROFINET Diagnosis PDU is made of a generic diagnosis header followed by a variable number of diagnosis blocks. The header specifies the submodule associated with the diagnosis and the type of the diagnosis blocks. This is shown in the next image:
The header is encoded with the following values:
Field | Value |
---|---|
usType | 0x0010 |
usLength | 16 + Length of all Diagnosis Blocks |
bVersionMajor | 1 |
bVersionMinor | 0 |
The data is organized as follows. The PROFINET Diagnosis header is defined with the following structure:
Field Name | Field Type | Description |
---|---|---|
ulApi | UINT32 | Api of the affected Submodule |
usSlot | UINT16 | Slot of the affected Submodule |
usSubslot | UINT16 | Subslot of the affected Submodule |
usChannelNum | UINT16 | Channel of the Diagnosis. Diagnoses can refer either to the Submodule itself (Value 0x8000) or to a Channel of the Submodule( Value < 0x8000). This can be used to detailed specify the origin of the Diagnosis within the submodule. E.g. Cable Break of Line 2 |
usChannelProperties | UINT16 | A bitfield characterizing the diagnosis:
|
usUserStructIdent | UINT16 | The type of the diagnosis:
|
The PROFINET Channel Diagnosis Block is defined with the following structure:
Field Name | Field Type | Description |
---|---|---|
usChannelNum | UINT16 | Channel of the Diagnosis. Diagnoses can refer either to the Submodule itself (Value 0x8000) or to a Channel of the Submodule( Value < 0x8000). This can be used to detailed specify the origin of the Diagnosis within the submodule. E.g. Cable Break of Line 2 |
usChannelProp | UINT16 | A bitmask characterizing the diagnosis |
usChannelErrType | UINT16 | The error code characterizing the Problem. |
The PROFINET Extended Channel Diagnosis Block is defined with the following structure:
Field Name | Field Type | Description |
---|---|---|
usChannelNum | UINT16 | Channel of the Diagnosis. Diagnoses can refer either to the Submodule itself (Value 0x8000) or to a Channel of the Submodule( Value < 0x8000). This can be used to detailed specify the origin of the Diagnosis within the submodule. E.g. Cable Break of Line 2 |
usChannelProp | UINT16 | A bitmask characterizing the diagnosis |
usChannelErrType | UINT16 | The error code characterizing the Problem. |
usExtChannelErrType | UINT16 | A detailed error code further characterizing the Problem |
ulExtChannelAddValue | UINT32 | A 32 bit value associated with the diagnosis. Meaning depends on usChannelErrType and usExtChannelErrType |
This can be encoded in C structures like
#pragma pack(push,1) typedef struct PN_DIAGNOSIS_PDU_HEAD_Ttag PN_DIAGNOSIS_PDU_HEAD_T; struct PN_DIAGNOSIS_PDU_HEAD_Ttag { uint32_t ulApi; uint16_t usSlot; uint16_t usSubslot; uint16_t usChannelNum; uint16_t usChannelProp; uint16_t usUserStructIdent; }; typedef struct PN_DIAGNOSIS_PDU_CHANNELDIAG_Ttag PN_DIAGNOSIS_PDU_CHANNELDIAG_T; struct PN_DIAGNOSIS_PDU_CHANNELDIAG_Ttag { uint16_t usChannelNum; uint16_t usChannelProp; uint16_t usChannelErrType; }; typedef struct PN_DIAGNOSIS_PDU_EXTCHANNELDIAG_Ttag PN_DIAGNOSIS_PDU_EXTCHANNELDIAG_T; struct PN_DIAGNOSIS_PDU_EXTCHANNELDIAG_Ttag { uint16_t usChannelNum; uint16_t usChannelProp; uint16_t usChannelErrType; uint16_t usExtChannelErrType; uint32_t ulExtChannelAddValue; }; #pragma pack(pop)
Example
A very simple and straight forward way is shown now using the Hilscher PROFINET IO Controller and the Hilscher cifXTest application.
A Read Request is issued for the IO Device with DeviceHandle 0, API 0, Slot 1, Subslot 1, Index 0xF80C. So a request for all entries in the IO Device's diagnosis buffer is issued. The request and response are shown in the following picture. Please refer to Profinet IO Controller API Manual for details regarding the firmware interface.
Having a closer look at the response the following data is returned by the IO Device:
00 00 00 00 00 00 00 00 00 00 00 00 1A 00 00 00 01 00 01 00 0C F8 00 00 00 00 00 00 00 10 00 16 01 01 00 00 00 00 00 01 00 01 80 00 08 00 80 00 00 80 08 00 00 01
This needs to be decoded as follows:
Parameter | Value |
---|---|
DeviceHandle | 0 |
PNIO error | 0 |
API | 0 |
Data length | 0x1A |
Slot | 1 |
Subslot | 1 |
Index | 0xFC08 |
AddValue1 | 0 |
AddValue2 | 0 |
Align | 0 |
adData | 00 10 00 16 01 01 00 00 00 00 00 01 00 01 80 00 08 00 80 00 00 80 08 00 00 01 |
In the next step abData needs to be decoded with the knowledge provided at the beginning of this FAQ. Please note that the byte order is now different to the byte order of the well defined PROFINET IO Controller API.
The first 6 byte represent the PROFINET BlockHeader.
Parameter | Value |
---|---|
BlockType | 0x10 |
BlockLength | 0x16 |
VersionMajor | 1 |
VersionMinor | 1 |
Data | 00 00 00 00 00 01 00 01 80 00 08 00 80 00 00 80 08 00 00 01 |
The BlockType is 0x10 thus it is a DiagnosisData unit with the layout as described above in PN_DIAGNOSIS_PDU_HEAD_T.
Parameter | Value |
---|---|
API | 0 |
Slot | 1 |
Subslot | 1 |
ChannelNumber | 0x8000 |
ChannelProperties | 0x0800 |
UserStructureIdentifier | 0x8000 |
Data | 00 80 08 00 00 01 |
The UserStructureIdentifier has the value 0x8000 thus the coding for ChannelDiagnosis PN_DIAGNOSIS_PDU_CHANNELDIAG_T applies.
Parameter | Value |
---|---|
ChannelNumber | 0x80 |
ChannelProperties | 0x0800 |
ChannelErrorType | 1 |
Thus the IO Device has the following diagnosis entry:
API 0, Slot 1, Subslot 1 has a ChannelDiagnosis on Channel 0x80 with ChannelErrorType 1 which is a Short circuit.