FAQ. Компилятор IAR C для микроконтроллеров AVR фирмы Atmel

   

В. Полетаев

Frequently asked questions
ответы на часто задаваемые вопросы по компилятору IAR C для микроконтроллеров AVR фирмы Atmel дает В. Полетаев ( Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript )

Компилятор IAR C для микроконтроллеров AVR фирмы Atmel

Существует несколько версий компилятора — 1.40, 1.41, 1.50, но по некоторым причинам наибольшее распространение в России получила версия 1.40c. Версия компилятора смотрится в файле ewa90d.txt — не путать с версией оболочки.

Вопрос: Я установил IAR Embedded Workbench и “патчи” к нему. Что мне ещё нужно?

Ответ: Версия 1.40 поставляется с не совсем корректными .xcl-файлами для линкера. Кроме того, описания регистров микроконтроллеров в нём неполные. Для нормальной работы имеет смысл либо взять комплект .xcl- и h-файлов от более новой версии компилятора, либо с сайта фирмы Atmel (ftp://; ftp://).

Файлы из этих архивов следует переписать в соответствующие каталоги вместо поставлявшихся с компилятором.

При работе в Embedded workshop правильное имя .xcl-файла следует указывать отдельно для каждой target в Project|Options|XLINK|Include|XCL file name, включив Override default.

Вопрос: С чего начать?

Ответ: Лучше всего — полностью прочитать весь help. Это значительно упростит дальнейшее освоение. Печатная документация на компилятор практически слово в слово повторяет help.

Как минимум, следует прочитать разделы Overview и Tutorial в AT90S Windows Workbench Help. Пытаться работать без знаний из этих разделов — бессмысленная трата времени.

Кроме того, рекомендуется посетить на сайте фирмы Atmel раздел и скачать оттуда ряд документов:

  • AVR030: Getting Started With C for AVR (). Хороший пример для быстрого начала работы. В качестве приложения к нему идёт ftp:// — сборник правильных .xcl-файлов для различных конфигураций микроконтроллеров.
  • AVR032: Linker Command Files for the IAR ICCA90 Compiler (). Здесь описывается, как составлять .xcl-файлы. Просто пересказ документации от IAR. Как приложение идёт ещё один пример с .xcl-файлами, но более ранний. Лучше пользоваться вариантом от Getting Started.

В этом разделе есть ещё ряд документов, посвящённых работе с Си и заслуживающих внимательного ознакомления, из которых особенно отмечу AVR035: Efficient C Coding for AVR ().

Для эффективной работы следует также взять с последнюю редакцию datasheet и errata на выбранный микроконтроллер и тщательно их изучить, особенно errata.

Вопрос: Отличается ли IAR C от стандартного ANSI C?

Ответ: Да. В IAR C входят различные расширения, связанные с реализацией компилятора для микропроцессора с гарвардской архитектурой (два адресных пространства — для кода и данных) и для более эффективной работы в ограниченных условиях микроконтроллеров. Подробнее смотрите AT90S C Compiler Programming Help, раздел Language extensions.

В исполняющей системе (библиотеке) отсутствуют функции, связанные с вызовами операционной системы (операции с файлами и пр.).

Вопрос: Можно ли разместить таблицы (строки и т. д.) в ПЗУ?

Ответ: Можно. Для этого существует расширение языка — зарезервированное слово flash. Переменная, описанная с применением данного слова, размещается в адресном пространстве кода и доступна только по чтению.
flash char aaa[] = “aaa”;flash char bbb[] = “bbb”;flash char ccc[] = “ccc”;flash char flash *xxx[] = {aaa, bbb, ccc, 0};

Если используется более чем один уровень вложенности, как в вышеприведённом примере (массив указателей на строки), то flash должен стоять для каждого уровня.

Вопрос: Как передать строку char flash * в функцию? Прямое написание строки в параметрах функции не проходит: printf_P(“Строка\n”);

Ответ: Вариант 1.

Описать её отдельно:
{ static flash char str[] = “Строка\n”; printf_P(str);}

Рекомендую обратить внимание, что не обязательно выносить описание строки в начало функции. Можно сделать локальный блок и описать в нём переменную, как в примере.

Вариант 2. Пользоваться явным преобразованием типа:
printf_P((char flash *)(int)“Строка\n”);

Можно слегка сократить запись при помощи #define:
#define F (char flash *)(int)printf_P(F“Строка\n”);

В этом варианте строка будет размещаться в сегменте CSTR. По умолчанию данный сегмент размещается в адресном пространстве данных, поэтому для корректной работы надо исправить XCL-файл. Надо убрать упоминание CSTR из строки:
-Z(DATA)CSTR,CONST=9000-FFFF

(если эта строка присутствует в исходном XCL-файле) и вставить его в строку:
-Z(CODE)INTVEC,RCODE,CDATA0, CDATA1,CCSTR,SWITCH,FLASH,CODE=0-1FFFF

Вариант 3. Использовать ключ –E.

Этот вариант возможен только при работе с компилятором из командной строки. После указания данного ключа компилятор размещает строковые данные в сегменте CSTR и данные типа const — в CONST, причём считает, что эти сегменты расположены в адресном пространстве кода.

В этом варианте также требуется исправление XCL-файла с переносом CSTR и CONST в строку -Z(CODE).

Кроме того, в этом варианте могут возникнуть проблемы с использованием библиотеки, оттранслированной без ключа –E.

Ну и наконец, в этом варианте компилятор выдаёт предупреждающее сообщение Dangerous configuration, которое можно отключить только вместе со всеми предупреждениями, что неудобно.

На мой взгяд, наиболее приемлимыми являются первый и второй варианты.

Вопрос: Как преобразовать указатель char * в char flash *?

Ответ: Воспользоваться промежуточным int:
char *s;char flash *p;p = (char flash *)(int)s;

Вопрос: Где размещаются переменные типа const?

Ответ: Это зависит от установленных опций компилятора. По умолчанию (если не задан ни один из параметров –y или –E) эти переменные размещаются в сегменте CONST, который считается находящимся в адресном пространстве данных. Данный режим делался с расчётом на использование внешней энергонезависимой памяти данных и в большинстве случаев не применяется. Кроме того, в этом режиме компоновщик помещает эти переменные в область кода по тем же адресам, что может вызвать серьёзные проблемы.

Если установлен режим –y –“Writable constants and strings”, то компилятор строит код в полном соотвествии со стандартом ANSI, размещая константы и строки в адресном пространстве данных. Их начальные значения сохраняются в адресном пространстве кода в сегментах CDATA0 или CDATA1 для констант и CCSTR — для строк, а в момент запуска они переписываются в ОЗУ в сегменты IDATA0/IDATA1 и ECSTR, соответственно. Основной недостаток данного режима — непроизводительное использование ОЗУ.

Вариант с указанием ключа –E рассматривался выше. Одновременное использование ключей –y и –E невозможно.

Для написания оптимального варианта программы лучше не пользоваться const, а описывать неизменяемые данные как flash, что приведёт к их явному размещению в памяти программ без лишнего расхода ОЗУ.

Вопрос: Как удобнее работать с битами в регистрах внешних устройств?

Ответ: Для начала описать полезный макрос:
#define Bit(n) (1 << (n))Для установки бита n в порту p:p |= Bit(n);Для сброса бита:p = ~Bit(n);Для проверки бита:if ((p Bit(n)) != 0) ...

и так далее.

Полный перечень всех битов доступен на сайте фирмы Atmel в разделе software, файл io_def.zip. Следует поместить эти .h-файлы из этого архива в каталог C:\IAR\EW22DEMO\A90\INC\ вместо существующих.

Вопрос: У меня не работает printf. Что делать для правильного вывода информации в последовательный порт?

Ответ: Во-первых, включить в свою программу отдельную функцию putchar:
int putchar(int c){ while ((USR (1 << UDRE)) == 0); UDR = c; return c;}

Стандартный putchar в библиотеке представляет один оператор RET и не выполняет никакого вывода.

Для доступа к именованным названиям битов регистров следует взять правильный .h-файл из io_def.zip.

Эту функцию следует включать только при компиляции под target=release, иначе под отладчиком может отказаться работать окно Terminal I/O. Простейший способ это сделать — определить для target=debug символ DEBUG (Project|Options|ICCA90|#define, ввести символ) и окружить определение putchar директивами условной компиляции (например, #ifndef DEBUG … #endif).

Во-вторых, следует вставить в начало своей программы процедуру установки скорости обмена последовательного порта. Например, для кварца 5,53 МГц и скорости обмена 115200 бод надо установить:
UBRR = 2; UCR = 0x18;

В-третьих, обычный printf будет работать только с включенным режимом –y –“Writable constants and strings”.

В-четвёртых, надо правильно выбрать вариант функции printf. Подробности смотрите в AT90S C Compiler Programming Help, Configuration, Input and output.

Стандартная функция printf требует для своей работы минимум 134 байт ОЗУ в стеке. Это страшное расточительство, поэтому есть сокращённые версии printf, обладающие значительно меньшими возможностями форматирования (в частности, не поддерживают задание поля ширины вывода), зато не требующие для работы так много ОЗУ.

В качестве окончательного решения проблемы я бы порекомендовал сделать следующее:

Взять за основу файл C:\IAR\ \EW22DEMO\A90\ETC\intwri.c и произвести в нём следующие изменения:

  • добавить строку #include “pgmspace.h”;
  • заменить описание функции на int printf_P (const char flash *format, ...);
  • изменить тип массива hex с const на flash: static flash char hex[] = “0123456789ABCDEF”.

После этого не забыть внести нужные изменения в XCL-файл (перенести CSTR в раздел CODE).

Разумеется, надо вставить putchar и инициализацию порта.

После этого забыть про существование printf и пользоваться только printf_P.

Вопрос: Мне не хватает ОЗУ. Что делать?

Ответ: Прочитать AVR035: Efficient C Coding for AVR и внедрить приведённые там рекомендации.

Если кратко — включить оптимизацию по размеру. По возможности, использовать байтовые (char) переменные. Hе перегружать стек локальными переменными большого размера. Стараться делать функции большого (в меру!) размера — так компилятор разложит максимум переменных по регистрам. Об эффективности лучше судить по листингу с включенным режимом insert mnemonics. Передавать в функции лучше не более 2 входных переменных — так они лягут в регистры. Размещать константы в ПЗУ, с ключевым словом flash.

Внимательно изучить используемый .xcl-файл — он приведён в поставке только для примера и кое-где неэффективен. Поставить нижнюю границу всех DATA сегментов (RSTACK, CSTACK, IDATA1, UDATA1, ECSTR) в 60 — так будет достигнуто полное, без дырок, использование ОЗУ. Уточнить размеры аппаратного (RSTACK) и программного (CSTACK) стеков.

Вопрос: У меня не работает порт A. Почему?

Ответ: Порт A используется как шина адреса-данных при работе с внешним ОЗУ. Если оно не используется, то в .xcl-файле следует закомментировать строку -e?RSTACK_IN_EXTERNAL_RAM=? C_STARTUP.

Вопрос: Можно ли создать выходной файл в двоичном виде?

Ответ: Да. Для этого следует указать в качестве выходного формата mpds. Полученный файл с расширением .tsk и будет образом ПЗУ.

Вопрос: Как заменить библиотечный модуль на свой?

Ответ: Проще всего поместить исходный файл с ним в свой рабочий каталог проекта и подключить его к файлу проекта. Дальше оболочка сама разберётся с его типом (.c или .s90) и позаботится о его пристыковке раньше библиотечного.

Вопрос: Как лучше отлаживать программу?

Ответ: Если нужно отладить алгоритм, не зависимый от работы периферии, можно воспользоваться C-SPY. Преимущество — отладка на уровне исходного текста (но можно посмотреть и ассемблерный текст), недостаток — периферия практически отсутствует.

Если нужна работа со стандартной периферией, можно воспользоваться Atmel AVR studio 3.0, которая достаточно точно эмулирует поведение кристаллов. Для передачи в неё файла следует указать xlink’у тип выходного формата debug. Если в окне исходного текста в Astudio символы искажены, то следует установить подходящий моноширинный фонт (например, terminal для ДОС-кодировки русских букв или Courier для Windows) в меню Edit|Fonts…ВHИМАHИЕ! IAR адресует память программ побайтно, в то время как Atmel — пословно. Поэтому, если в map-файле от компоновщика подпрограмма имеет адрес 1234h, то в astudio надо указывать адрес 1234h/2=091Ah.

Вопрос: EWA90 работает только под Windows?

Ответ: Оболочка — да. Однако есть command-line версии компилятора, ассемблера и компоновщика, которые прекрасно работают под MS-DOS, используя встроенный DOS Extender от Phar Lap Software, Inc.

Основная сложность при работе с ними — огромное количество ключей. Рекомендую для начала поработать в виндовой оболочке, а затем взять список ключей из шапки листинга и поместить его в make-файл.

Вопрос: Периодически при компиляции совершенно правильного файла выдаётся системная ошибка. Что делать?

Ответ: Повторить компиляцию. Это какая-то ошибка в компиляторе, которая иногда возникает.

Вопрос: Что ещё почитать об AVR, кому задать вопрос?

Ответ: На российском сайте фирмы Atmel есть подборка практических рекомендаций: AVR/AVR.htm и Spec/Spec.htm.

Ответы на вопросы по AVR, задаваемые посетителями сайта ATMEL, можно найти на FAQ/FAQ.htm.

Можно задать вопросы российским представителям Atmel — фирме ЭФО через конференцию Atmel на сайте .

Большое число специалистов по AVR регулярно общается и в конференции по микроконтроллерам на сайте Телесистем — .






Рекомендуемый контент




Copyright © 2010-2017 housea.ru. Контакты: info@housea.ru При использовании материалов веб-сайта Домашнее Радио, гиперссылка на источник обязательна.