Decoding of Profinet Diagnosis Records

Q

How to read and decode Profinet Diagnosis from a connected Profinet IO Device?

A

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 IndexRecord Object NameDiagnosis entries filtered by
0x800A

Diagnosis in channel coding for one subslot

Api; Slot; Subslot; Type must be Channel or ExtendedChannel
0x800BDiagnosis in all codings for one subslotApi; Slot; Subslot
0x800CDiagnosis, Maintenance, Qualified and Status for one subslotApi; Slot; Subslot; Severity one of Diagnosis, Maintenance, Qualified or Status
0x8010Maintenance required in channel coding for one subslotApi; Slot; Subslot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required
0x8011Maintenance demanded in channel coding for one subslotApi; Slot; Subslot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded
0x8012Maintenance required in all codings for one subslotApi; Slot; Subslot; Severity must be Maintenance Required
0x8013Maintenance demanded in all codings for one subslotApi; Slot; subslot; Severity must be Maintenance Demanded
0xC00ADiagnosis in channel codings for one slotApi; Slot; Type must be Channel or ExtendedChannel
0xC00BDiagnosis in all codings for one slotApi; Slot
0xC00CDiagnosis, Maintenance, Qualified and Status for one slotApi; Slot; Severity one of Diagnosis, Maintenance, Qualified or Status
0xC010Maintenance required in channel coding for one slotApi; Slot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required
0xC011Maintenance demanded in channel coding for one slotApi; Slot; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded
0xC012Maintenance required in all codings for one slotApi; Slot; Severity must be Maintenance Required
0xC013Maintenance demanded in all codings for one slotApi; Slot; Severity must be Maintenance Demanded
0xE00ADiagnosis in channel codings for one ARAR; Type must be Channel or ExtendedChannel
0xE00BDiagnosis in all codings for one ARAR;
0xE00CDiagnosis, Maintenance, Qualified and Status for one ARAR; Severity one of Diagnosis, Maintenance, Qualified or Status
0xE010Maintenance required in channel coding for one ARAR; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required
0xE011Maintenance demanded in channel coding for one ARAR; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded
0xE012Maintenance required in all codings for one ARAR; Severity must be Maintenance Required
0xE013Maintenance demanded in all codings for one ARAR; Severity must be Maintenance Demanded
0xF00ADiagnosis in channel codings for one APIApi; Type must be Channel or ExtendedChannel
0xF00BDiagnosis in all codings for one APIApi;
0xF00CDiagnosis, Maintenance, Qualified and Status for one APIApi; Severity one of Diagnosis, Maintenance, Qualified or Status
0xF010Maintenance required in channel coding for one APIApi; Type must be Channel or ExtendedChannel; Severity must be Maintenance Required
0xF011Maintenance demanded in channel coding for one APIApi; Type must be Channel or ExtendedChannel; Severity must be Maintenance Demanded
0xF012Maintenance required in all codings for one APIApi; Severity must be Maintenance Required
0xF013Maintenance demanded in all codings for one APIApi; Severity must be Maintenance Demanded
0xF80CDiagnosis, Maintenance, Qualified and Status for one DeviceSeverity 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:

FieldValue
usType0x0010
usLength16 + Length of all Diagnosis Blocks
bVersionMajor1
bVersionMinor0

The data is organized as follows. The PROFINET Diagnosis header is defined with the following structure:

Field NameField TypeDescription
ulApiUINT32Api of the affected Submodule
usSlotUINT16Slot of the affected Submodule
usSubslotUINT16Subslot of the affected Submodule
usChannelNumUINT16Channel 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
usChannelPropertiesUINT16

A bitfield characterizing the diagnosis:

  • Severity by Mask 0x0600:
    • 0x0000 Diagnosis
    • 0x0200 Maintenance Required
    • 0x0400 Maintenance Demanded
    • 0x0600 Qualified Diagnosis
  • Specifier by Mask 0x1800
    • 0x0800 Diagnosis Appears (Used in Diagnosis Record Objects and Alarms)
    • 0x1000 Diagnosis Appears (Used in Diagnosis Alarms)
    • 0x1800 Diagnosis Appears but others Exists (Used in Diagnosis Alarms)
usUserStructIdentUINT16

The type of the diagnosis:

  • 0x0000 - 0x7FFF: Exactly one manufacturer specific diagnosis block follows
  • 0x8000: One or more Channel Diagnosis Blocks follow
  • 0x8002: One or more Extended Channel Diagnosis Blocks follow

The PROFINET Channel Diagnosis Block is defined with the following structure:

Field NameField TypeDescription
usChannelNumUINT16Channel 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
usChannelPropUINT16A bitmask characterizing the diagnosis
usChannelErrTypeUINT16The error code characterizing the Problem.

The PROFINET Extended Channel Diagnosis Block is defined with the following structure:

Field NameField TypeDescription
usChannelNumUINT16Channel 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
usChannelPropUINT16A bitmask characterizing the diagnosis
usChannelErrTypeUINT16The error code characterizing the Problem.
usExtChannelErrTypeUINT16A detailed error code further characterizing the Problem
ulExtChannelAddValueUINT32A 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:

ParameterValue
DeviceHandle0
PNIO error0
API0
Data length0x1A
Slot1
Subslot1
Index0xFC08
AddValue10
AddValue20
Align0
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.

ParameterValue
BlockType0x10
BlockLength0x16
VersionMajor1
VersionMinor1
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.

ParameterValue
API0
Slot1
Subslot1
ChannelNumber0x8000
ChannelProperties0x0800
UserStructureIdentifier0x8000
Data
00 80 08 00 00 01 

The UserStructureIdentifier has the value 0x8000 thus the coding for ChannelDiagnosis PN_DIAGNOSIS_PDU_CHANNELDIAG_T applies.

ParameterValue
ChannelNumber0x80
ChannelProperties0x0800
ChannelErrorType1

 

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.