diff --git a/pw_checksum/BUILD.bazel b/pw_checksum/BUILD.bazel index 6cb4fe5462..d45d48fd3b 100644 --- a/pw_checksum/BUILD.bazel +++ b/pw_checksum/BUILD.bazel @@ -31,6 +31,7 @@ pw_cc_library( hdrs = [ "public/pw_checksum/crc16_ccitt.h", "public/pw_checksum/crc32.h", + "public/pw_checksum/internal/config.h", ], includes = ["public"], deps = [ diff --git a/pw_checksum/BUILD.gn b/pw_checksum/BUILD.gn index 7aef1a3c76..918a245566 100644 --- a/pw_checksum/BUILD.gn +++ b/pw_checksum/BUILD.gn @@ -15,16 +15,32 @@ import("//build_overrides/pigweed.gni") import("$dir_pw_bloat/bloat.gni") +import("$dir_pw_build/module_config.gni") import("$dir_pw_build/target_types.gni") import("$dir_pw_docgen/docs.gni") import("$dir_pw_unit_test/test.gni") -config("default_config") { +declare_args() { + # The build target that overrides the default configuration options for this + # module. This should point to a source set that provides defines through a + # public config (which may -include a file or add defines directly). + pw_checksum_CONFIG = pw_build_DEFAULT_MODULE_CONFIG +} + +config("public_include_path") { include_dirs = [ "public" ] } +pw_source_set("config") { + sources = [ "public/pw_checksum/internal/config.h" ] + public_configs = [ ":public_include_path" ] + public_deps = [ pw_checksum_CONFIG ] + visibility = [ ":*" ] # Only allow this module to depend on ":config" + friend = [ ":*" ] # Allow this module to access the config.h header. +} + pw_source_set("pw_checksum") { - public_configs = [ ":default_config" ] + public_configs = [ ":public_include_path" ] public = [ "public/pw_checksum/crc16_ccitt.h", "public/pw_checksum/crc32.h", @@ -34,6 +50,7 @@ pw_source_set("pw_checksum") { "crc32.cc", ] public_deps = [ + ":config", dir_pw_bytes, dir_pw_span, ] @@ -78,9 +95,19 @@ pw_size_diff("size_report") { label = "CRC16 with 256-entry table" }, { - target = "size_report:crc32_checksum" + target = "size_report:crc32_8bit_checksum" + base = "size_report:noop_checksum" + label = "CRC32: 8 bits per iteration, 256-entry table" + }, + { + target = "size_report:crc32_4bit_checksum" + base = "size_report:noop_checksum" + label = "CRC32: 4 bits per iteration, 16-entry table" + }, + { + target = "size_report:crc32_1bit_checksum" base = "size_report:noop_checksum" - label = "CRC32 with 256-entry table" + label = "CRC32: 1 bit per iteration, no table" }, { target = "size_report:fletcher16_checksum" diff --git a/pw_checksum/config.gni b/pw_checksum/config.gni new file mode 100644 index 0000000000..3d41a4d19e --- /dev/null +++ b/pw_checksum/config.gni @@ -0,0 +1,17 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/module_config.gni") diff --git a/pw_checksum/crc32.cc b/pw_checksum/crc32.cc index 46a8091675..85ae6a516d 100644 --- a/pw_checksum/crc32.cc +++ b/pw_checksum/crc32.cc @@ -17,60 +17,64 @@ namespace pw::checksum { namespace { -constexpr uint32_t kCrc32Table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; +template +constexpr uint32_t Crc32ProcessDataChunk(uint32_t value) { + for (uint32_t j = 0; j < kBits; j++) + value = (value >> 1) ^ (-(int32_t)(value & 1) & kPolynomial); + + return value; +} + +template +constexpr std::array GenerateCrc32Table() { + std::array table{}; + for (uint32_t i = 0; i < (1 << kBits); i++) { + table[i] = Crc32ProcessDataChunk(i); + } + return table; +} + +constexpr uint32_t kCrc32Polynomial = 0xEDB88320; } // namespace -extern "C" uint32_t _pw_checksum_InternalCrc32(const void* data, - size_t size_bytes, - uint32_t state) { - const uint8_t* array = static_cast(data); +extern "C" uint32_t _pw_checksum_InternalCrc32EightBit(const void* data, + size_t size_bytes, + uint32_t state) { + static constexpr std::array kCrc32Table = + GenerateCrc32Table<8, kCrc32Polynomial>(); + const uint8_t* data_bytes = static_cast(data); + + for (size_t i = 0; i < size_bytes; ++i) { + state = kCrc32Table[(state ^ data_bytes[i]) & 0xFFu] ^ (state >> 8); + } + + return state; +} + +extern "C" uint32_t _pw_checksum_InternalCrc32FourBit(const void* data, + size_t size_bytes, + uint32_t state) { + static constexpr std::array kCrc32Table = + GenerateCrc32Table<4, kCrc32Polynomial>(); + const uint8_t* data_bytes = static_cast(data); + + for (size_t i = 0; i < size_bytes; ++i) { + state ^= data_bytes[i]; + state = kCrc32Table[state & 0x0f] ^ (state >> 4); + state = kCrc32Table[state & 0x0f] ^ (state >> 4); + } + + return state; +} + +extern "C" uint32_t _pw_checksum_InternalCrc32OneBit(const void* data, + size_t size_bytes, + uint32_t state) { + const uint8_t* data_bytes = static_cast(data); for (size_t i = 0; i < size_bytes; ++i) { - state = kCrc32Table[(state ^ array[i]) & 0xFFu] ^ (state >> 8); + state = Crc32ProcessDataChunk<8, kCrc32Polynomial>(state ^ data_bytes[i]); } return state; diff --git a/pw_checksum/crc32_test.cc b/pw_checksum/crc32_test.cc index e9992e51cd..24e59e832f 100644 --- a/pw_checksum/crc32_test.cc +++ b/pw_checksum/crc32_test.cc @@ -16,6 +16,7 @@ #include #include "gtest/gtest.h" +#include "public/pw_checksum/crc32.h" #include "pw_bytes/array.h" #include "pw_span/span.h" @@ -40,43 +41,86 @@ constexpr uint32_t kStringCrc = 0x9EC87F88; TEST(Crc32, Empty) { EXPECT_EQ(Crc32::Calculate(span()), PW_CHECKSUM_EMPTY_CRC32); + EXPECT_EQ(Crc32EightBit::Calculate(span()), + PW_CHECKSUM_EMPTY_CRC32); + EXPECT_EQ(Crc32FourBit::Calculate(span()), + PW_CHECKSUM_EMPTY_CRC32); + EXPECT_EQ(Crc32OneBit::Calculate(span()), PW_CHECKSUM_EMPTY_CRC32); } TEST(Crc32, Buffer) { EXPECT_EQ(Crc32::Calculate(as_bytes(span(kBytes))), kBufferCrc); + EXPECT_EQ(Crc32EightBit::Calculate(as_bytes(span(kBytes))), kBufferCrc); + EXPECT_EQ(Crc32FourBit::Calculate(as_bytes(span(kBytes))), kBufferCrc); + EXPECT_EQ(Crc32OneBit::Calculate(as_bytes(span(kBytes))), kBufferCrc); } TEST(Crc32, String) { EXPECT_EQ(Crc32::Calculate(as_bytes(span(kString))), kStringCrc); + EXPECT_EQ(Crc32EightBit::Calculate(as_bytes(span(kString))), kStringCrc); + EXPECT_EQ(Crc32FourBit::Calculate(as_bytes(span(kString))), kStringCrc); + EXPECT_EQ(Crc32OneBit::Calculate(as_bytes(span(kString))), kStringCrc); } -TEST(Crc32Class, ByteByByte) { - Crc32 crc; +template +void TestByByte() { + CrcVariant crc; for (std::byte b : kBytes) { crc.Update(b); } EXPECT_EQ(crc.value(), kBufferCrc); } -TEST(Crc32Class, Buffer) { - Crc32 crc32; +TEST(Crc32Class, ByteByByte) { + TestByByte(); + TestByByte(); + TestByByte(); + TestByByte(); +} + +template +void TestBuffer() { + CrcVariant crc32; crc32.Update(as_bytes(span(kBytes))); EXPECT_EQ(crc32.value(), kBufferCrc); } -TEST(Crc32Class, BufferAppend) { - Crc32 crc32; +TEST(Crc32Class, Buffer) { + TestBuffer(); + TestBuffer(); + TestBuffer(); + TestBuffer(); +} + +template +void TestBufferAppend() { + CrcVariant crc32; crc32.Update(kBytesPart0); crc32.Update(kBytesPart1); EXPECT_EQ(crc32.value(), kBufferCrc); } -TEST(Crc32Class, String) { - Crc32 crc32; +TEST(Crc32Class, BufferAppend) { + TestBufferAppend(); + TestBufferAppend(); + TestBufferAppend(); + TestBufferAppend(); +} + +template +void TestString() { + CrcVariant crc32; crc32.Update(as_bytes(span(kString))); EXPECT_EQ(crc32.value(), kStringCrc); } +TEST(Crc32Class, String) { + TestString(); + TestString(); + TestString(); + TestString(); +} + extern "C" uint32_t CallChecksumCrc32(const void* data, size_t size_bytes); extern "C" uint32_t CallChecksumCrc32Append(const void* data, size_t size_bytes, diff --git a/pw_checksum/docs.rst b/pw_checksum/docs.rst index 329d75691f..9f5982928f 100644 --- a/pw_checksum/docs.rst +++ b/pw_checksum/docs.rst @@ -54,6 +54,52 @@ pw_checksum/crc32.h uint32_t crc = Crc32(my_data); crc = Crc32(more_data, crc); +.. _CRC32 Implementations: + +Implementations +--------------- +Pigweed provides 3 different CRC32 implementations with different size and +runtime tradeoffs. The below table summarizes the variants. For more detailed +size information see the :ref:`Size report` below. Instructions counts were +calculated by hand by analyzing the +`assembly `_. + + +.. list-table:: + :header-rows: 1 + + * - Variant + - Relative size (see Size Report below) + - Speed + - Lookup table size (entries) + - Instructions/byte (M33/-Os) + * - 8 bits per iteration (default) + - large + - fastest + - 256 + - 8 + * - 4 bits per iteration + - small + - fast + - 16 + - 13 + * - 1 bit per iteration + - smallest + - slow + - 0 + - 43 + +The default implementation provided by the APIs above can be selected through +:ref:`Module Configuration Options`. Additionally ``pw_checksum`` provides +variants of the C++ API to explicitly use each of the implementations. These +classes provide the same API as ``Crc32``: + +* ``Crc32EightBit`` +* ``Crc32FourBit`` +* ``Crc32OneBit`` + +.. _Size report: + Size report =========== The CRC module currently optimizes for speed instead of binary size, by using @@ -71,6 +117,24 @@ Dependencies ============ * ``pw_span`` +.. _Module Configuration Options: + +Module Configuration Options +============================ +The following configurations can be adjusted via compile-time configuration of +this module, see the +:ref:`module documentation ` for +more details. + +.. c:macro:: PW_CHECKSUM_CRC32_DEFAULT_IMPL + + Selects which of the :ref:`CRC32 Implementations` the default CRC32 APIs + use. Set to one of the following values: + + * ``PW_CHECKSUM_CRC32_8BITS`` + * ``PW_CHECKSUM_CRC32_4BITS`` + * ``PW_CHECKSUM_CRC32_1BITS`` + Zephyr ====== To enable ``pw_checksum`` for Zephyr add ``CONFIG_PIGWEED_CHECKSUM=y`` to the diff --git a/pw_checksum/public/pw_checksum/crc32.h b/pw_checksum/public/pw_checksum/crc32.h index 4a54bb155a..f97d481152 100644 --- a/pw_checksum/public/pw_checksum/crc32.h +++ b/pw_checksum/public/pw_checksum/crc32.h @@ -20,6 +20,8 @@ #include #include +#include "pw_checksum/internal/config.h" + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -33,9 +35,24 @@ extern "C" { #define _PW_CHECKSUM_CRC32_INITIAL_STATE 0xFFFFFFFFu // Internal implementation function for CRC32. Do not call it directly. -uint32_t _pw_checksum_InternalCrc32(const void* data, - size_t size_bytes, - uint32_t state); +uint32_t _pw_checksum_InternalCrc32EightBit(const void* data, + size_t size_bytes, + uint32_t state); + +uint32_t _pw_checksum_InternalCrc32FourBit(const void* data, + size_t size_bytes, + uint32_t state); +uint32_t _pw_checksum_InternalCrc32OneBit(const void* data, + size_t size_bytes, + uint32_t state); + +#if PW_CHECKSUM_CRC32_DEFAULT_IMPL == PW_CHECKSUM_CRC32_8BITS +#define _pw_checksum_InternalCrc32 _pw_checksum_InternalCrc32EightBit +#elif PW_CHECKSUM_CRC32_DEFAULT_IMPL == PW_CHECKSUM_CRC32_4BITS +#define _pw_checksum_InternalCrc32 _pw_checksum_InternalCrc32FourBit +#elif PW_CHECKSUM_CRC32_DEFAULT_IMPL == PW_CHECKSUM_CRC32_1BITS +#define _pw_checksum_InternalCrc32 _pw_checksum_InternalCrc32OneBit +#endif // Calculates the CRC32 for the provided data. static inline uint32_t pw_checksum_Crc32(const void* data, size_t size_bytes) { @@ -65,18 +82,20 @@ namespace pw::checksum { // // This class is more efficient than the CRC32 C functions since it doesn't // finalize the value each time it is appended to. -class Crc32 { +template +class Crc32Impl { public: // Calculates the CRC32 for the provided data and returns it as a uint32_t. // To update a CRC in multiple pieces, use an instance of the Crc32 class. static uint32_t Calculate(span data) { - return pw_checksum_Crc32(data.data(), data.size_bytes()); + return ~kChecksumFunction( + data.data(), data.size_bytes(), _PW_CHECKSUM_CRC32_INITIAL_STATE); } - constexpr Crc32() : state_(kInitialValue) {} + constexpr Crc32Impl() : state_(kInitialValue) {} void Update(span data) { - state_ = _pw_checksum_InternalCrc32(data.data(), data.size(), state_); + state_ = kChecksumFunction(data.data(), data.size(), state_); } void Update(std::byte data) { Update(span(&data, 1)); } @@ -93,6 +112,11 @@ class Crc32 { uint32_t state_; }; +using Crc32 = Crc32Impl<_pw_checksum_InternalCrc32>; +using Crc32EightBit = Crc32Impl<_pw_checksum_InternalCrc32EightBit>; +using Crc32FourBit = Crc32Impl<_pw_checksum_InternalCrc32FourBit>; +using Crc32OneBit = Crc32Impl<_pw_checksum_InternalCrc32OneBit>; + } // namespace pw::checksum #endif // __cplusplus diff --git a/pw_checksum/public/pw_checksum/internal/config.h b/pw_checksum/public/pw_checksum/internal/config.h new file mode 100644 index 0000000000..f35d28a432 --- /dev/null +++ b/pw_checksum/public/pw_checksum/internal/config.h @@ -0,0 +1,29 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#pragma once + +#define PW_CHECKSUM_CRC32_8BITS 8 +#define PW_CHECKSUM_CRC32_4BITS 4 +#define PW_CHECKSUM_CRC32_1BITS 1 + +#ifndef PW_CHECKSUM_CRC32_DEFAULT_IMPL +#define PW_CHECKSUM_CRC32_DEFAULT_IMPL PW_CHECKSUM_CRC32_8BITS +#endif // PW_CHECKSUM_CRC32_DEFAULT_IMPL + +#ifdef __cplusplus +static_assert(PW_CHECKSUM_CRC32_DEFAULT_IMPL == PW_CHECKSUM_CRC32_8BITS || + PW_CHECKSUM_CRC32_DEFAULT_IMPL == PW_CHECKSUM_CRC32_4BITS || + PW_CHECKSUM_CRC32_DEFAULT_IMPL == PW_CHECKSUM_CRC32_1BITS); +#endif // __cplusplus diff --git a/pw_checksum/size_report/BUILD.bazel b/pw_checksum/size_report/BUILD.bazel index 8ca52ef501..9a9c00f537 100644 --- a/pw_checksum/size_report/BUILD.bazel +++ b/pw_checksum/size_report/BUILD.bazel @@ -57,9 +57,35 @@ pw_cc_binary( ) pw_cc_binary( - name = "crc32_checksum", + name = "crc32_8bit_checksum", srcs = ["run_checksum.cc"], - copts = ["-DUSE_CRC32_CHECKSUM=1"], + copts = ["-DUSE_CRC32_8BIT_CHECKSUM=1"], + deps = [ + "//pw_bloat:bloat_this_binary", + "//pw_checksum", + "//pw_log", + "//pw_preprocessor", + "//pw_span", + ], +) + +pw_cc_binary( + name = "crc32_4bit_checksum", + srcs = ["run_checksum.cc"], + copts = ["-DUSE_CRC32_4BIT_CHECKSUM=1"], + deps = [ + "//pw_bloat:bloat_this_binary", + "//pw_checksum", + "//pw_log", + "//pw_preprocessor", + "//pw_span", + ], +) + +pw_cc_binary( + name = "crc32_1bit_checksum", + srcs = ["run_checksum.cc"], + copts = ["-DUSE_CRC32_1BIT_CHECKSUM=1"], deps = [ "//pw_bloat:bloat_this_binary", "//pw_checksum", diff --git a/pw_checksum/size_report/BUILD.gn b/pw_checksum/size_report/BUILD.gn index 87d3b3741a..0dc9546f75 100644 --- a/pw_checksum/size_report/BUILD.gn +++ b/pw_checksum/size_report/BUILD.gn @@ -28,7 +28,7 @@ pw_executable("noop_checksum") { defines = [ "USE_NOOP_CHECKSUM=1" ] } -pw_executable("crc32_checksum") { +pw_executable("crc32_8bit_checksum") { sources = [ "run_checksum.cc" ] deps = [ "$dir_pw_bloat:bloat_this_binary", @@ -37,7 +37,31 @@ pw_executable("crc32_checksum") { "$dir_pw_span", "..", ] - defines = [ "USE_CRC32_CHECKSUM=1" ] + defines = [ "USE_CRC32_8BIT_CHECKSUM=1" ] +} + +pw_executable("crc32_4bit_checksum") { + sources = [ "run_checksum.cc" ] + deps = [ + "$dir_pw_bloat:bloat_this_binary", + "$dir_pw_log", + "$dir_pw_preprocessor", + "$dir_pw_span", + "..", + ] + defines = [ "USE_CRC32_4BIT_CHECKSUM=1" ] +} + +pw_executable("crc32_1bit_checksum") { + sources = [ "run_checksum.cc" ] + deps = [ + "$dir_pw_bloat:bloat_this_binary", + "$dir_pw_log", + "$dir_pw_preprocessor", + "$dir_pw_span", + "..", + ] + defines = [ "USE_CRC32_1BIT_CHECKSUM=1" ] } pw_executable("crc16_checksum") { diff --git a/pw_checksum/size_report/run_checksum.cc b/pw_checksum/size_report/run_checksum.cc index 32b0f20669..021bd22e5a 100644 --- a/pw_checksum/size_report/run_checksum.cc +++ b/pw_checksum/size_report/run_checksum.cc @@ -24,9 +24,19 @@ using TheChecksum = pw::checksum::Crc16Ccitt; #endif -#ifdef USE_CRC32_CHECKSUM +#ifdef USE_CRC32_8BIT_CHECKSUM #include "pw_checksum/crc32.h" -using TheChecksum = pw::checksum::Crc32; +using TheChecksum = pw::checksum::Crc32EightBit; +#endif + +#ifdef USE_CRC32_4BIT_CHECKSUM +#include "pw_checksum/crc32.h" +using TheChecksum = pw::checksum::Crc32FourBit; +#endif + +#ifdef USE_CRC32_1BIT_CHECKSUM +#include "pw_checksum/crc32.h" +using TheChecksum = pw::checksum::Crc32OneBit; #endif namespace pw::checksum {