Главная arrow Программирование arrow ARM arrow ARM: записи чайника Wednesday, November 22 2017  
ГлавнаяКонтактыАдминистрированиеПрограммированиеСсылки
UK-flag-ico.png English Version
GERMAN-flag-ico.png Die deutsche Version
map.gif карта сайта
нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Поделиться:

ARM: записи чайника Версия для печати
Написал microsin   
12.12.2008

Здесь сырые записи, так что не судите строго.

20 ноября 2008
Что узнал нового?

1. Чип AT91SAM7X256 стоит всего 8 баксов, что ненамного дороже аналогичных ATmega.

2. В чипе AT91SAM7X256 применено ядро ARM7TDMI, которое характеризуется укороченными (Thumb) 16-битными командами. Сделано для экономии расхода памяти программ (с 32-битными инструкциями она улетает слишком быстро). Спохватились, что процессор стал слишком RISC-овый и сделали реверанс старым добрым CISC-процессорам (привет, 8086!). В режиме Thumb снизилось быстродействие, урезались возможности работы с регистрами.

3. Начал с того, что мне посоветовали - скачал доку на проц AT91SAM7X256, распечатал, засел за изучение. Поставил IAR Embedded Workbench IDE 5.3.0.622 (5.3.0.622) для ARM (далее просто IAR EW ARM). Создал новый C-проект HelloWorld и попытался поотлаживать прогу в симуляторе. В принципе, ничего пока принципально нового и хитрого.

-----------------------------------------------------------------------------------------
21 ноября 2008
Что узнал нового?

4. В IAR EW ARM есть возможность отлаживать проги в симуляторе, причем отладочный вывод можно сделать в окошко терминала (View -> Terminal I/O).

5. В чипе AT91SAM7X256 прорва внешних интерфейсов - 2 штуки USART, 2 SPI, TWI (I2C), debug UART, USB 2.0, Ethernet MAC.

6. 8 приоритетов прерываний, от 0 (самый низкий приоритет) до 7 (самый высокий). Приоритет задается в регистах AIC (Advanced Interrupt Controller), в специальном поле. Всего таких регистров 31, каждый соответствует своему источнику прерывания.

7. 256 кбайт памяти программ (flash), которая имеет 16 регионов (областей памяти), отдельно защищаемых от модификации.

8. Может питаться от одного напряжения 3.0..3.6 вольт (3.3 номинал). Есть внутренний регулятор напряжения на 100 ма для питания ядра и узлов тактирования.

9. Есть ножка ERASE с pull-down резистором, подача лог. 1 на длительность более 220 мс активизирует очистку всей памяти.

10. Имеется какой-то загадочный интерфейс EFC User Interface для установки конфигурационных бит (что-то типа фьюзов). Вроде там можно отключать BOD (Brown-out Detector, который отслеживает падение напряжения питания меньше допустимого значения, и если это случилось, то сбрасывает процессор), но делать это не рекомендуется во избежание проблем с flash-памятью.

11. Есть загрузчик SAM-BA SAM boot agent - менеджер загрузки программ во flash. Поддерживает загрузку по JTAG при частотах кварца 3..20 МГц или через USB, но только при частоте кварца 18.432 МГц.

12. Есть бит защиты программ, который однажды будучи установлен, запрещает чтение содержимого памяти программ. Этот бит можно сбросить только полной очисткой кристалла.

-----------------------------------------------------------------------------------------
22 ноября 2008
13. Ссылки по ARM, которые стоит посетить:
- Сравнительный анализ микроконтроллеров с ядром ARM http://www.gaw.ru/html.cgi/txt/publ/micros/arm.htm
- Справочное руководство по процессору ARM7TDMI http://www.gaw.ru/html.cgi/txt/doc/micros/arm/arh_7dtmi/index.htm
- 32-разрядные микроконтроллеры AT91SAM7S http://www.atmel.ru/Articles/Atmel32.htm
- Отладочные платы Olimex http://www.olimex.com/dev/index.html
- "Осваиваем AT91SAM7" или "Для тех, кому ресурсов AVR уже не хватает" http://sam7-ex256.narod.ru/ixbt.html
- CrossWorks for ARM - среда разработки, платная http://www.rowley.co.uk/crossworks/Downloads.htm.
- "Для тех, кому ресурсов AVR уже не хватает" на iXBT http://forum.ixbt.com/topic.cgi?id=48:5248
- ARM WiKi http://www.open-research.org.uk/ARMuC/

14. Отладчики JTAG.
- MT-Link - JTAG отладчик, российский (Питер) функциональный аналог SEGGER J-Link, подключаемый по USB. Совместим с IAR.
http://www.radioradar.net/news/electronics_news/2005-10-27_09-00-57.html
[Цены] В Митракон стоит 2983.49, $82 в ТерраЭлектронике. В Дельта Электроника (тел. 9701050) стоит 2956,66 руб. База Электроники (тел. 9375929) стоит 3194,09 руб. ТерраЭлектроника (тел. 2217804) стоит 2305 руб [$82] (ул. Дербеневская д.1, корпус 1, подъезд 23).

- ARM-JTAG в Чип-И-Дип стоит 872 рубля (http://www.chip-dip.ru/product0/446211127.aspx). Это аналог WIGGLER. Имеет какие-то ограничения в работе, лучше не покупать.

- J-LINK стоит 8500 рублей (в Чип-И-Дип он стоит 9500 рублей http://www.chip-dip.ru/product0/11688589.aspx).

- ULINK2 есть в компании SIMECS, стоит 167 евро - http://www.microcontroller.ru/catalog2.php?item_id=2412. Правда, непонятно, насколько он совместим с IAR EW.

- JTAG.LPT адаптер, известный под названием wiggler. Работает с ROWLEY ASSOCIATES - CrossWorks for ARM. Можно спаять самому, можно купить его аналог от Olimex под названием ARM-JTAG (http://www.rowley.co.uk/crossworks/Downloads.htm).

- SEGGER J-Link, http://www.segger.com/jlink.html - совместимый с IAR EW адаптер USB-JTAG.

15. Отладочные платы.
Отладочная плата, которую стоит купить -  SAM7-EX256 от компании Olimex http://www.olimex.com/dev/sam7-ex256.html, http://sam7-ex256.narod.ru/
Она стоит 6500 рублей в Чип-И-Дип, 4360 в Терраэлектроника. Для полноценной работы требуется JTAG-эмулятор: ARM-JTAG (OLIMEX), J-LINK (IAR), ULINK (KEIL).

Отладочная плата от Atmel AT91SAM7X-EK стоит $390 в Терраэлектроника (http://www.terraelectronica.ru/catalog_info.php?CODE=219151&Name=AT91SAM7X-EK&Razdel=967&TableName=class_19_2_26_6&Open=1). В Чип-И-Дип она под заказ 13500 рублей.
  
Отличие плат AT91SAM7X-EK (Atmel) от SAM7-EX256 (Olimex)
1. SAM7-EX256 дешевле (6500 р. в Чип-И-Дип, 4360 в Терраэлектроника [$141,25]), чем AT91SAM7X-EK (13500 р.). Все продавцы возят обычно только SAM7-EX256.

[Плюсы SAM7-EX256]
- хорошая цена
- плата компактная
- в комплекте есть цветной графический LCD индикатор NOKIA6610 (поганый индикатор, конечно, но что вы хотели за такие деньги?)
- на плате имеется распаянный интерфейс CAN, выведенный на разъем DB9
- разведен чуствительный усилитель для микрофона, есть аналоговый спикер с усилителем, выход на наушники.
- просто организован USB-вход (без специального чипа)
- плата существенно проще

[Минусы SAM7-EX256]
- только один разъем RS232 (DB9), который можно переключить либо на USART, либо на DBGU
- нет индикационных светодиодов
- нет макетного поля
- отсутствует документация (есть только принциальная схема)

[Плюсы AT91SAM7X-EK]
- есть 2 отдельных порта RS232 (DB9), один подключен на USART, другой на DBGU
- есть 5 индикационных светодиодов
- есть макетное поле
- все выводы процессора выведены на внешний коннектор
- плата гибко конфигурируется перемычками
- плата отлично документирована
- в IAR EW специально под эту плату есть много примеров

[Минусы AT91SAM7X-EK]
- дорогая
- нет в комплекте графического LCD индикатора
- не распаян CAN интерфейс
- аналоговый выход низкочастотный (только для очень низких частот и постоянного напряжения). Аналоговый вход низкочуствительный.
- все продавцы возят обычно только SAM7-EX256, а AT91SAM7X-EK только под заказ

Вывод. Принимая в виду цену, лучше все-таки купить плату SAM7-EX256. Возможностями она ненамного хуже AT91SAM7X-EK.

-----------------------------------------------------------------------------------------
23 ноября 2008
16. Отличия чипов AT91SAM7X256 и AT91SAM7S256
- эти чипы имеют одинаковые ядра ARM7TDMI.
- AT91SAM7S256 имеет меньше ножек (64), чем AT91SAM7X256 (100).
- у AT91SAM7S256 нет портов Ethernet и CAN.
- у AT91SAM7S256 один Parallel Input/Output Controller (PIOA), а у AT91SAM7X256 их два.
- у AT91SAM7S256 один Serial Peripheral Interfaces (SPI), а у AT91SAM7X256 их два.
- 11 DMA-каналов у AT91SAM7S256 и 13 у AT91SAM7X256

-----------------------------------------------------------------------------------------
25 ноября 2008
17. Отличия чипов AT91SAM7X256 и AT91SAM7XC256
- эти чипы имеют одинаковые ядра ARM7TDMI.
- AT91SAM7X256 имеет 13 каналов DMA у Peripheral DMA Controller (PDC), а AT91SAM7XC256 - 17 каналов
- только AT91SAM7XC256 имеет Advanced Encryption System (AES) и Triple Data Encryption System (TDES)
- чипы AT91SAM7XC256 просто так не купить из-за экспортных ограничений на криптографию.

18. Для всех чипов AT91SAM7X лучше применять кварц 18.432 MHz, только такая частота обеспечивает работу шины USB 2.0.
Чипы AT91SAM7X имеют встроенный генератор RC 32 KHz (для него не нужны внешние элементы, и частота имеет значительную погрешность - может быть от 22 до 42 кГц), от которого тактируется внутренняя логика и таймер PIT (Periodic Interval Timer).

19. Установка и первые опыты с MT-LINK.
Купил в Терраэлектронике MT-LINK. Драйверов не дали, консультант ничего конкретного про него не рассказал - как установить, начать работать - "смотрите в Интернете!" Принес домой, воткнул в домашний комп через USB. На задней стеночке MT-LINK замигали светодиодики (красный и зеленый), компьютер обнаружил устройство J-Link и затребовал драйвера. В комплекте не было никаких драйверов, поэтому стал искать в Интернете. Нашел на сайте http://www.segger.com/download_jlink.html, скачал файл Setup_JLinkARM_V396d.zip (Software and documentation pack V3.96d  [7075 kb]). После установки знак вопросика на устройстве J-Link пропал, и в папке Universal Serial Bus controllers появилось устройство J-Link driver. После этого светодиодики замигали по-другому. Зеленый светодиод загорелся постоянно, а красный мигает коротко с интервалом примерно секунда. При установке на компьютере, где ранее был установлен IAR EW ARM, пакет установки J-Link обнаружил этот факт, и предложил обновить JLinkARM.dll в папке "c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\bin", что и сделал.

Иногда при подключении J-Link драйвер не находится, и тогда его нужно указать из папки c:\Program Files\SEGGER\JLinkARM_V396d\USBDriver\x86\.

После установки в папке SEGGER\J-Link ARM V3.96d обнаружились следующие программы:

J-Flash ARM
 Эта программа позволяет манипулировать flash-памятью микроконтроллера ARM (работает как программатор) через J-LINK (MT-LINK). Я подключил к MT-LINK через JTAG купленную плату SAM7-EX256(на ней стоит проц AT91SAM7X256) и попытался считать её память. Сразу у меня ничего не заработало. Чтобы заработало, нужно сделать следующие настройки - в меню программы J-Flash ARM заходим в Options -> Project settings..., на закладке CPU выбираем радиокнопку Device и из выпадающего списка выбираем наш проц Atmel AT91SAM7X256. На закладке Production на всякий случай уберем галочки Erase и Program, чтобы не испортить прошивку платы SAM7-EX256. Жмем кнопку OK. Программа позволяет прошивать память только тогда, когда установлена лицензия (см. п. 30, rdikeygen).

J-Link Commander
Эта программа предоставляет консольный интерфейс к J-Link (MT-LINK).

J-Link DLL Updater
Эта программа проверяет версию файла JLinkARM.dll (интерфейс к J-Link в среде разработки IAR).

J-Link GDB Server
Пока не разобрался, зачем это надо и как использовать.

J-Link RDI Config
Основной конфигуратор J-Link (MT-LINK).

J-Link TCP-IP Server
Как применять пока не понял. Вроде для поддержки удаленной отладки через сеть.

J-Mem
Просмотрщик всего адресного пространства проца ARM (0x00000000..0xFFFFFFFF).

Для тех, кто запутался с настройками, выкладываю скриншоты программ управления MT-LINK (в таком состоянии нормально запускается отладка как во flash, так и в sram).

Режим отладчика J-Link/J-Trace

 J-LinkControlPanel01.JPG J-LinkControlPanel02.JPG   J-LinkControlPanel03.JPG  J-LinkControlPanel04.JPG J-LinkControlPanel05.JPG   J-LinkControlPanel06.JPG  J-LinkControlPanel07.JPG

Режим отладчика RDI

 J-LinkControlPanelRDI01.JPG J-LinkControlPanelRDI02.JPG  J-LinkControlPanelRDI03.JPG   J-LinkControlPanelRDI04.JPG  J-LinkControlPanelRDI05.JPG  J-LinkControlPanelRDI06.JPG J-LinkControlPanelRDI07.JPG 
 J-LinkControlPanelRDI08.JPG  J-LinkControlPanelRDI09.JPG  J-LinkControlPanelRDI10.JPG  J-LinkControlPanelRDI11.JPG  J-LinkControlPanelRDI12.JPG  J-LinkControlPanelRDI13.JPG  J-LinkControlPanelRDI14.JPG
 J-LinkControlPanelRDI15.JPG  J-LinkControlPanelRDI16.JPG  J-LinkControlPanelRDI17.JPG  J-LinkControlPanelRDI18.JPG  J-LinkControlPanelRDI19.JPG    

20. LIVE WATCH AND USE OF DCC (просмотр и модификация памяти во время работы программы). Для этого в проект надо добавить файлы (они все находятся в каталоге c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\src\debugger\DCC\) DCC_Write.c, JLINKDCC_HandleDataAbort.s, JLINKDCC_Process.c, а также в текст программы (где находится тело main) вставить #include <JLINKDCC.h> и в тело циклов вставить вызов функции DCC_Process().

-----------------------------------------------------------------------------------------
27 ноября 2008
[Разборки с тактовым генератором]

21. Когда пользователь включает главный генератор (Main Oscillator), пользователь должен инициализировать его счетчик величиной, соответствующей времени запуска генератора. Это время запуска зависит от частоты кварца, подключенного к главному генератору. Когда бит MOSCEN и OSCOUNT записаны в CKGR_MOR, чтобы включить главный генератор, бит MOSCS в PMC_SR (Status Register) очищается, и счетчик запускает счет в обратном порядке от частоты медленного тактового генератора, поделенной на разделенном на 8, начиная от значения OSCOUNT. Так как значение OSCOUNT закодировано с 8 битами, максимальное время запуска - приблизительно 62 ms. Когда счетчик достигает 0, бит MOSCS устанавливается, что указывает на окончание стабилизации частоты главного генератора. Установка бита MOSCS в PMC_IMR может вызвать прерывание на процессор (стр. 176, Clock Generator\Main Oscillator Control).

22. Есть способ определить частоту кварца с помощью Main Clock frequency counter (см. Main Clock Frequency Counter на стр. 176). Когда бит MAINRDY в регистре CKGR_MCFR (Main Clock Frequency Register) установлен, поле MAINF регистра CKGR_MCFR показывает, до какого числа счетчик успел досчитать за 16 периодов SLCK. Конечно же, значение тактовой частоты определяется неточно и-за погрешности частоты внутреннего генератора RC.

23. Можно отключить кварц и подать внешнюю тактовую частоту на ножку XIN. Для того, чтобы это работало правильно, нужно в регистре CKGR_MOR установить бит OSCBYPASS в 1, а бит MOSCEN сбросить в 0.

24. Когда поле делителя (DIV) установлено в 0, выход делителя и выход PLL дают непрерывный сигнал на уровне 0. После сброса каждое поле DIV устанавливается в 0, таким образом соответствующая входная тактовая PLL устанавливается в 0. PLL позволяет умножить выходную частоту делителя. PLLCK (тактовая частота, выходящая из PLL) имеет частоту, которая зависит от соответствующей исходной частоты сигнала (MAINCK) и параметров DIV и MUL. Множитель, прикладываемы к входной частоте, равен (MUL + 1)/DIV. Когда в MUL записан 0, PLL запрещен и потребляемая мощность уменьшается. Включить PLL можно, записав в поле MUL величину, бОльшую 0.

Независимо от того, была ли PLL снова разрешена, или были изменены её параметры, бит LOCK в регистре PMC_SR автоматически очищается. Величины, записанные в поле PLLCOUNT регистра CKGR_PLLR загружаются в счетчик PLL. Затем счетчик PLL декрементируется частотой SLCK, пока не достигнет величины 0. В этот момент бит LOCK в PMC_SR устанавливается и может вызвать прерывание для процессора. Пользователь должен загрузить количество циклов SLCK в поле PLLCOUNT, требуемое для перекрытия времени переходного процесса PLL. Начальное состояние PLL и его целевой частоты может быть вычислено, используя специальный инструмент, предоставляемый Atmel (см. http://atmel.com/dyn/resources/prod_documents/AT91SAM_pll.htm).

Резюме. Можно, конечно же, разбираться во всех этих премудростях, а можно поступить проще - взять готовый пример кода. Примеры находятся в c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91sam7x-ek\ и в c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib.

25. Для расчета параметров фильтра второго порядка PLL (PLLRC ножка для подключения RC-цепочки к узлу PLL) используется калькулятор ATMEL_PLL_LFT_Filter_CALCULATOR_AT91_2v71.zip, написанный на основе листа Excel (http://atmel.com/dyn/resources/prod_documents/PLL_LFT_filter_CALCULATOR_AT91.zip).

26. Power Management Controller (PMC).
Нужен для управления тактовыми частотами как ядра процессора, так и его периферии, что влияет на энергопотребление. Вырабатывает следующие таковые частоты:
- MCK Master Clock, основная частота, подаваемая на те модули процессора, которые работают постоянно (не отключаясь). Может быть запрограммирована на частоты от нескольких сотен герц до максимальной тактовой частоты устройства. Вырабатывается модулем PMC, при этом могут в качестве исходных могут браться SLCK, MAINCK, PLLCK.
- PCK Processor Clock - отключается, когда процессор переходит в idle mode. Вырабатывается модулем PMC.
- Peripheral Clocks тактовая частота, подаваемая на встроенную периферию (USART, SSC, SPI, TWI, TC, MCI, и т. п.). Обычно это MCK, но управляется отдельно. Вырабатывается модулем PMC.
- UDPCK USB Device Port Clock. Вырабатывается модулем PMC.
- Programmable Clock Outputs, тактовые сигналы, которые можно выводить на ножках PCKx. PMC (Power Management Controller) управляет 4 сигналами, программируемыми на выход ножек PCKx. Каждый сигнал может быть независимо запрограммирован через регистры PMC_PCKx. Имеются также регистры PMC_SCER, PMC_SCDR, PMC_SCSR. Подробнее см. стр. 181, Programmable Clock Output Controller.

27. Выбор частоты MCK происходит путем записи в поле CSS регистра PMC_MCKR необходимого значения. Далее выбранная частота поступает на прескалер, который управляется полем PRES того же регистра PMC_MCKR. Всякий раз, когда в регистр PMC_MCKR записывается новое значение, определяющее изменение MCK, в регистре PMC_SR обнуляется бит MCKRDY, и далее читается как 0, пока частота MCK устаканивается. После этого бит MCKRDY устанавливается и это событие может вызывать прерывание процессора. Это полезно, когда происходит переключение с высокой тактовой частоты на более низкую, чтобы приложение могло корректно определить момент реального изменения тактовой частоты.

28. Частота PCK (Processor Clock) может быть запрещена записью в регистр PMC_SCDR (System Clock Disable Register). Статус этой частоты можно прочитать в регистре PMC_SCSR. PCK разрешается при сбросе, и всегда автоматически разрешается при любом разрешенном прерывании (происходит выход процессора из режима Idle). При запрете PCK перед входом в режим Idle текущая инструкция завершает свое выполнение (перед тем, как такты остановятся), однако это не отменяет передач данных между другими мастерами на системной шине.

-----------------------------------------------------------------------------------------
29 ноября 2008
29. На форумах хорошо отзываются о связке CrossWorks + Wiggler - нет никаких проблем даже без специальных мер.

30. Мои приключения с MT-LINK.
На всех форумах мною было прочитано, что это полный аналог J-Link. Выставил в настройках проекта Debugger -> закладка Setup -> Driver -> J-Link/J-Trace, но так у меня ничего не заработало - при запуске отладки не работали шаги по исходному коду, шаги работали только по дизассемблированному коду (смена установок типа точек останова Auto, Hardware, Software ничего не давали: Debugger -> J-Link/J-Trace -> закладка Breakpoints -> Default breakpoint type), в окне Log выдавались предупреждения и ошибки:
Sat Nov 29 16:40:27 2008: DLL version: V3.86g, compiled Jul 11 2008 10:48:30
Sat Nov 29 16:40:27 2008: Firmware: J-Link compiled Jul 30 2008 11:24:37 ARM Rev.5
Sat Nov 29 16:40:27 2008: JTAG speed is initially set to: 32 kHz
Sat Nov 29 16:40:27 2008: TotalIRLen = 4, IRPrint = 0x01
Sat Nov 29 16:40:27 2008: Hardware reset with strategy 8 was performed
Sat Nov 29 16:40:27 2008: Initial reset was performed
Sat Nov 29 16:40:27 2008: J-Link found 1 JTAG device(s). ARM core Id: 3F0F0F0F ARM7
Sat Nov 29 16:40:27 2008: Device at TAP0 selected
Sat Nov 29 16:40:27 2008: JLINK command: ProjectFile = C:\asm\HelloWorld\settings\hw_Debug.jlink, return = 0
Sat Nov 29 16:40:27 2008: JLINK command: device = AT91SAM7X256, return = 0
Sat Nov 29 16:40:27 2008: RTCK seems to be bridged with TCK
Sat Nov 29 16:40:27 2008: Auto JTAG speed: 8000 kHz
Sat Nov 29 16:40:28 2008: 9090 bytes downloaded (13.21 Kbytes/sec)
Sat Nov 29 16:40:28 2008: Loaded debugee: C:\asm\HelloWorld\Debug\Exe\hw.out
Sat Nov 29 16:40:28 2008: Target reset
Sat Nov 29 16:40:52 2008: The stack 'CSTACK' is filled to 100% (8192 bytes used out of 8192). The warning threshold is set to 90.%
Sat Nov 29 16:40:52 2008: The stack 'IRQ_STACK' is filled to 100% (256 bytes used out of 256). The warning threshold is set to 90.%
Sat Nov 29 16:40:52 2008: The stack 'FIQ_STACK' is filled to 100% (256 bytes used out of 256). The warning threshold is set to 90.%
Sat Nov 29 16:40:52 2008: The stack pointer for stack 'CSTACK' (currently 0x00000000) is outside the stack range (0x00100000 to 0x00102000)
Sat Nov 29 16:40:52 2008: The stack pointer for stack 'IRQ_STACK' (currently 0x00000000) is outside the stack range (0x00102000 to 0x00102100)
Sat Nov 29 16:40:52 2008: The stack pointer for stack 'FIQ_STACK' (currently 0x00000000) is outside the stack range (0x00102100 to 0x00102200)
Sat Nov 29 16:40:58 2008: The stack 'CSTACK' is filled to 100% (8192 bytes used out of 8192). The warning threshold is set to 90.%
Sat Nov 29 16:40:58 2008: The stack 'IRQ_STACK' is filled to 100% (256 bytes used out of 256). The warning threshold is set to 90.%
Sat Nov 29 16:40:58 2008: The stack 'FIQ_STACK' is filled to 100% (256 bytes used out of 256). The warning threshold is set to 90.%
Sat Nov 29 16:40:58 2008: The stack pointer for stack 'CSTACK' (currently 0x00000000) is outside the stack range (0x00100000 to 0x00102000)
Sat Nov 29 16:40:58 2008: The stack pointer for stack 'IRQ_STACK' (currently 0x00000000) is outside the stack range (0x00102000 to 0x00102100)
Sat Nov 29 16:40:58 2008: The stack pointer for stack 'FIQ_STACK' (currently 0x00000000) is outside the stack range (0x00102100 to 0x00102200)
Sat Nov 29 16:41:00 2008: The stack 'CSTACK' is filled to 100% (8192 bytes used out of 8192). The warning threshold is set to 90.%
Sat Nov 29 16:41:00 2008: The stack 'IRQ_STACK' is filled to 100% (256 bytes used out of 256). The warning threshold is set to 90.%
Sat Nov 29 16:41:00 2008: The stack 'FIQ_STACK' is filled to 100% (256 bytes used out of 256). The warning threshold is set to 90.%
Sat Nov 29 16:41:00 2008: The stack pointer for stack 'CSTACK' (currently 0x00000000) is outside the stack range (0x00100000 to 0x00102000)
Sat Nov 29 16:41:00 2008: The stack pointer for stack 'IRQ_STACK' (currently 0x00000000) is outside the stack range (0x00102000 to 0x00102100)
Sat Nov 29 16:41:00 2008: The stack pointer for stack 'FIQ_STACK' (currently 0x00000000) is outside the stack range (0x00102100 to 0x00102200)

Попробовал включить драйвер RDI, как было указано в инструкции от SEGGER (JLinkRDI_rev7.pdf, JTAG RDI Interface for J-Link ARM Emulator -> Using J-Link RDI with different debuggers -> IAR Embedded Workbench IDE) - указал путь к драйверу на c:\Program Files\SEGGER\JLinkARM_V396d\JLinkRDI.dll (перед этим обязательно надо установить ПО для J-Link от SEGGER, см. пункт 19). После этого вывалилось "Sorry, no valid license for RDI found. J-Link S/N is 11111117. Please contact SEGGER Microcontroller (http://www.segger.com/, sales@segger.com) to obtain a license. Time limited trial versions are available." с кнопкой "Add License". Беда вылечилась поиском в Интернете rdikeygen.rar (rdikeygen.exe), его запуском и вводом лицензий (RDI, FlashBP, FlashDownload, J-Flash). После этого нормально заработал прошивальщик J-Flash ARM (см. п. 19).

Однако отладка все ещё не работала. Оказывается, для того, чтобы она заработала, необходимо подключить специальные модули для начального конфигурирования процессора. В моих проектах, которые я делал в IAR "с нуля", этого не было. Проще было взять готовый пример от Atmel (один из тех, что лежат в c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91sam7x-ek\), подредактировать его и работать как со своим проектом. Как перенести пример проекта в другую папку и дать ему произвольное имя, читайте здесь.

-----------------------------------------------------------------------------------------
30 ноября 2008
31. USB Clock Controller
Источником тактов для USB (UDPCK) является PLL. Если используется USB, пользователь должен запрограммировать PLL на генерацию 48 МГц, 96 МГц или 192 МГц с точностью ± 0.25% (выбор зависит от бит USBDIV в CKGR_PLLR).
 Когда частота PLL стабильна, другими словами, бит LOCK установлен, то такты USB (UDPCK) могут быть разрешены путем установки UDP бита PMC_SCER (System Clock Enable Register). Для сохранения мощности питания, когда USB не используется, может быть также установлен бит UDP в PMC_SCDR (System Clock Disable Register), он выключает активность UDPCK. Бит UDP регистра PMC_SCSR (System Clock Status Register) показывает текущее состояние тактов UDPCK. Порт USB требует одновременных сигналов 48 МГц и сигнала MCK (MCK управляется через Master Clock Controller).

32. Peripheral Clock Controller. Управляет тактами периферийных устройств, которые задаются соответствующими битами регистров PMC_PCER (Peripheral Clock Enable Register), PMC_PCDR (Peripheral Clock Disable Register). Статус тактов читается из PMC_PCSR (Peripheral Clock Status Register).

33. Последовательность программирования тактового генератора.
1. Разрешаем Main Oscillator - установка бита MOSCEN регистра CKGR_MOR (Main Oscillator Register). В некоторых случаях полезно задать время старта путем записи данных в поле OSCOUNT регистра CKGR_MOR. Как только регистр CKGR_MOR сконфигурирован, ждем, пока установится поле MOSCS регистра PMC_SR - либо постоянным опросом, либо по прерыванию (связанное с MOSCS прерывание должно быть разрешено в регистре PMC_IER).
Пример кода:
write_register(CKGR_MOR,0x00000701)
Start Up Time = 8 * OSCOUNT / SLCK = 56 Slow Clock Cycles (SLCK).
В этом примере main oscillator будет разрешен (MOSCS установится) после 56 Slow Clock Cycles (SLCK).
2. Необязательный шаг - проверка тактовой частоты MCK. Иногда необходимо точно измерить частоту генератора, что можно сделать с помощью регистра CKGR_MCFR. Как только поле MAINRDY регистра CKGR_MCFR установлено, пользователь может прочитать поле MAINF регистра CKGR_MCFR - в нем записано количество циклов MCK, укладывающееся в 16 циклов SLCK.
3. Установка PLL и делителя. Все параметры, необходимые для конфигурирования PLL, находятся в регистре CKGR_PLLR.
Поле DIV - для управления делителем, может ыбть запрограммировано величиной 0..255 (коэффициент деления частоты). По умолчанию записан 0, что означает отключение делителя.
Поле OUT используется для выбора диапазона частоты PLL B.
Поле MUL - множитель PLL (0..2047). Если MUL=0, то PLL отключена, иначе выходная частота PLL равна входной для PLL частоте умноженной на (MUL + 1).
Поле PLLCOUNT указывает количество циклов SLCK, проходящее перед тем, как бит LOCK регистра PMC_SR установится (после изменения параметров регистра CKGR_PLLR).

Можно со всем этим не заморачиваться, если воспользоваться готовыми примерами от Atmel (c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91sam7x-ek\).

-----------------------------------------------------------------------------------------
2 декабря 2008
34. Умный человек подсказал, почему у меня не заработал проект HelloWorld. Оказывается:
- в проекте должны присутствовать файлы Cstartup.s79 и Cstartup_SAM7.c
- в проекте должны присутствовать файлы типа at91SAM7X256_FLASH.icf (для 5-й версии) и at91SAM7X_256_FLASH.xcl (для 4-й версии). Ссылка на них присутствует в опциях проекта, категория Linker, закладка Config. Мне посоветовали взять за основу готовый пример и не париться, что я и с успехом проделал.

35. Иногда при остановке отладки выскакивает ошибка: "Failed to load the component "C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\common\plugins\Profiling\Profiling.dll"
The file may be missing or corrupt.
More info: "LoadLibrary failed"."
Так и не разобрался, что за беда. Решил просто забить на эти сообщения.

А иногда выскакивает похожая ошибка (тоже в режиме RDI):
Failed to load the component "C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\bin\armlibsupport.dll"
The file may be missing or corrupt.
More info: "LoadLibrary failed".

36. Регистры AT91SAM7X256 32-разрядные, используются в ассемблерных мнемониках как источник и назначение операндов.
R0..R7 регистры, не принадлежащие банкам (unbanked registers). Это значит, что в любом из режимов процессора они всегда доступны и указывают на те же самые физические регистры.
R8..R14 - banked registers. Это значит, что для каждого режима процессора (User and System Mode, Supervisor Mode, Abort Mode, Undefined Mode, Interrupt Mode, Fast Interrupt Mode) имеется отдельный набор регистров R8..R14.
В качестве указателя стека (SP) служит регистр R13. Этот стек используется только для программ, не для хранения адреса возврата из подпрограммы (!).
LR Link Register - R14. Этот регистр служит для сохранения адреса возврата (для R15) при вызове подпрограмм.
PC Program Counter - R15. Он указывает адрес следующей выполняемой команды. В режиме Thumb счетчик увеличивается на 2 с каждой командой, а в режиме ARM (более быстрый режим) - на 4.

37. При смене конфигурационного файла линкера (Project -> Options -> Linker -> Linker configuration file -> ставим галочку Override default, меняем $TOOLKIT_DIR$\config\generic.icf на $TOOLKIT_DIR$\config\at91SAM7X256_FLASH.icf) Failed to load the component "C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\bin\armlibsupport.dll"
The file may be missing or corrupt.
More info: "LoadLibrary failed".

38. Как сделать рабочий пустой проект в IAR Embedded Workbench for ARM
 Создать новый проект для IAR EW for ARM, который будет загружаться в отлаживаемое устройство с помощью JTAG-отладчика MT-LINK (питерский аналог SEGGER J-Link) не такая тривиальная процедура, как, например, в IAR EW для AVR. Дело все в том, что процессор ARM требует предварительной инициализации перед запуском программы (настройка тактового генератора, маппинг памяти и т. д.). Эту инициализацию необходимо настроить в проекте. Здесь рассматривается пошаговый процесс настройки на примере процессора AT91SAM7X256 (он у меня работал в этом примере на отладочной плате Olimex SAM7-EX256, к которой был подключен MT-LINK) и IAR EW ARM версии 5.3. Предполагается, что драйвера и ПО для MT-LINK Вы уже установили, и добавили для этого необходимые лицензии (как это сделать, описано в статье ...). Итак, начнем.
 
1. Создаем папку для нашего проекта. Пусть это будет папка c:\asm\HelloWorld.
2. Запускаем IAR EW ARM. Идем в меню Project -> Create New Project..., в дереве Project templates: выбираем C -> main, жмем OK.
 картинка01
3. В диалоговом окне выбираем имя для проекта hw, жмем OK.
 картинка02
4. Подредактируем текст модуля main, добавив туда бесконечный цикл. Должно получиться примерно как на рисунке.
 картинка03
5. Теперь можно откомпилировать проект в меню Project -> Rebuild All. Перед компилированием у Вас запросят имя для файла Workspace. Введем, не заморачиваясь, снова hw и нажмем OK. В область Build выведется информация об успешной компиляции:
Building configuration: hw - Debug
Updating build tree...
 
2  file(s) deleted.
Updating build tree...
main.c 
Linking
 
Total number of errors: 0
Total number of warnings: 0
6. Теперь можно проект поотлаживать, выбрав в меню Project -> Download and Debug (Ctrl+D), но это не очень интересно, так как проект по умолчанию запустит отладку в симуляторе (программном эмуляторе работы процессора). Наша цель - чтобы программа заработала в разрабатываемом нами устройстве. Для этого надо настроить опции проекта.
7. Выберите из выпадающего списка под словом Workspace конфигурацию Debug, и в дереве проекта выберите самую первую строку hw - Debug.
 картинка04
Выберите в меню Project -> Options... (Alt+F7). Появится окно настроек проекта.
8. General Options -> закладка Target, выберите Device Atmel AT91SAM7X256
 картинка05
9. Для упрощения отладки выберите C/C++ Compiler -> закладка Optimizations -> None (отключена оптимизация кода).
 картинка06
   Жмем OK.
10. Теперь нам осталось сделать самое важное - выбрать настроечный файл для линкера. Тут у меня поначалу от незнания были грабли. Без этого файла аппаратный отладчик MT-LINK не работает. Создадим для начала 2 добавочные конфигурации для проекта, которые позволят нам отлаживать программу как в RAM (отладка кода в RAM экономит ресурс кристалла, так как мы не меняем содержимое flash), так и во FLASH. Заходим в меню Project -> Edit Configurations..., там сейчас пока 2 конфигурации - Debug
и Release. Жмем кнопку New..., впечатываем имя Debug in RAM, жмем кнопку OK. Таким же образом создаем еще конфигурацию Debug in FLASH. В результате получим 4 конфигурации в проекте.
 картинка07
Жмем кнопку OK. Созданные конфигурации доступны для выбора в выпадающем списке Workspace.
11. Теперь найдем необходимый настроечный файл для линкера, он имеет расширение *.icf. Какой файл использовать, указывается в настройках проекта - меню Project -> Options... -> Linker -> закладка Config -> Linker configuration file, галочка Override default. По умолчанию предлагается использовать файл c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\config\generic.icf, но нам этот файл не подходит. Нужный файл можно найти, запустив поиск по расширению *.icf. Я нашел в примерах 2 файла - AT91SAM7X256_RAM.icf и at91SAM7X256_FLASH.icf, и скопировал их в папку c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\config\.
Выбираем из выпадающего списка Workspace конфигурацию Debug in RAM, идем в меню Project -> Options... -> Linker -> закладка Config -> Linker configuration file, ставим галочку Override default, кнопкой ... выбираем файл AT91SAM7X256_RAM.icf, жмем OK.
 картинка08
Таким же образом выбираем файл at91SAM7X256_FLASH.icf для конфигурации Debug in FLASH.
12. Теперь осталось выбрать тип драйвера отладчика для MT-LINK, для которого есть 2 варианта драйвера, J-Link/J-Trace и RDI. Сначала выберем J-Link/J-Trace, и рассмотрим процесс настройки на конфигурации Debug in FLASH (для конфигурации Debug in RAM все делается аналогично). Итак, выбираем конфигурацию Debug in FLASH, меню Project -> Options... -> Debugger -> закладка Setup -> из выпадающего списка выбираем J-Link/J-Trace.
 картинка09
Далее в дереве Category слева выбираем J-Link/J-Trace, на закладке Startup выбираем Reset -> Hardware, Atmel AT91SAM7.
 картинка10
Жмем OK.
13. Выбираем в меню Project -> Download and Debug, запустится окно отладчика C-SPY.
 картинка11
Теперь можно отлаживать программу по шагам, надимая клавишу F10.
14. В трее можно при этом видет значок драйвера J-Link.
 картинка12
 Двойным щелчком на нем можно вызвать окно настроек драйвера.
 картинка13
15. Настроим теперь работу MT-LINK через драйвер RDI, в конфигурации Debug in RAM (чисто для примера, можно выбрать и Debug in FLASH). Итак,
выбираем конфигурацию Debug in RAM, меню Project -> Options... -> Debugger -> закладка Setup -> из выпадающего списка выбираем RDI, Device description file ставим галочку Override default, выбираем файл $TOOLKIT_DIR$\config\debugger\Atmel\ioat91sam7x256.ddf. На закладке Download ставим галочки Verify download (галка Use flash loader(s) стоять не должна!). Далее в дереве Category слева выбираем RDI, уазываем путь до DLL драйвера Manufacturer RDI driver - C:\Program Files\SEGGER\JLinkARM_V396d\JLinkRDI.dll, ставим галочку Allow hardware reset. Жмем OK.
16. В появившемся меню RDI выбираем Configure..., на закладке Flash выбираем Enable flash programming.
 картинка14
 На закладке Breakpoints выбираем Use software breakpoints и Use flash breakpoints.
 картинка15
 Жмем OK.
17. Настройка отладчика в режиме RDI завершена. Можно запускать отладку. Драйвер RDI лучше тем, что обеспечивает неограниченное количество точек останова (если выбрать тип Software breakpoint).

39. Ассемблерный код запуска приложения находится по умолчанию в файлах c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\src\lib\arm\cstartup.s и c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\src\lib\low_level_init.c.
Чтобы изменить поведение инициализации по умолчанию, рекомендуется на править эти файлы, а создать свою версию функции
__interwork int __low_level_init(void)

40. Ошибки при компиляции файла dbgu.c:
Error[Pe020]: identifier "FILE" is undefined c:\asm\HelloWorld\dbgu.c 107
Error[Pe020]: identifier "stdout" is undefined c:\asm\HelloWorld\dbgu.c 109
Error[Pe020]: identifier "stderr" is undefined c:\asm\HelloWorld\dbgu.c 109
Error[Pe020]: identifier "FILE" is undefined c:\asm\HelloWorld\dbgu.c 128
Error[Pe020]: identifier "stdout" is undefined c:\asm\HelloWorld\dbgu.c 153

Нужно выбрать полную конфигурацию библиотеки: Project -> Options... -> General Options -> закладка Library Configuration -> в выпадающем списке Library выбрать Full.

-----------------------------------------------------------------------------------------
3 декабря 2008
41. Учимся работать с тактовым генератором.
По умолчанию после сброса чип AT91SAM7X256 работает от медленного тактового генератора (22..42 кГц). На выводе XOUT (ножка 98) тактов нет. Чтобы генератор заработал, нужно предпринять следующие действия (в данном примере мы рассмотрим типичную инициализацию чипа для работы с USB, кварц 18.432 МГц).

1. В модуле main создадим функцию __interwork int __low_level_init(void). Весь код инициализации будем писать в ней.
2. Создадим указатели на контроллер управления питанием, на контроллер сброса RSRC, и простую процедуру задержки.
#include "include/ioat91sam7x256.h"
AT91PS_PMC    pPMC     = AT91C_BASE_PMC;    //указатель на Power Management Controller
AT91PS_RSTC   m_pRSTC  = AT91C_BASE_RSTC;   //указатель на контроллер сброса
void Delay (unsigned long a) { while (--a!=0); }

2. Разрешаем сброс.
  m_pRSTC->RSTC_RCR = 0xA5000008; //разрешаем появление на ножке NRST лог. 0 (что означает сброс)
  m_pRSTC->RSTC_RMR = 0xA5000001; //появление 0 на ножке NRST разрешает пользовательский сброс
  Delay(1000);

3. Настраиваем Flash Memory Controler.
  // Set Flash Wait state - Flash Memory Controler
  AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(48 <<16)) | AT91C_MC_FWS_1FWS ;
4. Запрещаем WatchDog.
  // Watchdog Disabled
  AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
 
5. Для того, чтобы заработал узел USB, нам необходимо запрограммировать PLL на частоту 48 МГц.
  // Установим MCK на 47923200 Гц
  // Разрешаем Main Oscillator:
  // Период SCK = 1/32768 = 30.51 мкс
  // Время запуска (Start up time) = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 мс
  pPMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN ));
  // Ожидаем, пока не пройдет startup time
  while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));

6. Настройка PLL.
  //Set PLL and divider:
  // - div by 5 Fin = 3,6864 =(18,432 / 5)
  // - Mul 25+1: Fout = 95,8464 =(3,6864 *26)
  // for 96 MHz the error is 0.16%
  // PLLCOUNT pll startup time estimate at : 0.844 ms
  // PLLCOUNT 28 = 0.000844 /(1/32768)
  pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x05) | (AT91C_CKGR_PLLCOUNT & (28<<8)) | (AT91C_CKGR_MUL & (25<<16)));
  // Ожидаем, пока не пройдет startup time
  while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

7.
  // Selection of Master Clock and Processor Clock
  // select the PLL clock divided by 2
  pPMC->PMC_MCKR =  AT91C_PMC_PRES_CLK_2 ;
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

  pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK  ;
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

42. Контроллер сброса RSTC.
1. Базовый адрес регистров RSTC равен 0xFFFFFD00 и описан как (описание взято из AT91SAM7X256.h)
#define AT91C_BASE_RSTC      ((AT91PS_RSTC)  0xFFFFFD00) // (RSTC) Base Address
2. RSTC считывает уровень на ножке NRST, и если он 0, то может сбросить процессор (если установлен бит URSTEN в регистре RSTC_MR).

43. Все регистры чипа AT91SAM7X256 описаны как volatile-переменные через тип AT91_REG таким образом (описание взято из AT91SAM7X256.h):
typedef volatile unsigned int AT91_REG;// Hardware register definition

44. Команда перехода B addr, загружает в R15 новый addr.

45. Примеры команд и их расшифровка
LDR R0, [PC, #0x088] ;загружает в регистр R0 содержимое ячейки памяти по адресу (PC+0x088)
LDR R0, [R0, #0]  ;загружает в регистр R0 содержимое ячейки памяти по адресу R0
STR R1, [R0, #0]  ;сохраняет регистр R1 по адресу в R0
LDR pc, =label   ;загружает в PC адрес метки кода label
label:
LDR PC, [PC, #-&F20] ;загружает в PC содержимое ячейки по адресу PC-0x00000F20 (обычно используется как вход в прерывание)
DCD  Label001  ;Define Constant Data, определяет в памяти константу Label001
SUB     lr, lr, #4  ;вычесть 4 из LR и результат поместить в LR
STMFD   sp!, {lr}  ;сначала сделать декремент SP на 4, потом сохранить регистр LR (он указан в списке {LR}) по адресу в SP, измененный адрес сохранить в SP
MRS     lr, SPSR  ;записать в LR значение регистра SPSR
STMFD   sp!, {r0, lr} ;сохранить в стеке R0 и LR. По окончанию оперции SP уменьшится на 8, в памяти будет сначала лежать R0, а потом LR
LDR     lr, =AT91C_BASE_AIC ;записать в LR константу 0xFFFFF000 (AT91C_BASE_AIC)
LDR     r0, [r14, #AIC_IVR] ;записать в R0 содержимое ячейки памяти по адресу R14+256, т. к. #AIC_IVR==256
STR     lr, [r14, #AIC_IVR] ;записать значение LR по адресу R14+256, т. к. #AIC_IVR==256
MSR     CPSR_c, #ARM_MODE_SVC ;???
STMFD   sp!, {r1-r3, r12, lr} ;сохранить в стеке R1, R2, R3, R12, LR. Содержимое стека при этом уменьшится на 5*4 = 20
LDMIA   sp!, {r1-r3, r12, lr} ;вернуть из стека содержимое регистров. Содержимое стека при этом увеличится на 5*4 = 20
LDMIA   sp!, {pc}^    ;вернуть из стека содержимое PC. ^ означает установить S и вернуть пользовательский банк.
b label1                ;перейти (branch) по метке label1
CMP r0, r4     ; сравнить регистры r0 и r4 (устанавливаются соответствующие флаги в регистре CPSR)
BEQ label34    ; переход по метке label34, если r0 == r4
ldr r2,[r1]+4! ; Загрузить в регистр r2 содержимое того, на что указывает r1, а затем, после того как всё сделано, добавить 4 к r1.
ldr r2,[r1+4]! ; сначала добавить к r1 число 4, а потом загрузить в r2 содержимое ячейки по адресу r1
str r2,[r0]+4! ; сохранить содержимое r2 по адресу в r0, а потом к r0 добавить 4

Если немного разобраться, то оказывается, что ассемблер ARM очень простой и запоминающийся. Основные правила:
- Если к любой (!) арифметической или логической команде добавить суффикс S, то эта команда будет модифицировать флаги процессора (которые находятся в регистре CPSR) - это позволяет сильно оптимизировать код. 
- К команде перехода B (Branch) может быть добавлен суффикс условия (например EQ, и команда станет BEQ), и команда становится условной - если условие выполнено, то происходит переход.
    Флаги могут содержать следующие состояния:
EQ EQual / Равно
NE Not Equal / Не равно
VS oVerflow Set / Установка переполнения
VC oVerflow Clear / Очищение переполнения
HI HIgher / Выше
LS Lower or the Same / Ниже или то же самое
PL PLus / Плюс
MI MInus / Минус
CS Carry Set / Установка переноса
CC Carry Clear / Очищение переноса
GE Greater than or Equal / Больше или равно
GT Greater Than / Больше
LE Less than or Equal / Меньше или равно
LT Less Than / Меньше
Z is Zero / Ноль
NZ is not Zero / Не ноль

Добавление этих состояний как суффикса к любой (!) команде заставляет делать проверку условия перед выполнением команды - если условие не соответсвует флагам, то команда просто не выполняется.

- Выход из подпрограммы всегда BX LR.
- В ассемблере IAR есть псевдокоманды PUSH и POP, которые позволяют сохранить в стеке список нужных регистров (очень удобно).

Очень советую ознакомиться с циклом статьей «GBA ASM», автор Mike H, пер. Aquila, http://wasm.ru/series.php?sid=21. После этого станет намного понятнее ассемблер ARM.

46. Слова в памяти хранятся младшим байтом вперед (little endian), например, слово 0x12345678 будет лежать в памяти по адресу 0x00200000 вот так:
0x00200000: 78 56 34 12

47. Wed Dec 03 15:24:58 2008: The stack 'CSTACK' is filled to 100% (256 bytes used out of 256). The warning threshold is set to 90.%

48. Что такое General Options -> library configurations -> Library low-level interface implementation? Какой вариант выбрать?

49. Размер стека задается через файл *.icf, который указывается в опциях линкера.

50. Откуда берутся адреса (board_cstartup_iar.s): ???
        EXTERN  Undefined_Handler
        EXTERN  SWI_Handler
        EXTERN  Prefetch_Handler
        EXTERN  Abort_Handler
        EXTERN  FIQ_Handler

51. Тип int соответствует 32 битному слову и совпадает с разрядностью регистров AT91SAM7X256. Тип short имеет разрядность 16 бит.

52. Прерывания от внешних устройств конфигурируются процедурой PIO_ConfigureIt. Пример:
#define PIN_PUSHBUTTON_1    {1 << 7, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP} //порт PA7
#define PIN_PUSHBUTTON_2    {1 << 8, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP} //порт PA8
static const Pin pinPB1 = PIN_PUSHBUTTON_1;
static const Pin pinPB2 = PIN_PUSHBUTTON_2;
PIO_Configure(&pinPB1, 1);
PIO_Configure(&pinPB2, 1);
PIO_InitializeInterrupts(AT91C_AIC_PRIOR_LOWEST);
PIO_ConfigureIt(&pinPB1, (void (*)(const Pin *)) ISR_Bp1);
PIO_ConfigureIt(&pinPB2, (void (*)(const Pin *)) ISR_Bp2);
PIO_EnableIt(&pinPB1);
PIO_EnableIt(&pinPB2);

//обработчик прерывания от кнопки 1
static void ISR_Bp1(void)
{
    static unsigned int lastPress = 0;

    // Check if the button has been pressed
    if (!PIO_Get(&pinPB1))
    {
        // Simple debounce method: limit push frequency to 1/DEBOUNCE_TIME
        // (i.e. at least DEBOUNCE_TIME ms between each push)
        if ((timestamp - lastPress) > DEBOUNCE_TIME)
        {
            lastPress = timestamp;
            // Toggle LED state
            pLedStates[0] = !pLedStates[0];
            if (!pLedStates[0])
            {
                LED_Clear(0);
            }
        }
    }
}

//обработчик прерывания от кнопки 2
static void ISR_Bp2(void)
{
    static unsigned int lastPress = 0;

    // Check if the button has been pressed
    if (!PIO_Get(&pinPB2))
    {
        // Simple debounce method: limit push frequency to 1/DEBOUNCE_TIME
        // (i.e. at least DEBOUNCE_TIME ms between each push)
        if ((timestamp - lastPress) > DEBOUNCE_TIME)
        {
            lastPress = timestamp;
            // Disable LED#2 and TC0 if there were enabled
            if (pLedStates[1])
            {
                pLedStates[1] = 0;
                LED_Clear(1);
                AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
            }
            // Enable LED#2 and TC0 if there were disabled
            else
            {
                pLedStates[1] = 1;
                LED_Set(1);
                AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
            }
        }
    }
}

Функции PIO_Configure, PIO_ConfigureIt, PIO_InitializeInterrupts, PIO_EnableIt имеются в файле C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib\peripherals\pio\pio.c.

53. Прерывания от внутренних устройств конфигурируются процедурой AIC_ConfigureIT. Пример:
// настраиваем PIT для генерации прерывания каждую милисекунду
#define PIT_PERIOD          1000
#define BOARD_MCK           48000000
PIT_Init(PIT_PERIOD, BOARD_MCK / 1000000);
// конфигурируем прерывание на PIT
AIC_DisableIT(AT91C_ID_SYS);
AIC_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, ISR_Pit);
AIC_EnableIT(AT91C_ID_SYS);
PIT_EnableIT();
// разрешаем PIT
PIT_Enable();

//Обработчик прерывания от PIT. Инкрементирует счетчик времени timestamp
static void ISR_Pit(void)
{
    unsigned int status;

    // Прочитаем регистр статуса PIT
    status = PIT_GetStatus() & AT91C_PITC_PITS;
    if (status != 0)
    {
        // Прочитаем PIVR для подтверждения прерывания и получения количества тиков
        timestamp += (PIT_GetPIVR() >> 20);
    }
}

Еще пример:
// кофигурируем Timer Counter 0 для генерирования прерывания каждые 250 мс
unsigned int div;
unsigned int tcclks;
// Разрешаем такты периферии
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0;

// Конфигурируем TC на частоту 4Гц и срабатывание от сравнения RC
TC_FindMckDivisor(4, BOARD_MCK, &div, &tcclks);
TC_Configure(AT91C_BASE_TC0, tcclks | AT91C_TC_CPCTRG);
AT91C_BASE_TC0->TC_RC = (BOARD_MCK / div) / 4; // timerFreq / desiredFreq
// Конфигурируем и разрешаем прерывание от сравнения RC
AIC_ConfigureIT(AT91C_ID_TC0, AT91C_AIC_PRIOR_LOWEST, ISR_Tc0);
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
AIC_EnableIT(AT91C_ID_TC0);
// Запускаем счетчик
TC_Start(AT91C_BASE_TC0);

//Обработчик прерывания TC0.
static void ISR_Tc0(void)
{
    // Очистим бит статуса для подтверждения прерывания
    AT91C_BASE_TC0->TC_SR;

    // тут код
    ...
}

Функции PIT_Init, PIT_EnableIT, PIT_Enable имеются в файле C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib\peripherals\pit\pit.c.

Функции AIC_DisableIT, AIC_ConfigureIT, AIC_EnableIT имеются в файле C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib\peripherals\aic\aic.c.

54. Ножки AT91SAM7X256 конфигурируются подпрограммой u8 PIO_Configure(const Pin *list, u32 size). Здесь list - ссылка на массив описателей ножек, а size - количество записей в массиве. Каждая запись в массиве (экземпляр переменной Pin) должна быть в таком виде:
typedef struct
{
    u32 mask;   //маска из 32 бит, единички в которой задают номера портов, подлежащие настройке
    AT91S_PIO *pio; //указатель на базовый 32-битный адрес контроллера, которому принадлежат ножки.
     // AT91S_PIO - структура, в которй перечислены все регистры контроллера, а pio указывает на её начало.
     // Например, для контроллера PIOA (Parallel I/O Controller A) в pio надо загрузить адрес AT91C_BASE_PIOA,
     // или 0xFFFFF400
    u8 id;   //Идентификатор (ID) контроллера PIO, которому принадлежат ножки. Например, для Parallel IO Controller A это будет
     // число AT91C_ID_PIOA, или 2
    u8 type;  //Тип ножки. Типы могут быть такие - PIO_PERIPH_A (==0, периферия A), PIO_PERIPH_B (==1, периферия B),
     // PIO_INPUT (==2, вход), PIO_OUTPUT_0 (==3, выход с начальным нулем на выходе),
     // PIO_OUTPUT_1 (==3, выход с начальной единичкой на выходе)
    u8 attribute; //Атрибуты ножек. Тут нужно указать атрибуты PIO_DEFAULT (==0), PIO_PULLUP (==1), PIO_DEGLITCH (==2), PIO_OPENDRAIN (==4),
     // можно также указать несколько атрибутов, сложив их операцией OR.
} Pin;

unsigned char PIO_Configure(const Pin *list, unsigned int size)
//------------------------------------------------------------------------------
/// Configures a list of Pin instances, which can either hold a single pin or a
/// group of pins, depending on the mask value; all pins are configured by this
/// function.
/// Returns 1 if the configuration has been performed successfully; otherwise 0.
/// \param list  Pointer to a list of Pin instances.
/// \param size  Size of the Pin list (see <PIO_LISTSIZE>).
//------------------------------------------------------------------------------
{
    // Configure pins
    while (size > 0)
    {
        switch (list->type)
        {
        case PIO_PERIPH_A:
                PIO_SetPeripheralA(list->pio,
                                   list->mask,
                                   (list->attribute & PIO_PULLUP) ? 1 : 0);
                break;
   
        case PIO_PERIPH_B:
                PIO_SetPeripheralB(list->pio,
                                   list->mask,
                                   (list->attribute & PIO_PULLUP) ? 1 : 0);
                break;
  
        case PIO_INPUT:
                AT91C_BASE_PMC->PMC_PCER = 1 << list->id;
                PIO_SetInput(list->pio,
                             list->mask,
                             (list->attribute & PIO_PULLUP) ? 1 : 0,
                             (list->attribute & PIO_DEGLITCH)? 1 : 0);
                break;
   
        case PIO_OUTPUT_0:
        case PIO_OUTPUT_1:
                PIO_SetOutput(list->pio,
                              list->mask,
                              (list->type == PIO_OUTPUT_1),
                              (list->attribute & PIO_OPENDRAIN) ? 1 : 0,
                              (list->attribute & PIO_PULLUP) ? 1 : 0);
                break;
   
        default:
                return 0;
        }

        list++;
        size--;
    }

    return 1;
}

Пример использования:
#define PIN_PUSHBUTTON_1    {1 << 7, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP}
#define PIN_PUSHBUTTON_2    {1 << 8, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP}

static const Pin pinPB1 = PIN_PUSHBUTTON_1;
static const Pin pinPB2 = PIN_PUSHBUTTON_2;

PIO_Configure(&pinPB1, 1);
PIO_Configure(&pinPB2, 1);

Функция PIO_Configure имеется в файле C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib\peripherals\pio\pio.c.

55. Ножки AT91SAM7X256 можно прочитать подпрограммой u8 PIO_Get (const Pin *pin).
unsigned char PIO_Get(const Pin *pin)
//------------------------------------------------------------------------------
/// Возвращает 1, если одна или более ножек PIO (заданы в *pin) имеют высокий уровень,
///  иначе возвращает 0.
//------------------------------------------------------------------------------
{
    u32 reg;
    if ((pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1))
    {
        reg = READ(pin->pio, PIO_ODSR);
    }
    else
    {
        reg = READ(pin->pio, PIO_PDSR);
    }

    if ((reg & pin->mask) == 0)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

Пример:
#define PIN_PUSHBUTTON_1    {1 << 7, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP}
static const Pin pinPB1 = PIN_PUSHBUTTON_1;
if (!PIO_Get(&pinPB1))
{
 //определили, что на ножке PA7 логический 0
 ...
}

Функция PIO_Get имеется в файле C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib\peripherals\pio\pio.c.

56. Установить/сбросить ножки AT91SAM7X256 можно подпрограммами PIO_Set и PIO_Clear:
void PIO_Set(const Pin *pin)
{
    WRITE(pin->pio, PIO_SODR, pin->mask);
}
void PIO_Clear(const Pin *pin)
{
    WRITE(pin->pio, PIO_CODR, pin->mask);
}

Перед использованием ножек как выходов из надо настроить. Пример:
#define PIN_PB21_TEST66  {1 << 21, AT91C_BASE_PIOB, AT91C_ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
static const Pin outPB21_66 = PIN_PB21_TEST66;
PIO_Configure(&outPB21_66, 1);

Функции PIO_Configure, PIO_Set и PIO_Clear имеются в файле C:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib\peripherals\pio\pio.c.

57. Разрешить TC0 так:
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
    Запретить TC0 так:
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;

58. Перед тем, как работать с индикатором NOKIA6610 на плате SAM7-EX256, нужно определить, какого типа LCD-контроллер у Вас используется. Варианта два:
- контроллер Epson S1D15G00, стикер GE-8, тестовая программа (откомпилированная прошивка AT91SAM7X256) http://www.olimex.com/dev/soft/arm/SAM7/SAM7_EX256_GE8.zip
- контроллер Philips PCF8833, стикер GE-12, тестовая программа (откомпилированная прошивка AT91SAM7X256) http://www.olimex.com/dev/soft/arm/SAM7/SAM7_EX256_GE12.zip
Скачиваем обе прошивки SAM7_EX256_GE8.zip и SAM7_EX256_GE12.zip, по очереди записываем их по адресу 0x100000 (FLASH) с помощью программы SEGGER J-Flash и смотрим, какая работает. У меня прошивка SAM7_EX256_GE12.bin давала просто чистый экран, а SAM7_EX256_GE8.bin показала картинку - ползущий по скале человечек, и внизу надпись красными буквами OLIMEX. Значит, мой индикатор с контроллером Epson S1D15G00.

59. Как прикрутить SD card.
http://forum.ixbt.com/topic.cgi?id=48:5248-12
Советуют в качестве библиотеки для FAT применить EFSL, или операционную систему uCOS (uC/OS II). См. также
http://www.smxrtos.com/eval/index.html

60. Теперь понятно, что я не увидел тактовой частоты кварца. Оказывается, её размах всего лишь 60 мВольт...

61. Чтобы внешний сброс заработал, его надо сначала настроить. Нужно сделать следующее:
- в дереве проекта выбираем папку peripherals, жмем правую кнопу, выбираем Add, указываем на файл c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91lib\peripherals\rstc\rstc.c
- вставляем в main.c #include <rstc/rstc.h> (в свойствах проекта C/C++ Compiler -> закладка Preprocessor -> поле Additional include directories: должно содержать что-то типа $PROJ_DIR$\..\..\..\at91lib\peripherals)
- вставляем в начало кода, перед главным циклом main вызов RSTC_SetUserResetEnable(AT91C_BASE_RSTC, 1).

А еще лучше - доббавить такой код:
#include <rstc/rstc.h>
...
static const Pin pPins[]  = {PINS_DBGU};
volatile AT91PS_RSTC pRSTC  = AT91C_BASE_RSTC;
...
int main()
{
    //настройка ножек PA27(DRXD), PA28(DTXD)
    PIO_Configure(pPins, PIO_LISTSIZE(pPins));
    //настройка порта DBGU
    DBGU_Configure(DBGU_STANDARD, 115200, BOARD_MCK);
    printf("Board : %s, Chip ID : 0x%08X\n\r", BOARD_NAME, AT91C_BASE_DBGU->DBGU_CIDR);
    RSTC_SetUserResetEnable(pRSTC, 1); //разрешаем сброс от кнопки
    u32 resetType = (pRSTC->RSTC_RSR & AT91C_RSTC_RSTTYP)>>8;
    if (resetType==0)
        printf ("reset with input POWER\n\r");
    else if (resetType==2)
        printf ("reset with WATCHDOG\n\r");
    else if (resetType==3)
        printf ("reset with SOFTWARE\n\r");
    else if (resetType==4)
        printf ("reset with USER\n\r");
    else if (resetType==5)
        printf ("reset with BROWNOUT (power loss)\n\r");
    else
        printf ("reset has UNKNOWN source: %u\n\r", resetType);
 ...
 
62. Если во время сессии отладки в SRAM с помощью MT-LINK произойдет сброс процессора (например, по кнопке), то управление переходит в код, прошитый во flash. Поэтому точки останова и отладка по коду перестанут работать.

63. Как перенести проект в другую папку.
 Иногда надо сделать на основе одного проекта другой - например, из примера getting-started-project от IAR (находится в папке c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91sam7x-ek). Например, нам надо сделать на основе него новый проект, находящийся в папке c:\arm\myfirstproj. Далее будем для простоты путь c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\ заменять на $TOOLKIT_DIR$\, а папку проекта c:\arm\myfirstproj\ на $PROJ_DIR$\. Процесс по шагам:
1. Создаем папку c:\arm\myfirstproj ($PROJ_DIR$).
2. Содержимое папки $TOOLKIT_DIR$\examples\Atmel\at91sam7x-ek\getting-started-project копируем в папку $PROJ_DIR$.
3. Файл $PROJ_DIR$\getting-started-project.eww переименовываем в $PROJ_DIR$\myfirstproj.eww.
4. Файл $PROJ_DIR$\settings\getting-started-project.wsdt переименовываем в $PROJ_DIR$\settings\myfirstproj.wsdt.
5. Запускаем проект, и попробуем его перекомпилировать заново (Project\Rebuild All). Компилятор будет выдавать ошибки наподобие:
- Fatal Error[Pe005]: could not open source file "board.h"
- Fatal Error[Pe005]: could not open source file "pio/pio.h"
- Fatal Error[Pe005]: could not open source file "aic/aic.h"
- Fatal Error[Pe005]: could not open source file "utility/led.h"
- Fatal Error[Pe005]: could not open source file "utility/assert.h"
- Fatal Error[Lc002]: could not open file "c:\asm\pkrc-m\ewp\..\..\..\at91Iib\boards\at91sam7x-ek\at91sam7x256\sram.icf"
    Файл board.h находится в папке $TOOLKIT_DIR$\examples\Atmel\at91lib\boards\at91sam7x-ek\. В установках проекта этот путь задан относительно старого значения $PROJ_DIR$ - $PROJ_DIR$\..\..\..\at91lib\boards\at91sam7x-ek, но оно у нас поменялось. Поэтому исправим $PROJ_DIR$\..\..\..\at91lib\boards\at91sam7x-ek на $TOOLKIT_DIR$\examples\Atmel\at91lib\boards\at91sam7x-ek.
    Аналогично исправляем (Project -> Options... -> C/C++ Compiler -> закладка Preprocessor):
$PROJ_DIR$\..\..\..\at91lib\peripherals на $TOOLKIT_DIR$\examples\Atmel\at91lib\peripherals
$PROJ_DIR$\..\..\..\at91lib             на $TOOLKIT_DIR$\examples\Atmel\at91lib
    Чтобы исправить ошибку линкера Lc002, исправляем (Project -> Options... -> Linker -> закладка Config -> галочка Linker configuration file\Override default):
$PROJ_DIR$\..\..\..\at91lib\boards\at91sam7x-ek\at91sam7x256\sram.icf на $TOOLKIT_DIR$\examples\Atmel\at91lib\boards\at91sam7x-ek\at91sam7x256\sram.icf
    После этого пропадут все ошибки.
6. Исправляем путь к макросам отладчика (Project -> Options... -> Debugger -> галочка Use macro file(s)):
$PROJ_DIR$\..\..\..\resources\at91sam7xx-ek-sram.mac на $TOOLKIT_DIR$\examples\Atmel\resources\at91sam7xx-ek-sram.mac
7. Аналогичным образом правим все конфигурации, какие есть в проекте (at91sam7x128_flash, at91sam7x128_sram, at91sam7x256_flash,
at91sam7x256_sram, at91sam7x512_flash, at91sam7x512_sram).

64. Для того, чтобы функция компилировалась для RAM (это полезно для провышения быстродействия, например для обработчиков прерываний), нужно к ней добавить атрибут __ramfunc:
__ramfunc void timer0_c_irq_handler(void)
{
    ...
}
или так:
static __ramfunc void ISR_Tc1(void)
{
    ...
}

-----------------------------------------------------------------------------------------
9 декабря 2008
65. Вываливание в Abort Handler при проверке внешней переменной word5cnt у меня происходило потому, что я забыл у неё указать тип:
extern word5cnt;
    После того, как указал тип, эта ошибка пропала:
extern unsigned char word5cnt;

-----------------------------------------------------------------------------------------
10 декабря 2008
66. Почему перестает работать прерывание от PIT, когда я для него переделываю обработчик с static void ISR_Pit(void) на __irq __arm void ISR_Pit(void)?

-----------------------------------------------------------------------------------------
12 декабря 2008
67. Решил подвести маленький итог - записать, что успел узнать про процессор ARM.
- может быть запрограммирован 31 источник прерываний (их еще почему-то иногда называют "исключениями"), каждому из которых может быть назначен индивидуальный адрес. Каждому из 31 источника прерывания может быть назначен приоритет от 0 (самый низкий, устанавливается по умолчанию) до 7 (самый высокий). Однако реальных точек входа (адресов) для прерываний всего две - для IRQ (обычные прерывания IRQ) и FIQ (Fast IRQ). Адреса для 31 источника и приоритеты хранятся в специальных регистрах AIC.
- нет стека, поддерживающего вызовы подпрограмм, который был бы виден для программиста. Адрес возврата сохраняется в специальном регистре LP (он же R14). Несмотря на это, имеется 8-уровневый аппаратный стек в контроллере AIC, который нужен для обеспечения работы приоритетов прерываний (приоритетов всего 8) - поддерживается вложенность прерываний, т. е. прерывание, имеющее более весомый приоритет, может приостановить работу менее приоритетного прерывания.
- что плохо в AT91SAM7X256 (не знаю, может быть в чипах других производителей это не так), так то что невозможно точно спрогнозировать время реакции процессора на прерывание, даже для FIQ. Поэтому "абсолютный" реалтайм Вы с ним не получите (с определенной погрешностью, которая для низких частот будет достаточно мала из-за бешеной скорости ядра).
- почти все команды выполняются за 1 такт благодаря 3-уровневому конвейеру.
- чип AT91SAM7X256 занимает некое промежуточное положение между "железячными" микроконтроллерами ATmega, PIC и MCS51, и "умными" процессорами с ядром x86. По набору периферии и количеству ножек они приближены к железу, а по функционалу ядра и быстродействию слегка приближаются к процессорам рабочих станций.
- у процессора AT91SAM7X256 нет встроенной памяти EEPROM для хранения настроек при выключении питания (увы), есть только своя flash-память, которую может модифицировать программа. В принципе, её можно использовать для хранения настроек, но я нигде не прочитал, чтобы производитель Atmel рекомендовал такое (наверное, из-за ограниченного ресурса на перезапись flash).
- у процессора AT91SAM7X256 нет перемычек-фьюзов (fuses), которые регулируют режим работы ядра. Вместо этого требуется программная настройка частоты процессора при старте.
- имеется PLL, с помощью которой тактовая частота ядра может превышать в несколько раз частоту кварца (до 200 МГц).
- память flash как хранилище программ устойчиво работает на тактовых частотах ядра до 50 МГц. Если использовать память sram для программы, код будет исполняться быстрее (из-за отсутствия циклов задержек при чтении памяти).
- имеется 7 режимов работы ядра, отличающиеся набором регистров
- неправильный код команды генерирует специальное прерывание. Это может использоваться для расширения системы команд.
- попытка обращения к несуществующим адресам также вызывает прерывание (Abort Handler).

-----------------------------------------------------------------------------------------
13 декабря 2008 г.
    Сделал отдельный модуль isr-tmr1.c для обработчика прерывания TC1 с целью откомпилировать его в ассемблер, и потом исходник ассемблера подцепить к проекту. В опциях файла isr-tmr1.c поставил галку Override inherited settings, а потом на закладке List поставил 3 галки - Output assembler file, Include source и Include call frame information. После компиляции получился файл c:\asm\adkm\ewp\at91sam7x256_sram\List\isr-tmr1.s. Подключил его к проекту вместо исходного isr-tmr1.c, и все получилось!

-----------------------------------------------------------------------------------------
14 декабря 2008
    FreeRTOS
    Операционная система реального времени (свободная), которая портирована на многие семейства микроконтроллеров. См. http://www.freertos.org/. Систему можно скачать в виде одного файла FreeRTOSV5.1.1.zip размером 20266667 байт. Этот файл содержит исходный код для ядра, порт для каждого процессора и примеры приложений. Подробно о структуре архива можно почитать по ссылке http://www.freertos.org/a00017.html. Само ядро находится в папке FreeRTOS\Source и состоит из 3 файлов (эти 3 файла являются общими для всех микроконтроллеров) - list.c, queue.c и tasks.c. Может еще использоваться дополнительный файл croutine.c. Каждый микроконтроллер нуждается в порции кода ядра, который специфичен для этого процессора и выбранного компилятора. Этот код лежит в папке FreeRTOS\Source\portable.
    В папке FreeRTOS\Demo лежит код демонстрационных приложений. Общая для всех платформ часть кода лежит в папке FreeRTOS\Demo\Common. Другие папки содержат код для компиляции демо-приложений каждого отдельного порта.
    Если, например, Вы хотите скомпилировать код для процессора AT91SAM7S, Вам нужно взять 3 файла ядра (list.c, queue.c и tasks.c из папки FreeRTOS\Source) и файл FreeRTOS\Source\portable\GCC\ARM7_AT91SAM7S\port.c .
    Папка FreeRTOS/Portable/MemMang содержит примеры кода подпрограмм для выделения памяти.

-----------------------------------------------------------------------------------------
15 декабря 2008
68. Оказывается, интерфейс I2C (TWI) не может работать в режиме Slave.

-----------------------------------------------------------------------------------------
16 декабря 2008
69. Intrinsic functions - расширенные C-функции от IAR, которые компилируются в одну ассемблерную инструкцию ARM.

-----------------------------------------------------------------------------------------
25 декабря 2008
70. Оператор ассемблера CFI
CFI расшифровывается как Call frame information. Точно не разобрался что это такое. Видел в ассемблерном коде, который генерит компилятор C от IAR. Инструкции ассемблера CFI можно безболезненно убрать из кода.

71. При сбросе или при включении питания по умолчанию активируются нагрузочные резисторы на всех портах PIO процессора AT91SAM7X256.

-----------------------------------------------------------------------------------------
30 декабря 2008
ielftool error: Range must be 4-byte aligned: 0-0
Error while running Linker
    Появляется, когда ставишь галочку в свойствах линкера - заполнить неиспользуемую память байтом 0xFF. Чтобы ошибка пропала, нужно правильно указать границы flash (для AT91SAM7X256 границы будут 0x100000 и 0x13FFFF).
   
ielftool error: The checksum symbol was not found in string table
Error while running Linker
    Появляется, когда ставишь галочку в свойствах линкера - считать контрольную сумму. http://supp.iar.com/Support/?note=11927&from=note+91733
   
malloc не может выделить память потому, что размер кучи задан 0.

-----------------------------------------------------------------------------------------
11 января 2009
    Наконец-то разобрался с макросом $PROJ_DIR$. Теперь при переносе проекта в другую папку все компилируется все равно нормально. Лучшая проверка - переименовать папку проекта и сделать Rebuild All. Если успешно, то все относительные пути настроены правильно.

Можно посылать сообщения в лог "Build" директивой warning, например:
#warning "inofficial CSD-read patch active sd_Resp8b->if_spiSend"

Последнее обновление ( 18.09.2010 )
 

Комментарии  

  1. #7 Artur
    2013-01-0420:33:32 Добрый день,
    Огромное спасибо за сайт, много полезного почерпнул.

    Проблема такая - есть готовый проект на SAM7X128. В 2 словах - обмен данными с устройством, где ARM выступает в качестве транслятора команд, причем он подключен к USB.
    Иногда бывают случаи, что ARM перестает определяться системой, и Windows распознает его как Unknown Device. Помогает только ERASE, и перезаливка firmware. Какие могут быть идеи - что может портиться в прошивке?

    microsin: идей никаких, может быть все что угодно. Скорее всего какая-то программная ошибка. Попробуйте установить в коде firmware защиту на запись памяти FLASH, а также добавьте отладочный код, который позволит определить причину зависания.
  2. #6 CosmoS
    2012-01-1608:46:09 Большое спасибо за статью, она во многом помогла. Но у меня возникла проблема с USB: Вы бы не могли подсказать - с какими бубнами поплясать, и какое заклинание нужно прочесть, чтобы МК начал передачу данных по USB? (На данный момент Windows видит подключенное устройство, но пишет "Устройство не опознано". На осцилографе видно, что МК не отвечает на запросы PC)

    microsin: варианта собственно два - либо программа в микроконтроллер е с ошибкой, либо ПО хоста (т. е. программа, работающая с USB-устройством) не обращается к Вашему устройству. Возьмите проверенные примеры USB-устройств для микроконтроллер ов ARM - либо с сайта Atmel, либо из примеров IAR.
  3. #5 Петр
    2011-02-2801:31:31 Продолжаю потихоньку разбираться с ARM. Если не сложно, подскажите, зачем нужны регистры PIO_ASR и PIO_BSR. У Редькина вроде и говорится, но как то размыто.

    microsin: регистры PIO_ASR и PIO_BSR задают, какая ножка процессора к какой внутренней периферии подключена. Возможные варианты см. в таблицах даташита. Например, для чипа AT91SAM7X256(512) это таблицы Table 10-2. Multiplexing on PIO Controller A и Table 10-3. Multiplexing on PIO Controller B.
  4. #4 Петр
    2010-08-0217:34:33 Гигантское спасибо!
    Действительно, все эти конфигурации присутствуют!
    Понял, как выбирать!
    У нас полпервого ночи, глаз просто замылился!
    Еще раз спасибо!!!!!!!
  5. #3 Петр
    2010-08-0217:29:31 Спасибо!
  6. #2 Петр
    2010-08-0217:07:29 Действительно, в примерах от atmela эти конфигурации есть!
    Я пользовался готовыми проектами от iar, но там только старт из флеша! Как мне кажется…

    microsin: все готовые проекты IAR (примеры) для чипов ARM Atmel, которые идут в комплекте с IAR EWB ARM, предоставлены компанией Atmel (там даже в начале каждого исходника это прописано). И в каждом примере есть конфигурация как для flash, так и для SRAM.
  7. #1 Петр
    2010-08-0215:59:16 MicroSin, просвети, пожалуйста, в следующем. Взял готовый пример из ewarm, рассчитанный на работу из флеша, подогнал под себя, все работает как надо. Что надо поменять в настройках, чтобы работало из SRAM? У меня IAR EWB ARM версии 5, заливаю sam-ba. Спасибо!

    microsin: в каждом примере от Atmel в комплекте есть несколько конфигураций - на flash, на SRAM и на разные версии чипа. Например, обычно есть конфигурации at91sam7×128_flash, at91sam7×128_sram, at91sam7×256_flash, at91sam7×256_sram, at91sam7×512_flash, at91sam7×512_sram - из названия сразу понятно, что это за конфигурация. Отличаются конфигурации настройками проекта и картой памяти для линкера (файл *.icf).

    Чтобы Ваш проект заработал в SRAM, нужно просто выбрать перед компиляцией соответствующую конфигурацию, перекомпилирова ть проект, и потом залить полученный бинарник утилитой SAM-PROG. Конфигурации выбираются в выпадающем списке окошка с деревом файлов проекта (Workspace).

Добавить комментарий

:D:lol::-);-)8):-|:-*:oops::sad::cry::o:-?:-x:eek::zzz:P:roll::sigh:

Защитный код
Обновить

< Пред.   След. >

Top of Page
 
microsin © 2017