Можно ли использовать неабсолютный диапазон адресов в SRecord и вставить некоторые данные в последние байты двоичного файла?
Я делаю проект для микроконтроллера ARM Cortex-M4 с использованием STM32CubeIDE (IDE на основе Eclipse с компилятором gcc) и хочу встроить CRC всей прошивки в конец двоичного файла. Я уже модифицировал скрипт компоновщика, чтобы создать некоторые переменные, помещенные в конец скомпилированного двоичного файла. Вот мои модификации скрипта компоновщика:
... linker script ...
/* My section (it is the last section in linker script) */
.end_of_code :
{
. = ALIGN(4);
KEEP (*(.end_of_code.fwSize)) /* Force memory allocation even if variable is unused */
KEPP (*(.end_of_code.fwCrc)) /* Force memory allocation even if variable is unused */
_end_of_code = .; /* Get current address */
_size_of_code = ABSOLUTE (_end_of_code - ORIGIN(FLASH)); /* Subtruct current address from start of image */
} >FLASH
А вот объявление вышеуказанных переменных в C:
// Some C file
extern uint32_t _size_of_code; // Linker variable
const __attribute__((section(".end_of_code.fwSize"))) uint32_t fwSize = (uint32_t) &_size_of_code;
const __attribute__((section(".end_of_code.fwCrc"))) uint32_t fwCrc = 0xFFFFFFFF;
Последняя переменная, созданная с помощью скрипта компоновщика, должна хранить CRC32 всей прошивки. Я хочу использовать скрипт SRecord для вычисления значения CRC и иметь возможность ссылаться на это значение, как на обычную переменную в коде C.
Моя цель - создать скрипт SRecord, который будет открывать файл с помощью
-binary
формат, замените последние 4 байта CRC32, вычисленным SRecord, и сделайте вывод с замененным значением CRC. Но я не понимаю, как поместить неабсолютный диапазон адресов в
-crop
или же
-exclude
фильтры. Я хочу сделать что-то вроде этого:
# SRecord script
fw.bin -binary
-CRC32 -maximum-addr fw.bin -binary -4
-o fw_with_CRC.bin -binary
У меня вопрос: возможно ли и как использовать относительные адреса с SRecord? Или возможно и как перезаписать какие-то данные в конце бинарного файла с помощью SRecord?
Об альтернативных решениях: я знаю, что могу удалить переменную fwCrc из компоновщика и создать что-то вроде этого:
#define FW_CRC_ADDR ( ((uint32_t) &fwSize) + 0x04 )
#define GET_FW_CRC() ( *(uint32_t *) FW_CRC_ADDR )
но такое решение мне не подходит. Я хочу иметь переменную, в которой хранится значение CRC. Решения, которые вводят некоторые данные / переменные вместо неиспользуемых элементов вектора прерывания, тоже не подходят.
Возможно, я могу принять решение, в котором переменная fwCrc не выделяет память и добавляет CRC в конец двоичного файла с помощью SRecord, но я не знаю, как заставить компоновщик не выделять память для переменной, используемой в коде C.
1 ответ
Я нашел решение, которое может быть кому-то полезно, но оно не дает прямого ответа на мой вопрос об относительной адресации в SRecord. Это решение описывает, как добавить CRC к образу прошивки и получить доступ к значению CRC в C, как к переменной noramal.
Решение было протестировано с компилятором GCC и скриптом компоновщика, созданным STM32CubeIDE.
- Тип раздела компоновщика, в котором хранится значение CRC, следует изменить на
(NOLOAD)
. Это заставляет компоновщик НЕ выделять память для переменных, назначенных этому разделу в двоичном образе. Больше информации о(NOLOAD)
можно найти здесь.
... linker script ...
/* Last section in linker script */
.end_of_code :
{
. = ALIGN(4);
KEEP (*(.end_of_code.fwSize)) /* Last variable in flash memory */
_end_of_code = .; /* Get current address */
_size_of_code = ABSOLUTE (_end_of_code - ORIGIN(FLASH)); /* Subtruct current address from start of image */
} >FLASH
/* New section for CRC */
.crc (NOLOAD) :
{
. = ALIGN(4);
*(.crc.fwCrc))
. = ALIGN(4);
} >FLASH
... /DISCARD/ ...
} /* SECTIONS */
- Добавьте CRC в прошивку к максимальному адресу, например, во время выполнения команды post build:
srec_cat infile.bin -binary -STM32 -maximum-addr infile.bin -binary -o outfile.bin -binary
- Объявить переменную C справа
__attribute__
:
const __attribute__((section(".crc.fwCrc"))) uint32_t fwCrc;
В результате описанных выше манипуляций будет создан образ прошивки с добавленным к нему CRC. К значению CRC можно получить доступ, как к обычной переменной C, используя
fwCrc
переменная.
const
был использован квалификатор, поскольку значение этой переменной хранится во FLASH-памяти и не может быть изменено напрямую с помощью операторов присваивания, таких как
=
.