ГлавнаяСтатьиЭлектроника → Самодельная Arduino на Atmega8 и её программирование в Linux.

Самодельная Arduino на Atmega8 и её программирование в Linux.

28 декабря 2013 года
Ключевые слова: Arduino , Linux

Платы Arduino удобны тем, что с ними свободно распространяется хорошая стандартная библиотека и множество примеров кода.
Это сильно ускоряет работу. Программы (так называемые скетчи) пишутся в блокноте Arduino IDE на языке Proceeding.
Но совсем нетрудно программировать их и на обычном Си используя IDE Code Blocks.

Предыстория

Недавно мне понадобилось прототипировать пару устройств. По ряду причин лучше всего подошла Arduino Duelimanove, а в закромах как раз лежали две пустые платы купленные в китайском интернет магазинчике. Но оказалось, что в наших провинциях некоторые детали достать довольно трудно, поэтому пришлось собрать упрощенный вариант с питанием только от USB и процессором Atmega8.

Схема и монтаж платы.

Схема показана на Рис.1, расположение элементов на плате на Рис.2, а фотография платы в сборе на Рис.3.
Как уже говорилось по причине дефицита деталей цепи внешнего питания нет — микросхемы IC4 MC33269D-5.0, IC5 LM358D, транзистор NDT2955, конденсаторы C6, C7 и диод D1 не впаиваются. Вместо предохранителя F1 стоит диод Шоттки типа 10BQ100 (или SM5819), а сток и исток транзистора NDT2955 замкнуты перемычкой.

Важный момент! На схеме есть резистор R2 номиналом 100 Ом соединяющий вывод RTS FT232RL с выводом RESET ATMEGA8. Этот резистор впаивать НЕ НУЖНО, иначе возникнет ошибка программирования:

avrdude: stk500_recv(): programmer is not responding

Связана она с тем, что в ходе программирования на выводе RTS устанавливается низкий уровень и микроконтроллер зависает в состоянии сброса.

Программирование микроконтроллера.

Для программирования микроконтроллера я использовал программу Avrdude, Arduino IDE и программатор USBASP.

Разрешаем программатору доступ к USB.

Как известно в Ubuntu и других дистрибутивах Linux с ним возникает распространенная проблема доступа:

$ avrdude -c usbasp -p m8

avrdude: Warning: cannot query manufacturer for device: error sending control message: Operation not permitted
avrdude: error: could not find USB device "USBasp" with vid=0x16c0 pid=0x5dc

Т.е. диспетчер udev не дает права простому пользователю писать информацию в произвольное USB устройство.
Для её решения я сперва воспользовался советом [1]. Но в Ubuntu-12.04 ничего не получилось, вероятно из-за особенностей синтаксиса файла разрешений. Правильным оказался способ приведенный в [2].

Добавляем пользователя в группу ''users'' командой:
$ sudo gpasswd --add $LOGNAME users

Затем выходим и снова входим в его учетную запись.

Создаем файл разрешений для группы users:
$ sudo nano /etc/udev/rules.d/60-objdev.rules

Помещаем в него строку:
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0666"

Обновляем правила udev:
$ sudo udevadm trigger

Проверяем, теперь всё работает:
$ avrdude -c usbasp -p m8
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e9307
avrdude: safemode: Fuses OK
avrdude done. Thank you.

Запись загрузчика Ардуино.

С программатором USBASP прошивка бутлоадера Arduino очень проста и занимает от силы пару минут.
Между ножками 9 и 10 микроконтроллера обязательно подключаем любой кварцевый резонатор на частоту от 1 до 16 МГц.
Затем подсоединяем программатор к USB порту и запускаем Arduino IDE. В меню Сервис/Плата выбираем «Arduino NG or older w/ Atmega8», Сервис/Последовательный порт «/dev/ttyUSB0», далее Сервис/Программатор «USBasp» и кликаем на пункте Сервис «Записать загрузчик». Прошивка со всеми необходимыми фьюз-битами запишется автоматически. Далее устанавливаем микроконтроллер в плату и заливаем в неё скетч Blink (Примеры / 01. Basics ) и через несколько секунд контрольный светодиод начинает равномерно мигать.

Чуть сложнее обойтись без USBASP, применив любой подходящий программатор для COM порта, например DASA3. В папке с программой arduino находим под каталог hardware/arduino/bootloaders/atmega8. Переходим в него и открываем консоль. В ней сперва подаем команду на прошивку фьюзов:

$ avrdude -q -p atmega8 -c dasa3 -P /dev/ttyS0 -b 19200 -e -U lock:w:0x3F:m -U hfuse:w:0xca:m -U lfuse:w:0xdf:m

Если все в порядке, придет ответ:
Смотреть ответ
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9307
avrdude: erasing chip
avrdude: reading input file "0x3F"
avrdude: writing lock (1 bytes):
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3F:
avrdude: load data lock data from input file 0x3F:
avrdude: input file 0x3F contains 1 bytes
avrdude: reading on-chip lock data:
avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0xca"
avrdude: writing hfuse (1 bytes):
avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xca:
avrdude: load data hfuse data from input file 0xca:
avrdude: input file 0xca contains 1 bytes
avrdude: reading on-chip hfuse data:
avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xdf"
avrdude: writing lfuse (1 bytes):
avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xdf:
avrdude: load data lfuse data from input file 0xdf:
avrdude: input file 0xdf contains 1 bytes
avrdude: reading on-chip lfuse data:
avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: safemode: Fuses OK
avrdude done. Thank you.
avrdude done. Thank you.

Затем записываем бутлоадер:

$ avrdude -q -p atmega8 -c dasa3 -P /dev/ttyS0 -b 19200 -U flash:w:ATmegaBOOT-prod-firmware-2009-11-07.hex:i -U lock:w:0x0F:m

И аналогично:
Смотреть ответ
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9307
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "ATmegaBOOT-prod-firmware-2009-11-07.hex"
avrdude: writing flash (8170 bytes):
avrdude: 8170 bytes of flash written
avrdude: verifying flash memory against ATmegaBOOT-prod-firmware-2009-11-07.hex:
avrdude: load data flash data from input file ATmegaBOOT-prod-firmware-2009-11-07.hex:
avrdude: input file ATmegaBOOT-prod-firmware-2009-11-07.hex contains 8170 bytes
avrdude: reading on-chip flash data:
avrdude: verifying ...
avrdude: 8170 bytes of flash verified
avrdude: reading input file "0x0F"
avrdude: writing lock (1 bytes):
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0F:
avrdude: load data lock data from input file 0x0F:
avrdude: input file 0x0F contains 1 bytes
avrdude: reading on-chip lock data:
avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: safemode: Fuses OK
avrdude done. Thank you.

Использование загрузчика Ардуино.

Как было бы здорово забыть про тонкости эмбеддерского ремесла: все эти ассемблеры, отладку по JTAG, срывы стека, атомарные операции, допиливание глючных сторонних библиотек и писать исключительно на Proceeding. Но у Ардуины есть слабые места - низкая скорость выполнения кода, не получаться точные измерения малых интервалов времени, поддерживается всего несколько типов процессоров.
В общем, всегда найдутся задачи которые можно решить лишь средствами Си и ассемблера.
Чтобы записать скомпилированную hex прошивку, скажем некий файл bla-bla.hex в плату надо скомандовать в консоли:

$ avrdude -c arduino -p atmega8 -P /dev/ttyUSB0 -b 19200 -U flash:w:bla-bla.hex

Опции очевидны: -с тип программатора, -b скорость обмена с платой Arduino NG которая равна 19200 бит/сек.

Для платы Arduino Nano строка выглядела бы так:

$ avrdude -c arduino -p atmega328p -P /dev/ttyUSB0 -b 57600 -U flash:w:bla-bla.hex

Кстати, если мы написали удачный скетч, то где искать hex прошивку для тиражирования? Разработчики Arduino поступили хитро и зачем-то спрятали его в системный Linux каталог /tmp. При компилировании скетча в нем появится папка с замысловатым названием, наподобие build8802347608910980979.tmp в которой и находятся тексты Си исходников скетча и hex файл прошивки.

Альтернативный загрузчик.

Если по какой-либо причине не подходит бутлоадер Ардуино его всегда можно сменить на любой другой. Например, на загрузчик Мартина Томаса. О нём подробно и понятно рассказано на easyelectronics. Остается лишь вкратце пояснить как запустить его в Linux.

Сам бутлоадер находится в папке boot_linux в этом архиве. В нем возможно понадобится отредактировать два файла - исходник main.c и makefile. Имеющаяся прошивка main.hex скомпилирована под Atmega8.

Файл main.c подробно прокомментирован. Собственно надо только выбрать частоту кварца (предлагается 16МГц, как в Ардуино), можно изменить порт индикации работы загрузчика (предлагается PB5, светодиод L он же цифровой вывод D13 Arduino), условие старта загрузчика (предлагается прерывание по начальному сбросу) и время ожидания загрузчика (выбрано 5 секунд).

В makefile достаточно расскомментировать нужный тип процессора и выбрать размер загрузочного сектора (по умолчанию предлагается 512 байт и этого обычно хватает). Файл hex прошивки получается элементарно - консольной командой make. Если что-то поменяли в исходниках, то вычищаем папку от результатов предыдущих опытов командой make clean, затем снова make.

При прошивке надо выставить следующие фьюзы: BOOTRST=0, выбрать размер загрузочной секции 512 байт BOOTSZ=01, ВЧ кварцевый генератор 16 тыс циклов 0мс SUT=01.
Как и в предыдущем случае ставим кварц и шьем фьюзы:

$ avrdude -q -c usbasp -p atmega8 -P /dev/ttyUSB0 -b 19200 -U lfuse:w:0xDF:m -U hfuse:w:0xCA:m

Затем записываем загрузчик:

$ avrdude -q -c usbasp -p ATmega8 -P /dev/ttyUSB0 -b 19200 -U flash:w:main.hex

Проверяем плату - жмем кнопку сброса и даем команду avrdude:

$ avrdude -c avr109 -p m8 -P /dev/ttyUSB0 -b 19200

Connecting to programmer:
Found programmer: Id = "AVRBOOT"; type = S
Software Version = 0.8; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=64 bytes.
Programmer supports the following devices:
Device code: 0x77
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9307
avrdude done. Thank you.

Настройка IDE Code Blocks

Русификация.

Первым делом Code Blocks надо обучить русскому языку. В дистрибутивах ALT Linux русификация работает "из коробки". Если это не так, то в меню Settings/Enviroment/View отмечаем галку Intrnalization и выбираем язык Russian. После перезапуска IDE меню русифицируется. В дистрибутивах Ubuntu локализацию надо делать вручную [3]. Идем на сайт русского перевода Code Blocks. Скачиваем там файл локализации codeblocks.po и командуем:

$ msgfmt codeblocks.po -o codeblocks.mo

Полученный codeblocks.mo нужно поместить в каталог /usr/share/codeblocks/locale/ru_RU/

Отладка.

Устанавливаем набор инструментов компилятора:

$ sudo apt-get install gcc-avr avr-libc binutils-avr

Затем отладчик и пакет симуляции микроконтроллеров:

$ sudo apt-get install gdb-avr simulavr

Кстати, двух последних пакетов в Альт Линуксе нету, вместо них более менее подходят и работают пакеты от старой Федоры avr-gdb-6.6-8.fc9.i386.rpm и simulavr-1.0.0-6.9.i586.rpm. Их можно скачать на http://rpm.pbone.net/

Теперь в меню Настройки/Compiler and debugger... сверяем опции и пути компилятора avr-gcc.


Создаем проект. Выбираем "Создать новый проект", "AVR проект". Отмечаем галками обе цели сборки "Создать отладочную (Debug)..." и "Создать окончательную (Release)..." Далее задаем тип процессора и свойства сборки (см. Рис.6). Теперь еще нужно убедиться, что для текущей цели сборки выбраны правильные флаги компилятора. В меню Проект/Параметры сборки для цели Debug отмечаем галками "Создать отладочную информацию [-g]" и "Включить стандартные предупреждения компилятора [-W]" а для цели Release соответственно "Включить стандартные предупреждения компилятора [-W]" и "Оптимизировать сгенерированный код (для размера) [-Os]". Далее все просто - выбираем на панели инструментов цель сборки и жмем на иконку в виде синего колечка.




Программную отладку обеспечивает пакет gdb-avr и имитатор микроконтроллера simulavr. Имитатор, к слову, не особо хороший. Поддерживает мало типов процессоров и не все их функции (есть проблемы с таймерами). Но, по крайне мере, он есть. Gdb-avr обычно прикручивается автоматом (см. Рис.5), но в некоторых версиях Code Block в главном меню есть специальный пункт "Отладчик", где вручную можно создать нужную конфигурацию отладчика (указать название и путь где его искать). Такие версии встречаются в дистрибутивах ALT Linux.

Программы gdb-avr и simulavr работают параллельно и обмениваются данными по протоколу TCP. Их совместная настройка кратко описана в [4].
В меню Проект/Свойства.. и открываем вкладку "Отладчик"
На вкладке "Удаленное соединение" выбираем цель Debug, тип подключения TCP, IP адрес localhost (этот же компьютер), последовательный порт остается пустым, скорость не трогаем.
На вкладке "Дополнительные команды GDB" две строки:

load
break main

Перед сеансом отладки надо запустить в консоли simulavr:

$ simulavr -g -p 1212 -d atmega8

Отладчиком управляют при помощи пиктографических кнопок (см. Рис.7). Горячие клавиши работают лишь частично. Нужные окна отладки вызывают кнопкой с синим прямоугольником. Они по умолчанию "плавающие", но можно "прилепить" их к углам, как на рисунке.

Значения локальных переменных можно найти в выпадающем списке. А как просматривать служебные регистры (порты, таймеры и прочая)? Это делается при помощи указателей. Смотрим в datasheet на страницу Register Summary (для atmega8.pdf это стр.282) и ищем адрес нужного регистра. Например регистр DDRB имеет адрес 0x37, а следующий PORTB 0x38. Тогда, чтобы просмотреть DDRB в окошке Watch надо бы щелкнуть правой кнопкой мыши и записать Си строку, читающую значение по нужному адресу, т.е. *(0x37).
Но так выведется 16 разрядное число, т.е. 2 смежных байта. Чтобы отсечь старший байт нужно читать регистр DDRB строкой:
*(0x37)&(0xff).
На этом выражении можно щелкнуть правой кнопкой мыши и в меню "Edit watch" выбрать удобный для отображения битов двоичный вид числа. Любопытно, что если ввести смещение 0x8000 то значения байтов будут повторяться.

Симуляция таймеров поддерживается, но c большими оговорками зависящими от версий GDB и Simulavr. В Ubuntu 12.04 Таймер 0 не считает, а Simulavr выдает предупреждение:

memory.c:224: WARNING: **** Attempt to read invalid io reg: TCNT0 at 0x0052

В ALT Linux Таймер 0 работает, но может не считать Таймер1.

Программирование.

И, напоследок, осталось автоматизировать программирование. В Code Block имеется пункт меню Инструменты где можно сделать кнопку вызывающую Avrdude с нужными опциями. Мне понадобилось три инструмента.

Arduino NG:

Исполняемый файл:     avrdude -c arduino -p atmega8 -P /dev/ttyUSB0 -b 19200

Arduino Nano:
Исполняемый файл:     avrdude -c arduino -p atmega8 -P /dev/ttyUSB0 -b 57600

Pinboard AVR109:
Исполняемый файл:     avrdude -c avr109 -p atmega16 -P /dev/ttyUSB0 -b 19200

Строка "Параметры" всюду одинакова:
-e -U flash:w:${TARGET_OUTPUT_DIR}${TARGET_OUTPUT_BASENAME}.elf.hex

Разработчики что-то напутали с конфигами из-за чего файл прошивки имеет двойное расширение .elf.hex


PS.     Думаю, что послесловия не нужно. Статья итак длинная :)

Оставьте свой комментарий

Ваше имя:

Комментарий:

Формулы на латехе: $$f(x) = x^2-\sqrt{x}$$ превратится в $$f(x) = x^2-\sqrt{x}$$.
Для выделения используйте следующий код: [i]курсив[/i], [b]жирный[/b].
Цитату оформляйте так: [q = имя автора]цитата[/q] или [q]еще цитата[/q].
Ссылку начните с http://. Других команд или HTML-тегов здесь нет.

Сколько будет 28+3?