0

IRKitのブートローダーを破壊したので直した

ファームウェアを改造していたら、ブートローダーを壊した。
その結果、新しいファームウェアを書き込めなくなり、文鎮と化した。
AVRライターかArduinoがあれば直せる。

壊した原因

プログラムが28672byteを超えたため、Arduino互換機であるIRKitのブートローダー領域を上書きした。Arduinoはブートローダーと実行プログラムが同じプログラムメモリ上に共存しているのだ。
普通のArduino IDEを使っていれば書き込み前にサイズチェックして、こういう事にはならないのだが、inoだと考慮てくれないらしい。

githubでissueを立てたら助けてもらえた。


28672 byte以上書き込むとbootloader領域破壊する

書き込む前に.hexのサイズをチェックする
% /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-size -B .build/irkit/firmware.hex | tail -n 1 | cut -b 11-15
Arduino IDEの中にあるavr-sizeを使う。


直し方


3手必要

  1. IRKitにArduinoのブートローダーを書き込む
  2. IRKitにEEPROMを初期化するツールを書き込む
  3. IRkitのファームウェアを書き込む

前提としてIRKitのファームウェアを改造してセンサー読めるようにするに書いた、inoのインストールやboards.txtへパッチを当てる、などの作業が必要。
また、IRKitの基板上のAVRマイコンに書き込む「AVRライター」も必要。

1. IRKitにArduinoのbootloaderを書き込む


Arduino IDEのバージョンは1.0.5(現在の最新版)

基盤を取り出す


ケース背面のネジを4つ外せば取り出せる。
AVRライターを接続するためのピンヘッダ(オス)を付けた。ケースの蓋を閉めるためにピンヘッダのハンダ付けした側を少し削った。

IRKit

AVRライターを作る


純正のライターが今家に無いので、Arduino UNOをAVR書き込み器にした。
純正のSTK500やAVR-ISP、あるいはusbaspを持ってるなら必要なし。

Arduino – ArduinoISPを参考にした。

  • [ファイル]→[スケッチの例]→[ArduinoISP]

を適当なArduinoに書き込むだけ。


これでSTK500と同等のISPライターになる。
In System Programmingライター、つまり回路からターゲットCPUを取り出さずにプログラムを書き込む事ができる。

うまく書き込めない場合がある

このままライターとして使ってもうまく動かなかった。
"avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x14"
というエラーがでた。
Arduino UNOだからだろうか?他のArduinoだと大丈夫かもしれない。


のパッチをArdunoISPに当てる。empty_reply()を1回だけしか送らないようにする。
-
+int initSent=0;
int error=0;
int pmode=0;
// address for reading and writing, set by 'U' command
@@ -399,7 +399,8 @@
uint8_t ch = getch();
switch (ch) {
case '0': // signon
- empty_reply();
+ if(! initSent) empty_reply();
+ initSent = 1;
break;
case '1':
if (getch() == CRC_EOP) {
これをライター用Arduinoに書き込み直した。


IRKitとAVRライターを接続


IRKitの回路図を見ると、基板上のICPSコネクタにMISO/MOSI/SCK/RESET/5V/GNDの6ピンがある。これは上から見た図。

ICSPコネクタ
Arduino – ArduinoISPを参考に、オス-メスのジャンパワイヤ

  • Arduinoのピン13 → IRKitのSCK
  • ピン12 → MISO
  • ピン11 → MOSI
  • ピン10 → RESET
  • GND → GND
  • VCC → 5V
と接続する。

IRKit


ブートローダーを書き込む

  • [ツール]→[マイコンボード]→[IRKit]
  • [ツール]→[書込装置]→[Arduino as ISP]
  • [ツール]→[ブートローダを書き込む]

で「ブートローダの書き込みが完了しました。」と出ればok。
書き込み中はArduinoのRXとTXのLEDが点滅する。



2. IRKitにEEPROMを初期化するツールを書き込む

このままファームウェアを書き込んでも、IRKitがWiFiに接続できない。
ブートローダの書き込みにより、EEPROMが初期化されてしまっている為。(これはArduinoISPの設定でなんとかできるかもしれない)

EEPROMにはiOSアプリで設定した接続先のWiFiアクセスポイントの情報だけでなく、IRKit本体の設定用アドホックWiFiアクセスポイントの情報や、赤外線データの解析用のデータ構造も含まれている。

EEPROM初期化ツールをビルドしてIRKitに書き込む

前提としてIRKitのファームウェアを改造してセンサー読めるようにするに書いたinoのインストールやboards.txtへパッチを当てる、などの作業が必要。

IRKitのリポジトリからファームウェアやEEPROM初期化ツールのソースコードを持ってくる

% git clone git@github.com:irkit/device.git
% cd device/firmware/t/initialize-eeprom
% ino build -m irkit
% ino upload -m irkit

電源入れてすぐuploadすると書き込める。

設定用のアドホックWiFi APのパスワードはfirmware/t/initialize-eeprom/src/initialize.inoのsaveLimitedAPPassword関数で指定されている。

フルカラーLEDが赤→青に変わるとEEPROMの設定は終了。


3. IRKitにファームウェアを書き込む

IRKitのリポジトリからファームウェアをビルドする

% cd device/firmware
% ino build -m irkit
% ino upload -m irkit

なおmasterブランチが動かなければ
% git tag
% git checkout v1.3.5
などして安定版のファームウェアを書き込むと良い。


これで出荷時状態に戻る(パスワードはsaveLimitedAPPassword関数で指定したものだが)
iOSアプリで自宅のWiFiに接続する設定をして完了。

0

IRKitのファームウェアを改造してセンサー読めるようにする

読めるようにソフトウェアは改造してみたけど、肝心のセンサー自体はまだ何もつないでない。

IRKitはArduino派生のハードウェアなので、ファームウェアの改造もできる。
ファームウェアに関しては特にドキュメント読まなかった(というか何も無かった)けど、Arduinoの作法に従ってやればさくさくといじれた。プラットフォームは偉大。

とりあえずGET /messagesすると赤外線データだけでなくADコンバータ0〜5を読んでJSONに混ぜて返すようにできた

freqの次のsensorの配列がそれ。



Macでやる。多分Linuxでもできる。Windowsでは使ってるツール(ino)が動かなくて無理な気がする。


ソースをgithubからclone

https://github.com/irkit/device/wiki

% git clone git@github.com:irkit/device.git
% cd device

firmwareディレクトリ以下がソレ。

なお今いじってるリビジョンはMar 18 16:03:26 の 992a4a58b4d73d213f4083c285c8d7bac39533b3

なんか動かなくなったら
% git checkout v1.3.5
して安定版でビルドして書き込めば治せると思う。多分。


inoとは

ビルドとファームウェアの書き込みにはinoを使う。そういえば以前紹介してた。
ino使うとCUIでArduinoをビルドできて便利
inoはArduino.appを参照して使うpythonスクリプトなのでArduino.appもインストールしておく


update boards.txt

inoはboards.txtを読んでビルドや書き込み時の設定とするので、boards.txtにirkitを追加する。

それぞれ以下にある

Mac
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/boards.txt

Ubuntu
/usr/share/arduino/hardware/arduino/boards.txt

% patch -u /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/boards.txt < firmware/boards.txt.patch

irkitが使えるようになってるかチェック
% ino list-models


build


firmware/build.shを参考にした。しかし中でなんかrmしてたり、~/src/ino/bin/inoを使っていたりとハードコーディングしていたのでbuild.shを使わず手動でやった。
% cd firmware
% VERSION=`git describe --tags --long | sed -e "s/^v//" | sed -e "s/\-/./g"`
% sed -e "s/__VERSION__/$VERSION/" src/IRKit/version.template > src/IRKit/version.c
% ino build -m irkit
これでうまくいけばfirmware.hexができる。


upload hex

IRKitをMacにUSB接続してすぐ書き込む。
Arduinoは電源入ってから数秒間だけファームウェア書き込みを受け付ける為。
% ino upload -m irkit

※注意:ブートローダー破壊する可能性あり(追記)

28672 byte以上書き込むとbootloader領域破壊するので、書き込み前にhexのサイズを確認するべき。詳しくは→IRKitのブートローダーを破壊したので直した

serial monitor

なおシリアルモニタで見るとIRKitがDNSをlookupしたり色々通信しているのが見れる。
% ino serial
ctrl+a ctrl+xで終了。


ファームウェア改造


return analog sensor values on HTTP-GET /messages · 8a89128 · shokai/irkit-device


firmware/src/IRKit/IRKitHTTPHandler.cpp がHTTPのハンドラなので、
static int8_t on_get_messages_request関数にanalogReadを追加するなどした。
     gs.write("{\"format\":\"raw\",\"freq\":"); // format fixed to "raw" for now
gs.write(IrCtrl.freq);
+
+ gs.write(",\"sensor\":[");
+ for(char i = 0; i < 6; i++){
+ gs.write((uint8_t) analogRead(i));
+ if(i < 5) gs.write(",");
+ }
+ gs.write("]");
+
gs.write(",\"data\":[");
for (uint16_t i=0; i gs.write( IR_get() );

gs.write関数はGSwifi.cppに書かれている。

1

ino使うとCUIでArduinoをビルドできて便利

実際Arduinoは.inoを.cppにしてavrgccしてavrdudeしているだけなので、CUIだけで書き込むのは難しくないんだけど
いいツールがあったので今後はこれ使っていく事にしたい。

モニタついてないサーバーに接続したArduinoを直す時とかにも便利。
というかArduino IDE微妙だからいつもemacs使ってるし、もうinoでいいんじゃないかな

http://inotool.org

動作にはpythonが必要。


インストール

MacのMountain Lionでは最初からpythonとeasy_installが入っているので
% sudo easy_install ino
% which ino


プロジェクトを作る

プロジェクトのディレクトリは作ってくれない
% mkdir testapp
% cd testapp
% ino init
ディレクトリが2つ、libとsrcができる


src/sketch.ino に普通にArduinoのプログラムを書く
void setup(){
pinMode(13, OUTPUT);
}

void loop(){
digitalWrrrrrrrrrrrrrrite(13, HIGH);
delay(1000);
digitalWriteeeeeeeeeee(13, LOW);
delay(1000);
}


ボード一覧を確認

% ino list-models
Arduino Leonardoを使うので、以後のコマンドに “-m leonardo” というオプションを付ければいい


ビルド

% ino build --help
% ino build -m leonardo

ちゃんとコンパイルエラーも出る


src/sketch.inoを直す
void setup(){
pinMode(13, OUTPUT);
}

void loop(){
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}

ちゃんとhexができた


書き込む

% ino upload -m leonardo
“Guessing serial port”の後、
成功するとReading/Writing/Readingと3つのプログレスバーが100%まで伸びる。
失敗すると、最後だけ見るとdoneとか言ってるけどprogrammer is not respondingなどエラーが出る。

-p /dev/tty.usbmodem1234 のようなオプション付けるとシリアルポートを指定できる


シリアル通信

をモニタできる。


picocomが必要なのでインストールする。debian/ubuntuのaptにもあるらしい。
% brew install picocom

とりあえずSerial.printlnするようにプログラム直して
void setup(){
pinMode(13, OUTPUT);
Serial.begin(9600);
}

void loop(){
digitalWrite(13, HIGH);
delay(100);
Serial.println("on");
digitalWrite(13, LOW);
delay(100);
Serial.println("off");
}

% ino serial

ctrl+a ctrl+x で終了できる