Вставка файлов в прошивку — 2 часть

Вставка файлов в прошивку — 2 часть

Я уже писал о методе добавления внешних файлов в прошивку микроконтроллера, даже написал для этой цели онлайн-конвертер бинарного файла в c-хедер. Однако есть более простой и удобный способ, который предоставляет IAR, да и строго говоря, любой линкер обязан уметь так делать.

Конечно, вы уже поняли — мы полезем в параметры линкера.

Одна из самых частых моих задач за последнее время — это сборка прошивки основного девайса, в которую вкомпилена прошивка дочерней платы. Основной девайс при запуске проверяет версию прошивки дополнительной платы, и если она младше — обновляет её до свежей. Поэтому я должен включить в основную прошивку бинарный файл с дочерней прошивкой.

Открываем окно Options -> Linker -> Input:

Снимок экрана 2016-01-09 в 13.02.24

Внизу видим опции «Raw binary image». Это именно то, что нам нужно, указываем файл.

Что обозначают остальные опции?

  • Symbol — глобальный символ кода, это то имя, которое будет присвоено массиву с содержимым файла. Я написал здесь batp_fw, потому что это прошивка (firmware) платы BATP.
  • Section — секция линкера, в которой файл будет размещён. Напишем здесь «fw_section», только ещё надо будет создать и разместить эту секцию.
  • Align — выравнивание по границе байт, полуслов или слов. Обычно я ставлю здесь 4 (выровнять по границе слов).

Укажите имя символа в окошке «Keep symbols», иначе символ (и весь массив) будет выкинут линкером при сборке.

Снимок экрана 2016-01-09 в 13.14.46

Сохраните изменения, и пойдём править скрипт линкера. Он лежит в папке проекта, что-то вроде stm32f4xx_flash.icf.

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__    = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__      = 0x081FFFFF;
define symbol __ICFEDIT_region_RAM_start__    = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__      = 0x2002FFFF;
define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;
define symbol __ICFEDIT_region_CCMRAM_end__   = 0x1000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/


define memory mem with size = 4G;
define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
define region CCMRAM_region   = mem:[from __ICFEDIT_region_CCMRAM_start__   to __ICFEDIT_region_CCMRAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

>>> place at address mem:0x08100000 { readonly section fw_section }; <<<

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
block CSTACK, block HEAP };

Я добавил строчку

place at address mem:0x08001000 { readonly section fw_section };

практически в самом конце скрипта линкера. Это разместит тот файл во flash-памяти, начиная с адреса 0x08001000.

Файл batp_fw.bin в редакторе выглядит так:

Снимок экрана 2016-01-09 в 13.33.36

Компилируем, собираем проект и запускаем. Посмотрим редактор памяти (View -> Memory во время отладки):

Снимок экрана 2016-01-09 в 13.32.58

Как видим, файл действительно разместился по нужному нам адресу.

Ну и вишенка на торте, использование этого куска памяти, как массив в программе — это очень… нет, крайне просто!

extern uint32_t batp_fw[];

Конечно, тип данных может быть любой удобный вам. Хотите обращаться побайтово — используйте char или лучше uint8_t, хотите ускорить чтение — обращайтесь пословно с помощью unsigned int или лучше uint32_t.

Заключение.

Этот способ лучше, чем вклейка в код массива байт файла, как в прошлой статье. Но он, возможно, чуть сложнее. И если нужно что-то подправить в файле перед слияением — вам понадобится hex-редактор, в отличие от прошлого способа, где это можно сделать хоть Блокнотом.

Однако, этот способ даёт включить только один файл, если нужно включить несколько— потребуется ручная правка командной строки линкера.

Читайте также:

1 комментарий

  1. Петр:

    STM32F746GDISCOVERY
    AN4760 pg.58

    How to proceed to program QSPI Flash memory only once

    During an application development, the user needs to debug its project and needs to load the code to the internal Flash memory many times. For each load-Flash operation, the QSPI Flash memory is loaded as well, which makes the loading operation too long. In this case, if the user already loaded data to the QSPI Flash and does not need to repeat the operation, the user can simply generate the QUADSPI data related symbol definition file and add it to the project. The symbol definition file is a *.txt file for Keil MDK-ARM and a *.o file for IAR EWARM; it should replace, in the project, the original source code files (*.c or *.h) that were already programmed.

    Another easier alternative consists in simply removing the already added QSPI Flash memory loader.

    Вроде понятно все. Начинаю в IAR в линкере пытаться в меню что-то такое прописать, получаются танцы с бубном.

    В примере:

    STM32Cube_FW_F7_V1.14.0 \ Projects \ STM32746G-Discovery \ Applications \ QSPI \ QSPI_perfs

    Все грузится, читается… Как сделать, чтобы qspi не писалась каждый раз. Уж больно грузится долго.
    Может подскажите что… ))))))))

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Предлагаем в аренду парусные яхты и лодки комфорт класса Аренда яхт Сочи Тематические морские фотосессии, искупаться и позагорать.