Преодолевая пределы. Часть вторая. Ресурсы в IAR.
В первой части я продемонстрировал, как ресурсы могут быть созданы средствами ST Visual Develop. Но естественно держать проект в двух студиях несколько не удобно. В текущей публикации я расскажу, как все необходимые ресурсы могут быть созданы в среде разработки IAR.
Использование ресурсов в IAR
Кроме упомянутого способа задания адреса для ресурса через define, IAR поддерживает собственный способ задания адреса для переменных и констант через #pragma location. Так рассмотрим небольшой пример:
// Задание адреса с помощью макросов
#define intro ((const unsigned char*)0xA000)
#define string ((const char*)0xA1F8)
// Задание адреса с помощью директивы pragma
#pragma location=0xA200
__no_init const unsigned char intro2[504];
// Задание адреса в помощью оператора @
__no_init const char string2[8] @0xA3F8;
В результате для всех вариантов вызовов функций будет сгенерирован одинаковый код:
LCD_writeString("IAR Resources");
008459 AE8560 LDW X, #?<Constant "IAR Resources">
00845C CD819B CALL LCD_writeString
...
LCD_writeString( string );
008468 AEA1F8 LDW X, #0xA1F8
00846B CD819B CALL LCD_writeString
...
LCD_writeString( string2 );
008477 AEA3F8 LDW X, #string2
00847A CD819B CALL LCD_writeString
...
LCD_screen ( &intro[0] );
008483 AEA000 LDW X, #0xA000
008486 CD80F8 CALL LCD_screen
...
LCD_screen ( &intro2[0] );
00848F AEA200 LDW X, #intro2
008492 CD80F8 CALL LCD_screen
Какой из способов выбрать, решайте сами. Задание через #pragma и @ не переносимо на другие компиляторы, но "лучше следит" за типами данных. Правда есть сомнения, что с применением #pragma не даст о себе знать лимит по размеру кода. Проверить это пока не удалось.
Создание ASM проекта ресурсов в IAR
Создаем в рабочем пространстве разрабатываемого проекта новый ассемблерный проект и попробуем переделать его в проект ресурса.
Мне так и не удалось найти в ассемблере IAR простого способа задания адреса для участка кода, аналогичного .ORG в AVR. В целом способ задания адреса похож на способ, примененный в ассемблере STVD:
- объявляем регион памяти в определённой адресной области;
- объявляем помещение требуемых секций в выделенный регион памяти;
- указываем для кода/данных принадлежность к требуемой секции.
Только вот объявлять новые секции в ассемблерном коде, как это было в STVD, мы не можем. Для этих целей нужен отдельный файл, предназначенный для linker’а.
И так, создадим в папке проекта *.icf файл линкера:
/////////////////////////////////////////////////////////////////
// Replace ILINK command file for Resource
/////////////////////////////////////////////////////////////////
define memory with size = 16M;
define region ResourceZone = [from 0xA200 to 0xA3FF];
/////////////////////////////////////////////////////////////////
place at start of ResourceZone { ro section .recource2 };
/////////////////////////////////////////////////////////////////
Здесь мы объявили регион "ResourceZone" размером в 512 байт и начинающийся с адреса 0xA200. Далее мы указали что в данном регионе следует разместить секцию ".recource2".
Теперь нам надо указать линкеру использование нового файла конфигурации, взамен стандартного. Для этого убеждаемся что в окне Workspace у нас выбран проект ресурса, а не какой либо из файлов кода, после чего идем в меню Project -> Options и в открывшемся окне в списке категорий слева выбираем Linker. На закладке Config в группе Linker configuration file устанавливаем флажок Override default и в поле указываем путь к созданному *.icf файлу.
С линкером разобрались, теперь надо разобраться с компилятором. В ассемблерном *.s файле заменяем код на следующее:
MODULE asmmain
PUBLIC __iar_program_start
PUBLIC main
SECTION `.recource2`:CODE:NOROOT(0)
__iar_program_start:
main:
image:
db $5e, $a2, $40, $80, $00, $00, $00, $00
… ещё 61 строка данных …
db $07, $0f, $1f, $3f, $7e, $7c, $78, $30
string:
db "FD.IAR"
end
Строка с SECTION сообщает, что дальнейший код/данные должны помещаться в секцию ".recource2". Метки __iar_program_start и main нужны дабы утихомирить компилятор с отладчиком пытающихся разобраться, откуда должно начаться выполнение. Теперь осталось только задать формирование *.s19 файла, что в принципе не обязательно. В опциях проекта в категории Output Converter на закладке Output:
- устанавливаем флажок Generate additional output;
- в выпадающем списке Output format выбираем Motorola;
- в группе Output file устанавливаем флажок Override default и в окне задаем имя выходного файла с расширением *.s19.
Теперь о приятном. Если в опциях проекта в категории Debugger задать в качестве отладчика ST-Link, то при запуске на отладку проекта студия зальет собранный ресурс в контроллер без каких либо проблем и возражений (естественно, если вы выбрали в настройках проекта правильный контроллер). Да к тому же начнется отладка прошивки и отладчик будет активно мигать светодиодом. Авто-остановки не будет, т.к. меткой входа указан адрес ресурса, а он никогда не выполняется, но есть возможность приостановить выполнение вручную.
Создание С проекта ресурсов в IAR
Создаем в рабочем пространстве разрабатываемого проекта новый Си проект и попробуем переделать его в проект ресурса. А после разбора ассемблерного проекта это не должно составить большой проблемы.
Аналогично создаем *.icf файл линкера:
/////////////////////////////////////////////////////////////////
// Replace ILINK command file for Resource
/////////////////////////////////////////////////////////////////
define memory with size = 16M;
define region ResourceZone = [from 0xA400 to 0xA5FF];
/////////////////////////////////////////////////////////////////
place at start of ResourceZone { ro section .recource3 };
/////////////////////////////////////////////////////////////////
Точно так же подменяем в опциях проекта файл конфигурации линкера и выходной файл:
Содержимое *.c файла переписываем следующим образом:
typedef struct {
unsigned char image[504];
char string[8];
} Resource3;
#pragma location=".recource3"
const Resource3 recource3 = {
{
0x00, … ещё 5 сотен значений … , 0x0f, 0x06, 0x00,
},
"C.Image"
};
Все ресурсы оформлены в виде структуры, для которой указано размещение в секции ".recource3" которая в соответствии с правилами линкера находится по адресу 0xA400 и составляет 512 байт. Оформление в виде одной структуры нам необходимо, что бы при компиляции не были выброшены "неиспользуемые" данные.
Теперь о "точке входа". Функцию main мы выбросили, т.к. она нам не нужна. Так же нам не нужен и генерируемый средой код настройки окружения, не нужна таблица векторов прерываний. Что бы всё это дело отключить идей в настройки проекта в категорию Linker на закладку Library:
- снимаем флажок Automatic runtime library selection;
- устанавливаем флажок Override default program entry;
- выбираем пункт Entry symbol и в окне вводим имя нашей структуры recource3.
Благодаря этому, во-первых, сама структура не сможет быть удалена "как не используемая". Во-вторых, при компиляции проекта мы не получим ошибки "точка входа не найдена". В-третьих, в код не будет добавлено ничего лишнего. Как-то это получалось через Defined by application сделать, но уже не вспомню.
И снова о приятном. Указываем в качестве отладчика ST-Link и запускаем проект на отладку. Снова получаем автоматическую прошивку, только уже не без предупреждений:
В прочем ничего страшного тут нет. Просто отключаем лишний компонент среды и радуемся жизни.
Результат
В прочем результат не отличается от первой статьи. Все три способа работают одновременно, что не вызывает сомнения.
Плюсы и минусы
Несомненным плюсом является возможность собрать все проекты (код и ресурсы) разрабатываемого устройства в одном рабочем пространстве (workspace):
Вторым плюсом является простота прошивки с применением отладчика. Нет риска, ошибиться при указании диапазоне адресов и случайно затереть что-то нужное. Среда самостоятельно прошивает только относящуюся к проекту область.
Третьим плюсом является возможность отладки при работе с проектом ресурса. Правда, только в режиме инструкций и без подстановки кода, но это лучше чем ничего. Вероятно, есть способ научить среду подтягивать отладочную информацию из других проектов.
Из минусов по-прежнему остаётся шанс что-нибудь забыть/потерять при прошивке.
Вместо заключения
Естественно, что данная модель удобнее для сопровождения. Так возможность разрабатывать и прошивать одной средой позволяет держать все необходимые компоненты вместе. Меньше риск что-либо забыть записать или не нарочно стереть. Но при этом мы не можем создавать ресурсы большего размера, чем позволяет среда разработки. В прочем "Война и мир" в каждом проекте нам не требуется, так что данный подход вполне хорош.
В заключительной части я продемонстрирую более интересную возможность: формирование двоичных библиотек в среде IAR.
Файлы: odo_with_rc.zip, complite_iar.s19.zip
< Предидущая Следующая >