From 451904a0c5fae3bd28d35c7128df3a9db1a04b26 Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 26 Nov 2020 12:38:52 +0100 Subject: Add CRC32 implementation --- prototype/fw/Makefile | 14 +++++++++-- prototype/fw/src/crc32.c | 35 ++++++++++++++++++++++++++++ prototype/fw/src/crc32.h | 12 ++++++++++ prototype/fw/src/crc32_test.c | 20 ++++++++++++++++ prototype/fw/test/crc32_ref.py | 45 ++++++++++++++++++++++++++++++++++++ prototype/fw/upstream/PyCortexMDebug | 1 + 6 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 prototype/fw/src/crc32.c create mode 100644 prototype/fw/src/crc32.h create mode 100644 prototype/fw/src/crc32_test.c create mode 100644 prototype/fw/test/crc32_ref.py create mode 160000 prototype/fw/upstream/PyCortexMDebug (limited to 'prototype/fw') diff --git a/prototype/fw/Makefile b/prototype/fw/Makefile index db7952b..3fbd029 100644 --- a/prototype/fw/Makefile +++ b/prototype/fw/Makefile @@ -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 diff --git a/prototype/fw/src/crc32.c b/prototype/fw/src/crc32.c new file mode 100644 index 0000000..4b03fbb --- /dev/null +++ b/prototype/fw/src/crc32.c @@ -0,0 +1,35 @@ +#include "crc32.h" +#include + +/* 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; +} diff --git a/prototype/fw/src/crc32.h b/prototype/fw/src/crc32.h new file mode 100644 index 0000000..7a3a729 --- /dev/null +++ b/prototype/fw/src/crc32.h @@ -0,0 +1,12 @@ +#ifndef __CRC_32_H__ +#define __CRC_32_H__ + +#include + +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__ */ diff --git a/prototype/fw/src/crc32_test.c b/prototype/fw/src/crc32_test.c new file mode 100644 index 0000000..e23bb37 --- /dev/null +++ b/prototype/fw/src/crc32_test.c @@ -0,0 +1,20 @@ + +#include + +#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; +} diff --git a/prototype/fw/test/crc32_ref.py b/prototype/fw/test/crc32_ref.py new file mode 100644 index 0000000..7ac0582 --- /dev/null +++ b/prototype/fw/test/crc32_ref.py @@ -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)) + diff --git a/prototype/fw/upstream/PyCortexMDebug b/prototype/fw/upstream/PyCortexMDebug new file mode 160000 index 0000000..77e9717 --- /dev/null +++ b/prototype/fw/upstream/PyCortexMDebug @@ -0,0 +1 @@ +Subproject commit 77e9717a0e7c5b44214bdf70fbddf376cf2e8a7d -- cgit