diff --git a/Src/FirmwareLoader.c b/Src/FirmwareLoader.c index 684dd3c..41f69e3 100644 --- a/Src/FirmwareLoader.c +++ b/Src/FirmwareLoader.c @@ -47,6 +47,9 @@ uint32_t FirmwareLoader_crc32(uint8_t *data, uint32_t size) { return crc; } */ +#include +#include + // Таблица CRC32, предвычисленная для полинома 0xEDB88320UL (отражённая форма 0x04C11DB7) static const uint32_t crc_table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, @@ -94,15 +97,41 @@ static const uint32_t crc_table[256] = { 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; +/** + * @brief Быстрое обновление CRC32 с обработкой по 4 байта (uint32_t) + * @param crc Текущее значение CRC + * @param data Указатель на данные + * @param len Длина данных в байтах + * @return Обновленное значение CRC (без финальной инверсии) + */ +uint32_t UdsCrc32Update(uint32_t crc, const uint8_t *data, uint32_t len) { + // Обрабатываем выровненные 4-байтовые блоки + while (len >= 4) { + uint32_t word = *(const uint32_t*)data; -uint32_t -UdsCrc32Update(uint32_t crc, const uint8_t *data, uint32_t len) { - for (uint32_t i = 0; i < len; ++i) { - crc = (crc >> 8) ^ crc_table[(crc ^ data[i]) & 0xFF]; + // Оптимизированная обработка 4 байт за раз + crc = (crc >> 8) ^ crc_table[(crc ^ (word >> 0)) & 0xFF]; + crc = (crc >> 8) ^ crc_table[(crc ^ (word >> 8)) & 0xFF]; + crc = (crc >> 8) ^ crc_table[(crc ^ (word >> 16)) & 0xFF]; + crc = (crc >> 8) ^ crc_table[(crc ^ (word >> 24)) & 0xFF]; + + data += 4; + len -= 4; } - return crc; // Без финальной инверсии + + // Обрабатываем оставшиеся байты (0-3 байта) + while (len--) { + crc = (crc >> 8) ^ crc_table[(crc ^ *data++) & 0xFF]; + } + + return crc; } +/** + * @brief Финальная инверсия CRC32 + * @param crc Значение CRC перед финализацией + * @return Финальное значение CRC32 + */ uint32_t UdsCrc32Finalize(uint32_t crc) { return crc ^ 0xFFFFFFFF; }