Как загрузить программу через последовательный порт на микроконтроллер tinyAVR-0/1 с поддержкой Optiboot_X с помощью командной строки?

Предыстория

В 2019 году Microchip приобрела Atmel и выпустила несколько новых микроконтроллеров AVR, включая серии Tiny-0 и Tiny-1. На этих микроконтроллерах традиционное программирование Atmel ICSP не поддерживалось. Вместо этого они оснащены новым однопроводным программным интерфейсом, называемым Unified Programming and Debug Interface (UPDI). Новое оборудование также сделало устаревшим существующее программирование TTL-последовательного загрузчика. Таким образом, для работы с этими микроконтроллерами, такими как pyupdi, необходимо использовать собственный программатор UPDI.

Тем не менее, разработчики Optiboot разработали новую версию загрузчика под названием Optiboot_X и внедрили протокол программирования STK500 на этих новых микроконтроллерах, что позволяет программировать эти микроконтроллеры с использованием традиционного подхода TTL-последовательного загрузчика, и, похоже, сообщество Arduino уже некоторое время поддерживает их с помощью MegaCoreX и Мегатиникор, что было для меня хорошей новостью. Тем не менее, кажется, что за пределами этих предварительно упакованных ядер Arduino мало ресурсов, в частности, почти нет документации о том, как программировать их вручную из командной строки.

То, что я уже сделал

Я разработал специальную плату разработки AVR на основе микроконтроллера Atmel ATTiny1604, который является членом нового семейства Tiny-0. По техническим соображениям он должен быть запрограммирован через последовательный порт с использованием загрузчика, аналогичного традиционному Arduino, а не UPDI (UPDI используется только для записи загрузчика).

Для достижения этой цели я установил последнюю версию binutils, GCC и экспериментальный патч для avr-libc, чтобы компилятор мог генерировать код, нацеленный на мой микроконтроллер. Затем я скомпилировал свой личный загрузчик Optiboot_X.

$ git clone https://github.com/Optiboot/optiboot.git
$ cd optiboot/optiboot/bootloaders/optiboot
$ make -f Makefile.mega0 optiboot_attiny1604.hex UARTTX=A1 TIMEOUT=8 LED=A7 BAUD_RATE=57600 LED_START_FLASHES=10

Using Compiler at: /home/user/code/optiboot/optiboot/bootloaders/optiboot/avr-gcc
avr-gcc -g -Wall -Os -fno-split-wide-types -mrelax  -DWDTTIME=8  -DLED_START_FLASHES=10  -DLED=A7   -DUARTTX=A1 -DBAUD_RATE=57600       -Wl,-section-start=.text=0 -Wl,--section-start=.application=0x200 -Wl,--section-start=.version=0x1fe -Wl,--relax -nostartfiles -nostdlib  -mmcu=attiny1604 -o optiboot_attiny1604.elf optiboot_x.c
avr-size optiboot_attiny1604.elf
   text    data     bss     dec     hex filename
    494       9       0     503     1f7 optiboot_attiny1604.elf
avr-objdump -S  optiboot_attiny1604.elf > optiboot_attiny1604.lst
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_attiny1604.elf optiboot_attiny1604.hex

Затем я загрузил загрузчик Optiboot_X в микроконтроллер ATTiny1604 через UPDI, используя pyupdi.

# set fuse BOOTEND
$ pyupdi -d tiny1604 -c /dev/ttyUSB0 -fs 8:0x02 

# burn Optiboot_X
$ pyupdi -d tiny1604 -c /dev/ttyUSB0 -f optiboot_attiny1604.hex

# reset
$ pyupdi -d tiny1604 -c /dev/ttyUSB0 -r

После записи Optiboot_X через UPDI я смог увидеть 10 импульсов во время включения питания на A7 на осциллографе, что указывает на то, что Optiboot_X был активен.

Примечание: Технически установка еще не завершена. Поскольку UPDI и / RESET используют один и тот же пин, UPDI должен быть постоянно отключен через fuse, чтобы разрешить программирование через загрузчик, но это означает, что нефункциональный загрузчик может заблокировать чип. Я решил вручную сбросить чип, включив питание платы на данный момент.

Затем я написал тестовую программу.

$ cat blink.c

#define F_CPU 20000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    PORTB.DIRSET = 0b00000001;

    while(1) {
        PORTB.OUTSET = 0b00000001;
        _delay_ms(500);
        PORTB.OUTCLR = 0b00000001;
        _delay_ms(500);
    }
}

И я его скомпилировал.

$ make
avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c
avr-objcopy -j .text -j .data -j .rodata -O ihex blink.elf blink.hex

Вопрос

И что теперь? Как мне загрузить blink.hex в Optiboot_X на микроконтроллере?

На традиционном Arduino команда выглядит примерно так ...

$ avrdude -C/etc/avrdude/avrdude.conf -v -patmega328p \
  -carduino -P/dev/ttyUSB0 -b38400 -D -Uflash:w:blink.hex:i

Но это не ATmega328P, и в Интернете почти нет документации, у меня много вопросов, и я не уверен, как действовать дальше.

Начнем с того, что в man avrdudeнет упоминания о каких-либо устройствах Tiny0 или Tiny1. Каким должен быть аргумент -p? Кроме того, нужно ли мне использовать исправленную версию avrdude? Нужен ли мне настроенный файл avrdude.conf? Если да, то где я могу их найти?

, 👍1

Обсуждение

Поскольку вы используете optiboot, avrdude не должно волновать, что это за чип., @Majenko


1 ответ


Лучший ответ:

2

Покопавшись некоторое время в репозитории git, я решил проблему. Для работы с этими новыми микроконтроллерами tinyAVR-0/1 необходима новая версия avrdude. Поскольку avrdude еще не выпустил стабильный релиз, необходимо создать новый avrdude из исходного кода из SVN.

$ svn co https://svn.savannah.nongnu.org/svn/avrdude/trunk avrdude
$ cd avrdude/avrdude
$ ./bootstrap
$ mkdir build && cd build
$ ../configure
$ make
$ make install

После установки должны быть доступны /usr/local/bin/avrdude и /usr/local/etc/avrdude.conf. Можно видеть, что была добавлена куча новых деталей tinyAVR ...

$ avrdude -p?

Valid parts are:
  [...]
  t10      = ATtiny10
  t11      = ATtiny11
  t12      = ATtiny12
  t13      = ATtiny13
  t15      = ATtiny15
  t1604    = ATtiny1604
  t1606    = ATtiny1606
  t1607    = ATtiny1607
  t1614    = ATtiny1614
  t1616    = ATtiny1616
  t1617    = ATtiny1617
  t1634    = ATtiny1634
  t20      = ATtiny20
  t202     = ATtiny202
  t204     = ATtiny204
  t212     = ATtiny212
  t214     = ATtiny214
  t2313    = ATtiny2313
  t24      = ATtiny24
  t25      = ATtiny25
  t26      = ATtiny26
  t261     = ATtiny261
  t28      = ATtiny28
  t3214    = ATtiny3214
  t3216    = ATtiny3216
  t3217    = ATtiny3217
  t4       = ATtiny4
  t40      = ATtiny40
  t402     = ATtiny402
  t404     = ATtiny404
  t406     = ATtiny406
  t412     = ATtiny412
  t414     = ATtiny414
  t416     = ATtiny416
  t417     = ATtiny417
  t4313    = ATtiny4313
  t43u     = ATtiny43u
  t44      = ATtiny44
  t441     = ATtiny441
  t45      = ATtiny45
  t461     = ATtiny461
  t5       = ATtiny5
  t804     = ATtiny804
  t806     = ATtiny806
  t807     = ATtiny807
  t814     = ATtiny814
  t816     = ATtiny816
  t817     = ATtiny817
  t84      = ATtiny84
  t841     = ATtiny841
  t85      = ATtiny85
  t861     = ATtiny861
  t88      = ATtiny88
  t9       = ATtiny9
  [...]

Чтобы запрограммировать ATTiny1604, просто запустите...

$ avrdude -C/usr/local/etc/avrdude.conf -v -pt1604 \
  -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

Не забудьте изменить аргумент -b57600, чтобы он соответствовал бод вашей сборки Optiboot_X.

Усвоенный урок: когда RTFM невозможен, используй источник, Люк!

Потенциальные проблемы

avrdude: ошибка проверки; несоответствие содержимого

Вполне возможно, что avrdude успешно устанавливает связь с платой через последовательный порт, считывает правильную сигнатуру устройства, затем пытается загрузить программу, но в конечном итоге не проходит проверку.

$ avrdude -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9425 (probably t1604)
avrdude: reading input file "blink.hex"
avrdude: writing flash (204 bytes):

Writing | ################################################## | 100% 0.06s

avrdude: 204 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 contains 204 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.06s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x01 != 0x0c
avrdude: verification error; content mismatch

Решение: В tinyAVR 0/1 загрузчик расположен в начале флэш-памяти, занимает первые 512 байт. При компиляции программы для загрузки через загрузчик необходимо указать правильное смещение текстового раздела в 512 байт. В противном случае avrdude попытается запрограммировать с 0x00, что невозможно, поскольку это местоположение загрузчика. При повторном чтении вместо вашей программы avrdude считывает загрузчик, который вызывает соответствующий сбой проверки (стоит отметить, что 0x01, первый несовпадающий байт, который вызывает сбой проверки, на самом деле является первым байтом в двоичном коде Optiboot_X).

Вместо того, чтобы использовать...

avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c

Перекомпилируйте свою программу с помощью `

avr-gcc -mmcu=attiny1604 -Wall -Os -o blink.elf blink.c \
-Wl,--section-start=.text=0x200

avr-objcopy -j .text -j .data -j .rodata -O ihex blink.elf blink.hex

И снова загрузите его.

$ avrdude -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:blink.hex:i

avrdude: Device signature = 0x1e9425 (probably t1604)
avrdude: reading input file "blink.hex"
avrdude: writing flash (716 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 716 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 contains 716 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 716 bytes of flash verified

avrdude: safemode: Fuses OK (E:FF, H:FF, L:FF)

avrdude done.  Thank you.

avrdude: тип программатора jtagice3_updi не найден

Вполне возможно, что avrdude сообщает о следующей ошибке ...

/usr/bin/avrdude -C/usr/local/etc/avrdude.conf -v -pattiny1604 -carduino -P/dev/ttyUSB0 -b38400 -D -Uflash:w:blink.hex:i

avrdude: Version 6.3, compiled on Jul 24 2019 at 00:00:00
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/usr/local/etc/avrdude.conf"
avrdude: error at "/usr/local/etc/avrdude.conf:1091: programmer type jtagice3_updi not found
avrdude: error reading system wide configuration file "/usr/local/etc/avrdude.conf"

Решение: Вы пытаетесь запустить старую версию avrdude с новым файлом конфигурации. Убедитесь, что исполняемый файл avrdude, который вы запускаете, на самом деле является обновленной версией, скомпилированной из вышестоящего репозитория SVN.

,