Хочу рассказать вам, как использовать программаторы, основанные на микросхемах FTDI в avrdude под Linux.
Много лет назад я купил отладочный комплект Pinboard II. И ни разу за все это время не пожалел. Спроектирована с умом, содержит программатор на чипе FTDI 2232 (разработчик следит, чтобы не было подделок чипа FTDI, так что проблем не возникает). Есть GUI для avrdude с надстройкой под данное железо. Правда под Windows. Только вот я программирую в Linux. Да и GUI мне не нужен. По началу было тяжко, но когда осознал, насколько же удобна консоль… Но речь не об этом.
FTDI микросхема популярная. И её можно много где встретить. Программаторы Olimex, в Dev Kit Pinboard II, в ранних версиях Arduino… У меня, например, есть Freeduino разводки 2009 года. И на ней выведены ножки для программирования чипа без загрузчика. Правда есть небольшая проблемка, связанная с популярностью микросхемы. Её долгое время копировали, FTDI боролась с пиратами, блокировала работу, ломала микросхемы через драйвер… Однако Linux это не коснулось, так что продолжаем.
Итак. У нас есть задача: прошить микроконтроллер AVR. Для этого нужно подключить 4 сигнала: MOSI, MISO, SCK, RESET. Главное знать распиновку (какие именно ноги FTDI на какие сигналы настроены). Пока пропустим этот шаг, но запомним, что к нему, возможно, придется вернуться.
Однако, этого мало. При попытке вызвать avrdude с программатором, основанном на FTDI вываливается следующая ошибка:
avrdude: ft245r_open(): invalid device identifier ' '
Те, кто пользовался GUI в Windows, наверное, помнят, что там ещё указывался порт. Можно попробовать.
[walhi@b590] ~ $ avrdude -c ft232r -p m16 -P ft0
avrdude: ft245r_open(): invalid device identifier ' '
Увы, не сработало. Слишком много устройств может быть подключено одновременно и нужно выбрать правильное, чтобы не испортить работу остальных. Например, печатающего уже 10 часов 3D принтера. Так что требуется указать серийный номер микросхемы. Именно по нему современные версии avrdude различают устройства.
Этот серийный номер ещё нужно узнать. Для начала покажу на простом примере. Для чипа FT232, установленного на Freeduino. Он имеет всего один порт.
Смотрим список USB устройств командой lsusb
.
...
Bus 003 Device 009: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
...
Ищем в списке интересующий чип FTDI. Далее запрашивае подробную информацию по нему. Для этого нужно добавить пару аргументов: -s <bus>:<dev>
и -v
. Весь вывод не нужен, так что grep-аем строку с серийным номером.
[walhi@b590] ~ $ lsusb -s 003:009 -v |& grep iSerial
iSerial 3 A9YL3IBQ
Вот и получили серийный номер. Можно попробовать запустить avrdude. Правда она сразу сломается, так как микроконтроллер в данный момент не подключен.
[walhi@b590] ~ $ avrdude -c ft232r -p m16 -P usb:A9YL3IBQ
avrdude: Device is not responding to program enable. Check connection.
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.
avrdude done. Thank you.
Сработало. Теперь можно работать с программатором, основанным на FT232. Для старых плат Arduino в файле конфигурации avrdude имеется настроенный программатор с правильной распиновкой. Его имя diecimila
.
Теперь вернемся к Pinboard. В нем установлен FT2232, который имеет два порта. Так что с его серийным номером не все так просто.
[walhi@b590] ~ $ lsusb
...
Bus 003 Device 011: ID 0403:6010 Future Technology Devices International, Ltd FT2232C/D/H Dual UART/FIFO IC
...
[walhi@b590] ~ $ lsusb -s 003:011 -v |& grep iSerial
iSerial 0
Интересно… Серийный номер отсуствует. Но так ведь быть не должно… Посмотрим dmesg
[walhi@b590] ~ $ sudo dmesg | tail -20
...
[31533.766892] usb 3-2: new full-speed USB device number 11 using xhci_hcd
[31533.916484] usb 3-2: New USB device found, idVendor=0403, idProduct=6010, bcdDevice= 5.00
[31533.916488] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[31533.916490] usb 3-2: Product: Dual RS232
[31533.916492] usb 3-2: Manufacturer: FTDI
[31533.917689] ftdi_sio 3-2:1.0: FTDI USB Serial Device converter detected
[31533.917718] usb 3-2: Detected FT2232C
[31533.917859] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB0
[31533.918142] ftdi_sio 3-2:1.1: FTDI USB Serial Device converter detected
[31533.918168] usb 3-2: Detected FT2232C
[31533.918308] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB1
И тут тишина… Я не нашел ничего лучше, как использовать python под эту задачу. Для него есть модуль pylibftdi, которым можно воспользоваться для вывода списка устройств с их серийными номерами.
[walhi@b590] ~ $ pip3 install pylibftdi
Collecting pylibftdi
Downloading https://files.pythonhosted.org/packages/b0/b5/6413399489ebc7147079b0d6ebbd15cf5fe3b5ae06707cf3606977fa575b/pylibftdi-0.19.0-py2.py3-none-any.whl
Installing collected packages: pylibftdi
Successfully installed pylibftdi-0.19.0
[walhi@b590] ~ $ python3 -m pylibftdi.examples.info
pylibftdi version : 0.18.0
libftdi version : libftdi_version(major=1, minor=4, micro=0, version_str=b'1.4', snapshot_str=b'unknown')
libftdi library name : libftdi1.so.2
libusb version : libusb_version(major=1, minor=0, micro=22, nano=11312, rc=b'', describe=b'http://libusb.info')
libusb library name : libusb-1.0.so.0
Python version : 3.7.3
OS platform : Linux-4.19.0-12-amd64-x86_64-with-debian-10.6
[walhi@b590] ~ $ python3 -m pylibftdi.examples.list_devices
FTDI:FT232R USB UART:A9YL3IBQ
[walhi@b590] ~ $ python3 -m pylibftdi.examples.list_devices
FTDI:Dual RS232:
Опять мимо… Модуль выводит серийник у FT232, а вот FT2232 уже нет.
На этом я психанул, закрыл ноутбук, налил кофе, погладил кота, успокоился и посмотрел список программаторов, поддерживаемых avrdude.
[walhi@b590] ~ $ avrdude -c 1 |& grep 2232
2232HIO = FT2232H based generic programmer
avrftdi = FT2232D based generic programmer
Всегда в интернетиках читал, что FT2232 по сути два FT232 в одном корпусе. Но это не совсем верное утверждение. Попробовал указать avrftdi… И… Он заработал, но не нашел микроконтроллер.
[walhi@b590] ~ $ avrdude -c avrftdi -p m16
E avrftdi_program_enable(880): Device is not responding to program enable. Check connection.
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.
avrdude done. Thank you.
Отлично… Несколько часов были потрачены впустую. Ладно, идем дальше. Если чип не найден, то, скорее всего, он подключен не туда. Можно подключить в соответствии с конфигурацией avrdude, но лучше все же подправить конфигурацию, чтобы она соответствовала нашему железу.
На плате Pinboard использована следующая конфигурация:
miso = 5;
sck = 6;
mosi = 4;
reset = 7;
Как оформить в avrdude свой программатор или поправить существующий, думаю, разберетесь сами. Исходный файл конфигурации: /etc/avrdude.conf
.
И в результате получаем следующую картину:
[walhi@b590] ~ $ avrdude -c avrftdi -p m16 -C ~/avrdude.conf
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e9403 (probably m16)
avrdude: safemode: Fuses OK (E:FF, H:D1, L:FF)
avrdude done. Thank you.
Надеюсь, статья кому-нибудь помогла.
Здравствуйте! Можете ли вы приложить исходный код пересобранной avrdude? Очень хочется ее использовать на Linux, но эмулятор не тянет libusb.
Не понял вопроса… Я не пересобирал avrdude. Просто установил из репозитория. А если речь идет про Linux внутри Windows 10, то там все печально. Оно не уметь в USB устройства от слова совсем. Тогда уж лучше virtualbox, который в состоянии пробросить в виртуалку любое USB устройство.