Add CRC32 implementation
This commit is contained in:
parent
e282a5eb37
commit
451904a0c5
7 changed files with 128 additions and 2 deletions
|
|
@ -23,9 +23,9 @@ DEBUG ?= 1
|
|||
OPT ?= 0
|
||||
|
||||
BUILDDIR ?= build
|
||||
BINARY := safetyreset.elf
|
||||
BINARY := rotohsm_proto_rotor.elf
|
||||
LDSCRIPT := generic_stm32.ld
|
||||
DEVICE := STM32F302C8
|
||||
DEVICE := STM32F302CB
|
||||
|
||||
|
||||
########################################################################################################################
|
||||
|
|
@ -53,6 +53,7 @@ C_SOURCES += $(MUSL_SOURCES)
|
|||
|
||||
PREFIX ?= arm-none-eabi-
|
||||
|
||||
HOSTCC := gcc
|
||||
CC := $(PREFIX)gcc
|
||||
CPP := $(PREFIX)cpp
|
||||
CXX := $(PREFIX)g++
|
||||
|
|
@ -102,6 +103,8 @@ COMMON_CFLAGS += -O$(OPT) -std=gnu11 -g
|
|||
COMMON_CFLAGS += $(DEVICE_DEFINES)
|
||||
COMMON_CFLAGS += -DDEBUG=$(DEBUG)
|
||||
|
||||
HOST_CFLAGS += $(COMMON_CFLAGS)
|
||||
|
||||
# for musl
|
||||
CFLAGS += -Dhidden=
|
||||
|
||||
|
|
@ -193,6 +196,13 @@ $(BUILDDIR)/%.o: %.s
|
|||
mkdir -p $(@D)
|
||||
$(CC) $(COMMON_CFLAGS) $(CFLAGS) $(EXT_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILDDIR)/crc32_test: src/crc32_test.c src/crc32.c
|
||||
$(HOSTCC) $(HOST_CFLAGS) -o $@ $^
|
||||
|
||||
.PHONY: run_tests
|
||||
run_tests: $(BUILDDIR)/crc32_test
|
||||
$(PYTHON3) -m unittest test.crc32_ref
|
||||
|
||||
venv:
|
||||
test -d venv || python3 -m venv --system-site-packages venv
|
||||
source venv/bin/activate && pip install cxxfilt pyelftools libarchive matplotlib
|
||||
|
|
|
|||
35
prototype/fw/src/crc32.c
Normal file
35
prototype/fw/src/crc32.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include "crc32.h"
|
||||
#include <unistd.h>
|
||||
|
||||
/* Polynomial: 0xEDB88320 */
|
||||
|
||||
/* python3:
|
||||
* In [26]: apply = lambda st: ((st>>1) ^ 0xEDB88320) if (st & 1) else (st>>1)
|
||||
* In [27]: print(',\n'.join([ '0x{:08x}'.format(apply(apply(apply(apply(x))))) for x in range(16) ]))
|
||||
*/
|
||||
uint32_t crc32_table[16] = {
|
||||
0x00000000,
|
||||
0x1db71064,
|
||||
0x3b6e20c8,
|
||||
0x26d930ac,
|
||||
0x76dc4190,
|
||||
0x6b6b51f4,
|
||||
0x4db26158,
|
||||
0x5005713c,
|
||||
0xedb88320,
|
||||
0xf00f9344,
|
||||
0xd6d6a3e8,
|
||||
0xcb61b38c,
|
||||
0x9b64c2b0,
|
||||
0x86d3d2d4,
|
||||
0xa00ae278,
|
||||
0xbdbdf21c
|
||||
};
|
||||
|
||||
crc32_t crc32_update(crc32_t state, uint8_t c)
|
||||
{
|
||||
state ^= c;
|
||||
state = (state>>4) ^ crc32_table[state&0xf];
|
||||
state = (state>>4) ^ crc32_table[state&0xf];
|
||||
return state;
|
||||
}
|
||||
12
prototype/fw/src/crc32.h
Normal file
12
prototype/fw/src/crc32.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef __CRC_32_H__
|
||||
#define __CRC_32_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t crc32_t;
|
||||
|
||||
inline static uint32_t crc32_reset() { return ~0; }
|
||||
uint32_t crc32_update(uint32_t old_state, uint8_t c);
|
||||
inline static uint32_t crc32_finalize(uint32_t state) { return ~state; }
|
||||
|
||||
#endif /* __CRC_32_H__ */
|
||||
20
prototype/fw/src/crc32_test.c
Normal file
20
prototype/fw/src/crc32_test.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "crc32.h"
|
||||
|
||||
int main(void) {
|
||||
crc32_t state = crc32_reset();
|
||||
|
||||
do {
|
||||
char c;
|
||||
if (fread(&c, 1, 1, stdin) != 1)
|
||||
break;
|
||||
|
||||
state = crc32_update(state, (uint8_t)c);
|
||||
} while(23);
|
||||
|
||||
state = crc32_finalize(state);
|
||||
printf("%08x\n", state);
|
||||
return 0;
|
||||
}
|
||||
45
prototype/fw/test/crc32_ref.py
Normal file
45
prototype/fw/test/crc32_ref.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import zlib
|
||||
import os
|
||||
import itertools
|
||||
import unittest
|
||||
|
||||
INTERESTING = bytes([0x00, 0x42, 0xff, 0x01, 0x80])
|
||||
|
||||
class RefdataTest(unittest.TestCase):
|
||||
def run_test(self, test_data):
|
||||
ref_val = zlib.crc32(test_data)
|
||||
|
||||
binary = os.environ.get('CRC32_TEST_BINARY', 'build/crc32_test')
|
||||
|
||||
output = subprocess.check_output(binary, input=test_data)
|
||||
test_val = int(output, 16) & 0xffffffff
|
||||
|
||||
self.assertEqual(test_val, ref_val, f'mismatched results checking input {test_data}')
|
||||
|
||||
def test_empty(self):
|
||||
self.run_test(b'')
|
||||
|
||||
def test_one_byte(self):
|
||||
for x in range(256):
|
||||
self.run_test(bytes([x]))
|
||||
|
||||
def test_two_byte(self):
|
||||
for x, y in itertools.product(INTERESTING, repeat=2):
|
||||
self.run_test(bytes([x, y]))
|
||||
|
||||
def test_three_bytes(self):
|
||||
for x, y, z in itertools.product(INTERESTING, repeat=3):
|
||||
self.run_test(bytes([x, y, z]))
|
||||
|
||||
def test_four_bytes(self):
|
||||
for w, x, y, z in itertools.product(INTERESTING, repeat=4):
|
||||
self.run_test(bytes([w, x, y, z]))
|
||||
|
||||
def test_random_strings(self):
|
||||
for length in range(3, 24):
|
||||
for i in range(20):
|
||||
self.run_test(os.urandom(length))
|
||||
|
||||
1
prototype/fw/upstream/PyCortexMDebug
Submodule
1
prototype/fw/upstream/PyCortexMDebug
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 77e9717a0e7c5b44214bdf70fbddf376cf2e8a7d
|
||||
Loading…
Add table
Add a link
Reference in a new issue