espeink の現在の調査状況

とりあえず、問題点となるポイントが絞れてきました。

設定を終えて、再度起動するときに以下のようになります。

deep sleep 60s

þárl.lœž|.Œlà|....Œ.lì.b|Ž‚.ì.’r’bŒ.bŒònnžlnnœâì.b.pŒŽlrlrlpònà....‚.l......b.nâ|.Œll..ŽbŒònnî.lŒŽl`...nn.l`...nrŽ’’n...lœ.lpònà....rŒœœâà....b.nâ|.ŒŒŽ.à.bŒònnî...l`...nnlŒl`...nrŽ’’n..rŒ’`.`òn...žàb‚nlŒ.Œònnî..Ž.lpònà....rŒœœâàl’..b.nâ|.ìì쌎bŒònnî.lŒ.l`...nnlŒl`...nrŽ’’n..‚òl`..r’’n..‚òl`.är.Datasource http://192.168.1.17/server/espbm.php
mode : sta(18:fe:34:9b:99:a3)
add if0
scandone
add 0
aid 4
pm open phy_2,type:2 0 0
cnt 

connected with JunkHackAP, channel 6
dhcp client start...
ip:192.168.1.24,mask:255.255.255.0,gw:192.168.1.1
Wdt. This takes too long. Go to sleep.
rm match
pm close 7 0 0/19987670
deep sleep 60s

.árl.lœž|.Œlà|....Œ.lì.b|Ž‚.ì.’r’bŒ.bŒònnžlnnœâì.b.pŒŽlrlrlpònà....‚.l......b.nâ|.Œll..ŽbŒònnî.lŒŽl`...nn.l`...nrŽ’’n...lœ.lpònà....rŒœœâà....b.nâ|.ŒŒŽ.à.bŒònnî...l`...nnlŒl`...nrŽ’’n..rŒ’`.`òn...žàb‚nlŒ.Œònnî..Ž.lpònà....rŒœœâàl’..b.nâ|.ìì쌎bŒònnî.lŒ.l`...nnlŒl`...nrŽ’’n..‚òl`..r’’n..‚òl`.är.Datasource http://192.168.1.17/server/espbm.php
mode : sta(18:fe:34:9b:99:a3)
add if0
scandone
add 0
aid 4
pm open phy_2,type:2 0 0
cnt 

connected with JunkHackAP, channel 6
dhcp client start...
ip:192.168.1.24,mask:255.255.255.0,gw:192.168.1.1
Wdt. This takes too long. Go to sleep.
rm match
pm close 7 0 0/19987656
deep sleep 60s

þá

これは、DHCP でIP を取得するまえに、データソースのURL をフェッチしにいっているようで、WiFi のコネクトチェックがアボートしているので、URLにコネクトしていない状況です。どういうタイミングかはわかりませんが、極まれに以下のようになるときがあります。

deep sleep 60s

.árl.lœž|.Œlà|....Œ.lì.b|Ž‚.ì.’r’bŒ.bŒònnžlnnœâì.b.pìŽlrlrlpònà....‚.l......b.nâ|.ìllŽŽŽbŒònnî.lŒŽl`...nn.l`...nrŽ’’n..’lŽ.lpònà....rŒœœâà....b.nâ|.Œ.ŽŽŽbŒònnî...l`...nnlŒl`...nrŽ’’n..‚ŒŽ.l`òn...žàb‚nlŒ.Œònnî..Ž.lpònà....rŒœœâàlŒ..b.nâ|.ìlŽ.à.bŒònnî.lŒ.l`...nnlŒl`...nrŽ’’n..ò.œ.l.r’’n..ò.œ.lärlDatasource http://192.168.1.17:8266/server/espbm.php
mode : sta(18:fe:34:9b:99:a3)
add if0
scandone
reconnect
scandone
reconnect
scandone
reconnect
scandone
reconnect
scandone
reconnect
scandone
reconnect
scandone
reconnect
scandone
reconnect
scandone
add 0
aid 4
pm open phy_2,type:2 0 0
cnt 

connected with JunkHackAP, channel 6
dhcp client start...
No heap available, failed to malloc 440
No heap available, failed to malloc 440
Wdt. This takes too long. Go to sleep.
rm match
pm close 7 0 0/10213903
No heap available, failed to malloc 440
del if0
usl
sul 0 0
deep sleep 60s

.á

現在までで、SDK はとりあえず以下で調査しました。

SDK Version make可否 make問題点 実際の挙動 備考
0.9.2 X      
0.9.3 X      
0.9.5 O なし URL フェッチしない  
0.9.6_b1 X unknown type name ‘uint32_t’

unknown type name ‘uint16_t’

unknown type name ‘uint8_t’

  cgiwifi.c

io.h
1.0.0 X 同上    
1.0.1b1 X 同上    
1.0.1b2 X 同上    
1.0.1 O なし    
1.1.0 X eink.c で使われている

os_update_cpu_frequency

がこのSDKにない

  v1.1.0_15_05_26
1.1.1 X unknown type name ‘uint**_t’

conflicting types for ‘os_random’

  user/cgiwifi.c

user/io.h

include/espmissingincludes.h

1.1.2 X 同上   同上
1.2.0 X 同上   同上
1.3.0 X      
1.4.0 X      

※随時、更新予定。

 

SDK のバージョンがあがるごとに、廃止されたファンクションがあったり、引数が変わったりしたものがあったりと、それなりに対応が必要そうです。作者はおそらく、推測ですが0.9.5 あたりで作成しているかと思います。

 

esp-open-sdk の makefile を見ると以下のようにあり、まだ試すバージョンがあります。

VENDOR_SDK_ZIP_1.3.0 = esp_iot_sdk_v1.3.0_15_08_08.zip
VENDOR_SDK_DIR_1.3.0 = esp_iot_sdk_v1.3.0
VENDOR_SDK_ZIP_1.2.0 = esp_iot_sdk_v1.2.0_15_07_03.zip
VENDOR_SDK_DIR_1.2.0 = esp_iot_sdk_v1.2.0
VENDOR_SDK_ZIP_1.1.2 = esp_iot_sdk_v1.1.2_15_06_12.zip
VENDOR_SDK_DIR_1.1.2 = esp_iot_sdk_v1.1.2
VENDOR_SDK_ZIP_1.1.1 = esp_iot_sdk_v1.1.1_15_06_05.zip
VENDOR_SDK_DIR_1.1.1 = esp_iot_sdk_v1.1.1
VENDOR_SDK_ZIP_1.1.0 = esp_iot_sdk_v1.1.0_15_05_26.zip
VENDOR_SDK_DIR_1.1.0 = esp_iot_sdk_v1.1.0
# MIT-licensed version was released without changing version number
#VENDOR_SDK_ZIP_1.1.0 = esp_iot_sdk_v1.1.0_15_05_22.zip
#VENDOR_SDK_DIR_1.1.0 = esp_iot_sdk_v1.1.0
VENDOR_SDK_ZIP_1.0.1 = esp_iot_sdk_v1.0.1_15_04_24.zip
VENDOR_SDK_DIR_1.0.1 = esp_iot_sdk_v1.0.1
VENDOR_SDK_ZIP_1.0.1b2 = esp_iot_sdk_v1.0.1_b2_15_04_10.zip
VENDOR_SDK_DIR_1.0.1b2 = esp_iot_sdk_v1.0.1_b2
VENDOR_SDK_ZIP_1.0.1b1 = esp_iot_sdk_v1.0.1_b1_15_04_02.zip
VENDOR_SDK_DIR_1.0.1b1 = esp_iot_sdk_v1.0.1_b1
VENDOR_SDK_ZIP_1.0.0 = esp_iot_sdk_v1.0.0_15_03_20.zip
VENDOR_SDK_DIR_1.0.0 = esp_iot_sdk_v1.0.0
VENDOR_SDK_ZIP_0.9.6b1 = esp_iot_sdk_v0.9.6_b1_15_02_15.zip
VENDOR_SDK_DIR_0.9.6b1 = esp_iot_sdk_v0.9.6_b1
VENDOR_SDK_ZIP_0.9.5 = esp_iot_sdk_v0.9.5_15_01_23.zip
VENDOR_SDK_DIR_0.9.5 = esp_iot_sdk_v0.9.5
VENDOR_SDK_ZIP_0.9.4 = esp_iot_sdk_v0.9.4_14_12_19.zip
VENDOR_SDK_DIR_0.9.4 = esp_iot_sdk_v0.9.4
VENDOR_SDK_ZIP_0.9.3 = esp_iot_sdk_v0.9.3_14_11_21.zip
VENDOR_SDK_DIR_0.9.3 = esp_iot_sdk_v0.9.3
VENDOR_SDK_ZIP_0.9.2 = esp_iot_sdk_v0.9.2_14_10_24.zip
VENDOR_SDK_DIR_0.9.2 = esp_iot_sdk_v0.9.2

0.9.5 ~ 1.3.0 の間にまだあるので、それらをとりあえず全部試してみようかと。

コードの調査している部分は、

---- user_main.c
::
    httpclientFetch(myConfig.url, httpclientCb, httpclientHdrCb);
    
    einkDisplay(24*1024, tcpEinkNeedData, einkDoneCb);
::

です。古典的に、デバックにはシリアルプリントと delay を入れているんですが、コネクトしている部分がよくわからず、一体どこで、アクセスポイントに接続して、dhcp してIP をもらっているのかが良くわかっていません。このあたりは、C のデバックデックニックのスキルだと思いますが、もっと効率的なものはないでしょうかね。

 

原理的に、deep sleep から復帰したら、まずアクセスポイントにコネクトし、IP をゲットするまで delay させてからフェッチしたいんですが、そのdelay を入れるところがよくわかりません。

 

もう少し、簡単なアクセスポイントに接続するコードを書いて試してみようかと思います。部品とプリント基板を発注しようと考えていたんですが、もう少しソースコードを調査しないと動作しなさそうなので、来週以降に発注は持ち越しになりそうです。httpのtcp 経由じゃなく、ローカルのファイルシステム(espfs)に含まれる.bm ファイルは表示されている感じなので、表示することはできそうかなと思います。

 

さぁ、どこまで根気が続くかです。hack とは根気がいるものですね。推理と実験を繰り返し、1つづつ問題を把握しないといけませんが、問題を分解するのにスキルが足りていない部分は都度、勉強しながらとなるので、時間がかかります。

今のところ、このhack で勉強になったのは、基板を設計しお値打ちに作成する方法、open-sdk というものがあること、esptool にはpython 版と C 版があるということです。

 

▼まとめ

・作者はおそらく、0.9.5 か 1.0.1のSDK を使っていたと推測。

・esphttpd は、オリジナルがおそらく以下

https://github.com/OLIMEX/ESP8266/tree/master/esphttpd

・そして、最新のSDKなどにあわせて新しくなったものが以下にある

https://github.com/izhak2/esphttpd

・この単体をまず試してみようと思う。特に、新しいesphttpd は Makefile の書き方が参考になるし、新しいSDKにも対応しているようなので。

espeink の挙動

とりあえず、全体がまだ良くわかっていないけれども、E-ink とストリームするサーバが必要だということはわかったので、そのメモです。

 

ファームウェアの user/config.c 中にあるURL を以下のように書き換えて、ファームウェアをアップ。

---- user/config.c
::
void configLoad() {
    int c;
    spi_flash_read(ESP_PARAM_SEC*SPI_FLASH_SEC_SIZE, (uint32 *)&myConfig, sizeof(MyConfig));
    c=calcChsum();
    if (c!=myConfig.chsum) {
        // os_strcpy(myConfig.url, "http://meuk.spritesserver.nl/espbm.php");
        os_strcpy(myConfig.url, "http://192.168.1.17:8266/server/espbm.php");
    }
}
::

192.168.1.17:8266 は、とりあえずosx で起動しているapache です。

本来、mode が 3 で最初に起動するときは動作し、アクセスポイントに接続したら 192.168.4.1 でアクセスできるはずなんだろうけども、そのアクセスポイントに入るパスワードが良くわからず、ソースコード中でとりあえずアクセスポイントに接続するようにしてみた。そして、esp12 に他のブラウザからアクセスしてみたのが以下。

WiFi_connection

 

Datasource の URL にあるespbm.php はおそらく、.bm をストリームするものだと思うけれども、サンプルファイル中にはなく、とりあえず変換済みの.bm ファイルにリダイレクトするものを用意。具体的には、以下のようなもの。

<?php
fpassthru(fopen("../html/apconnect.bm", "r"));
exit(0);
?>

これが正しいのかどうかは、今のところ不明ですが、こうしてみると、シリアル通信は、以下のようになります。

★Reset 後の UART の内容
::

 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x40100000, len 31640, room 16 
tail 8
chksum 0x70
load 0x3ffe8000, len 2572, room 0 
tail 12
chksum 0x06
ho 0 tail 12 room 4
load 0x3ffe8a10, len 3528, room 12 
tail 12
chksum 0x7d
csum 0x7d
rlDatasource http://192.168.1.17:8266/server/espbm.php
mode : sta(18:fe:34:9b:99:a3)
add if0
scandone
reconnect
scandone
add 0
aid 5
pm open phy_2,type:2 0 0
cnt 

connected with JunkHackAP, channel 6
dhcp client start...
No heap available, failed to malloc 440★ヒープがないとさ。IPがとれていない
Wdt. This takes too long. Go to sleep.
del if0
usl
sul 3 0
rm mismatch
pm close 7 0 0/17956334
deep sleep 60s★一回スリープするが、

.árl.lœž|.Œlà|....Œ.lì.b|Ž‚.ì.’r’blŽbŒònnžlnnœâì.b.pìŽlrlrl.‚rò’nàbânbp.ü
★60秒後に起きた時には動作せず。

うーん、おしいところまではきていますが、何かがおかしいですね。

テストのために、ソースコードには以下の変更がしてあります。

1) 3.1V 以下でも動作するように定数を書き換え

2) 初回 mode(3) のアクセスポイントに入るパスワードが不明で、接続するよう設定してある

 

なんか、2の変更がまずそうかもしれません。

まぁ、でもここまでで、以下の事が、ぼやっとですがわかりました。

 

▼まとめ

・ESP12 から表示するURLは指定でき、そこから画像をストリームして表示しているだろう。

・ESP12 に表示させる画像は、別サーバから取得していることがわかった。

・初回ブートかどうかを判別させる、RTC_MAGICコード部分はうまく動作している

・初回アクセスポイントの設定に行ったとき、開発ボードのLED は光り、画像出力pin へはデータが流れているようだ。

 

▼不明なこと

・前回不明だったことがまだクリアされていない。

・最初の起動時に、192.168.4.1 で mode(3) のステーションで起動してくるが、このときのwifi アクセスポイントに入るパスワードは?

・EPS12 が設定を終えれば、定期間隔でWEB サーバを見に行くが、この処理はどうやればいいのか?

最初の部分は、ESP8266 の挙動を知れば解決できるかもしれないです。wifi_set_opmode(3); からリスタートがかかるときの挙動というか、サンプルにあるWEBサーバの挙動がどうなるか調査することに。

後者は、推測なのでなんとも言えないのですが、今のところ以下のように考えています。

・800×600 の画像を.bm の形式でストリームさせる。png を bm に変換させるサンプルスクリプトは、ソースコード中のmkimg.php がそれです。出力画像の部分をストリームさせればいいかと。どんなhttpヘッダーをつければいいのですかね?

<?php

//Small script to convert an 800x600 png into a .bm file the
//eink display can render from its internal espfs.

function convertImage($file, $out) {
    $im=imagecreatefrompng($file);
    $of=fopen($out, "w");
    for ($y=0; $y<600; $y++) {
        for ($x=0; $x<800; $x+=8) {
            $b=0;
            for ($z=0; $z<8; $z++) {
                $b<<=1;
                $c=imagecolorat($im, $x+$z, $y);
                if ((($c)&0xff)<0x80) $b|=1;
            }
            fprintf($of, "%c", $b);
        }
    }
    imagedestroy($im);
    fclose($of);
}

convertImage("icons/apconnect.png", "html/apconnect.bm");
//convertImage("★ソース画像", "★出力画像");

?>

espeink make その4

続きをやっています。昨日、esptool は C 製のを使うことがわかったので今回は実際に ESP12 に書き込んでみます。

まだ、PCB ボードは作っていませんが、開発ボードにとりあえず書き込めるかやってみようと思います。

 

書き込む開発ボードは、以下のものです。他2台は、以前にあれこれやっている最中に3.3V 以上入れすぎて壊れたようです。2台は昇天しましたので、正常なのはこれと、あと未開封のが1つあります。

dev

 

さて、ソースディレクトリに移動し、make flash してみます。

HOPE:espeink junkhack$ make flash
esptool vb64eebd - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
opening port /dev/cu.SLAB_USBtoUART at 115200
opening bootloader
resetting board
trying to connect
trying to connect
Uploading 37632 bytes from firmware/0x00000.bin to flash at 0x00000000
.....................................
starting app without reboot
closing bootloader
Please put the ESP in bootloader mode...★再度、RST を GND に
esptool vb64eebd - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
opening port /dev/cu.SLAB_USBtoUART at 115200
opening bootloader
resetting board
trying to connect
trying to connect
Uploading 166264 bytes from firmware/0x40000.bin to flash at 0x00040000
...................................................................................................................................................................
starting app without reboot
closing bootloader
HOPE:espeink junkhack$ 

 

こんな感じになれば書き込みはOK なようです。

esptool(esptool-ck) が、ファームウェアが2つ書き込むのですが、2つ目の時にも再度書き込みモードを要求してくるようなので、RST pin をGNDに落としてブートモードにします。このあたりは、実際のPCB 基盤につけた状態だとどうなるのでしょうかね?要検討です。

 

続いて、html を mkespfsimage というツールを使って圧縮しそれを 0x12000 の領域に書き込むようです。これは、以下のコマンドを使って作ることができます。

$ make webpages.espfs

が、ここで問題が2つ発生。まず、osx だと、これを実行すると、昨日試したように、

HOPE:espeink junkhack$ make webpages.espfs
cd html; find | ../mkespfsimage/mkespfsimage > ../webpages.espfs; cd ..
/bin/sh: ../mkespfsimage/mkespfsimage: cannot execute binary file
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
HOPE:espeink junkhack$

 

となってしまいfind の使い方が悪いよと、出てしまいます。make ファイルに書いてあるようにコマンドを実行してみますと

HOPE:espeink junkhack$ cd html/
HOPE:html junkhack$ find
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]

 

となります。osx の find は、引数を与えないとデフォルトでは出ない仕様のようです。なので、GNU の find を入れます。

$ brew install findutils --with-default-names

 

まず、1つ目の問題はこれでクリアです。しかし、まだ以下のようになります。

HOPE:espeink junkhack$ make webpages.espfs
cd html; find | ../mkespfsimage/mkespfsimage > ../webpages.espfs; cd ..
/bin/sh: ../mkespfsimage/mkespfsimage: cannot execute binary file

 

シェルが、mkespfsimage の、バイナリファイルを実行できないようです。このコマンドを再度 make してみます。

HOPE:mkespfsimage junkhack$ cd mkespfsimage

HOPE:mkespfsimage junkhack$ make clean
rm -f mkespfsimage main.o heatshrink_encoder.o
HOPE:mkespfsimage junkhack$ 

HOPE:mkespfsimage junkhack$ make
cc -I../lib/heatshrink -std=gnu99   -c -o main.o main.c
main.c:59:38: warning: passing 'char *' to parameter of type 'uint8_t *' (aka 'unsigned char *') converts between pointers to integer types with
      different sign [-Wpointer-sign]
                        sres=heatshrink_encoder_sink(enc, inp, insize, &len);
                                                          ^~~
../lib/heatshrink/heatshrink_encoder.h:97:14: note: passing argument to parameter 'in_buf' here
    uint8_t *in_buf, size_t size, size_t *input_size);
             ^
main.c:65:38: warning: passing 'char *' to parameter of type 'uint8_t *' (aka 'unsigned char *') converts between pointers to integer types with
      different sign [-Wpointer-sign]
                        pres=heatshrink_encoder_poll(enc, outp, outsize, &len);
                                                          ^~~~
../lib/heatshrink/heatshrink_encoder.h:102:14: note: passing argument to parameter 'out_buf' here
    uint8_t *out_buf, size_t out_buf_size, size_t *output_size);
             ^
2 warnings generated.
cc -I../lib/heatshrink -std=gnu99   -c -o heatshrink_encoder.o heatshrink_encoder.c
cc -o mkespfsimage main.o heatshrink_encoder.o
HOPE:mkespfsimage junkhack$

 

とりあえず、なんか警告は出ていますができたようです。Linux (Ubuntu)のgcc 4.8.2では以下のようになりました。

root@ub:~/work/espeink/mkespfsimage# rm mkespfsimage
root@ub:~/work/espeink/mkespfsimage# make clean
rm -f mkespfsimage main.o heatshrink_encoder.o
root@ub:~/work/espeink/mkespfsimage# 
root@ub:~/work/espeink/mkespfsimage# make
cc -I../lib/heatshrink -std=gnu99   -c -o main.o main.c
cc -I../lib/heatshrink -std=gnu99   -c -o heatshrink_encoder.o heatshrink_encoder.c
cc -o mkespfsimage main.o heatshrink_encoder.o
root@ub:~/work/espeink/mkespfsimage# 

 

osx では、gcc に以下を使っていたので出たようです。

HOPE:mkespfsimage junkhack$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

 

とりあえず、警告は出ていますが、ビルドはされているようなので、スルーします。さて、これで2番目の問題も解決できたはずです。実行してみますと、以下のようになりました。

HOPE:espeink junkhack$ make webpages.espfs
cd html; find | ../mkespfsimage/mkespfsimage > ../webpages.espfs; cd ..
140medley.min.js (74%)
apconnect.bm (15%)
batempty.bm (13%)
connecting.html (95%)
icons.png (100%)
neterror.bm (16%)
style.css (73%)
wifi.tpl (54%)
HOPE:espeink junkhack$ 

HOPE:espeink junkhack$ ll
total 120
-rw-r--r--@  1 junkhack  staff   4946  9 24 21:27 Makefile
-rw-r--r--@  1 junkhack  staff   3261  9 23 15:34 Makefile.patch
-rw-r--r--@  1 junkhack  staff   4960  9 11 00:13 Makefile_org
-rw-r--r--@  1 junkhack  staff    207  9 22 22:32 README
drwxr-xr-x   6 junkhack  staff    204  9 24 21:31 build
drwxr-xr-x   4 junkhack  staff    136  9 24 21:31 firmware
drwxr-xr-x  10 junkhack  staff    340  9 22 22:32 html
drwxr-xr-x   5 junkhack  staff    170  9 22 22:32 icons
drwxr-xr-x  10 junkhack  staff    340  9 22 22:32 include
drwxr-xr-x   3 junkhack  staff    102  9 22 22:32 lib
drwxr-xr-x   9 junkhack  staff    306  9 26 22:08 mkespfsimage
-rw-r--r--   1 junkhack  staff    638  9 22 22:32 mkimg.php
drwxr-xr-x   4 junkhack  staff    136  9 22 22:32 server
drwxr-xr-x  24 junkhack  staff    816  9 22 22:32 user
-rw-r--r--   1 junkhack  staff  31024  9 26 22:17 webpages.espfs★
HOPE:espeink junkhack$

 

★のファイルが生成されていればOK です。

なるほど、これでesp12 の中に入っているweb サーバがこのファイルシステムの中のファイルを読んで表示しているんですね。

やっとこれでhtml が書き込めるはずです。以下のようになりました。

HOPE:espeink junkhack$ make htmlflash
if [ $(stat -c '%s' webpages.espfs) -gt $(( 0x2E000 )) ]; then echo "webpages.espfs too big!"; false; fi
stat: illegal option -- c
usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
/bin/sh: line 0: [: -gt: unary operator expected
esptool -cp /dev/cu.SLAB_USBtoUART -cb 115200 -ca 0x12000 -cf webpages.espfs -v
esptool vb64eebd - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
opening port /dev/cu.SLAB_USBtoUART at 115200
opening bootloader
resetting board
trying to connect
trying to connect
Uploading 31024 bytes from webpages.espfs to flash at 0x00012000
...............................
starting app without reboot
closing bootloader
HOPE:espeink junkhack$ 

 

書き込めてはいるようですが、最初の部分で stat の使い方が悪そうと出ています。おそらくこれは、ファイルがでか過ぎないかどうかを見ているんだと思いますが、とりあえずスルーします。

あとは設定とか、WiFi E-ink とそれを見に行くサーバの設定などとなるはずです。

 

▼まとめ

・ESP12 で動作するWEB は、圧縮されたファイルシステムの中のファイルを見に行く

・そのファイルは、mkespfsimage で heatshrink を使った圧縮で作成される

・osx の find はデフォルト引数なしだと、動作しないので、gnu 版を入れる

・mkspsimage コマンドは、再度コンパイルする。

・ESP12 への書き込みは、ファームウェアは、make flash で書き込む

・ESP12 へのhtml ファイルの書き込みは、make htmlflash を使う

・make htmlflash を使ったとき、ファイルサイズの大きさをチェックしているようですがこれがosx では、動作していない模様

・おそらく書き込みには、Linux を使ったほうが楽です。

 

まだ、良くわからないことがありますが、それは追って調査します。

▼良くわからないこと

・最初の起動時に、192.168.4.1 で mode(3) のステーションで起動してくるが、このときのwifi アクセスポイントに入るパスワードは?

・EPS12 が設定を終えれば、定期間隔でWEB サーバを見に行くが、この処理はどうやればいいのか?

 

推測では、画像のURL を指定すればいける気がします。その画像ファイルは、bm 形式のもので。このあたりは、もう少し調査しないと白黒言えませんが、なんとかいけそうな気がしてきましたので、部品を発注したり、基板を発注したりするかどうか考えて見ます。実際のボードとE-ink ディスプレイがないとこれ以上の確認はちょっと厳しいです。できなくはないですが、あとは現場合わせで楽しんでもいいかなぁと。

espeink make その3

さて、その後esptool っていうのを調査しました。

Makefile には、-eo や、2番目の引数の変数に展開される –bo や –bs などがあります。

---- Makefile
::
# we create two different files for uploading into the flash
# these are the names and options to generate them
FW_FILE_1    = 0x00000
FW_FILE_1_ARGS    = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
FW_FILE_2    = 0x40000
FW_FILE_2_ARGS    = -es .irom0.text $@ -ec
::
$(FW_FILE_1): $(TARGET_OUT) firmware
    $(vecho) "FW $@"
    $(Q) $(ESPTOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)★
::

 

python の esptool.py の引数をチェックしてみると

https://github.com/themadinventor/esptool/blob/master/esptool.py

そんな引数はないので、おかしいよなぁと思い再度ググると、esptool-ck という C で書かれたヘルパーツールがあるじゃありませんか? esptool という名前は同じなので、てっきりpython のツールのことだと思っていました。

https://github.com/igrr/esptool-ck

あ、これですね、きっと。入れてみることに。

▼esptool-ck

・以下よりdownload

https://github.com/igrr/esptool-ck/releases

 

osx なので、ボリュームをマウントしておきます。

$ sudo hdiutil mount ~/Documents/case-sensitive.dmg
$ cd /Volumes/case-sensitive

バージョンは新しいのをまず試してみます。

$ wget https://github.com/igrr/esptool-ck/archive/0.4.6.tar.gz
$ tar xvfz 0.4.6.tar.gz 
$ mv esptool-ck-0.4.6/ esptool-ck
$ cd esptool-ck

 

gcc は入っているので、make し実行権限をつけます。

$make
$ chmod +x esptool

 

・/opt/配下にシンボリックリンクを張っておきます。

$ sudo ln -s /Volumes/case-sensitive/esp-open-sdk/ /opt/Espressif

・パスを反映

$ export PATH=/opt/Espressif/xtensa-lx106-elf/bin:/opt/Espressif/esptool-ck:$PATH
$ echo 'export PATH=/opt/Espressif/xtensa-lx106-elf/bin:/opt/Espressif/esptool-ck:$PATH' >> ~/.bashrc

・呼び出せればOK

$ which esptool
/opt/Espressif/esptool-ck/esptool

★espeink のソースディレクトリへ

sed -i 's/opt\/Espressif\/crosstool-NG\/builds\/xtensa-lx106-elf\/bin/opt\/Espressif\/xtensa-lx106-elf\/bin/g' Makefile
sed -i 's/\/opt\/Espressif\/ESP8266_SDK/\/opt\/Espressif\/sdk\//g' Makefile
sed -i 's/\/opt\/Espressif\/include/\/opt\/Espressif\/sdk\/include/g' Makefile
sed -i 's/\/opt\/Espressif\/arch\/lib/\/opt\/Espressif\/sdk\/lib/g' Makefile
sed -i 's/ttyUSB0/cu.SLAB_USBtoUART/g' Makefile

 

さて、make されてファームウェアもできるでしょうか?

$ make
CC user/cgiwifi.c
CC user/config.c
CC user/eink.c
CC user/espfs.c
CC user/heatshrink_decoder.c
CC user/httpd.c
CC user/httpdclient.c
CC user/httpdespfs.c
CC user/io.c
CC user/stdout.c
CC user/user_main.c
AR build/einkdisp_app.a
LD build/einkdisp.out
FW firmware/0x00000.bin
FW firmware/0x40000.bin

 

あっさり行けましたね。でも、サイズが小さいような気がします。

$ ls -al build/ firmware/
build/:
total 1464
drwxr-xr-x   6 junkhack  staff     204  9 25 02:03 .
drwxr-xr-x  16 junkhack  staff     544  9 25 02:03 ..
drwxr-xr-x   2 junkhack  staff      68  9 25 02:03 driver
-rwxr-xr-x   1 junkhack  staff  514717  9 25 02:03 einkdisp.out
-rw-r--r--   1 junkhack  staff  231744  9 25 02:03 einkdisp_app.a
drwxr-xr-x  13 junkhack  staff     442  9 25 02:03 user

firmware/:
total 408
drwxr-xr-x   4 junkhack  staff     136  9 25 02:03 .
drwxr-xr-x  16 junkhack  staff     544  9 25 02:03 ..
-rw-r--r--   1 junkhack  staff   37632  9 25 02:03 0x00000.bin
-rw-r--r--   1 junkhack  staff  166264  9 25 02:03 0x40000.bin

 

500k くらいあるeinkdisp.out がファームに入っていないような気がします。ユーザ領域じゃないのでしょうかね。メモリマップはあまり見ていないので、これをどのように書き込めばいいかはまだ不明です。

 

が、コンパイルはエラーなく通るようになりました。

SDK は、1.0.1 でとりあえずやっています。

$ cd /opt/Espressif/
HOPE:Espressif junkhack$ ll
total 128
-rw-r--r--   1 junkhack  staff  11263  9 22 22:52 Makefile
-rw-r--r--   1 junkhack  staff   5725  9 22 22:52 README.md
-rw-r--r--   1 junkhack  staff   1101  9 22 22:52 c_types-c99.patch
drwxr-xr-x  18 junkhack  staff   1462  9 22 23:24 crosstool-NG
-rw-r--r--   1 junkhack  staff    199  9 22 22:52 crosstool-config-overrides
-rw-r--r--   1 junkhack  staff    146  9 22 22:52 empty_user_rf_pre_init.c
drwxr-xr-x@ 10 junkhack  staff    442  9 23 22:34 esp_iot_sdk_v0.9.5
drwxr-xr-x@ 10 junkhack  staff    374  4 24 17:08 esp_iot_sdk_v1.0.1
drwxr-xr-x@ 10 junkhack  staff    408  9 23 14:43 esp_iot_sdk_v1.1.1
drwxr-xr-x@ 10 junkhack  staff    374  6 12 20:49 esp_iot_sdk_v1.1.2
drwxr-xr-x  10 junkhack  staff    442  9 23 00:24 esp_iot_sdk_v1.3.0
drwxr-xr-x@ 10 junkhack  staff    374  9 18 21:55 esp_iot_sdk_v1.4.0
drwxr-xr-x   2 junkhack  staff    272  9 22 22:56 esptool
drwxr-xr-x   9 junkhack  staff    646  9 24 19:58 esptool-ck
drwxr-xr-x   9 junkhack  staff    510  9 24 19:44 esptool-ck_git
drwxr-xr-x   2 junkhack  staff    170  9 22 22:52 examples
drwxr-xr-x   6 junkhack  staff    612  9 23 00:25 lx106-hal
-rw-r--r--   1 junkhack  staff  24726  8  8 16:20 release_note.txt
lrwxr-xr-x   1 junkhack  staff     18  9 23 23:53 sdk -> esp_iot_sdk_v1.0.1
drwxr-xr-x   8 junkhack  staff    306  9 23 00:21 xtensa-lx106-elf

 

Makefile には、以下のオプションも指定されているので、書き込みできるはずです。

::
flash: $(FW_FILE_1) $(FW_FILE_2)
    $(Q) $(ESPTOOL) -cp $(ESPPORT) -cb $(ESPBAUD) -ca 0x00000 -cf firmware/0x00000.bin -v
    $(Q) [ $(ESPDELAY) -ne 0 ] && echo "Please put the ESP in bootloader mode..." || true
    $(Q) sleep $(ESPDELAY) || true
    $(Q) $(ESPTOOL) -cp $(ESPPORT) -cb $(ESPBAUD) -ca 0x40000 -cf firmware/0x40000.bin -v

::


webpages.espfs: html/ mkespfsimage/mkespfsimage
    cd html; find | ../mkespfsimage/mkespfsimage > ../webpages.espfs; cd ..

mkespfsimage/mkespfsimage: mkespfsimage/
    make -C mkespfsimage

htmlflash: webpages.espfs
    if [ $$(stat -c '%s' webpages.espfs) -gt $$(( 0x2E000 )) ]; then echo "webpages.espfs too big!"; false; fi
    $(ESPTOOL) -cp $(ESPPORT) -cb $(ESPBAUD) -ca 0x12000 -cf webpages.espfs -v
::

土日にesp に書き込んでみることにします。

 

esp12 をつなげていないと、以下のようになりました。

HOPE:espeink junkhack$ make webpages.espfs
cd html; find | ../mkespfsimage/mkespfsimage > ../webpages.espfs; cd ..
/bin/sh: ../mkespfsimage/mkespfsimage: cannot execute binary file
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
HOPE:espeink junkhack$ 

HOPE:espeink junkhack$ make mkespfsimage/mkespfsimage
make: `mkespfsimage/mkespfsimage' is up to date.
HOPE:espeink junkhack$ 

HOPE:espeink junkhack$ make htmlflash
if [ $(stat -c '%s' webpages.espfs) -gt $(( 0x2E000 )) ]; then echo "webpages.espfs too big!"; false; fi
stat: illegal option -- c
usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
/bin/sh: line 0: [: -gt: unary operator expected
esptool -cp /dev/cu.SLAB_USBtoUART -cb 115200 -ca 0x12000 -cf webpages.espfs -v
esptool vb64eebd - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
opening port /dev/cu.SLAB_USBtoUART at 115200
opening bootloader
resetting board
trying to connect
trying to connect
trying to connect
resetting board
trying to connect
trying to connect
trying to connect
resetting board
trying to connect
trying to connect
trying to connect
warning: espcomm_sync failed
error: espcomm_open failed
make: *** [htmlflash] Error 255
HOPE:espeink junkhack$ 

HOPE:espeink junkhack$ make flash
esptool vb64eebd - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
opening port /dev/cu.SLAB_USBtoUART at 115200
opening bootloader
resetting board
trying to connect
trying to connect
trying to connect
resetting board
trying to connect
trying to connect
trying to connect
resetting board
trying to connect
trying to connect
trying to connect
warning: espcomm_sync failed
error: espcomm_open failed
make: *** [flash] Error 255
HOPE:espeink junkhack$ 

▼まとめ

・esptool は python のじゃなくて、C 製の esptool-ck というのを使う

・esptool-ck にはいろいろなオプションがあるようです。

・配線を以下のようにして、resetmethod=wifio などとすれば、UART の RTS and DTRを使ってブートモードにしたりできるようです。

https://github.com/esp8266/Arduino/issues/22

・できた2つのファームはサイズが小さいようだが?

・make のオプションに書き込みや、その他の何か作業するものがある

espeink make その2

作者にヘルプ要請を出しておきました。作者からレスポンスがあるまで、自分なりにもう少し調べみます。

その後、再調査でSDK 1.3.0を使うと、
unknown type name ‘uint16_t’
が出るようです。以下に情報が。

https://github.com/pfalcon/esp-open-sdk/issues/90

これは、再度指定すれば回避できそうです。
#include <stdint.h>

まぁ、でもこんなことは作者はやっていないわけで、ということは、もっと古いsdkでやっているということだと思うので代えてみます。esp_iot_sdk_v1.1.1 で とりあえずチャレンジ。

$ rm sdk
$ ln -s esp_iot_sdk_v1.1.1 sdk

・unknown type name は出なくなるが、conflicting types が出る。

    $ make
    CC user/cgiwifi.c
    In file included from user/cgiwifi.c:20:0:
    include/espmissingincludes.h:42:5: error: conflicting types for 'os_random'
     int os_random();
         ^
    In file included from user/cgiwifi.c:15:0:
    /Volumes/case-sensitive/esp-open-sdk/sdk/include/osapi.h:45:15: note: previous declaration of 'os_random' was here
     unsigned long os_random(void);
                   ^
    make: *** [build/user/cgiwifi.o] Error 1

 

・ちょっと状況は違うかもですが、以下に情報が。


http://www.esp8266.com/viewtopic.php?p=18868

おそらく作者からのコメントで、include/espmissingincludes.h のos_randomを取ってしまえば?と。

はい、とりました。

---- espmissingincludes.h
::
uint32 system_get_time();
//int os_random();
int rand(void);
::

 

・すると、user/cgiwifi.c は通り、次なるエラーが。プロトタイプ宣言がないようです。

    $ make
    CC user/cgiwifi.c
    CC user/config.c
    CC user/eink.c
    user/eink.c: In function 'einkTimerCb':
    user/eink.c:60:3: error: implicit declaration of function 'os_update_cpu_frequency' [-Werror=implicit-function-declaration]
       os_update_cpu_frequency(160);
       ^
    cc1: all warnings being treated as errors
    make: *** [build/user/eink.o] Error 1

 

 

einkTimerCb関数の中から呼ばれているようです。

こいつは、ソース全体をgrep しても出ないので、sdk の組み込み関数のようです。なんと宣言すればよいのでしょうかね?

以下のリリースノートによると、esp_iot_sdk_v1.1.0_15_05_26 でなくなったようです!

http://www.esp8266.com/viewtopic.php?p=18496

その前の、esp_iot_sdk_v1.0.1/include/osapi.h にはあるようです。

ということは、作者はesp_iot_sdk_v1.0.1より前のSDK を使っていたということですね。

ソース修正はとりあえず、後回しで、今は作者の環境を推測し、最後までコンパイルが通る環境を探るのが優先です。

http://bbs.espressif.com/viewforum.php?f=46

の一覧から、esp_iot_sdk_v1.0.1_15_04_24 がありました。

リリース日は、Fri Apr 24, 2015 10:49 pm です。

http://bbs.espressif.com/viewtopic.php?f=46&t=398

ダウンロードし、解凍してシンボリックリンクを張り直します。

$ rm sdk

$ ln -s esp_iot_sdk_v1.0.1 sdk

・再度make

$ make clean
$ make
CC user/cgiwifi.c
CC user/config.c
CC user/eink.c
CC user/espfs.c
CC user/heatshrink_decoder.c
CC user/httpd.c
CC user/httpdclient.c
CC user/httpdespfs.c
CC user/io.c
CC user/stdout.c
CC user/user_main.c
AR build/einkdisp_app.a
LD build/einkdisp.out
FW firmware/0x00000.bin
make: esptool: No such file or directory
make: *** [firmware/0x00000.bin] Error 1

 

・おおお、make は通ったようです。esptool がないとか言っていますね。

$ which esptool.py

/usr/local/bin/esptool.py

・あるので、以下のように指定し直します。

---- Makefile
::
#Esptool.py path and port
ESPTOOL        ?= /usr/local/bin/esptool.py
::

・さて、再度挑戦。

$ make clean
$ make
CC user/cgiwifi.c
CC user/config.c
CC user/eink.c
CC user/espfs.c
CC user/heatshrink_decoder.c
CC user/httpd.c
CC user/httpdclient.c
CC user/httpdespfs.c
CC user/io.c
CC user/stdout.c
CC user/user_main.c
AR build/einkdisp_app.a
LD build/einkdisp.out
FW firmware/0x00000.bin
usage: esptool [-h] [--port PORT] [--baud BAUD]
               
               {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,flash_id,read_flash,erase_flash}
               ...
esptool: error: argument operation: invalid choice: 'build/einkdisp.out' (choose from 'load_ram', 'dump_mem', 'read_mem', 'write_mem', 'write_flash', 'run', 'image_info', 'make_image', 'elf2image', 'read_mac', 'flash_id', 'read_flash', 'erase_flash')
make: *** [firmware/0x00000.bin] Error 2

 

・ううむ、esptool の使い方が違うよと出ているようです。

makefile には次のように書かれています。

---- Makefile
::
$(FW_FILE_1): $(TARGET_OUT) firmware
    $(vecho) "FW $@"
    $(Q) $(ESPTOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)
::

 

使い方は、以下のようです。

-eo とかなんでしょうね? 説明にありませんが、、、

 

    $ esptool.py -h
    usage: esptool [-h] [--port PORT] [--baud BAUD]
                   
                   {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,flash_id,read_flash,erase_flash}
                   ...
    
    ESP8266 ROM Bootloader Utility
    
    positional arguments:
      {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,flash_id,read_flash,erase_flash}
                            Run esptool {command} -h for additional help
        load_ram            Download an image to RAM and execute
        dump_mem            Dump arbitrary memory to disk
        read_mem            Read arbitrary memory location
        write_mem           Read-modify-write to arbitrary memory location
        write_flash         Write a binary blob to flash
        run                 Run application code in flash
        image_info          Dump headers from an application image
        make_image          Create an application image from binary files
        elf2image           Create an application image from ELF file
        read_mac            Read MAC address from OTP ROM
        flash_id            Read SPI flash manufacturer and device ID
        read_flash          Read SPI flash content
        erase_flash         Perform Chip Erase on SPI flash
    
    optional arguments:
      -h, --help            show this help message and exit
      --port PORT, -p PORT  Serial port device
      --baud BAUD, -b BAUD  Serial port baud rate

 

・変数には以下が入っているので、★は以下のようです。

/usr/local/bin/esptool.py -eo build/einkdisp.out -bo $@ -bs .text -bs .data -bs .rodata -bc -ec

 

うーん、よくわかりませんね。まぁ、とにかくesptool.pyの使い方ということを調査すれば解決するかもです。

esptool.pyっていうのは、アップロードするだけのものと思っていましたが、他にも用途があるということですかね。

 

---- Makefile
::
BUILD_BASE    = build
::
ESPTOOL        ?= /usr/local/bin/esptool.py
::
# name for the target project
TARGET        = einkdisp
::
TARGET_OUT    := $(addprefix $(BUILD_BASE)/,$(TARGET).out)
::
# we create two different files for uploading into the flash
# these are the names and options to generate them
FW_FILE_1    = 0x00000
FW_FILE_1_ARGS    = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
FW_FILE_2    = 0x40000
FW_FILE_2_ARGS    = -es .irom0.text $@ -ec
::
$(FW_FILE_1): $(TARGET_OUT) firmware
    $(vecho) "FW $@"
    $(Q) $(ESPTOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)★
::

 

・以下な感じにしてみると、作られますが、ファイルサイズが小さいので、やっぱりだめかな?

---- Makefile
::
$(FW_BASE)/%.bin: $(TARGET_OUT) | $(FW_BASE)
    $(vecho) "FW $(FW_BASE)/"
    $(Q) $(ESPTOOL) elf2image -o $(FW_BASE)/ $(TARGET_OUT)
#    $(Q) $(ESPTOOL) -o $(TARGET_OUT) $(FW_FILE_1_ARGS)

$(FW_FILE_2): $(TARGET_OUT) firmware
    $(vecho) "FW $(FW_BASE)/"
    $(Q) $(ESPTOOL) -o $(TARGET_OUT) $(FW_FILE_2_ARGS)
::

 

$ make
CC user/cgiwifi.c
CC user/config.c
CC user/eink.c
CC user/espfs.c
CC user/heatshrink_decoder.c
CC user/httpd.c
CC user/httpdclient.c
CC user/httpdespfs.c
CC user/io.c
CC user/stdout.c
CC user/user_main.c
AR build/einkdisp_app.a
LD build/einkdisp.out
FW firmware/

$ ls -ltr firmware/ build/
firmware/:
total 408
-rw-r--r--  1 junkhack  staff  166264  9 24 02:00 0x40000.bin
-rw-r--r--  1 junkhack  staff   37632  9 24 02:00 0x00000.bin

build/:
total 1464
drwxr-xr-x   2 junkhack  staff      68  9 23 02:05 driver
drwxr-xr-x  13 junkhack  staff     442  9 24 02:00 user
-rw-r--r--   1 junkhack  staff  231984  9 24 02:00 einkdisp_app.a
-rwxr-xr-x   1 junkhack  staff  514957  9 24 02:00 einkdisp.out

 

このあたりを読んでみますか。

https://github.com/themadinventor/esptool

とりあえず、本日はここまで。

▼まとめ

・sdk は、esp_iot_sdk_v1.0.1より前のを使っていたようです。

・esp_iot_sdk_v1.0.1_15_04_24 でコンパイルエラーはなくなった

・esptool.py でファームウェアを作るところがうまくいかない

・linux 版のesptool.py とかだと、あのオプション指定が通るのか?

・実行ファイルeinkdisp.outは、作成できている模様

・ファームウェアのどの領域にどうやって作成するのかを調査すればよさそう

espeink のソースをコンパイル

さて、ハードの調査が終わったので、今度はソースファイルの調査です。

まず、ざっとソースコードを見てみます。

osx 10.9.5 でやっています。

▼ソースをゲット
$ git clone http://git.spritesserver.nl/espeink.git/
$ cd espeink/
$ git submodule init
$ git submodule update

以下のことがわかりました。

▼ソフトウェア概略
・ESP12 の中で動作するwebサーバがmkespfsimageを使いe-ink にレンダリング
・データ受け渡しは、PhantomJS(pixelserver.js)を使っているよう
・画像形式は、.bm という白黒2値(グレー表示はあるのかな?)800×600を使用
・デフォルトで60秒ごとにsleep から目覚めるよう -> sleeptime , system_deep_sleep(60*1000*1000);
・初回起動時は、アクセスポイントの表示の初期設定が動作。メモリの特定領域に値があるかないかを見ている模様 -> RTC_MAGIC
・ライセンスは、Beer-Ware license 🙂
https://en.wikipedia.org/wiki/Beerware
  これは作者のジョークかと。GPLライブラリーにリンクしているのでこのソースもGPLになりますが、
  何か作者に送りたいですよね。
・圧縮ライブラリに、Heatshrink使用
https://github.com/atomicobject/heatshrink
  Lempel–Ziv–Storer–Szymanski (LZSS)ベースのようです。
・ソースをビルドするには、SDK (toolchain) が必要
・esp-open-sdkの環境を作れば良いかと思う
・環境構築は、osx でまずチャレンジ

 

PhantomJSって何でしょうか?

とりあえず、まぁ、使ってみれば理解も深まるはずです。

osx のローカルに入れてみます。

$ brew install phantomjs

サンプルはググって以下のようにしました。

---- test.js
// Headless ブラウザの生成
var page = require('webpage').create();

// URL を開く
page.open('http://hack.gpl.jp/about/', function(status) {
    if (status === 'success') {
        // スクリーンキャプチャ
        page.render('junkhack.png');
        // ブラウザ内で JS を実行してデータを受け取る
        var title = page.evaluate(function() {
            var title = document.title;
            return title;
        });
        console.log(title);
    }
    // exit しないと終了しない
    phantom.exit();
});

 

・実行してみます。

$ phantomjs test.js

カレントディレクトリに、junkhack.png ができている。ほーなるほど。

ということは、PhantomJSが動作するサーバが必要だってことでしょうかね?ESP12 でPhantomJSが動作するということですかね?ちょっとこのあたりは良くわかっていません。

その内、進むにつれ解るはずだと思うので、スルーします。

 

junkhack 2

とりあえず、osx でビルドする環境を整えてみることにしてみます。

 

▼ビルドする環境の構築 for osx 10.9.5

・以下にある説明通り

https://github.com/pfalcon/esp-open-sdk

$ brew tap homebrew/dupes

$ brew install binutils coreutils automake wget gawk libtool gperf gnu-sed –with-default-names grep

★ちょっと時間はかかります。エラーになっていないかコンソールを確認。

 

・sed は gnu のを使うようにするようです。以下のようにならなければ、パスを.bash_profileに設定しておきます。

    $ which sed

    /usr/local/opt/gnu-sed/libexec/gnubin/sed

$ export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"

 

・10G の大文字小文字ファイル名を区別するHFS+ボリュームを作製。マウントし、移動。

$ sudo hdiutil create ~/Documents/case-sensitive.dmg -volname "case-sensitive" -size 10g -fs "Case-sensitive HFS+"
$ sudo hdiutil mount ~/Documents/case-sensitive.dmg
$ cd /Volumes/case-sensitive

$ git clone --recursive https://github.com/pfalcon/esp-open-sdk.git

スタンドアローンなSDK を作れば、-Iと-Lフラグを付けなくてよいようですが、espeink のmakefile は

-I と -L は指定されているので、SDK を分離して作ります。

$ cd esp-open-sdk/

$ make STANDALONE=n

★ちょっと時間はかかります。コーヒータイムです。

ESP8266 のチップは、ケイデンス・デザイン・システムズ社が作っているXtensaプロセッサなんですね。

Espressif Systems社がカスタマイズした、テンシリカXtensaプロセッサが載っているということの

ようです。

https://www.cadence.co.jp/news/2015-01-29-929.html

 

・さて、以下のようになっていればOKです。パスを追加します。

    ::

    Xtensa toolchain is built, to use it:

    export PATH=/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin:$PATH

    Espressif ESP8266 SDK is installed. Toolchain contains only Open Source components

    To link external proprietary libraries add:

    xtensa-lx106-elf-gcc -I/Volumes/case-sensitive/esp-open-sdk/sdk/include -L/Volumes/case-sensitive/esp-open-sdk/sdk/lib

 

・ここもパスを通しておきます。

---- .bashrc 追記
export PATH=/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin:$PATH
以下に、コンパイラがあります。

$ ls /Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin

esptool.py            xtensa-lx106-elf-ct-ng.config    xtensa-lx106-elf-gcov        xtensa-lx106-elf-ranlib

xtensa-lx106-elf-addr2line    xtensa-lx106-elf-elfedit    xtensa-lx106-elf-gdb        xtensa-lx106-elf-readelf

xtensa-lx106-elf-ar        xtensa-lx106-elf-g++        xtensa-lx106-elf-gprof        xtensa-lx106-elf-size

xtensa-lx106-elf-as        xtensa-lx106-elf-gcc        xtensa-lx106-elf-ld        xtensa-lx106-elf-strings

xtensa-lx106-elf-c++        xtensa-lx106-elf-gcc-4.8.2    xtensa-lx106-elf-ld.bfd        xtensa-lx106-elf-strip

xtensa-lx106-elf-c++filt    xtensa-lx106-elf-gcc-ar        xtensa-lx106-elf-nm

xtensa-lx106-elf-cc        xtensa-lx106-elf-gcc-nm        xtensa-lx106-elf-objcopy

xtensa-lx106-elf-cpp        xtensa-lx106-elf-gcc-ranlib    xtensa-lx106-elf-objdump

 

・コンパイラが呼び出せればOKです。

$ which xtensa-lx106-elf-gcc

/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc

$ xtensa-lx106-elf-gcc –version

xtensa-lx106-elf-gcc (crosstool-NG 1.20.0) 4.8.2

Copyright (C) 2013 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

・何かコンパイルして動作確認してみましょう。

$ git clone https://github.com/esp8266/source-code-examples.git
$ cd source-code-examples/blinky

 

・sed で make ファイルの指定を書き換えます。

※パスがあるので、解りにくい。sed は s/置き換え前/置き換え後/g です。

以下だと、

Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin

を以下に置き換え

esp-open-sdk/xtensa-lx106-elf/bin

  Espressif/ESP8266_SDK

  を以下に置き換え

  esp-open-sdk/sdk

  Espressif

  を以下に置き換え

  esp-open-sdk

  opt/

  を以下に置き換え

  Volumes/case-sensitive/

$ sed -i 's/Espressif\/crosstool-NG\/builds\/xtensa-lx106-elf\/bin/esp-open-sdk\/xtensa-lx106-elf\/bin/g' Makefile
$ sed -i 's/Espressif\/ESP8266_SDK/esp-open-sdk\/sdk/g' Makefile
$ sed -i 's/Espressif/esp-open-sdk/g' Makefile
$ sed -i 's/opt\//Volumes\/case-sensitive\//g' Makefile

 

make してみます。

$ make

・以下が実行結果です。エラーなくビルドできればまぁ、動くでしょう。

$ tree

.

├── Makefile

├── README

├── build

│   ├── app.out★実行バイナリファイル

│   ├── app_app.a

│   ├── driver

│   └── user

│       └── user_main.o

├── firmware

│   ├── 0x00000.bin★

│   └── 0x40000.bin★

└── user

    ├── user_config.h

    └── user_main.c

5 directories, 9 files

 

▼とりあえず、esp-open-sdk でコンパイルしてみます。Makefile のコピーを取ってパスを書き換え。

$ cd espeinkのソース

$ cp Makefile Makefile_org

※行頭の$ は取ってあります。

sed -i 's/Espressif\/crosstool-NG\/builds\/xtensa-lx106-elf\/bin/esp-open-sdk\/xtensa-lx106-elf\/bin/g' Makefile
sed -i 's/Espressif\/ESP8266_SDK/esp-open-sdk\/sdk/g' Makefile
sed -i 's/Espressif/esp-open-sdk/g' Makefile
sed -i 's/opt\/Espressif\/arch\/lib/Volumes\/case-sensitive\/esp-open-sdk\/sdk\/lib/g' Makefile
sed -i 's/opt\//Volumes\/case-sensitive\//g' Makefile

・osx じゃなく、Linux でやっている場合はほどよく書き換え。以下のようにパスを変更しました。

$ diff Makefile Makefile_org 
15c15
< XTENSA_TOOLS_ROOT ?= /Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin
---
> XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
18,19c18,19
< SDK_EXTRA_INCLUDES ?= /Volumes/case-sensitive/esp-open-sdk/include
< SDK_EXTRA_LIBS ?= /Volumes/case-sensitive/esp-open-sdk/sdk/lib
---
> SDK_EXTRA_INCLUDES ?= /opt/Espressif/include
> SDK_EXTRA_LIBS ?= /opt/Espressif/arch/lib
22c22
< SDK_BASE    ?= /Volumes/case-sensitive/esp-open-sdk/sdk
---
> SDK_BASE    ?= /opt/Espressif/ESP8266_SDK

 

・さて、makeしてみます。

make しましたが、なんかエラーでますね。作者は、SDK バージョンいくつを使っていたのでしょうか?

unknown type name ‘uint32_t’

unknown type name ‘uint8_t’

unknown type name ‘uint16_t’

conflicting types for ‘os_random’

    $ make

    CC user/cgiwifi.c

    In file included from /Volumes/case-sensitive/esp-open-sdk/sdk/include/os_type.h:10:0,

                     from /Volumes/case-sensitive/esp-open-sdk/sdk/include/user_interface.h:9,

                     from user/cgiwifi.c:17:

    /Volumes/case-sensitive/esp-open-sdk/sdk/include/ets_sys.h:14:1: error: unknown type name ‘uint32_t’

     typedef uint32_t ETSSignal;

     ^

    /Volumes/case-sensitive/esp-open-sdk/sdk/include/ets_sys.h:15:1: error: unknown type name ‘uint32_t’

     typedef uint32_t ETSParam;

     ^

    /Volumes/case-sensitive/esp-open-sdk/sdk/include/ets_sys.h:27:1: error: unknown type name ‘uint32_t’

     typedef uint32_t ETSHandle;

     ^

    /Volumes/case-sensitive/esp-open-sdk/sdk/include/ets_sys.h:32:5: error: unknown type name ‘uint32_t’

         uint32_t              timer_expire;

         ^

    /Volumes/case-sensitive/esp-open-sdk/sdk/include/ets_sys.h:33:5: error: unknown type name ‘uint32_t’

         uint32_t              timer_period;

         ^

    In file included from user/cgiwifi.c:17:0:

    /Volumes/case-sensitive/esp-open-sdk/sdk/include/user_interface.h:316:1: error: unknown type name ‘uint8_t’

     void wifi_promiscuous_set_mac(const uint8_t *address);

     ^

    In file included from user/cgiwifi.c:20:0:

    user/io.h:3:16: error: unknown type name ‘uint16_t’

     void ioSpiSend(uint16_t data);

                    ^

    user/io.h:8:18: error: unknown type name ‘uint8_t’

     void ioEinkWrite(uint8_t data);

                      ^

    In file included from user/cgiwifi.c:21:0:

    include/espmissingincludes.h:42:5: error: conflicting types for ‘os_random’

     int os_random();

         ^

    In file included from user/cgiwifi.c:16:0:

    /Volumes/case-sensitive/esp-open-sdk/sdk/include/osapi.h:45:15: note: previous declaration of ‘os_random’ was here

     unsigned long os_random(void);

                   ^

    make: *** [build/user/cgiwifi.o] Error 1

 

▼sdk をいろいろ代えて試し、0.9.5あたりから試しました。

$ cd /Volumes/case-sensitive/esp-open-sdk/

$ ln -s esp_iot_sdk_v0.9.5 sdk

▼バイナリはできるけども、ファームウェアができないので、Makefile を書き換え。

※ まだ実機で試していないので、これで良いか不明ですが。

$ cat Makefile.patch 
--- Makefile_org    2015-09-11 00:13:00.000000000 +0900
+++ Makefile    2015-09-23 15:29:56.000000000 +0900
@@ -12,18 +12,18 @@ BUILD_BASE    = build
 FW_BASE        = firmware
 
 # Base directory for the compiler
-XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
+XTENSA_TOOLS_ROOT ?= /Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin
 
 #Extra Tensilica includes from the ESS VM
-SDK_EXTRA_INCLUDES ?= /opt/Espressif/include
-SDK_EXTRA_LIBS ?= /opt/Espressif/arch/lib
+SDK_EXTRA_INCLUDES ?= /Volumes/case-sensitive/esp-open-sdk/include
+SDK_EXTRA_LIBS ?= /Volumes/case-sensitive/esp-open-sdk/sdk/lib
 
 # base directory of the ESP8266 SDK package, absolute
-SDK_BASE    ?= /opt/Espressif/ESP8266_SDK
+SDK_BASE    ?= /Volumes/case-sensitive/esp-open-sdk/sdk
 
 #Esptool.py path and port
-ESPTOOL        ?= esptool
-ESPPORT        ?= /dev/ttyUSB0
+ESPTOOL        ?= esptool.py
+ESPPORT        ?= /dev/tty.SLAB_USBtoUART
 #ESPDELAY indicates seconds to wait between flashing the two binary images
 ESPDELAY    ?= 3
 ESPBAUD        ?= 115200
@@ -61,9 +61,9 @@ SDK_INCDIR    = include include/json
 # we create two different files for uploading into the flash
 # these are the names and options to generate them
 FW_FILE_1    = 0x00000
-FW_FILE_1_ARGS    = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
+#FW_FILE_1_ARGS    = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
 FW_FILE_2    = 0x40000
-FW_FILE_2_ARGS    = -es .irom0.text $@ -ec
+#FW_FILE_2_ARGS    = -es .irom0.text $@ -ec
 
 # select which tools to use as compiler, librarian and linker
 CC        := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
@@ -117,13 +117,17 @@ endef
 
 all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2)
 
-$(FW_FILE_1): $(TARGET_OUT) firmware
-    $(vecho) "FW $@"
-    $(Q) $(ESPTOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)
-
-$(FW_FILE_2): $(TARGET_OUT) firmware
-    $(vecho) "FW $@"
-    $(Q) $(ESPTOOL) -eo $(TARGET_OUT) $(FW_FILE_2_ARGS)
+$(FW_BASE)/%.bin: $(TARGET_OUT) | $(FW_BASE)
+    $(vecho) "FW $(FW_BASE)/"
+    $(Q) $(ESPTOOL) elf2image -o $(FW_BASE)/ $(TARGET_OUT)
+    
+#$(FW_FILE_1): $(TARGET_OUT) firmware
+#    $(vecho) "FW $@"
+#    $(Q) $(ESPTOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)
+
+#$(FW_FILE_2): $(TARGET_OUT) firmware
+#    $(vecho) "FW $@"
+#    $(Q) $(ESPTOOL) -eo $(TARGET_OUT) $(FW_FILE_2_ARGS)
 
 $(TARGET_OUT): $(APP_AR)
     $(vecho) "LD $@"
@@ -138,14 +142,20 @@ checkdirs: $(BUILD_DIR) $(FW_BASE)
 $(BUILD_DIR):
     $(Q) mkdir -p $@
 
-firmware:
+#firmware:
+#    $(Q) mkdir -p $@
+$(FW_BASE):
     $(Q) mkdir -p $@
 
+#flash: $(FW_FILE_1) $(FW_FILE_2)
+#    $(Q) $(ESPTOOL) -cp $(ESPPORT) -cb $(ESPBAUD) -ca 0x00000 -cf firmware/0x00000.bin -v
+#    $(Q) [ $(ESPDELAY) -ne 0 ] && echo "Please put the ESP in bootloader mode..." || true
+#    $(Q) sleep $(ESPDELAY) || true
+#    $(Q) $(ESPTOOL) -cp $(ESPPORT) -cb $(ESPBAUD) -ca 0x40000 -cf firmware/0x40000.bin -v
 flash: $(FW_FILE_1) $(FW_FILE_2)
-    $(Q) $(ESPTOOL) -cp $(ESPPORT) -cb $(ESPBAUD) -ca 0x00000 -cf firmware/0x00000.bin -v
-    $(Q) [ $(ESPDELAY) -ne 0 ] && echo "Please put the ESP in bootloader mode..." || true
-    $(Q) sleep $(ESPDELAY) || true
-    $(Q) $(ESPTOOL) -cp $(ESPPORT) -cb $(ESPBAUD) -ca 0x40000 -cf firmware/0x40000.bin -v
+    $(ESPTOOL) --port $(ESPPORT) write_flash $(FW_FILE_1_ADDR) $(FW_FILE_1) $(FW_FILE_2_ADDR) $(FW_FILE_2)
+
+
 
 clean:
     $(Q) rm -f $(APP_AR)

・再度make

$ make clean

$ make

CC user/cgiwifi.c

CC user/config.c

CC user/eink.c

CC user/espfs.c

CC user/heatshrink_decoder.c

CC user/httpd.c

CC user/httpdclient.c

CC user/httpdespfs.c

CC user/io.c

CC user/stdout.c

CC user/user_main.c

AR build/einkdisp_app.a

LD build/einkdisp.out

FW firmware/

エラーはなくなりました。

・とりあえず、こんな感じになっています。

$ tree

.

├── Makefile

├── Makefile.patch

├── Makefile_org

├── README

├── build

│   ├── driver

│   ├── einkdisp.out★これはどの領域に書き込めばいいのでしょうかね?

│   ├── einkdisp_app.a

│   └── user

│       ├── cgiwifi.o

│       ├── config.o

│       ├── eink.o

│       ├── espfs.o

│       ├── heatshrink_decoder.o

│       ├── httpd.o

│       ├── httpdclient.o

│       ├── httpdespfs.o

│       ├── io.o

│       ├── stdout.o

│       └── user_main.o

├── firmware

│   ├── 0x00000.bin★

│   └── 0x40000.bin★

├── html

│   ├── 140medley.min.js

│   ├── apconnect.bm

│   ├── batempty.bm

│   ├── connecting.html

│   ├── icons.png

│   ├── neterror.bm

│   ├── style.css

│   └── wifi.tpl

├── icons

│   ├── apconnect.png

│   ├── batempty.png

│   └── neterror.png

├── include

│   ├── espmissingincludes-ip.h

│   ├── espmissingincludes.h

│   ├── ip_addr.h

│   ├── lwipopts.h

│   ├── spi_register.h

│   ├── stdint.h

│   ├── uart_hw.h

│   └── user_config.h

├── lib

│   └── heatshrink

│       ├── LICENSE

│       ├── Makefile

│       ├── README.md

│       ├── dec_sm.dot

│       ├── enc_sm.dot

│       ├── greatest.h

│       ├── heatshrink.c

│       ├── heatshrink_common.h

│       ├── heatshrink_config.h

│       ├── heatshrink_decoder.c

│       ├── heatshrink_decoder.h

│       ├── heatshrink_encoder.c

│       ├── heatshrink_encoder.h

│       ├── test_heatshrink_dynamic.c

│       ├── test_heatshrink_dynamic_theft.c

│       └── test_heatshrink_static.c

├── mkespfsimage

│   ├── Makefile

│   ├── espfsformat.h

│   ├── heatshrink_encoder.c

│   ├── heatshrink_encoder.o

│   ├── main.c

│   ├── main.o

│   └── mkespfsimage

├── mkimg.php

├── server

│   ├── README

│   └── pixelserver.js

└── user

    ├── cgiwifi.c

    ├── cgiwifi.h

    ├── config.c

    ├── config.h

    ├── eink.c

    ├── eink.h

    ├── espfs.c

    ├── espfs.h

    ├── heatshrink_config_httpd.h

    ├── heatshrink_decoder.c

    ├── httpd.c

    ├── httpd.h

    ├── httpdclient.c

    ├── httpdclient.h

    ├── httpdconfig.h

    ├── httpdespfs.c

    ├── httpdespfs.h

    ├── io.c

    ├── io.h

    ├── stdout.c

    ├── stdout.h

    └── user_main.c

12 directories, 86 files

 

▼まとめ

・SDK にいくつを使っていたか不明。作者に聞くことに

・PhantomJS で動作する pixelserver.js は別サーバにおくのかどうか?

・ビルドするには、esp-open-sdk を使えばいいのか、それとも他の方法か不明。

・ビルドしてできたものは、どのようにどの領域に書き込めばいいのか不明。

 

▼参考

http://nemuisan.blog.bai.ne.jp/?eid=215341

http://dsas.blog.klab.org/

http://www.homu.net/esp8266%E7%94%A8open-sdk%E3%82%92macosx%E7%94%A8%E3%81%AB%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B/

http://bbs.espressif.com/viewforum.php?f=46

https://github.com/esp8266/esp8266-wiki/tree/master/sdk

http://nemuisan.blog.bai.ne.jp/?eid=215341