Инструменты пользователя

Инструменты сайта


prog:uart:run_ram_uart

Загрузка программы в ОЗУ и запуск через UART

В статье Тестируем Bootloader в режиме UART мы опробовали команды управления UART загрузчиком и запустили программу, записанную в Flash. Команды загрузчика позволяют записать массив байт в ОЗУ и запустить программу с заданного адреса. Этого достаточно, чтобы записать в ОЗУ программу и её запустить. Это мы сейчас и сделаем.

Для запуска в ОЗУ, нам потребуется программа, которая использует только адреса ОЗУ. Мы такой пример уже делали в статье - Запуск программы в ОЗУ из Keil, программа называется HelloWorld_RAM. Давайте откроем проект и внесем одно изменение.

Получение bin файла

Для начала необходимо получить бинарный файл нашего примера. В этом файле нет ничего лишнего, а только байты кода нашей программы. Есть различные конвертеры, которые позволяют из hex файла, получить bin файл. Можно было бы использовать их. Но мы воспользуемся штатной возможностью Keil, описанной здесь - Keil: GENERATING BINARY OUTPUT DURING A BUILD

Bin файл будет автоматически генерироваться при сборке проекта. В настройках проекта идем в Options - User, находим пункт AfterBuild/Rebuild и ставим галочку в опции Run #1. В поле команды данного пункта необходимо вписать следующее:

$K\ARM\ARMCC\bin\fromelf.exe --bin --output=@L.bin !L

Теперь делаем Rebuild проекта HelloWorld_RAM и в папке проекта находим файл "HelloWorld_RAM.bin". Кейл и проект можно закрыть, они больше не потребуются.

Загрузка bin файла в ОЗУ

Далее нам необходимо узнать размер файла, поскольку для команды LOAD нам потребуется указать количество байт записываемых в ОЗУ. Кликаем правой кнопкой мыши на "HelloWorld_RAM.bin", выбираем свойства и смотрим точный размер файла в байтах.

В шестнадцатеричной системе 3116 равно 0х0С2С. Теперь у нас есть все данные для загрузки программы.

Открываем программу Terminal v1.9b и повторяем все действия, описанные в статье тестируем Bootloader в режиме UART до получения приглашения от микроконтроллера. При желании можно также увеличить скорость обмена по UART, чтобы загрузка прошла быстрее. Я выставил 19200 бод.

Давайте напишем макрос M10. Код команды = 'L', адрес = 0x2000_0000, количество байт = 0x0000_0C2C. Записать программу необходимо с адреса, который был указан в поле IROM1 закладки Options - Target при сборке проекта "HelloWorld_RAM". У нас там был указан стартовый адрес ОЗУ, поэтому и параметр адрес = 0x2000_0000.

Код макроса М10:
  L$00$00$00$20$2C$0C$00$00

Нажимаем М10. Нам пришло подтверждение команды загрузки - 'L'. Теперь UART загрузчик ожидает приема 3116-ти байт. Посылаем ему наш файл "HelloWorld_RAM.bin". Для этого находим кнопку Send File и в открывшемся окне выбираем наш "HelloWorld_RAM.bin". Жмем ОК и файл передается в UART.

Спустя несколько секунд, приходит символ 'K' - подтверждение от микроконтроллера об успешном получении 3116 байт. Теперь наша программа находится в ОЗУ. В терминале это выглядит так:

>LK

Запуск

Для запуска напишем макрос М11, код команды = 'R', стартовый адрес = 0x2000_0000.

Код макроса М11:
  R$00$00$00$20
  
>R 00 00 00 20
  <  52  = 'R' - подтверждение команды запуска

ОСОБЕННОСТЬ: В некоторых микроконтроллерах требуется указать не стартовый адрес программы, а сразу адрес обработчика Reset_Handle. Этот адрес необходимо взять из загружаемого образа программы, с адреса 4. Первые 4 байта используются для указателя стека, а вторые 4 байта - это и есть необходимый адрес обработчика. Похоже, что код внутри загрузчика проверяет этот адрес.

Запускаем М11, нам приходит подтверждение команды запуска, символ 'R'. Светодиод на плате начинает мигать, значит, наша программа успешно стартовала из ОЗУ.

Таким вот не сложным образом мы научились загружать программу в ОЗУ и запускать ее на исполнение. На основе данного примера можно реализовать прошивку и Flash памяти процессора. Только загрузить потребуется две программы:

  1. пользовательскую программу, которую необходимо зашить в Flash.
  2. программу "прошиватель", которая умеет писать в Flash.

После загрузки обеих программ, запускается программа "прошиватель". Эта программа "прошиватель" будет брать код пользовательской программы и писать ее в Flash. Давайте это осуществим - Прошивка программы в Flash и запуск через UART.

На самом деле загрузчик Bootloader, который работает в МК и обеспечивает связь по UART является программой, написанной на Си. Поэтому младшие адреса заняты под глобальные переменные и кучу, а старшие адреса ОЗУ заняты под стек. Загружая программу с адреса 0х2000_0000, мы рискуем затереть данные программы загрузчика. Поэтому при загрузке в память следует отступить от края ОЗУ. На форуме приводится рекомендация при загрузке программы по UART использовать диапазон адресов 0x2000_0100 - 0x2000_7E00.

Будем считать, что нам повезло. Видимо, никаких важных данных в начальных адресах ОЗУ не содержалось, поэтому пример отработал успешно.

UPD: Добавлена программа на Python для стирания памяти через UART - GitHub. Эта программа делает автоматически все, что описано в данной статье. Т.е. загружает по UART в ОЗУ микроконтроллера программу, которая при запуске стирает флеш память.

prog/uart/run_ram_uart.txt · Последнее изменение: 2022/04/03 23:09 (внешнее изменение)