Программирование ARM: решение проблем, FAQ ARM: записи чайника Fri, December 13 2024  

Поделиться

Нашли опечатку?

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


ARM: записи чайника Печать
Добавил(а) microsin   

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

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 мс активизирует очистку всей памяти. После очистки памяти начинает работать нестираемый загрузчик SAM-BA. С помощью этого загрузчика можно управлять содержимым памяти, загружать в FLASH новую программу (для этого применяются специальные утилиты от Atmel). Управление с помощью SAM-BA происходит через USB или DBGU (последовательный порт RS232). Таким образом, даже без отладчика JTAG уже можно писать программы по принципу написал-залил-попробовал.

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

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

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

-----------------------------------------------------------------------------------------
22 ноября 2008

14. Отладчики JTAG.

- MT-Link - JTAG отладчик, российский (Питер) функциональный аналог SEGGER J-Link, подключаемый по USB [3]. Совместим с IAR.

[Цены] В Митракон стоит 2983.49, $82 в ТерраЭлектронике. В Дельта Электроника (тел. 9701050) стоит 2956,66 руб. База Электроники (тел. 9375929) стоит 3194,09 руб. ТерраЭлектроника (тел. 2217804) стоит 2305 руб [$82] (ул. Дербеневская д.1, корпус 1, подъезд 23).

- ARM-JTAG в Чип-И-Дип стоит 872 рубля. Это аналог WIGGLER. Имеет какие-то ограничения в работе, лучше не покупать.

- J-LINK стоит 8500 рублей (в Чип-И-Дип он стоит 9500 рублей).

- ULINK2 есть в компании SIMECS, стоит 167 евро. Правда непонятно, насколько он совместим с IAR EW.

- JTAG.LPT адаптер, известный под названием wiggler. Работает с ROWLEY ASSOCIATES - CrossWorks for ARM. Можно спаять самому, можно купить его аналог от Olimex под названием ARM-JTAG.

- SEGGER J-Link [4], совместимый с IAR EW адаптер USB-JTAG. Полный аналог этого отладчика MT-LINK.

15. Отладочные платы.
Отладочная плата, которую стоит купить - SAM7-EX256 от компании Olimex [2]. Она стоит 6500 рублей в Чип-И-Дип, 4360 в Терраэлектроника. Можно напрямую в Olimex. Для полноценной работы требуется JTAG-эмулятор: ARM-JTAG (OLIMEX), J-LINK (IAR), ULINK (KEIL).

Отладочная плата от Atmel AT91SAM7X-EK стоит $390 в Терраэлектроника. В Чип-И-Дип она под заказ 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 и затребовал драйвера. В комплекте не было никаких драйверов, поэтому стал искать в Интернете. Драйвер нашел на сайте Segger [5], скачал файл 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 и в тело циклов вставить вызов функции 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 и его целевой частоты может быть вычислено, используя специальный инструмент [6], предоставляемый Atmel.

Резюме. Можно, конечно же, разбираться во всех этих премудростях, а можно поступить проще - взять готовый пример кода. Примеры находятся в 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 [7].

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.

3. В диалоговом окне выбираем имя для проекта hw, жмем OK.

4. Подредактируем текст модуля main, добавив туда бесконечный цикл. Должно получиться примерно как на рисунке.

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. Выберите в меню Project -> Options... (Alt+F7). Появится окно настроек проекта.
8. General Options -> закладка Target, выберите Device Atmel AT91SAM7X256.
9. Для упрощения отладки выберите C/C++ Compiler -> закладка Optimizations -> None (отключена оптимизация кода). Жмем OK.
10. Теперь нам осталось сделать самое важное - выбрать настроечный файл для линкера. Тут у меня поначалу от незнания были грабли. Без этого файла аппаратный отладчик MT-LINK не работает. Создадим для начала 2 добавочные конфигурации для проекта, которые позволят нам отлаживать программу как в RAM (отладка кода в RAM экономит ресурс кристалла, так как мы не меняем содержимое flash), так и во FLASH. Заходим в меню Project -> Edit Configurations..., там сейчас пока 2 конфигурации - Debug
и Release. Жмем кнопку New..., впечатываем имя Debug in RAM, жмем кнопку OK. Таким же образом создаем еще конфигурацию Debug in FLASH. В результате получим 4 конфигурации в проекте. Жмем кнопку 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. Таким же образом выбираем файл 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. Далее в дереве Category слева выбираем J-Link/J-Trace, на закладке Startup выбираем Reset -> Hardware, Atmel AT91SAM7. Жмем OK.
13. Выбираем в меню Project -> Download and Debug, запустится окно отладчика C-SPY. Теперь можно отлаживать программу по шагам, нажимая клавишу F10.
14. В трее можно при этом видеть значок драйвера J-Link. Двойным щелчком на нем можно вызвать окно настроек драйвера.
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. На закладке Breakpoints выбираем Use software breakpoints и Use flash breakpoints. Жмем 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, и простую процедуру задержки.

1
2
3
4
#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); }

3. Разрешаем сброс.

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

4. Настраиваем Flash Memory Controler.

//Установка длительности циклов ожидания памяти программ
// (Wait state) путем программирования Flash Memory Controler
AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN) & (48 << 16)) | AT91C_MC_FWS_1FWS;

5. Запрещаем WatchDog.

AT91C_BASE_WDTC -> WDTC_WDMR = AT91C_WDTC_WDDIS;

6. Для того, чтобы заработал узел 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));

7. Настройка PLL.

//Установка PLL и делителя:
// - точное деление на 5 равно 3,6864 =(18,432 / 5)
// - умножить на 25+1: Fout = 95,8464 =(3,6864 *26)
// для 96 МГц ошибка составит 0.16%
// PLLCOUNT pll startup time составит 0.844 мс
// 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));

8. Выбор главной частоты (Master Clock) и частоты процессора (Processor Clock).

// Такты PLL будут делиться на 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)
2. RSTC считывает уровень на ножке NRST, и если он 0, то может сбросить процессор (если установлен бит URSTEN в регистре RSTC_MR).

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

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, которые позволяют сохранить в стеке список нужных регистров (очень удобно).

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. Пример:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//К порту PA7 подключена кнопка 1.
#define PIN_PUSHBUTTON_1 {1 << 7, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP}
//К порту PA8 подключена кнопка 2.
#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_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;
//Проверка, нажата ли кнопка. if (!PIO_Get(&pinPB1)) { //Простой метод отсеивания помех (debounce): ограничение частоты нажатий до 1/DEBOUNCE_TIME // (т. е. должно быть как минимум DEBOUNCE_TIME мс времени между нажатиями). if ((timestamp - lastPress) > DEBOUNCE_TIME) { lastPress = timestamp; // Переключение состояние светодиода LED pLedStates[0] = !pLedStates[0]; if (!pLedStates[0]) { LED_Clear(0); } } } }
//Обработчик прерывания от кнопки 2. static void ISR_Bp2(void) { static unsigned int lastPress = 0;
//Проверка, нажата ли кнопка. if (!PIO_Get(&pinPB2)) { //Простой метод отсеивания помех (debounce): ограничение частоты нажатий до 1/DEBOUNCE_TIME // (т. е. должно быть как минимум DEBOUNCE_TIME мс времени между нажатиями). if ((timestamp - lastPress) > DEBOUNCE_TIME) { lastPress = timestamp; //Запрет LED номер 2 и TC0, если они разрешены. if (pLedStates[1]) { pLedStates[1] = 0; LED_Clear(1); AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; } //Разрешение LED номер 2 и TC0, если они запрещены. 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. Пример:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Настройка PIT для генерации прерывания каждую 1 мс.
#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); } }

Еще пример:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Конфигурирование 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) должна быть в таком виде:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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;

Список экземпляров Pin и количество портов для настройки принимает функция PIO_Configure.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//------------------------------------------------------------------------------
/// Функция конфигурирует некоторое количество (size) списка выводов Pin.
/// Каждый элемент в списке может соответствовать описания одного вывода
/// или нескольких (группы выводов), в зависимости от маски. С помощью
/// этой функции могут быть отконфигурированы все выводы микроконтроллера.
///
/// Возвращает 1, если конфигурирование выполнено успешно, иначе вернет 0.
/// \param list Указатель на список экземпляров Pin.
/// \param size Размер списка Pin (см. макрос < PIO_LISTSIZE >).
//------------------------------------------------------------------------------
unsigned char PIO_Configure(const Pin *list, unsigned int size)
{
    // 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; }

Пример использования:

1
2
3
4
5
6
7
8
#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).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//-----------------------------------------------------------------------
/// Возвращает 1, если одна или более ножек PIO (заданы в *pin)
/// имеют высокий уровень, иначе возвращает 0.
//-----------------------------------------------------------------------
unsigned char PIO_Get(const Pin *pin)
{
    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; } }

Пример:

1
2
3
4
5
6
7
#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:

1
2
3
4
5
6
7
8
9
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); }

Перед использованием ножек как выходов из надо настроить. Пример:

1
2
3
#define PIN_PB21_LED {1 << 21, AT91C_BASE_PIOB, AT91C_ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
static const Pin outLED = PIN_PB21_LED;
PIO_Configure(&outLED, 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. Таймер/счетчик 0, TC0. Разрешить 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) SAM7_EX256_GE8.zip [8].
- контроллер Philips PCF8833, стикер на плате GE-12, тестовая программа (откомпилированная прошивка AT91SAM7X256) SAM7_EX256_GE12.zip [8].

Скачайте [8], распакуйте. По-очереди запишите их по адресу 0x100000 (FLASH) с помощью программы SEGGER J-Flash, или SAM-BA v2.11, или SAM-PROG v2.4, и посмотрите, какая из них работает. У меня прошивка SAM7_EX256_GE12.bin давала просто чистый экран, а SAM7_EX256_GE8.bin показала картинку - ползущий по скале человечек, и внизу надпись красными буквами OLIMEX. Значит, мой индикатор с контроллером Epson S1D15G00.

59. Как прикрутить SD card [9]. Можно использовать как EFSL, так и FatFS. Если не нужно много возможностей, или есть жесткие ограничения по размеру кода (например, для булоадера), то можно использовать PetitFS.

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 подключение заголовка rstc.h (#include <rstc/rstc.h>), и в свойствах проекта C/C++ Compiler -> закладка Preprocessor -> отредактируйте поле Additional include directories: оно должно содержать что-то типа $PROJ_DIR$\..\..\..\at91lib\peripherals. Это для того, чтобы компилятор мог найти заголовок rstc.h.
- вставьте в начало кода, перед главным циклом main вызов RSTC_SetUserResetEnable(AT91C_BASE_RSTC, 1).

А еще лучше - добавьте такой код:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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. Как перенести проект в другую папку [10].

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 - операционная система реального времени (свободная), которая портирована на многие семейства микроконтроллеров (см. сайт www.freertos.org). Систему можно скачать в виде одного zip-архива наподобие FreeRTOSV5.1.1.zip. Этот файл содержит исходный код для ядра, порт для каждого процессора и примеры приложений. Подробно о структуре архива см. результаты поиска Source Code Organization site:freertos.org. Само ядро находится в папке 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

Появляется, когда ставишь галочку в свойствах линкера - считать контрольную сумму. См. также результаты поиска Checksum calculation with IELFTOOL after linking with ILINK site:supp.iar.com.
   
malloc не может выделить память потому, что размер кучи задан 0.

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

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

[Ссылки]

1. Макетная плата AT91SAM7X.
2. SAM3-H256, SAM3-P256, SAM7-EX256, SAM7-H256, SAM7-H64, SAM7-LA2, SAM7-MT256, SAM7-NRF24LR, SAM7-P256, SAM7-P64, SAM9-L9260, SAM9-L9261 - отладочные платы Olimex для Atmel ARM site:olimex.com. Описание на русском языке - sam7-ex256 site:sam7-ex256.narod.ru.
3. Недорогой отечественный USB-JTAG адаптер MT-LINK для ARM микроконтроллеров site:radioradar.net
4. J-Link: JTAG/SWD Emulator with USB interface site:segger.com.
5. J-Link downloads site:segger.com - драйвера и программное обеспечение для JTAG-адаптеров J-Link, ST-LINK, MT-LINK.
6. AT91 TOOLS: PLL Ratio Computing site:atmel.com
7. PLL LFT filter CALCULATOR AT91 Excel site:atmel.com
8. SAM7_EX256_GE8.zip, SAM7_EX256_GE12.zip.
9. Работа с библиотеками файловых систем для микроконтроллеров.
10. IAR EW ARM: как перенести проект в другую папку.

 

Комментарии  

 
0 #4 Петр 28.02.2011 04: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.
Цитировать
 
 
0 #3 Петр 02.08.2010 20:34
Гигантское спасибо!
Действительно, все эти конфигурации присутствуют!
Понял, как выбирать!
У нас полпервого ночи, глаз просто замылился! :-x
Еще раз спасибо!!!!!!!
Цитировать
 
 
0 #2 Петр 02.08.2010 20:07
Действительно, в примерах от atmela эти конфигурации есть!
Я пользовался готовыми проектами от iar, но там только старт из флеша! Как мне кажется...

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

microsin: в каждом примере от Atmel в комплекте есть несколько конфигураций - на flash, на SRAM и на разные версии чипа. Например, обычно есть конфигурации at91sam7x128_flash, at91sam7x128_sram, at91sam7x256_flash, at91sam7x256_sram, at91sam7x512_flash, at91sam7x512_sram - из названия сразу понятно, что это за конфигурация. Отличаются конфигурации настройками проекта и картой памяти для линкера (файл *.icf).

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

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


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

Top of Page