Files
es-abschlussprojekt/Software/CRC_Test/crc.c
T
2025-02-11 12:01:22 +01:00

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;
}