Как я могу заставить Леонардо перезагрузиться с помощью avrdude?



Я хочу самостоятельно скомпилировать и перенести программу Arduino на плату Leonardo.



Все отлично работает с Arduino official IDE. Я включил подробный режим для компиляции и передачи байт-кода.



Я вижу каждую командную строку.
Я хочу понять каждую строчку.



Все хорошо, кроме последнего шага: передача с avrdude.
Если я наберу точно такую же команду, то получу ошибку:



.avrdude: butterfly_recv(): programmer is not responding


Эта ошибка отсутствует, если я загружаю код с Arduino ИНТЕГРИРОВАННАЯ СРЕДА РАЗРАБОТКИ.



Я вижу разницу - Arduino IDE отображает эту строку перед вызовом avrdude:



Forcing reset using 1200bps open/close on port /dev/cu.usbmodem1431


Итак, мой вопрос заключается в том, как я могу сделать этот сброс с помощью командной строки?

545   5  

5 ответов:

Ну, вы в значительной степени написали ответ сами. Вам нужно открыть последовательное соединение на скорости 1200 БОД с Arduino, а затем закрыть соединение. Затем Arduino загрузится в SAM-BA и перезагрузится, и теперь он готов к новой программе.

Для загрузки из Windows я сделал bat файловую оболочку для avrdude.

Он идентифицировал COM-порт Leonardo с помощью WMI, сбрасывает этот COM-порт до 1200 БОД с помощью команды mode, затем идентифицирует COM-порт загрузчика и вызывает avrdude.

Прошивка должна быть помещена в прошивку.hex, но его можно изменить, чтобы он был предоставлен из командной строки

Код находится на репозитории GitHub здесь https://github.com/p1ne/arduino-leonardo-uploader

Или ниже:

@echo off
setlocal

for /f "tokens=1* delims==" %%I in ('wmic path win32_pnpentity get caption  /format:list ^| find "SparkFun Pro Micro"') do (
    call :resetCOM "%%~J"
)

:continue

:: wmic /format:list strips trailing spaces (at least for path win32_pnpentity)
for /f "tokens=1* delims==" %%I in ('wmic path win32_pnpentity get caption  /format:list ^| find "Arduino Leonardo bootloader"') do (
    call :setCOM "%%~J"
)

:: end main batch
goto :EOF

:resetCOM <WMIC_output_line>
:: sets _COM#=line
setlocal
set "str=%~1"
set "num=%str:*(COM=%"
set "num=%num:)=%"
set port=COM%num%
echo %port%
mode %port%: BAUD=1200 parity=N data=8 stop=1
goto :continue

:setCOM <WMIC_output_line>
:: sets _COM#=line
setlocal
set "str=%~1"
set "num=%str:*(COM=%"
set "num=%num:)=%"
set port=COM%num%
echo %port%
goto :flash

:flash
avrdude -v -C./avrdude.conf -patmega32u4 -cavr109 -P%port% -b57600 -D -V -Uflash:w:./firmware.hex:i

У меня была такая же проблема на macOS, я придумал следующий сценарий bash:

# find the Arduino port
ARDUINO_UPLOAD_PORT="$(find /dev/cu.usbmodem* | head -n 1)"

# reset the Arduino
stty -f "${ARDUINO_UPLOAD_PORT}" 1200

# wait for it...
while :; do
  sleep 0.5
  [ -c "${ARDUINO_UPLOAD_PORT}" ] && break
done

# ...upload!
avrdude "${OPTIONS[@]}"

Петля while - это трюк! Это будет продолжаться, как только порт Arduino снова заработает.

Это часть файла Makefile, который я написал для этого проекта: github.com/gibatronic/sesame

В Windows, в командной строке, то же решение, немного другой пакетный файл. Определяет также com-порт загрузчика. Обратите внимание, что только тот Леонардо, который будет мигать, должен быть подключен!!

@echo off
echo Upgrade procedure starting.
if %1.==. goto error
set hexfile=%1
set comportA=NONE
set comportB=NONE
if not exist %hexfile% goto error
for /f "usebackq" %%B in (`wmic path Win32_SerialPort Where "Caption LIKE '%%Leonardo%%'" Get DeviceID ^| FIND "COM"`) do set comportA=%%B
if %comportA%==NONE goto nodevice
echo Com Port for Arduino device is detected as %comportA%.
echo Reset Arduino into bootloader
mode %comportA%: baud=12 > nul
timeout 2 > nul
for /f "usebackq" %%B in (`wmic path Win32_SerialPort Where "Caption LIKE '%%Leonardo%%'" Get DeviceID ^| FIND "COM"`) do set comportB=%%B
if %comportB%==NONE goto nobldevice
echo Com Port for Arduino bootloader device is detected as %comportB%.
echo.
echo Starting AVR Downloader/UploaDEr.....
avrdude -pm32u4 -cavr109 -D -P%comportB% -b57600 -Uflash:w:%hexfile%
goto upgradedone
:nodevice
echo No matching module found, you should connect the module you want to upgrade.
goto end
:nobldevice
echo Reset into bootloader failed, please try again...
goto end
:error
Echo Missing parameter or file, you should provide the full filename of an existing .hex file you want to use.
goto end
:upgradedone
echo.
echo Upgrade done!
:end

У меня была такая же проблема. Я пробовал открывать и закрывать порт ACM0 с помощью скрипта python на скорости baudrate 1200, как кто-то уже упоминал. На меня это не подействовало. Затем я получил половину совета попробовать переключить rts/dts, и это сделает автосет. Так что в конце концов я нашел решение (по крайней мере, для меня) на Linux Mint 18.2 (Sonya).

#! /usr/bin/python

import sys
import serial

com = serial.Serial(sys.argv[1], 1200)
com.dtr=False
com.close()

Питон ./reset.py "/dev/ttyACM0 "

Dmesg показывает мне:

[21850.047120] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
[22093.700327] usb 1-1: USB disconnect, device number 53
[22094.034133] usb 1-1: new full-speed USB device number 54 using xhci_hcd
[22094.175377] usb 1-1: New USB device found, idVendor=2341, idProduct=0036
[22094.175381] usb 1-1: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[22094.175384] usb 1-1: Product: Arduino Leonardo
[22094.175387] usb 1-1: Manufacturer: Arduino LLC
[22094.175964] cdc_acm 1-1:1.0: ttyACM0: USB ACM device

Comments

    Ничего не найдено.