STM8–Выполнение кода из ОЗУ
Рассмотрим как реализовать выполнение программного кода из ОЗУ работая с компилятором Cosmic.
Пример
Самый простой способ выделить область памяти и объявить её отдельной секцией.
Для этого правим файл компоновщика (*.lkf).
Вот типичный пример распределения памяти в простом проекте:
Что есть что:
секция | назначение |
bsct | так называемая “нулевая страница”, предназначена для инициализируемых переменных. Переменные значение которых требуется инициализировать до запуска основного кода. “Нулевая страница” вероятно из-за расположения в памяти, всегда должна быть первой. |
ubsct | предназначена для переменных не требующих начальной инициализации. |
bit | предназначенная для переменных размеров в один бит. |
data | предназначена для инициализируемых переменных. |
bss | предназначена для переменных не требующих начальной инициализации. |
Как видим у последних двух секций назначение совпадает с предыдущими, это связанно с различием в адресации. Для адресации всех данных в нулевой странице достаточно одного байта (short range), для секций data и bss, требуется уже два байта (long range).
Размер секции, начальный адрес и прочие опции определяется с помощью ключей:
+seg | добавляем секцию |
.bsct | имя секции (точка в начале имени обязательна) |
-b 0х00 | начальный адрес секции |
-m 0x100 | размер секции |
-n .bsct | имя секции (как я понял по этому имени секция доступна извне) |
Так как нам заранее не известен размер секций (bsct, ubsct, bit), самым простым способом оказалось объявление размера у одной (bsct) и добавление последующих двух (ubsct, bit) в неё. (ключ -a).
Аналогично для секций data и bss.
Код предпочтительно размещать за пределами нулевой секции.
Выделим кусочек для нашего кода:
Для экономии места я просто добавил секцию in_ram без жесткой привязки к памяти.
Ключик –ic помечает указывает что сегмент предназначен для перемещаемого кода, т.е. после компиляции мы будем иметь нужный нам код во флеш-памяти, который нужно будет скопировать в ОЗУ перед использованием.
Для тех кто работает с STVD, все ещё проще нужно просто прописать секцию в настройках проекта:
Место выделено, теперь нужно “обрамить” требуемые функции следующим образом:
и перед вызовом скопировать код из флеш-памяти в ОЗУ:
Это библиотечная функция предназначена специально для перемещаемого кода, в качестве её аргумента необходимо указать первую букву от названия секции, в данном случае это буква “i” от имени in_ram.
Для использования библиотечной функции нужно сделать её объявление в проекте:
Функция возвращает ноль при успешном копировании, и не нулевое значение при ошибке.
Ну вот собственно и все.
Как видим все очень просто, если вы свободно владеете английским, к сожалению я такими способностями не обладаю ;( поэтому возможно ошибаюсь в некоторых моментах.
Алгоритм работы описан в документации к компилятору:
C Cross Compiler User’s Guide for ST Microelectronics STM8
в разделе “Перемещаемый код” (Moveable Code).
Стоит заметить что нужно быть внимательным при выполнении кода из ОЗУ, так как если в коде используются библиотечные функции, то будем иметь смешанный код. При чем сами того не замечая мы очень часто используем библиотечные коды, например работа с переменными размером 32 бита требует библиотечные функции (сложение, вычитание и т.п.).
Аналогичным образом реализована работа с кодом в ОЗУ у GCC, используемого мной в работе с микроконтроллерами STM32.
При выполнении кода из ОЗУ как правильно микроконтроллер потребляет меньший ток. Так же при некоторых операциях с памятью (флеш, EEPROM) необходимо выполнение кода из ОЗУ.
comments powered by Disqus