Tagessicherung
This commit is contained in:
200
src/FSI Funktionen/Logikbausteine/CrcGen.scl
Normal file
200
src/FSI Funktionen/Logikbausteine/CrcGen.scl
Normal file
@@ -0,0 +1,200 @@
|
||||
FUNCTION_BLOCK "CrcGen"
|
||||
TITLE = 'CRC_GEN'
|
||||
{ S7_Optimized_Access := 'FALSE' }
|
||||
AUTHOR : hugo
|
||||
FAMILY : LOGIC
|
||||
NAME : CRCGEN
|
||||
VERSION : 2.0
|
||||
//
|
||||
//CRC_GEN generates a CRC checksum from a block of data and returns the checksum in a DWORD to be connected to the data for transmission.
|
||||
//the CRC Polynom is specified with the config variable PN and the length of the Polynom is specified by PL
|
||||
//A Polynom x4 + X + 1 is represented by 0011 with length 4, the highest order bit is not specified at all..
|
||||
//The input data is an array of byte of any size, the function is called by CRC_GEN(ADR(array),SIZEOF(array), ....).
|
||||
//
|
||||
//uses: REVERSE (FC310)
|
||||
// REFLECT (FC426)
|
||||
VAR_INPUT
|
||||
PT : Pointer;
|
||||
_PT { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} AT PT : Struct
|
||||
DBNr { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : Word;
|
||||
Adr { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : DWord;
|
||||
END_STRUCT;
|
||||
SIZE : Int;
|
||||
PL : Int;
|
||||
PN : DWord;
|
||||
INIT : DWord;
|
||||
REV_IN : Bool;
|
||||
REV_OUT : Bool;
|
||||
XOR_OUT : DWord;
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
CRC_GEN : DWord;
|
||||
_CRC_GEN { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} AT CRC_GEN : Array[0..31] of Bool;
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
pos : Int;
|
||||
shift : Int;
|
||||
dx : Byte;
|
||||
_dx AT dx : Array[0..7] of Bool;
|
||||
bits : Int;
|
||||
rTEST_DB : Int;
|
||||
Adr : Int;
|
||||
DB_LENGTH : Word;
|
||||
WRITE_PROT : Bool;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
(*#################################################################################################
|
||||
|
||||
Copyright (c) Fondium Singen GmbH
|
||||
|
||||
### Änderungshistorie ###
|
||||
|
||||
Datum: Version: Bearbeiter: Beschreibung:
|
||||
04.03.2021 0.0 St. Maier Neuerstellung
|
||||
|
||||
#################################################################################################*)
|
||||
|
||||
(*#################################################################################################
|
||||
|
||||
Beschreibung:
|
||||
Die Funktion generiert eine CRC-Checksumme aus einen beliebig großen Array of Byte. Beim Aufruf
|
||||
wird der Funktion ein Pointer auf das zu bearbeitende Array und dessen Größe in Bytes übergeben.
|
||||
Das Polynom kann ein beliebiges POLYNOM bis maximal 32 Bit Länge sein. Ein Polynom X³ + X² + 1
|
||||
wird mit 101 dargestellt (1*X³ + 1*X² + 0*X¹ + 1* X⁰). Das höchstwertige Bit, in diesem Fall
|
||||
1*X³ wird dabei im Polynom nicht angegeben den es ist immer eins. Es können Polynome bis X³²
|
||||
(CRC 32) verarbeitet werden. Durch den Wert INIT kann dem CR eine Startwert übergeben werden,
|
||||
üblich sind hier 0000 und FFFF. Der zu verwendende Startwert ist der in der Literatur übliche
|
||||
„Direct Initial Value“. Der Eingan XOR_OUT legt fest mit welcher Bitfolge die Checksumme am Ende
|
||||
mit XOR verknüpft wird. Die Eingänge REV_IN und REV_OUT legen die Bitfolge der Daten Fest.
|
||||
Wenn REV_IN = TRUE wird jedes Byte mit LSB beginnend verarbeitet, REV_IN = FALSE wird jeweils
|
||||
mit MSB begonnen. REV_OUT=TRUE dreht entsprechend die Bitfolge der Checksumme um. Der Bautein
|
||||
benötigt eine Mindestlänge der zu verarbeitenden Daten von 4 Bytes, und ist nach oben nur durch
|
||||
die maximale Array Größe begrenzt.
|
||||
Die weiter unten folgende CRC Tabelle gibt nähere Auskunft über gebräuchliche CRC's und deren
|
||||
Setup Daten für CrcGen. Aufgrund der Vielzahl von möglichen und auch gebräuchlichen CRC's ist
|
||||
es uns nicht möglich eine vollständige Liste aufzuführen. Für weitergehende Recherchen ist die
|
||||
Webseite http://regregex.bbcmicro.net/crc-catalogue.htm zu empfehlen.
|
||||
Online Berechnungen zum testen sind mit folgendem Java Tool möglich:
|
||||
http://zorc.breitbandkatze.de/crc.html
|
||||
|
||||
#################################################################################################*)
|
||||
|
||||
(* Datenbaustein Testen *)
|
||||
#rTEST_DB := TEST_DB(DB_NUMBER := #_PT.DBNr
|
||||
, DB_LENGTH => #DB_LENGTH
|
||||
, WRITE_PROT => #WRITE_PROT
|
||||
);
|
||||
|
||||
// Ende wenn Test-DB <> 0 = Fehler
|
||||
IF #rTEST_DB <> 0 THEN
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
// Ende wenn DB zu klein
|
||||
IF WORD_TO_INT(#DB_LENGTH) / 1 < #SIZE THEN
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
#Adr := DWORD_TO_INT(SHR(IN := SHL(IN := #_PT.Adr, N := 8), N := 11));
|
||||
|
||||
// align polygon
|
||||
#shift := 32 - #PL;
|
||||
#PN := SHL(IN := #PN, N := #shift);
|
||||
|
||||
(* load first 4 bytes into register minimum message size is 4 bytes
|
||||
for smaller messages fill with 0#s at the beginning*)
|
||||
FOR #pos := 0 TO 3 DO
|
||||
|
||||
IF #REV_IN THEN
|
||||
#CRC_GEN := SHL(IN := #CRC_GEN, N := 8) OR "Reverse"(WORD_TO_BLOCK_DB(#_PT.DBNr).DB(#Adr + #pos));
|
||||
ELSE
|
||||
#CRC_GEN := SHL(IN := #CRC_GEN, N := 8) OR WORD_TO_BLOCK_DB(#_PT.DBNr).DB(#Adr + #pos);
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
#pos := 4;
|
||||
|
||||
// XOR with #INIT value
|
||||
#CRC_GEN := #CRC_GEN XOR SHL(IN := #INIT, N := #shift);
|
||||
|
||||
// calculate CRC FOR each byte
|
||||
WHILE #pos < #SIZE DO
|
||||
|
||||
IF #REV_IN THEN
|
||||
#dx := "Reverse"(WORD_TO_BLOCK_DB(#_PT.DBNr).DB(#Adr + #pos));
|
||||
ELSE
|
||||
#dx := WORD_TO_BLOCK_DB(#_PT.DBNr).DB(#Adr + #pos);
|
||||
END_IF;
|
||||
|
||||
#pos := #pos + 1;
|
||||
|
||||
// crc calculation FOR one byte
|
||||
FOR #bits := 0 TO 7 DO
|
||||
|
||||
IF #_CRC_GEN[7] THEN
|
||||
#CRC_GEN := (SHL(IN := #CRC_GEN, N := 1) OR BOOL_TO_DWORD(#_dx[7])) XOR #PN;
|
||||
ELSE
|
||||
#CRC_GEN := SHL(IN := #CRC_GEN, N := 1) OR BOOL_TO_DWORD(#_dx[7]);
|
||||
END_IF;
|
||||
|
||||
#dx := SHL(IN := #dx, N := 1);
|
||||
|
||||
END_FOR;
|
||||
END_WHILE;
|
||||
|
||||
// all bytes are processed, need TO finish the registers 32 bits
|
||||
FOR #bits := 0 TO 31 DO
|
||||
IF #_CRC_GEN[7] THEN
|
||||
#CRC_GEN := (SHL(IN := #CRC_GEN, N := 1) OR BOOL_TO_DWORD(#_dx[7])) XOR #PN;
|
||||
ELSE
|
||||
#CRC_GEN := SHL(IN := #CRC_GEN, N := 1) OR BOOL_TO_DWORD(#_dx[7]);
|
||||
END_IF;
|
||||
END_FOR;
|
||||
|
||||
// final XOR
|
||||
#CRC_GEN := SHR(IN := #CRC_GEN, N := #shift) XOR #XOR_OUT;
|
||||
|
||||
// "Reverse" the crc_out put IF necessary
|
||||
IF #REV_OUT THEN
|
||||
#CRC_GEN := "Reflect"(I_D := #CRC_GEN,
|
||||
I_L := #PL);
|
||||
END_IF;
|
||||
|
||||
|
||||
(* typical crc polynoms
|
||||
|
||||
CRC-4-ITU x4 + x + 1 (ITU G.704, p. 12) 0x3 or 0xC (0x9)
|
||||
CRC-5-ITU x5 + x4 + x2 + 1 (ITU G.704, p. 9) 0x15 or 0x15 (0x0B) Bluetooth
|
||||
CRC-5-USB x5 + x2 + 1 (use: USB token packets) 0x05 or 0x14 (0x9)
|
||||
CRC-6-ITU x6 + x + 1 (ITU G.704, p. 3) 0x03 or 0x30 (0x21)
|
||||
CRC-7 x7 + x3 + 1 (use: telecom systems, MMC) 0x09 or 0x48 (0x11)
|
||||
CRC-8-ATM x8 + x2 + x + 1 (use: ATM HEC) 0x07 or 0xE0 (0xC1)
|
||||
CRC-8-CCITT x8 + x7 + x3 + x2 + 1 (use: 1-Wire bus) 0x8D or 0xB1 (0x63)
|
||||
CRC-8-Dallas/Maxim x8 + x5 + x4 + 1 (use: 1-Wire bus) 0x31 or 0x8C (0x19)
|
||||
CRC-8 x8 + x7 + x6 + x4 + x2 + 1 0xD5 or 0xAB (0x57)
|
||||
CRC-8-SAE J1850 x8 + x4 + x3 + x2 + 1 0x1D or 0xB8
|
||||
CRC-10 x10 + x9 + x5 + x4 + x + 1 0x233 or 0x331 (0x263)
|
||||
CRC-12 x12 + x11 + x3 + x2 + x + 1 (use: telecom systems) 0x80F or 0xF01 (0xE03)
|
||||
CRC-15-CAN x15 + x14 + x10 + x8 + x7 + x4 + x3 + 1 0x4599 or 0x4CD1 (0x19A3)
|
||||
CRC-16-Fletcher Not a CRC; see Fletcher's checksum Used in Adler-32 A & B CRCs
|
||||
CRC-16-CCITT x16 + x12 + x5 + 1 (XMODEM,X.25, V.41, Bluetooth, PPP, IrDA; known as "CRC-CCITT") 0x1021 or 0x8408 (0x0811)
|
||||
CRC-16-IBM x16 + x15 + x2 + 1 (USB, many others; also known as "CRC-16") 0x8005 or 0xA001 (0x4003)
|
||||
CRC-24-Radix-64 x24 + x23 + x18 + x17 + x14 + x11 + x10 + x7 + x6 + x5 + x4 + x3 + x + 1 0x864CFB or 0xDF3261 (0xBE64C3)
|
||||
CRC-32-Adler Not a CRC; see Adler-32 See Adler-32
|
||||
CRC-32-MPEG2 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 0x04C11DB7 or 0xEDB88320 (0xDB710641) Also used in IEEE 802.3
|
||||
CRC-32-IEEE 802.3 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 (V.42) 0x04C11DB7 or 0xEDB88320 (0xDB710641)
|
||||
CRC-32C (Castagnoli) x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1 0x1EDC6F41 or 0x82F63B78 (0x05EC76F1)
|
||||
CRC-64-ISO x64 + x4 + x3 + x + 1 (use: ISO 3309) 0x000000000000001B or 0xD800000000000000 (0xB000000000000001)
|
||||
CRC-64-ECMA-182 x64 + x62 + x57 + x55 + x54 + x53 + x52 + x47 + x46 + x45 + x40 + x39 + x38 + x37 + x35 + x33 + x32 + x31 + x29 + x27 + x24 + x23 + x22 + x21 + x19 + x17 + x13 + x12 + x10 + x9 + x7 + x4 + x + 1
|
||||
(as described in ECMA-182 p.63) 0x42F0E1EBA9EA3693 or 0xC96C5795D7870F42 (0x92D8AF2BAF0E1E85)
|
||||
*)
|
||||
|
||||
|
||||
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
Reference in New Issue
Block a user