Program Resource

開発者向け各種コード、アルゴリズム、リソース情報ライブラリ もしくはねふぁの覚え書き

Arduinoへのスケッチ書き込み等を行う際、avrdudeを使う。普段はArduino IDEから書き込み実行するので気にする事はないが、hexファイルを直接書き込む場合やヒューズの設定を確認する場合はコマンドラインから使ったりする。

通常はUSB / シリアルで接続して使うが、avrdudeはネットワーク経由での接続にも対応している。

ESP8266やESP32とArduinoをICSP接続して、ESPに中継用スケッチを書き込みWiFiでネットワークに接続、avrdudeでESPに繋ぐ事でESPを中継してArduinoにアクセスする事が可能だ。

コマンドラインは

avrdude.exe -Cavrdude.conf -v -patmega328p -cavrisp -P net:192.168.1.100:328 -Uflash:w:somesketch.hex

の様な形式でnetパラメーターにIPアドレスとポートを指定して記述する。

が、2021年9月現在、Arduino IDEに付属しているavrdude.exe 6.3はlinuxは上記コマンドで動作するがWindows上ではエラーが発生し上手く動かない。具体的には以下の様なエラーが出る。

avrdude.exe: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "c:\Program Files (x86)\Arduino\hardware\tools\avr\etc\avrdude.conf"

             Using Port                    : net:192.168.1.100:328
             Using Programmer              : arduino
avrdude.exe: ser_drain(): read error: パラメーターが間違っています。

avrdude.exe: ser_drain(): read error: パラメーターが間違っています。

avrdude.exe: ser_drain(): read error: パラメーターが間違っています。

             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : Arduino
             Description     : Arduino

avrdude.exe: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x14

avrdude.exe: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x10
             Hardware Version: 4744608
             Firmware Version: 0.2
             Topcard         : STK502
             Vtarget         : 1.8 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

avrdude.exe: stk500_initialize(): (b) protocol error, expect=0x10, resp=0x01
avrdude.exe: initialization failed, rc=-1
             Double check connections and try again, or use -F to override
             this check.

avrdude.exe: stk500_disable(): protocol error, expect=0x14, resp=0x10

avrdude.exe done.  Thank you.

ser_drain(): や stk500_getparm(): のエラーが発生する。

avrdudeのソースを探してみるとVisual Studioでビルド出来る様にした人のソースを見つけた。

https://github.com/mariusgreuel/avrdude

上記ソース(6.3.1.1)を元に動作を調べてみると、ser_drain()はネットワーク処理が抜けていて、 stk500_getparm()はバッファに溜まった受信データが影響している様だったので、ser_drain()にネットワークの処理を追加して stk500_getparm はパラメータ取得前に古い受信データを掃除する様にしてみた。

修正したのは以下の二か所。

ser_win32.c

static int ser_drain(union filedescriptor *fd, int display)
{
#ifdef HAVE_LIBWS2_32 //added serial_over_ethernet 2021.9.16 nefa
    if (serial_over_ethernet) {
        unsigned long l;
        unsigned char buf[8];
        while (1) {
            ioctlsocket(fd->ifd, FIONREAD, &l);
            if (l == 0) {
                if (display) avrdude_message(MSG_INFO, "<drain\n");
                break;
            }
            net_recv(fd, buf, 1);
            if (display) avrdude_message(MSG_INFO, "%02x ", buf[0]);
        }
        return 0;
    }
#endif
    // int rc;
	unsigned char buf[10];
	BOOL readres;
	DWORD read;
	

stk500.c

static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
{
  unsigned char buf[16];
  unsigned v;
  int tries = 0;

 retry:
  tries++;
  buf[0] = Cmnd_STK_GET_PARAMETER;
  buf[1] = parm;
  buf[2] = Sync_CRC_EOP;

  stk500_drain(pgm, 0); //added drain 2021.9.16 nefa
  stk500_send(pgm, buf, 3);

  if (stk500_recv(pgm, buf, 1) < 0)

上記修正を入れてビルドしたバイナリを以下に置いておく。

Print Friendly, PDF & Email

This post is also available in: 英語

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


*

CAPTCHA