Перейти к содержанию
    

Как расположить секцию в конце hex-файла

Хочу иметь в конце hex/bin файла значение контрольной суммы для всего, что находится до неё. Без использования фиксированных адресов, т.е. значение должно располагаться в конце автоматически.

Есть статья примерно как это сделать для Keil: How to calculate CRC value in IAR and KEIL

Настроил, работает, но не совсем так, как мне надо. Компоновщик располагает значение только в конце всего кода, а мне нужно, чтобы в конце кода и вообще всех других возможных секций. К примеру, инициализация данных в ОЗУ находится в hex/bin файле в более старших адресах.

Вот пример из map-файла:

    0x00003d00   0x00003d00   0x00000004   Data   RO          521    CHECKSUM            checksum.o


    Execution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x00003d04, Size: 0x00002900, Max: 0x00008000, ABSOLUTE, COMPRESSED[0x00000054])

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x20000000   COMPRESSED   0x00000018   Data   RW            9    .data               main.o


Как видно, CHEKSUM идёт последней секцией, но Load base следующей находится дальше (0x00003d04).

Я знаю как такое можно сделать в скриптах компоновщика для IAR и GCC, но не пойму как сделать то же для SCT-файлов Keil'а.

Вот пример скрипта компоновщика:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x00000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)   
   checksum.o (CHECKSUM, +Last)
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }

  RW_IRAM2 0x20100000 0x00004000  {
   *.o (EXECUTABLE_MEMORY_SECTION) 
   .ANY (+RW +ZI)   
;   *(RAM2)  
  }
}


Посоветуйте, можно ли как-то поправить sct файл для этого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрел такую же тему ниже: Линкер-скрипт .sct - размещение секции

Жаль, похоже не получится в конце.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, не то, чтобы совсем не работает, как костыль может и сойти такой вариант:
 

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x00000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)      
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }

  RW_IRAM2 0x20100000 0x00004000  {
   *.o (EXECUTABLE_MEMORY_SECTION) 
   .ANY (+RW +ZI)   
;   *(RAM2)  
  }
  ER_IROM2 +0 {
    checksum.o (CHECKSUM, +Last)
  }
}

Теперь значение CRC находится в конце hex-файла, только при "развёртывании" символ будет иметь адрес в ОЗУ.

Костыль может быть такой:

- формируем BIN из ELF с учётом пустых областей (заполняем 0xFF);
- внешней утилитой считаем CRC для BIN файла без учёта последних 4-х байт (фиктивного значения CRC);
- подправленным BAT-файлом ищем сначала адрес в ОЗУ, а по нему LOAD BASE во флеш и исправляем в HEX файле это значение;
- в Keil при отладке загружаем этот подправленный HEX-файл.

Мне для полного счастья не хватает только для Keil такой процедуры. Будем костылизировать.

П.С. Забыл, что в runtime непонятно откуда взять смещение для инициализатора crc значения. Посчитать целостность самого себя пока не получается. Можно, правда, раскрутить таблицы инициализации, ведь адрес в ОЗУ у нас есть, но это хардкор уже.

Изменено пользователем uni

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 часов назад, uni сказал:

Я знаю как такое можно сделать в скриптах компоновщика для IAR и GCC, но не пойму как сделать то же для SCT-файлов Keil'а.

По ссылке, которую я указал выше, стандартный вариант для IAR'а. Я же имел в виду альтернативный вариант на основе маркеров: IELFTOOL Checksum - Placing the checksum

Его можно упростить и оно вполне работает, но пока только на тестовом проекте:

1913046510_crc32last(iar9.30).thumb.png.274ec998cfa6e02a1c513e485b2fef2e.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 hours ago, uni said:

- внешней утилитой считаем CRC для BIN файла без учёта последних 4-х байт (фиктивного значения CRC);
- подправленным BAT-файлом ищем сначала адрес в ОЗУ, а по нему LOAD BASE во флеш и исправляем в HEX файле это значение;

А не проще будет srecord'ом (чтобы велосипед не изобретать) подсчитать CRC, и положить его по зарезервированному адресу в начале прошивки вместе с длиной?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Внешняя утилита может и не нужна, я просто этот srec недолюбливаю. Похожее решение для CubeIDE потребовало наличие внешней утилиты, которая может выдать значение CRC как HEX-число в консоль. Как я не мучался, не смог заставить srec так сделать (чтоб без лишнего мусора, а только число). Пришлось писать внешнюю программу для расчёта CRC на C#, что не очень хорошо, но сейчас компилятор .Net встроен в Windows. В общем, пришлось помучится, чтобы генерация проекта из CubeMX не влияла на автоматическую подпись в виде контрольной суммы.

Я к этому уже привык и хочу подтянуть IAR и Keil проекты для единообразия. Значение CRC где-то вначале мне не нравится, т.к. порой мне нужно знать действительно ли тот hex-файл я шью. Для этого я смотрю последние 4 байта у BIN или 4 байта данных у HEX-файла и использую их для определения прошивки, это удобно (на всякий случай как доп проверка). Ну и в коде я обычно не сравниваю значения CRC, а считаю целиком вместе с ним (всю прошивку полностью), а проверяю уже на равенство нулю (или HAL_OK).

При передаче по линии связи прошивка уже содержит CRC в конце.

Судя по пакету XCUBE-CLASSB, где это решение для Keil приведено, у меня не совсем велосипед. Я бы и не стал заморачиваться, если бы не нашёл уже готовое. Его нужно только немного доработать напильником. Кстати, батники эти (crc_gen_keil.bat) я нашёл только в ранних версиях пакета.

Если получится намутить проект с CRC в конце для Keil, то я выложу здесь. Во всех трёх вариантах (keil, iar и gcc) меня интересует только случай, когда я в отладчике могу проверить целостность, а не подписывать hex постфактум. Т.е. собрал проект, запустил и прямо в отладке проверяю целостность. Это немного сложнее, чем просто выходной файл подписать.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...