При реализации загрузчика для STM32 необходимо получить алгоритм подсчета контрольной суммы, совпадающий как на стороне микроконтроллера, так и утилиты PC, которая формирует прошивку.
Как вариант, можно воспользоваться утилитой ielftool и инструкцией [1] (см. также ссылки [2, 3, 4]). Этот метод довольно прост, но у него есть существенный недостаток - формируется прошивка, у которой размер всегда одинаковый, равный всей области памяти, отведенной под firmware приложения. А это может быть довольно большой объем данных, что может оказаться неприемлемым, если для передачи прошивки в загрузчике используется медленный канал связи.
Более интересный вариант - формировать контрольную сумму только от полезных данных firmware, и для утилиты PC воспользоваться стандартным алгоритмом CRC32 [5]. Конечно, тот же самый алгоритм можно реализовать программно и на стороне STM32.
Алгоритм функции crc32_formula_normal [5] одинаково работает как на стороне PC, так и на стороне STM32. Он вычисляет CRC32 программно, от любого количества байт, даже нечетного.
Достоинства показанного выше программного решения - результат работы алгоритма совпадает со стандартным (по тестовой строке "123456789" получается 0xCBF43926), реализация занимает мало места в памяти. Однако по понятным причинам работает эта реализация медленно, что может быть иногда проблемой на стороне STM32.
Конечно, на стороне PC как вычислительных ресурсов, так и ресурсов памяти предостаточно, так что нет никаких проблем реализовать как медленный программный, так и табличный алгоритм вычисления CRC32 (см. 5). Но нас стороне микроконтроллера STM32 такой роскоши нет, зато есть аппаратный блок вычисления контрольной суммы [6, 7]. Поэтому возникает вопрос - можно ли как-то на стороне PC получить алгоритм, результат работы которого будет совпадать с алгоритмом PC? Оказывается, это возможно, но необходимо в реализации PC учесть следующее:
1. Алгоритм [5] подразумевает вычисление CRC32 по байтам, т. е. можно вычислить контрольную сумму от любого количества байт, даже нечетного. Аппаратный блок CRC32 не у всех моделей микроконтроллеров STM32 дает такую возможность. Например, у STM32F407 вычислять CRC32 можно только словами, т. е. блоками по 4 байта. Поэтому на стороне PC и на стороне STM32, если размер области данных, по которым вычисляется CRC, не делится нацело на 4, то надо дополнить эту область необходимым количеством данных с заранее известным значением.
2. На стороне PC необходимо подавать байты в алгоритм вычисления CRC32 в порядке, соответствующем порядку байт в слове (uint32_t) STM32.
Ниже во врезке показан код для PC, который вычисляет контрольную сумму от данных так же (т. е. дает тот же конечный результат), как это делает аппаратный блок CRC32 микроконтроллера STM32Fxx. Функция reorder4 решает вышеупомянутые проблемы 1 и 2. Она дополняет размер вычисляемых данных до значения, нацело делящееся на 4, значение дополняемых байт выбрано 0xFF (значение байт "чистой" области FLASH), и одновременно упорядочивает порции данных по 4 байта в необходимой (обратной) последовательности.
Алгоритм функции crc32_formula_normal_STM32 предназначен для работы на стороне PC. Он вычисляет CRC32 от любого количества байт, даже нечетного. Если это количество байт не делится нацело на 4, то оно дополняется байтами 0xFF. CRC32 вычисляется порциями по 4 байта, перестановку байт в четверках и дополнение выполняет функция reorder4.
На стороне STM32 получается такой же результат. Обратите внимание, что в качестве входных данных передается массив размером 12 байт, потому что 12 нацело делится на 4 (в HAL_CRC_Calculate передается 3 слова). В конце полезных данных добавлено 3 байта 0xFF, это такие же данные, как подставляет в алгоритм на стороне PC функция reorder4 из первой врезки "Оригинальный алгоритм CRC32 по полиному 0x04C11DB7".
1. CRC прошивки средствами IAR и STM32 site:tqfp.org. 2. Checksum calculation with IAR ILINK Linker and IELFTOOL site:iar.com. 3. Calculating CRC32 with IAR ELF Tool the same way as STM32 hardware site:iar.com. 4. IELFTOOL Checksum - The basic actions site:iar.com. 5. Демистификация CRC32. 6. STM32F4xx: блок вычисления CRC. 7. STM32: использование аппаратного блока CRC. 8. STM32 CRC32 software implementation code site:programmersought.com. 9. 210427122559SD-card-boot.zip - загрузчик akospasztor / stm32-bootloader, портированный на STM32F407, проект C# утилиты PC, которая программно подсчитывает контрольную сумму так же как это делает аппаратура STM32.