В. Полетаев
Frequently asked questions
ответы на часто задаваемые вопросы по компилятору IAR C для микроконтроллеров
AVR фирмы Atmel дает В. Полетаев (vmp@aha.ru)
Существует несколько версий компилятора ≈ 1.40, 1.41, 1.50, но по некоторым причинам наибольшее распространение в России получила версия 1.40c. Версия компилятора смотрится в файле ewa90d.txt ≈ не путать с версией оболочки.
Вопрос: Я установил IAR Embedded
Workbench и ⌠патчи■ к нему. Что мне еще нужно?
Ответ: Версия 1.40 поставляется
с не совсем корректными .xcl-файлами для линкера. Кроме того, описания
регистров микроконтроллеров в нем неполные. Для нормальной работы имеет
смысл либо взять комплект .xcl- и h-файлов от более новой версии компилятора,
либо с сайта фирмы Atmel (ftp://www.atmel.com/pub/atmel/avr030.zip;
ftp://www.atmel.com/pub/atmel/io_def.zip).
Файлы из этих архивов следует
переписать в соответствующие каталоги вместо поставлявшихся с компилятором.
При работе в Embedded workshop
правильное имя .xcl-файла следует указывать отдельно для каждой target
в Project|Options|XLINK|Include|XCL file name, включив Override default.
Вопрос: С чего начать?
Ответ: Лучше всего ≈ полностью
прочитать весь help. Это значительно упростит дальнейшее освоение. Печатная
документация на компилятор практически слово в слово повторяет help.
Как минимум, следует прочитать
разделы Overview и Tutorial в AT90S Windows Workbench Help. Пытаться работать
без знаний из этих разделов ≈ бессмысленная трата времени.
Кроме того, рекомендуется посетить
на сайте фирмы Atmel раздел http://www.atmel.com/atmel/products/prod201.htm
и скачать оттуда ряд документов:
- AVR030: Getting Started With C for AVR (http://www.atmel.com/atmel/acrobat/doc1483.pdf). Хороший пример для быстрого начала работы. В качестве приложения к нему идет ftp://www.atmel.com/pub/atmel/avr030.zip ≈ сборник правильных .xcl-файлов для различных конфигураций микроконтроллеров.
- AVR032: Linker Command Files for the IAR ICCA90 Compiler (http://www.atmel.com/atmel/acrobat/doc1079.pdf). Здесь описывается, как составлять .xcl-файлы. Просто пересказ документации от IAR. Как приложение идет еще один пример с .xcl-файлами, но более ранний. Лучше пользоваться вариантом от Getting Started.
В этом разделе есть еще ряд документов,
посвященных работе с Си и заслуживающих внимательного ознакомления, из
которых особенно отмечу AVR035: Efficient C Coding for AVR (http://www.atmel.com/atmel/acrobat/doc1497.pdf).
Для эффективной работы следует
также взять с http://www.atmel.com/atmel/products/prod200.htm
последнюю редакцию 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 есть подборка практических рекомендаций: http://www.atmel.ru/AVR/AVR.htm
и http://www.atmel.ru/Spec/Spec.htm.
Ответы на вопросы по AVR, задаваемые
посетителями сайта ATMEL, можно найти на http://www.atmel.ru/FAQ/FAQ.htm.
Можно задать вопросы российским
представителям Atmel ≈ фирме ЭФО через конференцию Atmel на сайте http://www.efo.ru.
Большое число специалистов по
AVR регулярно общается и в конференции по микроконтроллерам на сайте Телесистем
≈ http://www.telesys.ru.
Vabriokped пишет... Если вы приняли решение получить мгновенный займ, вам следует определиться с организацией, где лучше взять займ онлайн. В наши дни не все МФО выдают срочные займы. Если вы стремитесь получить быстрые займы, вам надо просмотреть перечень МФО, которые предоставляют займы на хороших условиях.
15/12/2018 03:34:55 |
NafomaNuaby пишет... Неповторимая обувь в МО стоит прилично. Если вы стремитесь подобрать кроссы в столице, вам нужно изучить разные варианты в интернет-магазинах. Сейчас в сети очень удобно приобретать разные товары, в том числе и обувь.
18/12/2018 19:07:25 |
Ваш комментарий к статье | ||||