The calculation of a 32-bit CRC signature over an array of N octets with the help of lookup tables, using “C” as programming language, is shown below:
// VARIANT A: presumably easier to implement on little endian machines uint32_t crctab32[256]; // lookup table uint32_t CRC32_Backward(char *array, int16_t N){ // input is array of N octets // containing the data, see Figure 23
uint32_t result = 1; // seed value for the calculated CRC int16_t i; // index for(i=N-1;i>=0;i--) // process array in reversed order result = crctab32 [((result >> 24) ^ array[i]) & 0xff] ^ (result << 8); if (result==0) return 1;else return result; } |
where the lookup-table crctab32 has to be initialized as shown in Table B.1.
// VARIANT B: presumably easier to implement on big endian machines uint32_t crctab32[256]; // lookup table uint32_t CRC32_Forward(char *array, int16_t N){ // input is array of N octets // containing the data in reversed // order, see e. g. Figure 24 uint32_t result = 1; // seed value for the calculated CRC int16_t i; // index for(i=0;i<N;i++) // process array result = crctab32 [((result >> 24) ^ array[i]) & 0xff] ^ (result << 8); if (result==0) return 1;else return result; } |
where the lookup-table crctab32 has to be initialized as shown in Table B.1.
Table B.1 – The CRC32 lookup table for 32-bit CRC signature calculations
CRC32 lookup table (0 to 255) |
|||||||
00000000 |
F4ACFB13 |
1DF50D35 |
E959F626 |
3BEA1A6A |
CF46E179 |
261F175F |
D2B3EC4C |
77D434D4 |
8378CFC7 |
6A2139E1 |
9E8DC2F2 |
4C3E2EBE |
B892D5AD |
51CB238B |
A567D898 |
EFA869A8 |
1B0492BB |
F25D649D |
06F19F8E |
D44273C2 |
20EE88D1 |
C9B77EF7 |
3D1B85E4 |
987C5D7C |
6CD0A66F |
85895049 |
7125AB5A |
A3964716 |
573ABC05 |
BE634A23 |
4ACFB130 |
2BFC2843 |
DF50D350 |
36092576 |
C2A5DE65 |
10163229 |
E4BAC93A |
0DE33F1C |
F94FC40F |
5C281C97 |
A884E784 |
41DD11A2 |
B571EAB1 |
67C206FD |
936EFDEE |
7A370BC8 |
8E9BF0DB |
C45441EB |
30F8BAF8 |
D9A14CDE |
2D0DB7CD |
FFBE5B81 |
0B12A092 |
E24B56B4 |
16E7ADA7 |
B380753F |
472C8E2C |
AE75780A |
5AD98319 |
886A6F55 |
7CC69446 |
959F6260 |
61339973 |
57F85086 |
A354AB95 |
4A0D5DB3 |
BEA1A6A0 |
6C124AEC |
98BEB1FF |
71E747D9 |
854BBCCA |
202C6452 |
D4809F41 |
3DD96967 |
C9759274 |
1BC67E38 |
EF6A852B |
0633730D |
F29F881E |
B850392E |
4CFCC23D |
A5A5341B |
5109CF08 |
83BA2344 |
7716D857 |
9E4F2E71 |
6AE3D562 |
CF840DFA |
3B28F6E9 |
D27100CF |
26DDFBDC |
F46E1790 |
00C2EC83 |
E99B1AA5 |
1D37E1B6 |
7C0478C5 |
88A883D6 |
61F175F0 |
955D8EE3 |
47EE62AF |
B34299BC |
5A1B6F9A |
AEB79489 |
0BD04C11 |
FF7CB702 |
16254124 |
E289BA37 |
303A567B |
C496AD68 |
2DCF5B4E |
D963A05D |
93AC116D |
6700EA7E |
8E591C58 |
7AF5E74B |
A8460B07 |
5CEAF014 |
B5B30632 |
411FFD21 |
E47825B9 |
10D4DEAA |
F98D288C |
0D21D39F |
DF923FD3 |
2B3EC4C0 |
C26732E6 |
36CBC9F5 |
AFF0A10C |
5B5C5A1F |
B205AC39 |
46A9572A |
941ABB66 |
60B64075 |
89EFB653 |
7D434D40 |
D82495D8 |
2C886ECB |
C5D198ED |
317D63FE |
E3CE8FB2 |
176274A1 |
FE3B8287 |
0A977994 |
4058C8A4 |
B4F433B7 |
5DADC591 |
A9013E82 |
7BB2D2CE |
8F1E29DD |
6647DFFB |
92EB24E8 |
378CFC70 |
C3200763 |
2A79F145 |
DED50A56 |
0C66E61A |
F8CA1D09 |
1193EB2F |
E53F103C |
840C894F |
70A0725C |
99F9847A |
6D557F69 |
BFE69325 |
4B4A6836 |
A2139E10 |
56BF6503 |
F3D8BD9B |
07744688 |
EE2DB0AE |
1A814BBD |
C832A7F1 |
3C9E5CE2 |
D5C7AAC4 |
216B51D7 |
6BA4E0E7 |
9F081BF4 |
7651EDD2 |
82FD16C1 |
504EFA8D |
A4E2019E |
4DBBF7B8 |
B9170CAB |
1C70D433 |
E8DC2F20 |
0185D906 |
F5292215 |
279ACE59 |
D336354A |
3A6FC36C |
CEC3387F |
F808F18A |
0CA40A99 |
E5FDFCBF |
115107AC |
C3E2EBE0 |
374E10F3 |
DE17E6D5 |
2ABB1DC6 |
8FDCC55E |
7B703E4D |
9229C86B |
66853378 |
B436DF34 |
409A2427 |
A9C3D201 |
5D6F2912 |
17A09822 |
E30C6331 |
0A559517 |
FEF96E04 |
2C4A8248 |
D8E6795B |
31BF8F7D |
C513746E |
6074ACF6 |
94D857E5 |
7D81A1C3 |
892D5AD0 |
5B9EB69C |
AF324D8F |
466BBBA9 |
B2C740BA |
D3F4D9C9 |
275822DA |
CE01D4FC |
3AAD2FEF |
E81EC3A3 |
1CB238B0 |
F5EBCE96 |
01473585 |
A420ED1D |
508C160E |
B9D5E028 |
4D791B3B |
9FCAF777 |
6B660C64 |
823FFA42 |
76930151 |
3C5CB061 |
C8F04B72 |
21A9BD54 |
D5054647 |
07B6AA0B |
F31A5118 |
1A43A73E |
EEEF5C2D |
4B8884B5 |
BF247FA6 |
567D8980 |
A2D17293 |
70629EDF |
84CE65CC |
6D9793EA |
993B68F9 |
This table contains 32-bit values in hexadecimal representation for each value (0 to 255) of the argument a in the function crctab32 [a]. The table should be used line-by-line in ascending order from top left (0) to bottom right (255). For instance, crctab32[10] is highlighted using a darker background and red colour. |
The most basic type of communication is unidirectional communication, where a safety application on one device (Controller A in Figure B.1) sends data to a safety application on another device (Controller B in Figure B.1).
Figure B.1 – Unidirectional communication
This is accomplished by placing a SafetyProvider on Controller A and a SafetyConsumer on Controller B. The connection between SafetyProvider and SafetyConsumer can be established and terminated during runtime, allowing different consumers to connect to the same SafetyProvider at different times. Furthermore, the protocol is designed in such a way, that it is necessary for the SafetyConsumer to know the parametrized set of IDs of the SafetyProvider such that it is able to safely check whether the received data is coming from the expected source. On the other hand, as SafetyData flows in one direction only, it is not necessary for the SafetyProvider to check the ID of the SafetyConsumers. Hence, Controller A can – one after another – serve an arbitrarily large number of SafetyConsumers, and new SafetyConsumers can be introduced into the system without having to update Controller A.
Bidirectional communication means the exchange of data in both directions, which is accomplished by placing a SafetyProvider and a SafetyConsumer on each controller. Hence, bidirectional communication is realized using two safety connections according to this document. See Figure B.2 for an example.
Figure B.2 – Bidirectional communication
NOTE Connections can be established and terminated during runtime.
Multicast is defined as sending the same set of data from one device (Controller A) to several other devices (Controller B1, B2,…,BN) simultaneously.
Safety multicast is accomplished by placing multiple SafetyProviders on Controller A, and one SafetyConsumer on each of the Controllers B1, B2, … BN. Each of the SafetyProviders running on Controller A is connecting to one of the SafetyConsumers running on one of the Controllers B1, B2, … BN. See Figure B.3 for an example.
The safety protocol in this document is designed in such a way that:
- the state machine of the SafetyProvider has a low number of states, and thus very low memory demands,
- all safety-related message-checks are executed on the consumer and thus the computational demand on the SafetyProvider is low.
Therefore, even if many SafetyProviders are instantiated on a device, the performance requirements will still be moderate.
The properties of simple unicast are also valid for safety multicast; different sets of consumers can connect to SafetyProviders at different times, and new SafetyConsumers can be introduced into the system without having to reconfigure the SafetyProvider instances. As all SafetyProvider instances send the same safety application data (the same data source), it is irrelevant from a safety point of view to which SafetyProvider instance a given SafetyConsumer is connected. Thus, all SafetyProvider instances can be parametrized with the same set of IDs for the SafetyProvider.
This document supports operator acknowledgment both on the SafetyProvider side and on the SafetyConsumer side. For this purpose, both the interface of the SafetyProvider and the SafetyConsumer comprise a Boolean input called OperatorAckProvider and OperatorAckConsumer, respectively. The safety application can get the values of these parameters on the consumer side via the Boolean outputs OperatorAckRequested and OperatorAckProvider on the SafetyConsumer’s SAPI (see 6.3.4.2).
Subclauses B.3.2 to B.3.5 show some examples on how to use these inputs and outputs. Dashed lines indicate that the corresponding input or output is not used in the use case. For details, see 6.3.3 and 6.3.4.
Figure B.4 – OA in unidirectional safety communication
In the scenario shown in Figure B.4, operator acknowledgment is done on the SafetyConsumer side, operator acknowledgment on the SafetyProvider side is not possible.
Figure B.5 – Two-sided OA in bidirectional safety communication
In the scenario shown in Figure B.5, operator acknowledgment is done independently for both directions.
Figure B.6 – One sided OA in bidirectional safety communication
In the scenario of Figure B.6, an operator acknowledgment activated at controller A suffices for re-establishing the bidirectional connection. Both sides will cease delivering fail-safe values and continue sending process values. This is accomplished by connecting OperatorAckProvider with OperatorAckConsumer at the SafetyConsumer of controller B. Activating operator acknowledgment at controller B is not possible in this scenario.
Figure B.7 – One sided OA on each side is possible
Figure B.7 shows a scenario where an operator acknowledgment activated at controller A or controller B suffices for re-establishing the bidirectional connection. Both sides will cease delivering fail-safe values and continue sending process values. This is accomplished by the logic circuits shown in the safety applications.