47417

[i] Запуск программы из ОЗУ в среде Keil

Дата последнего изменения: 18.07.2022 11:24:22

Flash-память процессора имеет ограниченный ресурс порядка 10000 циклов перезаписи. По этой или иным причинам иногда возникает необходимость разместить программу целиком в ОЗУ-памяти микроконтроллера. Рассмотрим, как это можно реализовать средствами Keil, на примере программы мигания светодиодами - Hello World - светодиод. на примере микроконтроллера К1986ВЕ1QI.

Первым шагом нужно прошить и запустить в микроконтроллере проект "HelloWorld" и убедиться, что светодиод мигает.

Вторым шагом - сделать копию проекта и назвать ее, например, HelloWorld_RAM, чтобы не испортить исходный проект. Кроме этого в новом проекте нужно уменьшить в два раза значение задержек, определяющих период мигания светодиодом. Теперь мигание будет происходить в 2 раза чаще. Таким образом, при загрузке из Flash мигание будет в 2 раза медленней, чем при выполнении программы из ОЗУ. Таким образом можно будет узнать, какая программа работает в текущий момент.

Настройка проекта

Важно понимать, что все данные, функции, адреса переходов в программе должны находится по адресам в ОЗУ. Поэтому в закладке Options - Target в разделе IROM1 вместо диапазонов памяти Flash необходимо указать адреса ОЗУ. Для этого ту память ОЗУ, которая в обычном проекте целиком была определена в IRAM1 (Internal RAM1), поделим на две части и одну половину отдадим под раздел IROM1 (рисунок 1).

 Рисунок 1 - Options for Target. Вкладка 'Target' для микроконтроллера К1986ВЕ92QI

В МК К1986ВЕ1QI уже имеется две области памяти ОЗУ IRAM1 и IRAM2, поэтому можно одну из них целиком выделить под IROM1. Однако, для этого подходит только память IRAM2, адреса которой начинаются с 0x20100000. Только к этой памяти имеет доступ шина AHB_Lite, поэтому код из этой памяти может исполняться (рисунок 2).

 Рисунок 2 - Options for Target. Вкладка 'Target' для микроконтроллера K1986ВЕ1QI

Далее в опциях проекта переходим в закладку Linker. В ней необходимо выбрать опцию Use Memory Layout from Target Dialog (рисунок 3).

 Рисунок 3 - Options for Target. Вкладка 'Linker'

В закладке Debug необходимо подключить в опции "Initialization File" - файл инициализации. Для этого нужно зайти в папку проекта и создать текстовый файл Setup.ini. Листинг этого файла приведен ниже:

FUNC void Setup (unsigned int region) {
region &= 0xFFFFF000;
SP = _RDWORD(region); // Setup Stack Pointer
PC = _RDWORD(region + 4); // Setup Program Counter
_WDWORD(0xE000ED08, region); // Setup Vector Table Offset Register
}
Setup(&__Vectors);

В файле Setup.ini функция Setup() указывает отладчику, как инициализировать необходимые регистры в зависимости от стартового адреса программы. По адресу начала таблицы векторов, согласно файлу startup_xxx.S, расположена переменная __Vectors, адрес расположения которой зависит от настроек проекта, что можно использовать в качестве аргумента функции Setup(). Адрес переменной __Vectors в данном случае равен адресу, который указан в IROM1, то есть 0x20000000 (рисунки 1 и 2). 

Подключим созданный файл Setup.ini (рисунок 4).

 Рисунок 4 - Options for Target. Вкладка 'Debug' 

Во вкладке Debug->Settings нужно установить те же настройки, которые были использованы при работе с Flash. Настройки при использовании программатора ULINK2 приведены на рисунке 5.

 Рисунок 5 - Настройки программатора ULINK2

Во вкладке FlashDownload необходимо выбирать опцию "Do not Erase" и удалить алгоритм программирования. Таким образом Keil не сможет изменить записанную в Flash программу при запуске текущего проекта в ОЗУ (рисунок 6).

 Рисунок 6 - Настройки алгоритма программирования. 'Do not Erase'

Последняя вкладка - Utilites. Выключим использование драйвера для программирования Flash выбором Use External Tool for Flash Programming (рисунок 7).

 Рисунок 7 - Options for Target. Вкладка 'Utilities'

Теперь можно переходить к испытаниям.

Запуск программы

Произведем сборку проекта нажатием клавиши F7 (в окне "Build Output" среды будут указаны основные сведения о сборке, в том числе наличие ошибок или предупреждений), после чего для запуска программы перейдем в режим отладки Ctrl+F5. В этот момент программа загружается в ОЗУ. Затем осуществляем запуск, F5. Наблюдаем мигание светодиода. В окне ассемблера видим, что исполняемая программа располагается в адресах ОЗУ, с 0х20000000 и т.д.

В режиме исполнения из ОЗУ нельзя поставить точку останова. Keil выводит сообщение Keil: "Cannot set breakpoint(s) …". Чтобы этого не возникало, перед запуском программы нужно поставить первую точку останова. Затем когда процессор остановится на ней, можно поставить следующую и так далее. Если запуск F5 уже состоялся, то необходимо в тулбаре нажать кнопку стоп и в остановленном режиме поставить точки останова там, где это необходимо.

Теперь нажмем Reset. По изменившемуся периоду мигания светодиода видно, что программа исполняется из Flash. Это объяснимо - ведь загрузку и запуск новой программы в ОЗУ выполнил отладчик через JTAG. А при возникновении Reset запуск произошел штатным режимом.


Сохранить статью в PDF

Теги

Была ли статья полезной?