ProfinetConnector/profinet_stack/p-net/doc/implementation_details.rst

1027 lines
57 KiB
ReStructuredText

Implementation details
======================
This software stack is written in C, version C99.
For running the unit tests C++ (version C++11 or later) is required.
The primary p-net use case is to run in embedded devices, why there in general
are no functions to shut down the stack.
Application relations, communication relations and sessions
-----------------------------------------------------------
An "Application Relation" (AR) is a connection to an IO-controller (PLC). An AR
consists of two "Communication Relations" (CR) for cyclic data; one input and
one output.
There might be multiple ARs, as several PLCs can use the same IO-device.
On the wire an AR is identified by an UUID (the ARUUID).
The first AR has AREP=1, next has AREP=2 etc.
Each AR has its own CMDEV state machine.
Each AR has two sessions. One session is used for incoming DCE/RPC communication via UDP,
and uses the main listening UDP socket.
That session is created at the first incoming Connect message, and is reused for
the subsequent messages.
A separate session is created for the outgoing CControl request to the IO-controller,
and it creates its own UDP socket.
For an incoming Read Implicit request a session is created, and then closed
after the response.
Each session has an input and output buffer, in order to be able to handle
fragmented messages (larger than a single Ethernet frame).
On the wire, the session is identified by the activity UUID in the DCE/RPC
header.
C header files
--------------
The header file ``pnet_export.h`` is generated by cmake. It ends up in
``build/include/pnet_export.h``.
Incoming frame PDU types
------------------------
* A_Data Acyclic RTA_CLASS_1
* C_Data Cyclic RT_CLASS_1 or RT_CLASS_2 or RT_CLASS_3
* N_Data RT_CLASS_UDP or RTA_CLASS_UDP
* P_Data TimeStamped
* R_Data RSI
Stack development helper functions
----------------------------------
Use ``pf_memory_contents_show()`` to show the contents of a buffer/memory area.
State machines
--------------
* ALPMI Alarm Protocol Machine Initiator. Initiates alarm (for sending to IO-controller)
* ALPMR Alarm Protocol Machine Responder. Responds to alarm (from IO-controller)
* APMR Acyclic Protocol Machine Receiver. Receives high- and low priority alarm Ethernet frames from the IO-controller (both alarms triggered by IO-Controller, and ack to alarms we trigger)
* APMS Acyclic Protocol Machine Sender. Sends alarm Ethernet frames to IO-controller (both alarms we trigger, and ack to alarms triggered by IO-Controller)
* CMDEV Context Management protocol machine Device, handles connection establishment for IO-Devices.
* CMDMC Multicast communication between IO devices via DCP Identify messages.
* CMINA Context Management Ip and Name Assignment protocol machine
* CMIO Context Management Input Output protocol machine
* CMPBE Context Management Parameter Begin End protocol machine. Optional.
* CMRDR Context Management Read Record Responder protocol machine, responds to parameter read from the IO-controller
* CMRPC Context Management RPC Protocol Machine, handles RPC communication via UDP
* CMSM Context Management Surveillance protocol Machine, monitors the establishment of a connection.
* CMSU Context Management Start Up machine. Starts other state machines, for example PPM and CPM
* CMWRR Context Management Write Record Responder protocol machine
* CPM Consumer Protocol Machine, for receiving cyclic data
* FSPM Fieldbus Application Layer Service Protocol Machine. Interaction with user application; implements callbacks.
* PPM Provider Protocol Machine, for sending cyclic data
Alarm related state machines
----------------------------
* APMS: It resends the Alarm DATA frame until it gets a TACK (transport acknowledge) back.
* APMR: Receives Alarm DATA frames, and sends TACK.
* ALPMI: Issues an Alarm Notification PDU, and waits for the Alarm ACK PDU.
* ALPMR: Hands over Alarm Notification PDU to the application, and waits for the application to respond to it. Waits for the sent ACK PDU to have its TACK.
Overview of alarm communication: (right-click "View Image" to magnify)
.. image:: illustrations/AlarmStateMachines.png
Sections in 61784-2 (profiles) describing alarms:
+---------------+------------------------------------------------------------------------+
| Section | Description |
+===============+========================================================================+
| 7.1.3.2.1 | Communication (Class D should support one additional Device Access AR) |
+---------------+------------------------------------------------------------------------+
Sections in 61158-5-10 (services) describing alarms:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 7.1.6.2 | Application process rules (for pull module alarm allowed) |
+---------------+-------------------------------------------------------------+
| 7.3.1.3.6.2.5 | State table DEVSM (Multicast Communication Mismatch Alarm) |
+---------------+-------------------------------------------------------------+
| 7.3.1.4.6.1.5 | Behavior on transitions (Alarms on IOCS/IOPS) |
+---------------+-------------------------------------------------------------+
| 7.3.1.6 | Alarm class |
+---------------+-------------------------------------------------------------+
| 7.3.4.2.6.2 | Alarm Behavior (for diagnosis class) |
+---------------+-------------------------------------------------------------+
Sections in 61158-6-10 (protocol) describing alarms:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 4.8.2 | RTA transfer syntax |
+---------------+-------------------------------------------------------------+
| 4.8.4.2 | APMS |
+---------------+-------------------------------------------------------------+
| 4.8.4.3 | APMR |
+---------------+-------------------------------------------------------------+
| 5.1.2 | APDU abstract syntax |
+---------------+-------------------------------------------------------------+
| 5.2.3 | Coding section related to RTA-SDU specific fields |
+---------------+-------------------------------------------------------------+
| 5.2.9 | Coding section related to Alarm and Diagnosis Data |
+---------------+-------------------------------------------------------------+
| 5.2.42.2.6 | AlarmCRBlockReq Check incoming message |
+---------------+-------------------------------------------------------------+
| 5.2.42.3.5 | AlarmCRBlockRes Check incoming message |
+---------------+-------------------------------------------------------------+
| 5.6.1 | ALPMI |
+---------------+-------------------------------------------------------------+
| 5.6.2 | ALPMR |
+---------------+-------------------------------------------------------------+
| 5.6.3.9 | CMPBE (Alarms during startup) |
+---------------+-------------------------------------------------------------+
| A.3 | Startup of Alarm transmitter and receiver |
+---------------+-------------------------------------------------------------+
Diagnosis
---------
Sections in 61784-2 (profiles) describing LLDP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 7.1.3.2.2.1 | Diagnosis (less than 65536 octets) |
+---------------+-------------------------------------------------------------+
Sections in 61158-5-10 (services) describing diagnosis:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 7.1.4.5.3.6 | Channel and channel numbers |
+---------------+-------------------------------------------------------------+
| 7.3.1.5.6.3 | Behavior of the Module Diff Block regarding diagnosis |
| | (failed parameterization) |
+---------------+-------------------------------------------------------------+
| 7.3.1.6.1.2 | Alarm types attached to diagnosis ASE |
+---------------+-------------------------------------------------------------+
| 7.3.1.6.5.1 | "Alarm Notification" Lists of diagnosis data |
+---------------+-------------------------------------------------------------+
| 7.3.2.5 | Observer class (PD Port Data Check etc) |
+---------------+-------------------------------------------------------------+
| 7.3.4 | Diagnosis ASE |
+---------------+-------------------------------------------------------------+
| Annex F | Precondition for Diagnosis |
+---------------+-------------------------------------------------------------+
Sections in 61158-6-10 (protocol) describing diagnosis:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 5.1.2 | APDU abstract syntax |
+---------------+-------------------------------------------------------------+
| 5.2.3.2 | Coding of the field AlarmSpecifier |
+---------------+-------------------------------------------------------------+
| 5.2.4.4.3 | Grouping of DiagnosisData for the diagnosis records |
+---------------+-------------------------------------------------------------+
| 5.2.9 | Coding section related to Alarm and Diagnosis Data |
+---------------+-------------------------------------------------------------+
See also the "Diagnosis for Profinet" Guideline published by the Profinet
organisation.
For general discussions on diagnosis usage, see the section "A.6 PROFINET
Diagnosis" in the "Specification for GSDML" document.
An array of PNET_MAX_DIAG_ITEMS diagnosis items is available for use. Each
subslot uses a linked list of diagnosis items, and stores the index to the
head of its list.
Logbook
-------
For details, see:
* Profinet 2.4 Services, section 7.3.6
* Profinet 2.4 Protocol, section 5.2.38 "Coding section related to logbook"
* "Specification for GSDML", section 8.26 "LogBookEntryItem"
(allowed error codes)
FSPM - Fieldbus application layer Service Protocol Machine
----------------------------------------------------------
Stores the user-defined configuration, and calls the user-defined callbacks.
Create logbook entries. Reads and writes identification & maintenance records.
CMRPC - Context Management RPC device protocol machine
------------------------------------------------------
Handles the DCE/RPC UDP communication in the start up phase, especially these
messages:
* connect
* release
* DControl ("Parameter end" is sent to IO-Device)
* CControl ("Application ready" is sent to IO-Controller)
* parameter read (Uses CMRDR)
* parameter write
Incoming UDP packets are parsed by ``pf_cmrpc_dce_packet()``, which also
prepares the return UDP packet. This is done by putting together incoming
fragments and then calling ``pf_cmrpc_rpc_request()``.
On DCE RPC connect requests the function ``pf_cmrpc_rm_connect_ind()`` is
called, and it will create a DCE RPC connect response. It will also trigger
these user callbacks:
* ``pnet_exp_module_ind()``
* ``pnet_exp_submodule_ind()``
* ``pnet_connect_ind()``
* ``pnet_state_ind()`` with PNET_EVENT_STARTUP
The function ``pf_cmrpc_rm_write_ind()`` is called for incoming (parameter)
write request messages, and it will trigger the ``pnet_write_ind()`` user
callback for certain parameters.
Other parameters are handled by the stack itself.
Incoming control (DControl) requests are handled by
``pf_cmrpc_rm_dcontrol_ind()`` which typically triggers these user callbacks:
* ``pnet_dcontrol_ind()`` with PNET_CONTROL_COMMAND_PRM_END
* ``pnet_state_ind()`` with PNET_EVENT_PRMEND
When the IO-device is sending a request to an IO-Controller (and expects a
response) a new separate session is started.
Incoming CControl responses are handled by ``pf_cmrpc_rm_ccontrol_cnf()``,
which will trigger these user callbacks:
* ``pnet_state_ind()`` with PNET_EVENT_DATA.
* ``pnet_ccontrol_cnf()``
Show current details on the CMRPC state machine::
pf_cmrpc_show(0xFFFF);
Explicit AR = The incoming RPC request has same AR UUID as an existing AR.
DCP
---
Handles these DCP messages:
* Set
* Get
* Ident
* Hello
Flashes a LED on reception of the "Set request" DCP message with suboption
"Signal".
CMINA - Context Management Ip and Name Assignment protocol machine
------------------------------------------------------------------
This state machine is responsible for assigning station name and IP address.
Does factory reset when requested by IO-controller.
States:
* SETUP
* SET_NAME
* SET_IP
* W_CONNECT
Helps handling DCP Set and DCP Get requests.
CMRDR - Context Management Read record Responder protocol machine
-----------------------------------------------------------------
Contains a single function ``pf_cmrdr_rm_read_ind()``, that handles
RPC parameter read requests.
Triggers the ``pnet_read_ind()`` user callback for some values.
Other values, for example the Identification & Maintenance (I&M)
values, are handled internally by the stack.
This state machine is used by CMRPC.
CMWRR - Context Management Write Record Responder protocol machine
------------------------------------------------------------------
Handles RPC parameter write requests.
Triggers the ``pnet_write_ind()`` user callback for some values.
CMDEV - Context Management protocol machine Device
--------------------------------------------------
This handles connection establishment for IO-Devices.
For example pulling and plugging modules and submodules in slots and
subslots are done in this file. Also implements handling connect, release,
CControl and DControl.
States:
* POWER_ON, Data initialization. (Must be first)
* W_CIND, Wait for connect indication (in the connect UDP message)
* W_CRES, Wait for connect response from app and CMSU startup.
* W_SUCNF, Wait for CMSU confirmation.
* W_PEIND, Wait for PrmEnd indication (in the DControl UDP message)
* W_PERES, Wait for PrmEnd response from app.
* W_ARDY, Wait for app ready from app.
* W_ARDYCNF, Wait for app ready confirmation from controller.
* WDATA, Wait for established cyclic data exchange.
* DATA, Data exchange and connection monitoring.
* ABORT, Abort application relation.
Implements these user functions (via ``pnet_api.c``):
* ``pnet_plug_module()``
* ``pnet_plug_submodule()``
* ``pnet_pull_module()``
* ``pnet_pull_submodule()``
* ``pnet_application_ready()`` Triggers the ``pnet_state_ind()`` user callback with PNET_EVENT_APPLRDY.
* ``pnet_ar_abort()``
Show the plugged modules and sub-modules, and number of bytes sent and received
for subslots::
pf_cmdev_device_show();
Show current state for CMDEV state machine::
pf_cmdev_ar_show(p_ar);
CMSM - Context Management Surveillance protocol Machine
-------------------------------------------------------
The CMSM component monitors the establishment of a connection. Once the
device enters the DATA state this component is done.
This is basically a timer, which has two states; IDLE and RUN. If not stopped
before it times out, the stack will enter PNET_EVENT_ABORT state.
The timer returns to state IDLE at timeout. Typically the timeout setting is
around 20 seconds (can be adjusted by the IO-Controller).
The timer is started on PNET_EVENT_STARTUP (at the connect request message),
and stopped at PNET_EVENT_DATA.
It also monitors these response and indication messages:
* Read
* Write
* DControl
It starts the timer at sending the "response" message, and stops the timer
when the "indication" message is received.
CPM - Consumer Protocol Machine
-------------------------------
Receives cyclic data. Monitors that the incoming data fulfills the protocol,
and that the timing of incoming frames is correct. Stores incoming data into a
buffer.
Several instances of CPM can be used in parallel.
States:
* W_START Wait for initialization
* FRUN
* RUN Running
If there is a timeout in the RUN state, it will transition back to state
W_START.
Implements these user functions (via ``pnet_api.c``):
* ``pnet_output_get_data_and_iops()``
* ``pnet_input_get_iocs()``
Triggers the ``pnet_new_data_status_ind()`` user callback on data status
changes (not on changes in the data itself).
PPM - Provider Protocol Machine
-------------------------------
Sends cyclic data.
States:
* W_START
* RUN
Implements these user functions (via ``pnet_api.c``):
* ``pnet_input_set_data_and_iops()``
* ``pnet_output_set_iocs()``
* ``pnet_set_primary_state()``
* ``pnet_set_redundancy_state()``
* ``pnet_set_provider_state()``
Relevant sections in 61158-6-10 (protocol):
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 4.5.3 | "WorkingClock" |
+---------------+-------------------------------------------------------------+
| 4.7.2.1.2 | "Coding of the field CycleCounter" |
+---------------+-------------------------------------------------------------+
| 4.7.4.2 | "Provider protocol machine" PPM |
+---------------+-------------------------------------------------------------+
| 4.12.4.5 | "Send list control" |
+---------------+-------------------------------------------------------------+
| 5.2.5.58 | "Coding of the field SendClockFactor" |
+---------------+-------------------------------------------------------------+
| 5.2.5.59 | "Coding of the field ReductionRatio" |
+---------------+-------------------------------------------------------------+
Block reader and writer
-----------------------
The files ``pf_block_reader.c`` and ``pf_block_writer.c`` implement functions
for parsing and writing data in buffers.
ETH
---
Registers and invokes frame handlers for incoming raw Ethernet frames.
Module diff block
-----------------
Informs about differences between expected and plugged modules,
and also about diagnosis in modules etc. The information for each submodule
is indicated by bit fields in a 16-bit number.
Relevant sections in 61158-5-10 (services):
+--------------------------+--------------------------------------------------+
| Section | Description |
+==========================+==================================================+
| 7.3.1.5.5.5 - 7.3.1.5.6 | "Read Module Diff Block for one AR" |
+--------------------------+--------------------------------------------------+
Relevant sections in 61158-6-10 (protocol):
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 5.1.2 | "APDU abstract syntax" |
+---------------+-------------------------------------------------------------+
| 5.2.5.65 | "Coding of the field SubmoduleState" |
+---------------+-------------------------------------------------------------+
| 5.2.42.3.6 | "ModuleDiffBlock" |
+---------------+-------------------------------------------------------------+
LLDP - Link Layer Discovery Protocol
------------------------------------
Sections in 61784-2 (profiles) describing LLDP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 7.1.4.6 | Link layer discovery protocol (Transmission times) |
+---------------+-------------------------------------------------------------+
| 7.1.11 | Conformance class behaviors (LLDP MIBs) |
+---------------+-------------------------------------------------------------+
Sections in 61158-5-10 (services) describing LLDP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 6.3.13.2 | IEEE 802.1AB class specification (LLDP) |
+---------------+-------------------------------------------------------------+
| 6.3.13.3 | IEEE 802.1AB service specification (LLDP) |
+---------------+-------------------------------------------------------------+
| 7.3.3.3 | Communication Interface Management class (LLDP blocking) |
+---------------+-------------------------------------------------------------+
| 7.3.3.10 | MIB class (LLDP MIB) |
+---------------+-------------------------------------------------------------+
Sections in 61158-6-10 (protocol) describing LLDP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 4.11 | Link layer discovery (LLDP abstract & transfer syntax) |
+---------------+-------------------------------------------------------------+
| 4.16.6 | MIB cross reference (LLDP MIB) |
+---------------+-------------------------------------------------------------+
| 4.16.8 | LLDP EXT MIB (found in Annex U) |
+---------------+-------------------------------------------------------------+
| Annex U | LLDP EXT MIB |
+---------------+-------------------------------------------------------------+
Simple Network Management Protocol (SNMP)
-----------------------------------------
Sections in 61158-5-10 (services) describing SNMP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 6.3.5 | Simple network management ASE |
+---------------+-------------------------------------------------------------+
| 6.3.13.1 | IEEE 802.1AB ASE Overview |
+---------------+-------------------------------------------------------------+
| 7.3.3.1 | Communication Interface Management ASE Overview |
+---------------+-------------------------------------------------------------+
| 7.3.3.3.4 | Attributes for Communication Interface Management class |
+---------------+-------------------------------------------------------------+
| 7.3.3.3.5 | Services for Communication Interface Management class |
+---------------+-------------------------------------------------------------+
| 7.3.3.3.6.2 | Persistency |
+---------------+-------------------------------------------------------------+
| 7.3.3.3.6.5 | Station Name / IP address. DHCP requirement. |
+---------------+-------------------------------------------------------------+
| 7.3.3.10 | MIB class |
+---------------+-------------------------------------------------------------+
Sections in 61158-6-10 (protocol) describing SNMP:
+---------------+-------------------------------------------------------------------------+
| Section | Description |
+===============+=========================================================================+
| 4.11.3.18 | Coding section related to LLDP |
+---------------+-------------------------------------------------------------------------+
| 4.16 | Simple network management |
+---------------+-------------------------------------------------------------------------+
| 5.2.41 | Coding of the field SNMPControl, CommunityStringLength, CommunityString |
+---------------+-------------------------------------------------------------------------+
| Annex S | List of supported MIBs |
+---------------+-------------------------------------------------------------------------+
| Annex U | Extension to a MIB |
+---------------+-------------------------------------------------------------------------+
| Annex W.4 | Statistic counters in SNMPv1 and SNMPv2 |
+---------------+-------------------------------------------------------------------------+
Sections in 61784-2 (profiles) describing SNMP:
+---------------+-------------------------------------------------------------------------+
| Section | Description |
+===============+=========================================================================+
| 7.1.4.11 | Simple Network Management Protocol (Community strings and timeouts) |
+---------------+-------------------------------------------------------------------------+
| 7.1.11 | Conformance class behaviors (Mandatory MIBs) |
+---------------+-------------------------------------------------------------------------+
See also the "Topology and Asset Discovery" guideline published by the Profinet
organisation, and the list of supported OIDs in the test case specification
"Topology discovery check".
Dynamic Host Configuration Protocol (DHCP)
------------------------------------------
The GSDML file should have the ``AddressAssignment`` attribute set to
``"DCP;DHCP"`` if DHCP is a supported way to set the IP address.
During the ART Tester test case DCP_OPTIONS_SUBOPTIONS some aspects of DHCP
handling are tested, if the ``AddressAssignment`` attribute is set accordingly.
Sections in 61158-5-10 (services) describing DHCP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 6.3.11.2 | DCP class specification |
+---------------+-------------------------------------------------------------+
| 6.3.11.3 | DCP service specification |
+---------------+-------------------------------------------------------------+
| 6.3.12 | Dynamic host configuration ASE |
+---------------+-------------------------------------------------------------+
| 7.3.3.3.6 | Communication Interface Management class - Behavior |
+---------------+-------------------------------------------------------------+
Sections in 61158-6-10 (protocol) describing DHCP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 4.3.1.2 | DCP APDU abstract syntax |
+---------------+-------------------------------------------------------------+
| 4.3.1.4 | Coding section of block fields |
+---------------+-------------------------------------------------------------+
| 4.15 | Dynamic host configuration |
+---------------+-------------------------------------------------------------+
| 5.6.3.11 | "Context Management IP and Name Assignment" CMINA |
+---------------+-------------------------------------------------------------+
Sections in 61784-2 (profiles) describing DHCP:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 7.1.4.12 | "Dynamic Host Configuration Protocol" DHCP options |
+---------------+-------------------------------------------------------------+
Media Redundancy Protocol (MRP)
-------------------------------
Sections in 61784-2-3 2021 (profiles) describing MRP:
+---------------+---------------------------------------------------------------+
| Section | Description |
+===============+===============================================================+
| 4.2.3.3 | Media redundancy protocol (Max time and packet size) |
+---------------+---------------------------------------------------------------+
| 4.2.5 | Media redundancy classes |
+---------------+---------------------------------------------------------------+
| 4.2.3.13.2.4 | PDEV parameters (PDInterfaceMrpDataAdjust etc) |
+---------------+---------------------------------------------------------------+
| 4.2.9.2 | Index (PDInterfaceMrpDataAdjust etc) |
+---------------+---------------------------------------------------------------+
| 4.4.4.2.8 | Basic network topology dependency on Redundancy recovery time |
+---------------+---------------------------------------------------------------+
| 4.5.3.1.5 | Options (Services for Class B, "MRP is an optional service") |
+---------------+---------------------------------------------------------------+
IEC 61158-5-10 2021 (services) describing MRP:
+---------------+---------------------------------------------------------------+
| Section | Description |
+===============+===============================================================+
| 6.3.9.2 | RTC class specification (for MRP in Profinet class C) |
+---------------+---------------------------------------------------------------+
| 6.3.9.3.3 | PPM Activate (for MRP in Profinet class C) |
+---------------+---------------------------------------------------------------+
| 6.3.9.3.9 | CPM Set RedRole (for Profinet class C) |
+---------------+---------------------------------------------------------------+
| 6.3.9.3.10 | CPM Activate (for MRP in Profinet class C) |
+---------------+---------------------------------------------------------------+
| 6.3.11.4.2 | Set (RESET_COMMUNICATION_PARAMETER) |
+---------------+---------------------------------------------------------------+
| 6.3.13.2 | IEEE 802.1AB class specification (LLDP PnioMRPPortStatus) |
+---------------+---------------------------------------------------------------+
| 6.3.14 | **Media redundancy ASE** |
+---------------+---------------------------------------------------------------+
| 6.3.19 | Fragmentation ASE (MRP frames are not fragmented) |
+---------------+---------------------------------------------------------------+
| 7.3.1.6.1.2 | Alarm types attached to diagnosis ASE |
+---------------+---------------------------------------------------------------+
| 7.3.1.7.6.1.1 | Read (References to 7.3.3.9.5) |
+---------------+---------------------------------------------------------------+
| 7.3.1.7.6.2.1 | Write (References to 7.3.3.9.5) |
+---------------+---------------------------------------------------------------+
| 7.3.2.5.2 | Relations (Mismatch) |
+---------------+---------------------------------------------------------------+
| 7.3.2.5.5 | Services (References to 7.3.3.9.5) |
+---------------+---------------------------------------------------------------+
| 7.3.3.3.5.2 | Read PD Real Data (References to 7.3.3.9.5) |
+---------------+---------------------------------------------------------------+
| 7.3.3.3.5.3 | Read PD Expected Data (References to 7.3.3.9.5) |
+---------------+---------------------------------------------------------------+
| 7.3.3.7 | IEEE 802.1Q class (Yellow Time for conformance class C and D) |
+---------------+---------------------------------------------------------------+
| 7.3.3.9 | **Media Redundancy class** |
+---------------+---------------------------------------------------------------+
| 7.3.3.11.7 | MRP-MIB (for SNMP) |
+---------------+---------------------------------------------------------------+
| 7.4.2 | Network topology |
+---------------+---------------------------------------------------------------+
| Annex F | Preconditions for channel error type |
+---------------+---------------------------------------------------------------+
Sections in 61158-6-10 2021 (protocol) describing MRP:
+---------------+---------------------------------------------------------------+
| Section | Description |
+===============+===============================================================+
| 4.2.2.4 | Coding of the field LT (0x88E3 for MRP) |
+---------------+---------------------------------------------------------------+
| 4.6 | Media redundancy |
+---------------+---------------------------------------------------------------+
| 4.11.2.2 | LLDP APDU abstract syntax |
+---------------+---------------------------------------------------------------+
| 4.11.3 | LLDP transfer syntax |
+---------------+---------------------------------------------------------------+
| 5.1.2 | APDU abstract syntax (RecordDataRead + RecordDataWrite) |
+---------------+---------------------------------------------------------------+
| 5.2.8.5 | Coding of the field ExtChannelErrorType |
+---------------+---------------------------------------------------------------+
| 5.2.12.3.23 | Coding of the field LinkState |
+---------------+---------------------------------------------------------------+
| 5.2.12.10 | Coding section related to Media Redundancy |
+---------------+---------------------------------------------------------------+
| Annex S | List of supported MIBs |
+---------------+---------------------------------------------------------------+
| Annex V | Cross reference to the IEC 62439-2 |
+---------------+---------------------------------------------------------------+
| Annex W | Maintaining statistic counters for Ethernet (mandatory) |
+---------------+---------------------------------------------------------------+
It is possible to read and write MRP parameters via DCE-RPC, using the index
range 0x8050-0x8057. It uses these blocks:
=================================== ========================================================
Block Description
=================================== ========================================================
PDInterfaceMrpDataReal (read only) Actual interval time and frame count setting.
PDInterfaceMrpDataAdjust Setting of interval time and frame count.
PDInterfaceMrpDataCheck Two booleans whether to check Domain UUID and set alarm
PDPortMrpDataAdjust Setting of MRP instance and UUID values
PDPortMrpDataReal (read only) Actual MRP instance and UUID values
MrpManagerParams
MrpClientParams
MrpRingStateData
MrpInstanceDataAdjustBlock
MrpInstanceDataRealBlock
PDPortMrpIcDataAdjust For interconnection ring
PDPortMrpIcDataCheck For interconnection ring
PDPortMrpIcDataReal (read only) For interconnection ring
=================================== ========================================================
The MRP client uses a state machine with these states:
* Power_On
* AC_STAT1. Waiting for the first Ethernet port.
* DE_IDLE. First port available. This will be named the primary port.
* PT. Temporary state when both ports just have been available.
Send MRP_LinkChange frames. The UpTimer is running.
* PT_IDLE. Normal condition where both ports are available.
* DE. Temporary state when one port is lost. Send MRP_LinkChange frames. The
DownTimer is running.
A MRP client has three settings; the delay between frames at port down, the
corresponding delay at port_up and the number of frames to send.
The client state is controlled by the state of the links (as given by the
Ethernet hardware) and incoming MRP_TopologyChange frames. It will update or
clean the forwarding table, set ports to BLOCKED or FORWARDING and it will
send MRP_LinkChange frames to the MRP manager.
A separate state machine is used to keep track of the time until the forwarding
table should be cleaned (as given in the incoming MRP_TopologyChange frame).
A MRP client should support these services:
* Start MRC: UUID, port IDs, VLAN ID, intervals, count, Blocked supported
* Stop MRC: UUID
* Read MRC: UUID. Returns current values.
See the standard IEC 62439-2 for details on how to implement the MRP protocol.
The Linux kernel has support for the MRM and MRC roles since version 5.8. A
user space daemon is available at https://github.com/microchip-ung/mrp/
Legacy startup mode
-------------------
The startup mode is parsed at connect. It uses legacy start up mode when
this value is set to false::
p_ar->ar_param.ar_properties.startup_mode
Section 17 "Startup Mode" in the guideline "PROFINET IRT Engineering" discusses
the differences between legacy and advanced startup modes.
Sections in 61784-2 (profiles) describing Legacy Startup mode:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 7.1.9.2 | "Index" ARFSUDataAdjust (0xE050) |
+---------------+-------------------------------------------------------------+
Sections in 61158-5-10 (services) describing Legacy Startup mode:
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 7.3.1.3.4 | "Attributes" Allowed values for Startup Mode and for CM |
| | Initiator Activity Timeout Factor. The fields "IR Info |
| | Block", "SR Info Block", "Redundancy Info" and "List of |
| | AR Vendor Blocks" only in advanced startup mode. |
+---------------+-------------------------------------------------------------+
| 7.3.1.3.5.1.2 | "Connect" Usage of "IR Info Block" , "SR Info Block" and |
| | "AR Server Block" |
+---------------+-------------------------------------------------------------+
| 7.3.1.3.5.11 | "Read Expected Fast Startup Data" Only in legacy mode, and |
| | only for fast startup. |
+---------------+-------------------------------------------------------------+
| 7.3.1.3.5.12 | "Write Expected Fast Startup Data" Only in legacy mode, and |
| | only for fast startup. |
+---------------+-------------------------------------------------------------+
| 7.3.1.3.6.3 | "IO controller during startup" Record data ARFSUDataAdjust |
| | (0xE050) supported only for legacy mode |
+---------------+-------------------------------------------------------------+
| 7.3.1.4.4 | "Attributes" RT Class and startup mode combinations |
+---------------+-------------------------------------------------------------+
Sections in 61158-6-10 (protocol) describing Legacy Startup mode:
(search for "startupmode")
+---------------+-------------------------------------------------------------+
| Section | Description |
+===============+=============================================================+
| 5.1.2 | "APDU abstract syntax" IODConnectReq with StartupMode:=1 |
+---------------+-------------------------------------------------------------+
| 5.2.4.4.4 | "Record index" Index 0xE050 ARFSUDataAdjust |
+---------------+-------------------------------------------------------------+
| 5.2.42.2.4 | "ARBlockReq" Checking of CMInitiatorActivityTimeoutFactor |
+---------------+-------------------------------------------------------------+
| 5.6.3.1.1 | "General" Use Profinet v 2.2 for Legacy startup mode. |
+---------------+-------------------------------------------------------------+
| 5.6.3.3.4 | "CMSU state table" Legacy startup mode implemented in CMSU, |
| | PPM and CPM. |
+---------------+-------------------------------------------------------------+
| Figure A.2 | Startup in advanced mode |
+---------------+-------------------------------------------------------------+
| Figure B.2 | Startup in legacy mode |
+---------------+-------------------------------------------------------------+
Conformance class D
-------------------
7.1.3.2.1 Communication (Class D should support one additional Device Access AR)
Messages and function calls at startup
--------------------------------------
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | Incoming | | Outgoing | | CMDEV | Application | Other |
| | message | | message | | state | | |
+==================+====================+=======================+============================================+=====================================+
| Connect req | | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_exp_module_ind() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_exp_submodule_ind() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_connect_ind() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | W_CRES | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | | PPM starts sending cyclic data |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | | PF_CPM_STATE_FRUN |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | W_SUCNF | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_connect_ind() with PNET_EVENT_STARTUP | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | | CMSM timer started |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_new_data_status_ind() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | | PF_CPM_STATE_RUN |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | W_PEIND | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | Connect resp | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| Write req | | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_write_ind() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | Write resp | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| DControl req | | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | W_PERES | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_dcontrol_ind() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | W_ARDY | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | (PRMEND) | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_connect_ind() with PNET_EVENT_PRMEND | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | Run pnet_input_set_data_and_iops() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | DControl resp | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | Run pnet_application_ready() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | (APPLRDY) | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_connect_ind() with PNET_EVENT_APPLRDY | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | CControl req | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | W_ARDYCNF | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| CControl resp | | | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | WDATA | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_ccontrol_cnf() | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | | pnet_connect_ind() with PNET_EVENT_DATA | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
| | | DATA | | |
+------------------+--------------------+-----------------------+--------------------------------------------+-------------------------------------+
Useful functions
----------------
Show lots of details of the stack state::
pnet_show(net, 0xFFFF);
Coding rules
------------
In order to be platform independent, use ``CC_ASSERT()`` instead of ``assert()``.
Use ``ASSERT()`` for rt-kernel-specific code.
Include headers in sorted groups in this order:
* Interface header (Corresponding to the .c file)
* Headers from same project
* Headers from the operating system
* Standard C headers
New files should have the rt-labs standard header comment, with description of
the license and "Copyright YYYY rt-labs AB, Sweden."
Avoid "Yoda conditions"::
if (3 == a) { /* ... */ }
Use C-style comments in C files, C or C++ comments in C++ files::
/* C style comment */
// C++ style comment
Declare (and initialize) internal variables in the beginning of a function.
Function names should start with the file name, for example functions in
``src/common/pf_ppm.c`` are named ``pf_ppm_xxx``.
Typically functions should return 0 on success and -1 on error.
Name functions and variables using "snake_case", for example
``pf_lldp_get_chassis_id ()`` and ``min_device_interval``.
Avoid to start pointer names with ``p_``. It can be useful in some special situations
but we will gradually remove those names from the p-net stack.
For error handling, the use of ``goto`` is acceptable.
If possible, avoid the modulo operator as it is slow on some platforms.
Instead of::
if (have_dhcp == true){...}
if (!have_dhcp){...}
use::
if (have_dhcp){...}
if (have_dhcp == false){...}
(Note that this not yet is fully implemented in the stack.)
Run clang-format on staged files before committing::
$ git add .
$ git clang-format
This will format the commit using clang-format. Examine and stage
modified files before finalizing the commit.
Static code analyzer
--------------------
To install the clang static analyzer tool::
sudo apt-get install clang-tools
Run it using::
rm -rf build
scan-build cmake -B build
scan-build -o clangreports make -C build -j4
The resulting HTML reports will end up in the ``clangreports`` subdirectory.
Workflow
--------
We have chosen to host the code on Github to ease the collaboration between
users and different developers, and we take advantage of the standard
Github workflow:
* Open a Github issue on https://github.com/rtlabs-com/p-net/ for each
separate bug found.
* Fork the repository to your own account on Github, and make a local
clone on your laptop.
* Create a branch with a descriptive name.
* Commit your fix to the branch. Add the line ``Closes #123`` (for example)
in the commit message, to indicate which Github issue it closes.
* Push the branch to your Github account.
* Create a pull request to https://github.com/rtlabs-com/p-net
* After review the fix will be merged.