【问题标题】:How can I force an Arduino Leonardo to reset with AVRDUDE?如何强制 Arduino Leonardo 使用 AVRDUDE 重置?
【发布时间】:2017-03-25 13:33:33
【问题描述】:

我想在 Leonardo 板上自己编译和传输一个 Arduino 程序。

Arduino 官方 IDE 一切正常。我为编译和字节码传输启用了详细模式。

我可以看到每个命令行。
我想了解每一行。

一切都很好,除了最后一步:使用 AVRDUDE 转移。如果我输入完全相同的命令,我会得到一个错误:

.avrdude: butterfly_recv(): programmer is not responding

如果我使用 Arduino IDE 上传代码,则不会出现此错误。

我可以看到差异 - Arduino IDE 在 AVRDUDE 调用之前显示此行:

在端口 /dev/cu.usbmodem1431 上使用 1200 bps 打开/关闭强制重置

如何通过命令行进行重置?

【问题讨论】:

    标签: arduino


    【解决方案1】:

    我在 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 端口重新上线,它就会继续进行。

    这是我为 Sesame 项目编写的 Makefile 的一部分。

    【讨论】:

    【解决方案2】:

    为了从 Windows 上传,我为 AVRDUDE 制作了一个 bat 文件包装器。

    它使用 WMI 识别 Leonardo COM 端口,使用 MODE 命令将此 COM 端口重置为 1200 波特,识别引导加载程序 COM 端口并调用 AVRDUDE。

    固件应该放在firmware.hex中,但可以更改为从命令行提供。

    代码在 GitHub 存储库中,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
    

    【讨论】:

    • 我需要在启动时上传我的草图,我正在使用 Arduino UNO,这个解决方案适合我吗?
    【解决方案3】:

    我遇到了同样的问题。正如有人已经提到的,我已经尝试使用 1200 波特的 Python 脚本打开和关闭 ACM0 端口。它对我不起作用。然后我收到了半建议尝试切换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()
    
    
    python ./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
    

    【讨论】:

    • 对我来说,这(加上等待 2 秒)终于让我的 atmeg32u4 得到了它的小程序。哇!
    • 这似乎也是 Arduino Nano Every 开发板的方法。
    【解决方案4】:

    在 Windows 上,在命令提示符下,相同的解决方案,批处理文件略有不同:

    它也决定了引导加载程序的 COM 端口。请注意,只有应该连接要闪烁的 Leonardo!

    @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
    

    【讨论】:

      【解决方案5】:

      我将它用于 Nano-ever: 我认为基本要素是:

      1. 在 DTR = ON 的情况下以 1200 波特配置适当的 COM 端口
      2. 关闭 DTR。
      3. 具有正确版本的 avrdude 和 avrdude.config 的闪存设备。我的版本附带了我的 Nano-every 设备的安装。 对于其他板,可能会有所不同。第 1、2 行重置端口,我认为这与板无关,但更改端口号!

      c:\windows\system32\mode.com com6: baud=1200 dtr=on

      c:\windows\system32\mode.com com6: dtr=off

      C:\Users\Ludo\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\Ludo\AppData\Local\Arduino15\packages\arduino \tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega4809 -cjtag2updi -PCOM6 -b115200 -e -D -Uflash:w:C:\Users\Ludo\AppData\Local\Temp\arduino_build_385557/ sketch_dec11a.ino.hex:i -Ufuse2:w:0x01:m -Ufuse5:w:0xC9:m -Ufuse8:w:0x00:m {upload.extra_files}

      【讨论】:

        【解决方案6】:

        嗯,你几乎自己写了答案。

        您需要以 1200 波特的速率打开到 Arduino 的串行连接,然后关闭连接。然后 Arduino 将启动进入 SAM-BA,并自行重置,现在已准备好执行新程序。

        【讨论】:

        • 我不明白 arduino 将如何理解仅通过打开/关闭端口来重置?
        • 这里有一些内容供您阅读,arduino.cc/en/main/arduinoBoardLeonardo - 请参阅“自动(软件)重置和引导加载程序启动”部分
        【解决方案7】:

        我对 arduino leonardo 也有同样的问题。

        我想与希望使用 Qt 解决此问题的人们分享我的解决方案。

        这是可以复制和粘贴的解决方案,同时还要注意超时:

        
        #include <QtCore/QString>
        #include <QtCore/QDebug>
        #include <QtCore/QThread>
        #include <QtCore/QElapsedTimer>
        #include <QtSerialPort/QSerialPort>
        #include <QtSerialPort/QSerialPortInfo>
        
        bool forceResetComPort(const QString& portName)
        {
            QSerialPort serial;
            serial.setPortName(portName);
            serial.setBaudRate(1200);
        
            qDebug() << "Forcing reset using 1200bps open/close on port ") << portName;
            if(!serial.open(QIODevice::ReadWrite))
                return false;
        
            // This seems optional
            serial.setDataTerminalReady(false);
        
            qDebug() << "Waiting for the new upload port...";
        
            QElapsedTimer timeoutWatcher;
            qint64 timeoutMs = 10000;
            bool isPortPresent = true;
        
            const auto fetchIsPortPresent = [&]() -> bool
            {
                const auto ports = QSerialPortInfo::availablePorts();
                for(const auto& info : ports)
                {
                    if(info.portName() == serial.portName())
                        return true;
                }
                return false;
            };
        
            timeoutWatcher.start();
        
            // Wait for port to disconnect
            while(isPortPresent && !timeoutWatcher.hasExpired(timeoutMs))
            {
                isPortPresent = fetchIsPortPresent();
        
                if(isPortPresent)
                    QThread::msleep(1);
            }
        
            serial.close();
        
            // Wait for port to reconnect
            while(!isPortPresent && !timeoutWatcher.hasExpired(timeoutMs))
            {
                isPortPresent = fetchIsPortPresent();
        
                if(!isPortPresent)
                    QThread::msleep(1);
            }
         
            return !timeoutWatcher.hasExpired(timeoutMs);
        }
        
        

        一切都与时间有关。我真的需要等待串口断开才能关闭串口。

        • 关闭太快没有任何效果。
        • 关闭太慢,usb 串口正在重新连接,但端口名称不同。 (例如 /dev/ttyACM0 到 /dev/ttyACM1)。
        • 在我的情况下等待端口重新连接很重要,因为之后我在 QProcess 中调用了 avrdude。

        这里是 dmesg:

        [ 8566.623621] cdc_acm 1-8:1.0: failed to set dtr/rts
        [ 8566.979697] usb 1-8: new full-speed USB device number 21 using xhci_hcd
        [ 8567.133193] usb 1-8: New USB device found, idVendor=2341, idProduct=0036, bcdDevice= 0.01
        [ 8567.133197] usb 1-8: New USB device strings: Mfr=2, Product=1, SerialNumber=0
        [ 8567.133199] usb 1-8: Product: Arduino Leonardo
        [ 8567.133200] usb 1-8: Manufacturer: Arduino LLC
        [ 8567.134820] cdc_acm 1-8:1.0: ttyACM0: USB ACM device
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-05
          • 2021-08-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多