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).

image036.png

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.

image037.png

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.

image038.png

Figure B.3 – Safety multicast

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.

image039.png

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.

image040.png

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.

image041.png

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.

image042.png

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.