diff --git a/Makefile b/Makefile index a864180ca43e5ad0d8c45979c34b8f8356bcfba3..beb889e4e8702ef63f284dd65b82a898454d3f63 100644 --- a/Makefile +++ b/Makefile @@ -122,6 +122,7 @@ LDSCRIPT= $(STARTUPLD)/STM32F411xE.ld # C sources that can be compiled in ARM or THUMB mode depending on the global # setting. CSRC = $(ALLCSRC) \ + $(SRCDIR)/crc32.c \ $(SRCDIR)/main.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global diff --git a/src/crc32.c b/src/crc32.c new file mode 100644 index 0000000000000000000000000000000000000000..be5099f21957e58d92f526a24b7579cc97b45e1a --- /dev/null +++ b/src/crc32.c @@ -0,0 +1,102 @@ +// This file is part of the execution-time evaluation for the qronos observer abstractions. +// Copyright (C) 2022-2023 Tim Rheinfels <tim.rheinfels@fau.de> +// See https://gitlab.cs.fau.de/qronos-state-abstractions/execution-time +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +/// +/// @file crc32.c +/// +/// @brief Provides the implementation of the CRC driver +/// +/// @author Tim Rheinfels <tim.rheinfels@fau.de> +/// + +#include "crc32.h" + +#include <string.h> + +#include <hal.h> + +// The bit-reversing was implemented based on Enix's answer on +// https://stackoverflow.com/questions/39646441/how-to-set-stm32-to-generate-standard-crc32 + +/// +/// @brief Only a remnant +/// +/// This is a remnant of previous debugging. It's here for the artifact evaluation as removing in changes alignment in the binary thus causing some execution time measurements to be off by one cycle. +/// +/// @todo Remove after artifact evaluation +/// +uint32_t processed = 0; + +/// +/// @brief Wrapper for the reverse bit (rbit) instruction +/// +/// @param[in] in The 32-bit word to reverse +/// +/// @returns Bit-wise reversed version of @p in +/// +static inline __attribute__((always_inline)) uint32_t rbit(uint32_t in) +{ + uint32_t result; + asm("rbit %1,%0" : "=r" (result) : "r" (in)); + return result; +} + +void crc32_init(void) +{ + + // Reset CRC peripheral + RCC->AHB1RSTR |= RCC_AHB1RSTR_CRCRST; + RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_CRCRST); + + // Enable CRC peripheral + RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN; + + crc32_reset(); + +} + +void crc32_reset(void) +{ + + CRC->CR |= CRC_CR_RESET; + while(CRC->CR &= CRC_CR_RESET); + + processed = 0; + +} + +void crc32_add(uint8_t data) +{ + + // Store data in the lower byte of a 32 bit word and pad with zeros + uint32_t edata = 0u; + memcpy(&edata, &data, sizeof(data)); + + // Append to the current checksum in reverse order (yields the default CRC32 polynomial*) + CRC->DR = rbit(edata); + + ++processed; + +} + +uint32_t crc32_get(void) +{ + + // (* after inverting the bits) + return ~rbit(CRC->DR); + +} diff --git a/src/crc32.h b/src/crc32.h new file mode 100644 index 0000000000000000000000000000000000000000..ca1bca2dbb3f5c9f457e022a29ff2057f60010b9 --- /dev/null +++ b/src/crc32.h @@ -0,0 +1,55 @@ +// This file is part of the execution-time evaluation for the qronos observer abstractions. +// Copyright (C) 2022-2023 Tim Rheinfels <tim.rheinfels@fau.de> +// See https://gitlab.cs.fau.de/qronos-state-abstractions/execution-time +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +/// +/// @file crc32.h +/// +/// @brief Provides the interface for the CRC driver +/// +/// @author Tim Rheinfels <tim.rheinfels@fau.de> +/// + +#ifndef CRC32_H +#define CRC32_H + +#include <stdint.h> + +/// +/// @brief Initializes the CRC driver +/// +void crc32_init(void); + +/// +/// @brief Resets the currently stored checksum +/// +void crc32_reset(void); + +/// +/// @brief Adds a byte @p data to the checksum +/// +/// @param[in] data Byte to add to the checksum +/// +void crc32_add(uint8_t data); + +/// +/// @brief Retrieves the currently stored checksum +/// +/// @returns Currently stored 32-bit checksum +/// +uint32_t crc32_get(void); + +#endif // CRC32_H