Думаю, ни для кого не секрет, что первоначально программу в микроконтроллер заливают при помощи специального устройства — программатора. Конечно, ардуинщикам обычно не нужно об этом беспокоиться — у них есть bootloader (загрузчик), заранее прошитый в микроконтроллер, и прошивку он забирает по UART через COM-порт или через USB. Но чтобы прошить этот загрузчик или другую прошивку в «чистый» МК, нужен программатор.
Но в этой статье мы не будем рассматривать сборку и пайку программатора с нуля, а воспользуемся возможностями Arduino. Дело в том, что на большинстве плат Arduino до версии Uno есть микросхема FT232RL компании FTDI.
Эта микросхема представляет собой конвертор UART->USB, предоставляя операционной системе виртуальный COM-порт, работающий через USB. Но в данном случае нам нужна другая её возможность — управление отдельными выводам микросхемы, именуемое режимом bit-bang, которое позволяет «завернуть» произвольный протокол в USB. Задача состоит в том, завернуть в USB протокол прошивки МК.
Микроконтроллеры AVR, используемые в Arduino, прошиваются по уже знакомому нам протоколу SPI через разъём для внутрисхемного программирования — ISP (In-System Programming). Он так называется потому, что позволяет прошивать МК прямо в конечном устройстве. Вот как выглядит этот разъём на плате CraftDuino:
MISO, MOSI, SCK, RESET — это всё линии шины SPI, только вместо SS — RESET.
Но нам ещё нужен доступ выводам FT232RL, через которые будет осуществляться прошивка, и разработчики Arduino позаботились об этом, сделав разъём X3 (икс-три):
Если на вашей плате только контактные площадки для X3, нужно будет припаять кусок PLS-гребёнки самим.
Пины этого разъёма имеют следующее назначение для ISP-программатора:
- 1 (CTS) — MISO
- 2 (DSR) — SCK
- 3 (DCD) — MOSI
- 4 (RI) — RESET
А у CraftDuino вместо X3 есть стандартный разъём RS232, тоже соединённый с FT232RL, из которого нам нужны те же 4 вывода:
- 1 (CD) — MOSI
- 6 (DSR) — SCK
- 8 (CTS) — MISO
- 9 (RI) — RESET
Пораскинув мозгами, сделаем кабель для нашего импровизированного ISP-программатора:
С одного конца кабеля — разъёмы для Arduino X3/CraftDuino UART, и для питания:
А с другого конца — стандартный разъём ISP:
Обычно для прошивки AVR используется популярная утилита avrdude, которая поддерживает множество различных программаторов и моделей МК, её использует даже среда Arduino IDE для заливки скетча. Для этой утилиты есть патч, позволяющий прошивать МК через микросхему FT232RL, используя режим bit-bang. Нашлись добрые люди, которые уже пропатчили Windows-версию avrdude для работы с bit-bang-программатором на базе этой микросхемы, а я сделал то же и для Linux:
- Патченая версия 5.3.1 для Windows.
- Версия 5.10, deb-пакет для Linux i386 и amd64 (x86_64).
- Архив с исходными кодами версии 5.10, библиотекой libftd2xx-1.0.4 с официального сайта FTDI и правлеными Makefile.in и avrdude.conf, чтобы всё это собиралось, корректно устанавливалось и работало. Проверял только на Ubuntu 11.04 (i386 и amd64).
Собственно, deb-пакеты собраны из выложенного тут патченого дистрибутива, но для параноиков есть другой вариант — пропатчить и собрать avrdude самолично, про это читайте тут. Только в avrdude.conf нужно добавить следующие строчки, а не то, что написано в статье по ссылке:
programmer id = "ftbb"; desc = "FT232R Synchronous BitBang"; type = ft245r; miso = 3; # CTS X3(1) sck = 5; # DSR X3(2) mosi = 6; # DCD X3(3) reset = 7; # RI X3(4) ;
Если вы работаете в Linux, придётся сделать ещё несколько действий (FTDI нас любит):
- Убить драйвер ftdi_sio, который мешает avrdude открыть COM-порт FTDI:
sudo rmmod ftdi_sio
Если хотите, можете занести этот модуль ядра в чёрный список, внеся в /etc/modprobe.d/blacklist.conf строчку:
blacklist ftdi_sio
Только имейте ввиду, что для работы с виртуальным портом /dev/ttyUSB0 и т.п. (нужно Arduino IDE) этот модуль должен быть запущен. Это можно делать командой
sudo modprobe ftdi_sio
- По умолчанию, система при попытке avrdude открыть виртуальный COM-порт FTDI покажет ему кукиш, а он вам — не слишком информативное сообщение об ошибке. Нужно дать себе права на полный доступ к виртуальным COM-портам, создав в /etc/udev/rules.d/ файлик с именем 80-ftdi.rules следующего содержания:
SYSFS{idVendor}=="0403", SYSFS{idProduct}=="6001", MODE="660", GROUP="ftdi-user"
USB Vendor ID и Product ID можно для верности уточнить командой lsusb, если Arduino подключена к компу:
... Bus 005 Device 012: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC ...
Потом нужно создать группу ftdi-user и добавить себя в неё:
sudo addgroup ftdi-user sudo usermod -a -G ftdi-user <имя пользователя>
после чего нужно перелогиниться.
Ну и, чтобы служба udev узнала про изменения, нужно либо перезагрузить комп, либо вызвать
sudo udevadm trigger
В статье про программирование AVR на C товарищ noonv уже описал, как пользоваться avrdude, а я опишу лишь заливку загрузчика на Arduino Diecimila с ATmega168:
- Устанавливаем необходимые для быстрой прошивки загрузчика fuse-биты: кварц > 8 МГц, встроенный делитель на 8 выключен:
avrdude -c ftbb -P ft0 -p m8 -B 9600 -U hfuse:w:0xdd:m -U lfuse:w:0xff:m
- Заливаем загрузчик:
avrdude -c ftbb -P ft0 -p ATMega168 -B 19200 -U flash:w:ATmegaBOOT_168_diecimila.hex
Но консоль не всегда лучше гуя, особенно для задания fuse-битов, и есть гораздо более удобный и надёжный способ — воспользоваться программой SinaProg, разработанной иранскими программистами. Их сайт давно сдох, зато программа живёт и здравствует и по сей день. О её настройке подробно написано у Di Halt’а, ну а мы не будем терять времени и возьмём готовую настроенную сборку с пропатченным avrdude (в сборке Di Halt’а ошибка в одном из конфигов). Версии под Linux, увы, не существует.
В секции Hex file выбирается hex-файл, который нужно залить или считать. Записывать и считывать можно как память программ (Flash), так и энергонезависимую (EEPROM). В секции Device нужно указать конкретный МК, в секции Programmer — программатор (у нас это ftbb), порт (FTDI0) и скорость порта (9600).
Ну и то, ради чего стоит пользоваться этой программой — секция Fuses. В раскрывающемся списке можно выбрать предопределённые конфигурации fuse-битов, которые задаются в Fuse.txt. Но самое главное открывается нашему взору по нажатию кнопки Advanced:
Здесь можно набивать fuse-байты вручную, а можно нажимать на кнопки «C» рядом со значением байтов и выставлять фьюзы тыканием галочек с описаниями. Для заливки загрузчика сначала нажмём кнопку Read, чтобы считать текущие значения fuse, а затем настроим Low fuse: частота кварца — более 8 МГц, время старта МК — 65 мс, делитель на 8 выключен:
После настройки жмём кнопку Write и ждём появления надписи «Writing Fuses… OK».
Теперь можно в главном окне в секции Hex file выбирать файл загрузчика ATmegaBOOT_168_diecimila.hex и в секции Flash жать кнопку Program. Если в процессе будут возникать ошибки, то над индикатором прогресса есть кнопка «>», открывающая сбоку в окне лог работы avrdude.
А давайте-ка прошьём какой-нибудь другой МК — например, ATtiny13.
Поставим МК на макетку, подсоединим к ней все линии разъёма ISP от нашего bit-bang-программатора, прицепим светодиод через резистор на 500 Ом к 3-й ножке (DB4) и подтянем RESET к питанию резистором на 10 кОм:
Пишем в любимом текстовом редакторе простой код простой мигалки светодиодом в файл blink.c:
#include <avr/io.h> #include <util/delay.h> enum { LED_BIT = 1 << PORTB4 }; int main() { DDRB |= LED_BIT; while (1) { PORTB |= LED_BIT; _delay_ms(500); PORTB &= ~LED_BIT; _delay_ms(500); } }
Компилируем:
avr-gcc -DF_CPU=1200000 -Os -mmcu=attiny13 blink.c -o blink.out
Делаем hex-файл прошивки:
avr-objcopy -O ihex blink.out blink.hex
Заливаем на МК:
avrdude -c ftbb -P ft0 -p attiny13 -B 9600 -U flash:w:blink.hex
Загрузка пошла:
burjui@blackbox:~/tmp$ avrdude -c ftbb -P ft0 -p attiny13 -B 9600 -U flash:w:blink.hex avrdude: BitBang OK avrdude: pin assign miso 3 sck 5 mosi 6 reset 7 avrdude: drain OK ft245r: bitclk 4800 -> ft baud 2400 avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.00s avrdude: Device signature = 0x1e9007 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip ft245r: bitclk 4800 -> ft baud 2400 avrdude: reading input file "blink.hex" avrdude: input file blink.hex auto detected as Intel Hex avrdude: writing flash (78 bytes): Writing | ################################################## | 100% 0.64s avrdude: 78 bytes of flash written avrdude: verifying flash memory against blink.hex: avrdude: load data flash data from input file blink.hex: avrdude: input file blink.hex auto detected as Intel Hex avrdude: input file blink.hex contains 78 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 0.50s avrdude: verifying ... avrdude: 78 bytes of flash verified avrdude: safemode: Fuses OK avrdude done. Thank you.
Перевтыкаем Arduino в USB и наблюдаем мигание светодиода при условии, что нет ошибок подключения (:
Вот так, путём нехитрых манипуляций руками и мозгами, можно сделать себе USB ISP-программатор, так что не нужно париться с отсутствием LPT на современных компах и COM-порта почти на любом ноутбуке — уж USB-то есть везде.
7 комментариев на «“Делаем ISP-программатор из Arduino”»
Давно хотел узнать! Спасибо1
это одна из самых ценных статей этого ресурса
Спс!!! Как раз делаю клон мелкий на атмега8а для ночника (нашел по очень смешной цене в дип корпусе меньше 2$) а вот прошивкой никогда не занимался(((
А на ардуино уно R3 подобное возможно?
Похоже, что нет, т.к. там вместо FT232RL установлен МК ATmega32U со спец прошивкой. Во всяком случае, для такого функционала придётся писать свою прошивку (мегагемор).
Понятно, спасибо)
тоже готовил статью на эту тему, но всё никак не мог её завершить 🙂
несколько картинок:
ардуина:
с питанием:
крафтина: