224 lines
5.9 KiB
C
224 lines
5.9 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
// PC speichert mit LITTLE ENDIAN
|
|
|
|
// Berechnen einer 8 Bit CRC-Pruefsumme
|
|
uint8_t calcCRC8(uint8_t* data, size_t size);
|
|
|
|
// Berechnen einer 16 Bit CRC-Pruefsumme
|
|
uint16_t calcCRC16(uint8_t* inBytes, size_t size);
|
|
|
|
// Berechnen einer 32 Bit CRC-Pruefsumme mit allen Parametern
|
|
uint32_t calcCRC32(
|
|
uint8_t* inBytes,
|
|
size_t size,
|
|
uint32_t polynomial,
|
|
uint32_t initialValue,
|
|
uint32_t finalXOR,
|
|
uint8_t inputReflected,
|
|
uint8_t outputReflected
|
|
);
|
|
|
|
// Check einer 32 Bit CRC-Pruefsumme
|
|
int checkCrc32(
|
|
uint8_t* data,
|
|
size_t size,
|
|
uint32_t crc,
|
|
uint32_t polynomial,
|
|
uint32_t initialValue,
|
|
uint32_t finalXOR,
|
|
uint8_t inputReflected,
|
|
uint8_t outputReflected
|
|
);
|
|
|
|
// Berechnung der Pruefsummen fuer Testbench
|
|
void calc_axis_crc_tb();
|
|
|
|
|
|
int main()
|
|
{
|
|
// Testweise Pruefsumme berechnen und ausgeben
|
|
char msg[] = "Hello World!";
|
|
uint32_t crc = calcCRC32((uint8_t*) msg, strlen(msg), 0xF4ACFB13, 0xFFFFFFFF, 0xFFFFFFFF, 1, 1);
|
|
printf("CRC32 of '%s': 0x%08x\n\n", msg, crc);
|
|
|
|
char msg2[] = "ABCDEFGHIJKL";
|
|
crc = calcCRC32((uint8_t*) msg2, strlen(msg2), 0xF4ACFB13, 0xFFFFFFFF, 0xFFFFFFFF, 1, 1);
|
|
printf("CRC32 of '%s': 0x%08x\n\n", msg2, crc);
|
|
|
|
uint8_t data[128];
|
|
for (int i = 0; i < 128; i++) data[i] = 0;
|
|
for (uint32_t i = 0; i < 32; i++) {
|
|
data[4*i] = i;
|
|
}
|
|
crc = calcCRC32((uint8_t*) data, 64, 0xF4ACFB13, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0);
|
|
printf("CRC32: 0x%08x\n\n", crc);
|
|
crc = calcCRC32((uint8_t*) (data+64), 64, 0xF4ACFB13, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0);
|
|
printf("CRC32: 0x%08x\n\n", crc);
|
|
|
|
// uint8_t crc8 = calcCRC8((uint8_t*) msg, strlen(msg));
|
|
// printf("CRC8 of '%s': 0x%02x\n\n", msg, crc8);
|
|
|
|
// uint16_t crc16 = calcCRC16((uint8_t*) msg, strlen(msg));
|
|
// printf("CRC16 of '%s': 0x%04x\n\n", msg, crc16);
|
|
|
|
// test mit crccalc.com
|
|
uint8_t daten[4] = {0x12, 0x34, 0x56, 0x78};
|
|
crc = calcCRC32(daten, 4, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0);
|
|
printf("0x%08x\n\n", crc);
|
|
|
|
// calc_axis_crc_tb();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void calc_axis_crc_tb()
|
|
{
|
|
char test_data[] = "Hello World!";
|
|
|
|
uint32_t testPolynomials[3] = {
|
|
0x4C11DB7,
|
|
0x1EDC6F41,
|
|
0x814141AB,
|
|
};
|
|
|
|
uint32_t initalValues[2] = {
|
|
0x0,
|
|
0xFFFFFFFF,
|
|
};
|
|
|
|
for (int polynomial = 0; polynomial < 3; polynomial++) {
|
|
for (int intialValue = 0; intialValue < 2; intialValue++) {
|
|
uint32_t checksum;
|
|
checksum = calcCRC32((uint8_t*) test_data, 16, testPolynomials[polynomial], initalValues[intialValue], 0x0, 0, 0);
|
|
printf("Polynom %d, iV %d: x\"%08x\"\n", polynomial, intialValue, checksum);
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t calcCRC8(uint8_t* inBytes, size_t size)
|
|
{
|
|
const uint8_t polynomial = 0xD5;
|
|
uint8_t crc = 0x0; // initial value
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
|
crc ^= inBytes[i];
|
|
|
|
for (int bit = 0; bit < 8; bit++) {
|
|
if ((crc & 0x80) != 0) {
|
|
crc = (uint8_t) ((crc << 1) ^ polynomial);
|
|
}
|
|
else {
|
|
crc = (uint8_t)(crc << 1);
|
|
|
|
}
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
uint16_t calcCRC16(uint8_t* inBytes, size_t size)
|
|
{
|
|
const uint16_t polynomial = 0x1021;
|
|
uint16_t crc = 0;
|
|
|
|
for (size_t b = 0; b < size; b++) {
|
|
crc ^= (uint16_t) (inBytes[b] << 8);
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
if ((crc & 0x8000) != 0) {
|
|
crc = (uint16_t) (crc << 1) ^ polynomial;
|
|
} else {
|
|
crc = (uint16_t)(crc << 1);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return crc;
|
|
}
|
|
|
|
uint32_t calcCRC32(
|
|
uint8_t* inBytes,
|
|
size_t size,
|
|
uint32_t polynomial,
|
|
uint32_t initialValue,
|
|
uint32_t finalXOR,
|
|
uint8_t inputReflected,
|
|
uint8_t outputReflected
|
|
) {
|
|
uint32_t crc = initialValue;
|
|
uint8_t byte;
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
|
byte = inBytes[i];
|
|
|
|
if (inputReflected != 0) {
|
|
uint8_t reflected = 0;
|
|
|
|
for (int b = 0; b < 8; b++) {
|
|
if ((byte & (1<<b)) != 0) {
|
|
reflected |= (uint8_t) (1<<(7-b));
|
|
}
|
|
}
|
|
byte = reflected;
|
|
}
|
|
|
|
crc ^= (uint32_t) (byte << 24);
|
|
|
|
for (int bit = 0; bit < 8; bit++) {
|
|
if ((crc & (uint32_t)(1<<31)) != 0) {
|
|
crc = (uint32_t) (crc << 1) ^ polynomial;
|
|
} else {
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (outputReflected != 0) {
|
|
uint32_t reflected = 0;
|
|
|
|
for (int i = 0; i < 32; i++) {
|
|
if ((crc & (uint32_t) (1<<i)) != 0) {
|
|
reflected |= (uint32_t) (1<<(31-i));
|
|
}
|
|
}
|
|
crc = reflected;
|
|
}
|
|
|
|
return crc ^ finalXOR;
|
|
}
|
|
|
|
int checkCrc32(
|
|
uint8_t* data,
|
|
size_t size,
|
|
uint32_t crc,
|
|
uint32_t polynomial,
|
|
uint32_t initialValue,
|
|
uint32_t finalXOR,
|
|
uint8_t inputReflected,
|
|
uint8_t outputReflected
|
|
) {
|
|
// Daten und CRC zusammenhaengend in den HEAP Speicher kopieren
|
|
uint8_t *dataCrc = malloc(size + 4);
|
|
memcpy_s(dataCrc, size+4, data, size);
|
|
memcpy_s((dataCrc+size), 4, &crc, 4);
|
|
// for (uint32_t i = 0; i < 4; i++) {
|
|
// dataCrc[size+i] = (crc >> (24 - 8 * i)) & 0xFF; // Extract the MSB first
|
|
// }
|
|
|
|
// CRC von Daten mit CRC-Pruefsumme berechnen
|
|
// Bei validen Daten bzw. Pruefsumme kommt Null heraus
|
|
uint32_t ret = calcCRC32(dataCrc, size+4, polynomial, initialValue, finalXOR, inputReflected, outputReflected);
|
|
if (ret == 0) {
|
|
ret = 1;
|
|
} else {
|
|
ret = 0;
|
|
};
|
|
|
|
free(dataCrc);
|
|
return ret;
|
|
} |