2015年11月7日

[mbed]mbed OSのHAL

我ながら、あきらめが悪い。
もうちょっとだけ、mbed OSのHAL構成を見ていく。

  1. mbed-hal
  2. mbed-hal-<vendor>
    • module.jsonだけを含む
    • mbed-hal-stもそうなっている
      • targetDependencies
        • "stm32f4"
          • "mbed-hal-st-stm32f4"
  3. mbed-hal-<vendor>-<chip family>
    • spi_api.c, uart_api.cなどを含む
    • mbed-hal-st-stm32f4もそうなっている
      • dependencies
        • "uvisor-lib"
        • "mbed-hal-st-stm32cubef4"
        • "mbed-hal"
      • targetDependencies
        • "stm32f429zi"
          • "mbed-hal-st-stm32f429zi"
  4. mbed-hal-<vendor>-<vendor hal>
    • ベンダ依存のHAL(オプショナル)
    • たぶんmbed-hal-st-stm32cubef4
      • dependencies
        • "uvisor-lib"
        • "mbed-hal-st-stm32cubef4"
      • targetDependencies
        • 無し
  5. mbed-hal-<vendor>-<chip>
    • チップ依存の定義
    • F411REに該当するものが今はない。
      F429ZI向けは、mbed-hal-st-stm32f429ziだろう
      FRDM-K64Fは、mbed-hal-k64fか
  6. mbed-hal-<vendor>-<target>
    • ターゲット依存の定義
    • F411REもF429ZIも該当するものが今はない。
      FRDM-K64Fは、mbed-hal-frdm-k64fか

 

https://github.com/ARMmbed?utf8=%E2%9C%93&query=stm
ここを見ると、STM向けは数日前に更新されたばかりみたいなので、待つという手もある。
でも、一番めんどくさそうな<chip family>と<vendor hal>が実装されているので、<chip>をF429ZIを参考に、<target>をfrdm-k64fを参考にすればできそうな気もする。。。

それよりも思ったのは、こういう構成ならば自分用のARMボードを作ったとしても、<target>の層だけ作ればよいから、mbed Enabledとか関係なくなるんじゃなかろうか、というものだ。
ビルドもローカル環境で行っているし。
もともとそういう構想なのかもしれないけど、そうなったらmbedのコンパイルサイトもまた変わってくるのかもなぁ。

[mbed]mbed OSをNUCLEO-F411RE用にビルドしようとして挫折

昨日はyottaのことを書いたが、mbed OSを使ったアプリを作ってみた方がよいんじゃないかと思った。
いきなり海に飛び込んで、足が吊ったのと同じようになっているからだ。

Getting Started Guides
一番上に、mbed-driversというのがあるから、それを試してみよう。


mbed-drivers

昨日Windowsにインストールしたyottaを立ち上げ、適当にディレクトリを作って、

(workspace) E:\Prog\mbed\mbed-drivers>yotta install mbed-drivers
info: get versions for mbed-drivers
info: download mbed-drivers@0.11.2 from the public module registry
info: get versions for win
error: could not install target win at  for win
error: win does not exist in the targets registry. Check that the name is correct, and that it has been published.

インストールする前にターゲットの切替をするのね。。。
昨日はFreescaleのを選んだけど、もっとふさわしいのはないかねぇ。


とかやっている間に、もっとチュートリアルっぽいのがないか探したところ、こちらが見つかった。
Running your first mbed OS application

 

Step 2

(workspace) E:\Prog\mbed>cd blinky
(workspace) E:\Prog\mbed\blinky>yotta init
Enter the module name: <blinky>
Enter the initial version: <0.0.0>
Is this an executable (instead of a re-usable library module)? <no> yes
Short description: LED blink test
Author: hiro99ma
What is the license for this project (Apache-2.0, ISC, MIT etc.)?  <Apache-2.0>

最初に入力を求められるmodule nameは、デフォルトはフォルダ名になるみたい。
あとは、適当だ。

生成したファイルを見ると、blinkyってのがない。
ヘッダが入るらしいフォルダらしいのだが、まああとで考えよう。

 

Step 3

次は、targetの検索。
そうそう、これが知りたかったのだ。
今朝の時点では、こうだった(2015/11/07 10:27)。

(workspace) E:\Prog\mbed\blinky>yotta search --limit 1000 target
test-target-dep 0.0.2:
    Test Target Test Dependencies
    autopulated
st-nucleo-f401re-gcc 0.1.0:
    Official mbed build target for the mbed st-nucleo-f401re development board.
    mbed-target:nucleo-f401re, mbed-official, nucleo-f401re, gcc
bbc-microbit-classic-armcc 0.1.0:
    Official mbed build target for the microbit, using the armcc toolchain.
    mbed-target:nrf51822, mbed-official, nrf51822, nordic, armcc, microbit
stm32f429i-disco-gcc 0.0.16:
    Official mbed build target for the mbed stm32f429i-disco development board.
    mbed-target:discovery-f429zi, mbed-official, stm32f429i-disco, gcc
nordic-nrf51822-16k-gcc 0.0.11:
    Official mbed build target for the mbed nrf51822 development board, using the armgcc toolchain.
    mbed-target:nrf51822, mbed-official, nrf51822, nordic, gcc
target-onsemi-ncs36510-gcc 0.1.0:
    Official mbed build target for .
    mbed-official, mbed, onsemi, ncs36510, gcc
st-stm32f439zi-gcc 0.0.4:
    Official mbed build target for the st stm32f439zi microcontroller.
    mbed-target:nucleo-f439zi, mbed-official, stm32f439i, gcc
nordic-nrf51822-32k-gcc 0.0.8:
    Official mbed build target for the nrf51822 32KB chip.
    mbed-target:nrf51822, mbed-official, nrf51822, nordic, gcc
stm32f411re-nucleo-gcc 0.1.0:
    Official mbed build target for the mbed st-nucleo-f411re development board.
    mbed-target:nucleo-f411re, mbed-official, stm32f411re-nucleo, gcc
nordic-nrf51822-16k-armcc 0.0.11:
    Official mbed build target for the mbed nrf51822 development board, using the armcc toolchain.
    mbed-target:nrf51822, mbed-official, nrf51822, nordic, armcc
bbc-microbit-classic-gcc-nosd 0.1.2:
    Official mbed build target for the BBC micro:bit, using the armgcc toolchain, without Softdevice.
    mbed-target:nrf51822, mbed-official, nrf51822, nordic, gcc
nrf51dk-gcc 0.0.4:
    Official mbed build target for the nRF51-DK 32KB platform.
    mbed-official, mbed-target:nrf51_dk, gcc
efm32gg-stk-gcc 0.3.4:
    Official mbed build target for the mbed EFM32GG STK3700 development board, using the GCC toolchain.
    mbed-target:efm32gg-stk, mbed-official, efm32gg, efm32gg-stk, gcc
nrf51dk-armcc 0.0.4:
    Official mbed build target for the nRF51-DK 32KB platform.
    mbed-official, mbed-target:nrf51_dk, armcc
bbc-microbit-classic-armcc-nosd 0.1.0:
    Official mbed build target for the microbit, using the armcc toolchain, without soft device.
    mbed-target:nrf51822, mbed-official, nrf51822, nordic, armcc, microbit
x86-linux-native 1.0.0:
    Build target for programs compiled natively for Linux
    linux, native
mbed-gcc 0.1.3:
    base mbed build target for gcc toolchain
    mbed-official, gcc
x86-osx-native 0.0.7:
    Build target for programs compiled natively for OS X
libc 0.0.3:
    libc shim module: pulls in the platform libc when compiling for nostdlib targets
    libc
    James Crosby <james.crosby@arm.com>
x86-linux-native-coverage 0.0.3:
    Build target for programs compiled natively for Linux with gcov
    linux, native, coverage
ublox-odin-w2-gcc 0.0.4:
    Official mbed build target for the ublox odin-w2 module.
    ublox-odin-w2, mbed-official, odin-w2, gcc
kinetis-k64-armcc 1.0.0:
    Official mbed build target for Freescale Kinetis K64 family chips, using the
 armcc toolchain.
    mbed-official, mbed, kinetis, kinetis-k64, freescale, mk64f, mk64fn1m0vll12, armcc
ublox-c029-gcc 0.0.3:
    Official mbed build target for the mbed ublox c029 development board.
    ublox-c029, mbed-official, c029, gcc
blenano-gcc 0.0.2:
    Unofficial mbed build target for the RedBearLab BLE Nano board
    mbed-official, gcc
mkit-gcc 0.0.4:
    Official mbed build target for the nrf51822 16KB chip.
    mbed-official, gcc
seeedtinyble-gcc 0.0.2:
    Official mbed build target for the nrf51822 16KB chip.
nxp-lpc111x-gcc 0.1.1:
    Community member maintained build target for the NXP LPC111x using GCC
    nxp, lpc1114, lpc111x, lpc11cxx, gcc
    Scott Tsai <scottt.tw@gmail.com>
mkit-armcc 0.0.4:
    Official mbed build target for the mkit nrf51822 16KB chip.
    mbed-official, armcc
mkit-classic-armcc 0.0.1:
    mbed classic build target for nrf51822 mkit.
mingw 0.0.1:
    Build target for programs compiled natively for Windows via MinGW
bbc-microbit-gcc 0.0.2:
    Official mbed build target for the BBC micro:bit chip.
    gcc, mbed-official
bbc-microbit-armcc 0.0.2:
    Official mbed build target for the BBC micro:bit chip.
    armcc, mbed-official

おお、stm32f411re-nucleo-gccというのがあるではないか!

(workspace) E:\Prog\mbed\blinky>yotta target stm32f411re-nucleo-gcc
info: get versions for stm32f411re-nucleo-gcc
info: download stm32f411re-nucleo-gcc@0.1.0 from the public module registry
info: get versions for mbed-gcc
info: download mbed-gcc@0.1.3 from the public module registry

armccとか買えるような身分でもないから、gccでよいのだ。

 

Step 4

ここで、mbed-driversをインストールするみたいだ。
依存しているもののインストールらしいので、mbed-driversは単独で動くものじゃなくて、文字通りドライバに相当するものということか。

(workspace) E:\Prog\mbed\blinky>yotta install mbed-drivers
info: get versions for mbed-drivers
info: download mbed-drivers@0.11.2 from the public module registry
info: dependency mbed-drivers: ~0.11.2 written to module.json
info: get versions for mbed-hal
info: download mbed-hal@1.0.5 from the public module registry
info: get versions for cmsis-core
info: download cmsis-core@1.0.1 from the public module registry
info: get versions for ualloc
info: download ualloc@1.0.2 from the public module registry
info: get versions for minar
info: download minar@1.0.1 from the public module registry
info: get versions for core-util
info: download core-util@1.0.1 from the public module registry
info: get versions for compiler-polyfill
info: download compiler-polyfill@1.1.1 from the public module registry
info: get versions for mbed-hal-st
info: download mbed-hal-st@1.0.0 from the public module registry
info: get versions for mbed-hal-st-stm32f4
info: download mbed-hal-st-stm32f4@1.0.3 from the public module registry
info: get versions for uvisor-lib
info: download uvisor-lib@1.0.6 from the public module registry
info: get versions for mbed-hal-st-stm32cubef4
info: download mbed-hal-st-stm32cubef4@1.0.2 from the public module registry
info: get versions for cmsis-core-st
info: download cmsis-core-st@1.0.0 from the public module registry
info: get versions for cmsis-core-stm32f4
info: download cmsis-core-stm32f4@1.0.2 from the public module registry
info: get versions for dlmalloc
info: download dlmalloc@1.0.0 from the public module registry
info: get versions for minar-platform
info: download minar-platform@1.0.0 from the public module registry
info: get versions for minar-platform-mbed
info: download minar-platform-mbed@1.0.0 from the public module registry

yotta_modulesというフォルダにいろいろ入ってきた。

 

Step 5

sourceフォルダにapp.cppというファイルを作って、アプリを書く。
エントリポイントは、main()ではなくapp_start()とのこと。

#include "mbed-drivers/mbed.h"
namespace {
    void blinky()
    {
        static DigitalOut led(LED2);
        led = !led;
        printf("LED = %d\r\n", led.read());
    }
}
void app_start(int argc, char** argv)
{
    minar::Scheduer::postCallback(blinky).period(minar::milliseconds(500));
}

 

Step 6

ビルド!

(workspace) E:\Prog\mbed\blinky>yotta build
(中略)
In file included from E:/Prog/mbed/blinky/yotta_modules/cmsis-core/cmsis-core/cmsis_nvic.h:35:0,
                 from E:/Prog/mbed/blinky/yotta_modules/uvisor-lib/uvisor-lib/uvisor-lib.h:23,
                 from E:/Prog/mbed/blinky/yotta_modules/uvisor-lib/source/unsupported.cpp:17:
E:/Prog/mbed/blinky/yotta_modules/cmsis-core-stm32f4/cmsis-core-stm32f4/cmsis.h:
35:23: fatal error: stm32f4xx.h: No such file or directory
#include "stm32f4xx.h"
                       ^

おーーーい!!

以下を、blinky\yotta_modules\cmsis-core-stm32f4\cmsis-core-stm32f4にコピーすると、進んだ。
mbed/stm32f4xx.h at master · mbedmicro/mbed
mbed/stm32f411xe.h at master · mbedmicro/mbed
mbed/stm32f4xx_hal_conf.h at master · mbedmicro/mbed

が、今度はこんなエラーが。

E:/Prog/mbed/blinky/yotta_modules/mbed-drivers/mbed-drivers/platform.h:21:20: fatal error: device.h: No such file or directory
#include "device.h"
                    ^

これは、NUCLEOって感じね。
FRDM-K64Fだと、yotta_modules\mbed-hal-frdm-k64f\mbed-hal-frdm-k64fに揃っていた。
mbedのコンパイルサイトで見てみると、mbed-src/targets/hal/TARGET_STM/TARGET_STM32F4/TARGET_NUCLEO_F411REに中にあるものがそれっぽい。

image

これをexportして、解凍したファイルから適当に見繕って、yotta_modules\mbed-hal-st-stm32f4にコピーした。

E:/Prog/mbed/blinky/yotta_modules/minar-platform-mbed/minar-platform/minar_platform_types.h:29:17: error: 'MINAR_PLATFORM_TIME_BASE' was not declared in this scope
     Time_Base = MINAR_PLATFORM_TIME_BASE,
                 ^

これは、mbed-drivers\yotta_modules\mbed-hal-frdm-k64f\mbed-hal-frdm-k64f\target_config.hにあるんだけど、値の意味がわからん。
mbed-hal-st-stm32f429zi/mbed-hal-st-stm32f429zi at master · ARMmbed/mbed-hal-st-stm32f429zi
ここはSTM32F429ZIなんだけど、これだとdevice.hとかtarget_config.hなんかもある。
https://github.com/ARMmbed?utf8=%E2%9C%93&query=stm
検索しても、STM32F411はないなぁ。

もしかして、yotta buildする最初のメッセージの「unsupported platform」がすべての原因なのか?

*******************************************************************
* WARNING (uvisor-lib): unsupported platform; your code will still
*                       work but no security feature is provided;
*                       UVISOR_DISABLED is set by default
*******************************************************************

試しに、
(workspace) E:\Prog\mbed\blinky>yotta target stm32f429i-disco-gccしてからyotta buildすると、そういうメッセージは出ない。
でも、ビルドはやはりうまく行かない。
objects.hとか、その辺が関係しそうだ。。。

https://github.com/ARMmbed/mbed-hal
ここに、移植の際の説明が書かれている。

  1. mbed-hal
  2. mbed-hal-<vendor>
  3. mbed-hal-<vendor>-<chip family>
  4. mbed-hal-<vendor>-<chip>
  5. mbed-hal-<vendor>-<target>

が基本的な階層らしい。
いま私が使っている構成を見ると、こうなっている。

  1. mbed-hal
  2. mbed-hal-st
  3. mbed-hal-st-stm32f4
    mbed-hal-st-stm32cubef4

うん、<target>に相当するものがないですね。

それに、さっきコピーしたPeripheralNames.hなんかは<chip-family>にあるべきもの。
それがmbed-hal-st-stm32f4に入っていなかったことからすると、まだこの辺はSTM32向けには整備されてないのかもしれない。

 

よし、今回は断念だ!

2015年11月6日

hexdumpのフォーマット

バイナリファイルを、C言語の配列形式に落とし込もうとした。
ちまちま打ち込むのは耐えられないので、ツールがあったはず、と記憶を頼りに探すも、見つからない。
あきらめて、バイナリダンプを出力するツールを使うことにした。
Linuxコマンド集 - 【hexdump】16進数や8進数で出力する:ITpro
  • 繰返し回数
  • バイト数
  • フォーマット
$ hexdump -e '"%07.7_ax  " 8/2 "%04x  " "\n"' sample

???
これで、確かに書かれているように、最初にオフセット、続けて16進数で2byteごとに8列並んだ出力になるのだが、何を意味しているかわからん・・・。

フォーマットの書きかたにならって、上記を分解する。
  • 1番目
    • フォーマット
      • "%07.7_ax "
  • 2番目
    • 繰返し回数
      • 8
    • バイト数
      • 2
    • フォーマット
      • "%04x "
  • 3番目
    • フォーマット
      • "\n"
これを言葉にすると、こうか。
  • 最初の_axのところは、オフセットの16進数表記で、%07.7は0パディングの7桁。
  • 次の8/2は、次のフォーマットを8回繰り返し、1回のバイト数は2byteという意味。
  • フォーマットの%04xは、0パディングの4桁16進数。
  • 最後は改行。
なるほど。

では、C言語の配列風にするとなると、こんな感じだろう。
  • オフセットはいらない
  • 1byteずつにする
  • 各バイトの先頭には0x、後ろにはコンマがいる
  • 1行は8列くらいが妥当か
えい!

$ hexdump -e '8/1 "0x%02x, " "\n"'  abcdef.bin
0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02,
0x81, 0x81, 0x00, 0xc7, 0x78, 0x20, 0x72...


おー、こういうのでいいんだよ、こういうので。

[mbed]yotta

yotta | mbed

mbed OSを見ると、なんか「yotta」という言葉がよく出てくる。
インストーラーっぽいので、こういうのは酔った勢いでインストールしてみよう、くくくっ(いや、飲んでないけどさ)。

 

うちはWindowsなので、exeをダウンロードして実行。
ウィザード形式で進む。

image

インストーラかと思っていたが、どちらかというとmakeみたいなビルド環境のようだ。

なんか、いろいろある。。。うちはgccもgitも入っているから、デフォルトからgccだけ外した。
自動でpython2.7をインストールしている。。既に入ってるのに。。。

ファイアウォールがあるといろいろ失敗するので、うまいこと外した方がよい。


うちはWindowsなので、デスクトップにできた「Run Yotta」を起動。
すると、コマンドプロンプトが出てきた。
で、どうしたらよいのだ?

まずは、yottaでビルドできそうなものをダウンロードすることにした。
mbedtls/yotta/data at development · ARMmbed/mbedtls
mbedtlsがGet Startedにもあったので、gitでcloneしてきた。

どうもそれだけだとだめっぽくて、yottaの中にあるcreate-module.shを実行するみたいだ。
Windowsだと実行できないので、ここはcygwinを起動して実行した。
yottaの中に入らず、yotta/create-module.shと書いてあったので、そのまま実行した。
そうすると、なんかやってくれた。

そしてYottaコンソールに戻り、

(workspace) mbedtls>cd yotta
(workspace) mbedtls\yotta>cd module
(workspace) mbedtls\yotta\module>yotta build

とすると、「winはできないよ」みたいなメッセージが出てきた。
私もWindows版をビルドしたいわけではないので、ターゲットを切り替えた。

(workspace) mbedtls\yotta\module>yotta target frdm-k64f-gcc

どうも、frdm-k64fというのはFreescaleのmbedプラットフォームらしい。
なんだかわからないけど、すごそうだ。

これを実行すると、ブラウザが立ち上がってyotta.mbed.comにログインを要求された。
特にアカウントがいるわけでもなさそうだが、ログインすると「Woohoo!」って出てきてコンソールが先に進んだ。

info: get versions for kinetis-k64-gcc
info: download kinetis-k64-gcc@1.0.0 from the public module registry
info: get versions for mbed-gcc
info: download mbed-gcc@0.1.3 from the public module registry

(workspace) mbedtls\yotta\module>yotta build

1時間近くビルドしていたような気がする。
yotta/module/build/frdm-k64f-gcc/testの中に*.binができていたけど、これなのかな?

 

これでよいのかわからないが、この「frdm-k64f」をなんとかせんといかん。
依存しているのかどうかすらわからんのだが、写真を見るとRJ45が載ってそうだから、うちのNUCLEOでは動かなさそうな気がする。

[mbed]publishしないと取って来れません(たぶん)

mbedを使うことになったので、まずはコンパイルのサイトをどう使うか調べていた。

久しぶりにサイトを見に行ったのだが、見栄えが変わってた。
今はbeta版らしい。
Getting Startedに行くと、こっちはmbed OSのことが少し書かれていた。
今のところ、mbed OSもbeta版らしい。
動かしてはいないが、比較的シンプルな構成で、スレッド単位で動作させるようなものっぽかった。
(main()にスレッドを作って動かすところがあったので。)
組込みの機器だと消費電力を気にすることが多いので、こういうOSがどこら辺までやってくれるのか興味があるところだ。

 

さて、今回はお仕事でmbedを使うので、ファイルが消えたりすると困る。
mbedのサイトではそういうことはほとんどないと思うが、それにかまけてもいられまい。
そういうわけで、ローカルにも取ってこようと思った。

調べると、mercurialで管理されていて、それで取ってこれるらしい。
SourceTreeもmercurialが使えるので、それで取ってこようとした。

 

Mercurialでバージョン管理を行う | mbed
リポジトリのURLを指定してcloneすればよいということなので、「Repository Toolbox」を探した。
が・・・自分の作ったプログラムにはそういうのが出てきてない。
よく読むと「commitまたはpublishされている必要があります」とのこと。
確かに、まだコミットしていなかったので、サイトでコミットしようとした。

お試しで、SSLのライブラリをインポートして、ちょっと自分用に変更していたのだが、こういうダイアログが出てきた。
image

ぱ、パブリッシュですか・・・。
いくらお試しとはいえ、パブリッシュまではしたくない・・・。

twitterでちょろっと書いたら、経由して教えていただいた。
知り合いが少ないので、こういうのは非常にありがたい。
publishしなくても、commitだけ出来ますよ。
びくびくしながら「コミット」を押すと、コミットだけできた。
よかったよかった。
(このメッセージ文は、いずれ変更になるかも。)

 

では、これでリポジトリができたかと思ったら、変わらない。
コミットはされているけど、コミットされただけだ。
実はこれより前に、エクスポートでプロジェクトをzipで落としてきて、それをSourceTreeに登録するのを試していたのだが、そちらはリポジトリとしては見えてくれるのだけど、mbedのコンパイラサイトと連動している感じではなかった。

mbedのダッシュボードのサイトに行くと、こっちには「Code」というタブがあり、そこにリポジトリが見えているようだ。
そして、そこには作ったプログラムが載っていない。
それだけじゃなくて、以前パブリッシュしたRC730関連のリポジトリしか出ていなかった。

つまり、mbedのコンパイラサイトで見えているリポジトリはローカルのリポジトリで、外のリポジトリに上げるためにはパブリッシュしないといかん、ということだろう。
gitでいうところのpushが、mbedサイトではパブリッシュと呼んでいるということか。
なんとなく、ブラウザでネット上のリポジトリを見ていると、直接一番上のリポジトリを見ていると認識していたのだ。

 

今回は内部用なのでPrivateでパブリッシュすると、ダッシュボードのCodeにもリポジトリが出てきた。
Repository Toolboxも表示され、そこのhttps://~をSourceTreeでcloneすると、ちゃんと取って来れた。
ローカルで編集してコミットとプッシュすると、mbedのコンパイラサイトで「アップデート」が出るので、それを押すとプルに相当する動きをしてくれた。

変更されたプログラムは、ツリーではこういうアイコンになっている。
image

ここで、まだコンパイルサイトでコミットしていない変更があるときに「アップデート」をしようとすると、こういう警告が出てくる。

image

ここで「強制的にアップデート」とすると、サイトの変更は破棄してダウンロードする。
「コミット」をすると、コミットされる。
されるのだが、ここでマージは行われずにブランチが分かれるようだ。
「リビジョン」を見ると、こうなっていた。

image

上がアップデートした方、その下がさっきコミットした方だ。

この状態でパブリッシュすると、こういう警告が出てくる。

image

「マージした方がいいんじゃないの、ほれほれ」みたいなメッセージだ。
せっかくなので、試す。

さっきの「リビジョン」で、ブランチした方をクリックすると「マージ」ボタンが有効になる。
そしてマージボタンを押すと、こうなった。

image

trunkとも切り離されてしまった・・・。
ここでコミットすると、こうなった。

image

5--6(サイトで変更)--8(サイトでマージ、コミット後)となり、7(ローカルで変更)が枝になったのだな。

 

いままでは「パブリッシュしなければ大丈夫」で済ませていたけど、ローカルでも編集したいとなるともうちょっと動きがわからないといけなさそうだったので、今回はいろいろ試してみた。
失敗するのは小さいうちにやっとかないとねー。

2015年11月5日

[勉]ベアメタルスイッチ

知らん言葉を調べようシリーズ。
今回は「ベアメタルスイッチ」

だんだんペースが落ちてきたので、がんばります。
最近わかってきたけど、知らない言葉はだいたい興味が無い分野のことだから、それを調べることがおっくうなのですな。。


スイッチ向けOS「Cumulus Linux」でベアメタルスイッチのシェア拡大を目指す――、米Cumulus - クラウド Watch

「Linux」以外の単語がわからないことだらけでした。。。

ベアなんとかというと、ベアクローとかが思いつくが、ベアメタルとなるとかなり強そうに見える。
が、ベアクローはbear clawとクマなのだけど、ベアメタルはbare metalで綴りが違う。
こっちのベアは「むき出しの」という意味だ。

ホワイトペーパー:SDN製品最新事情(1):SDN、ベアメタルスイッチ、そしてOpenStack - ITmedia エンタープライズ

こっちは、イーサネットスイッチというものがあって、それにソフトウェアが載っていないものを「ベアメタルスイッチ」と呼んでいるようである。

イーサネット(Ethernet)のしくみ(4) -ハブとスイッチ- - ネットワークエンジニアを目指して

ここでは、「ハブ」と「スイッチ」の違いを説明してある。
いま、よく使われているのは「スイッチングハブ」だと思うけど、ここでは「ハブ」が「リピータハブ」(ばかハブとか呼んだり)、「スイッチ」が「スイッチングハブ」を意味しているようだ。

ベアメタルスイッチ | イノテック株式会社

ようやく、ものの写真が見られた。
うーん、サーバ室とかにあって、管理の人に言われた通りに接続する機械、というイメージしかない。。。

 

用語解説辞典|【公式】NTTPC

ここの説明が一番わかりやすかった。
スイッチングハブの大きいやつは、以前はOS組込済みのパソコンみたいな感じで売られていたけど、今や使われ方が高度になってきたので、ハードだけ提供して、ソフトは状況に応じて使い分けるのかなんか知らないけど、組み替えられるようにした、というところか。

知らんことだらけですな。

2015年11月2日

[esp8266]ATコマンドでHTTPプロトコルを投げよう

HTTPプロトコルを投げるのだ。

が、その前に・・・。
以前はつながっていたESP8266が、接続できなくなっていた。
調べたところ、ESP8266のMACアドレスが全部FFになっていたため、うちのMACアドレスフィルタリングしたAPに接続できなかったのだ。
幸い、フィルタリングしている一覧から探し出して登録し直したのだが、危ないところだった・・・。

でも、このMACアドレスはSilex社のものみたい。
ESPRESSIFさんは「18:FE:34」で始まるアドレスのようなのだが、うちのAPには登録されていなかったので、違うのだろう。
http://bbs.espressif.com/viewtopic.php?f=57&t=433
ここには「最近のチップは5C:CF:7Fを使っているので、18:FE:34をハードコーディングしないでね」と書いてある。
うーん、そっちのアドレスも登録してなかったしなぁ。

うちにSilex社の製品がないし、それ以外はAppleのアドレスだったから消去法でこうなったのだけど、すっきりしない。
コンソールのログを残しておけばよかった・・・。

追記(2016/01/06):
FLASHに焼いているときに気付いたが、MACアドレスがちゃんと出ていた。
そう、18:FE:34で始まる数字だ(STAモード時)。
消えてなくてよかった。


さて、使用できるATコマンドは、PDFから探すことができる。
[Document list 4A-4B] ESP8266 AT Commands - ESP8266 Developer Zone

ここから探すのはめんどうだから、ネットで探そう。
が、その前に、このPDFに載っているのが使える全部のATコマンドなのかが気になった。
もしかしたら、隠しコマンドがあるのでは・・・。

libat.aの中に、3コマンドほどなさそうな文字列があった。

  • AT+CIPALIVE
  • AT+CIPCHECKQUEUE
  • AT+IPR

けど、打ってみたら全部ERRORで返ってきた。
なので、そういう変な心配はしなくてよかろう。

AT v0.50.0からかもしれないが、いくつかのコマンドがdeprecated扱いになっている。

  • UART
  • CWMODE
  • CWJAP
  • CWSAP
  • CWDHCP
  • CIPSTAMAC
  • CIPAPMAC
  • CIPAP

これらの代わりに、後ろに「_CUR」がついたコマンドと「_DEF」がついたコマンドができた。
「_CUR」はFLASHに保存せずに反映、「_DEF」はFLASHに保存して反映、だ。
まだ上記コマンドも使えるけれども、FLASHに保存しないコマンドは便利なこともあるかもね。


巷で話題の超小型 Wi-Fi モジュール ESP8266 で遊んでみる | FIRMLOGICS

こちらに、ATコマンドでHTTPクライアントとしてつなぐ例があったので、やってみた。
つなぎ先は、「hiro99ma.blogspot.com/」にする。
nslookupで173.194.126.204とか3つくらい出てきたので、それで接続できるのだろう。

 

AT+CIPMUX=0(CRLF)

OK
AT+CIPSTART="TCP","173.194.126.204",80(CRLF)
CONNECT

OK
AT+CIPSEND(CRLF)

ERROR
AT+CIPSEND=5(CRLF)

OK
>
Recv 5 bytes

SEND OK

CIPSENDコマンドは、送信したいデータ長がいるようだった。
ここでは「GET /」と5文字入力すると、自動的に「Recv 5bytes」「SEND OK」まで出てきた。

で?
受信はどうしたらいいんだろう。。。と放置していたら「CLOSED」と出てきた。

 

「AT+CIPSEND」とだけ打った場合がブログで説明してある「unvarnished transmission」という状態になるようだ。
けど、これだけ打ってもエラーになる。。。
このコマンドが有効なのはtransparent transmissionのときらしく、その設定は「AT+CIPMUX=0」でできる。
接続が切れていないと設定できないらしい。
「AT+CIPMUX?」で現状を確認できるが、0になってるな。。。

もうあきらめて、普通にGET要求した感じにしてみよう。

AT+CIPSEND=41(CRLF)

OK
>
GET / HTTP/1.1(CRLF)
Host: 173.194.126.204(CRLF)
(CRLF)
Recv 41 bytes

SEND OK

+IPD,540:HTTP/1.1 301 Moved Permanently
Location:
http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Mon, 02 Nov 2015 02:43:28 GMT
Expires: Wed, 02 Dec 2015 02:43:28 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
                                                                              <TITLE>301 Moved</TITLE></HEAD><BODY>
                                                                                                                   <H1>301 Moved</H1>
          The document has moved
                                <A HREF="
http://www.google.com/">here</A>.
</BODY></HTML>

お、それっぽく出てきた。
「GET~」のところは、コンソールには出てこないけど、こういう文字列を入力したのだ。

CURLをちょっとだけやったときに知ったのだが、こういうのをGETで取得したら、今度はその内容を解析して、また別のGETをどんどん投げていかないとだめなのね。。。当たり前だけどさ。。。


私はTeraTermを使って受信しているのだが、CR/LFを受信してもラインフィードしかしてくれず、キャリッジリターンしてくれてないようなのだ(設定の受信改行はデフォルトの「CR」のまま)。
受信の改行設定を「LF」にすると、ちゃんととれた。

+IPD,540:HTTP/1.1 301 Moved Permanently
Location:
http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Mon, 02 Nov 2015 02:52:24 GMT
Expires: Wed, 02 Dec 2015 02:52:24 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="
http://www.google.com/">here</A>.
</BODY></HTML>

これは、設定をAUTOにしてもこうなった。
なんでじゃ?と思ってヘルプを見ると、

  • CR:変換無し
  • CR+LF:受信したCRをCR+LFに変換
  • LF:受信したLFをCR+LFに変換
  • AUTO:CRかLFをCR+LFに変換

とのこと。
バイナリで確認したが、受信データはCR+LFで改行していた。
ヘルプにも書いてあるが、「CR+LF」時にCR+LFを受信すると、CR+CR+LFに変換していることになるし、「AUTO」時は変換していないことになる。
じゃあ、CRだと変換しないからAUTOと同じになってもよさそうなんだけど・・・。

まあ、深くは追求すまい。


もう1つ。

戻ってきたHTMLを見ると、Googleの検索サイトに飛ばしているように見える。
なんでだろう?

GET / HTTP/1.1
Host: hiro99ma.blogspot.com

こっちにすると、hiro99ma.blogspot.jpの方を指示された。
そして、Hostをcomからjpにすると、だああああっと受信された。
そういうもんなのだね。

[勉]ダイバーシティー

知らん単語を調べるシリーズ。
今回は「ダイバーシティー」。
たぶん、アンテナじゃない。

いつものことだが、調べながら書いているため、無駄が多いことはご勘弁を。


瀧口範子のシリコンバレー通信 - ダイバーシティーはビジネス問題の解決に重要、OracleのCEOが語る:ITpro

ダイバーシティーといえば、アンテナのことだろうと思っていたのだが、どうもそう言うわけではなさそうだ。
つづりは「diversity」。
英単語を調べると「多様性」とか「雑多」という意味になっている。

上記の記事では「多様性」の意味を持つようだ。
もう1つ「インクルージョン(inclusion)という言葉も出てきて、こちらは「受容する」ということらしい(weblio)。
どういう多様性かというと、人種とか性別とかLGBT/GLBTとかいろいろある。

この記事としては「多様性が現場にないと、いまの問題は複雑になってきているので、硬直した組織では解決ができなくなりますよ」というビジネスの観点で話をしている。
この辺が長いこと問題に取り組んでいることの強みなのかな。

 

もう1つ、diversityとinclusionから検索していて見つけた記事を。
Insight Report | HUMAN VALUE
これは2008年の記事らしいから、こういう言葉を私が知らなかっただけっぽい。。。
しかも、取り組みとしては1960年代から、とあるので、うん、知らなかっただけなのだろう。

組織としての取り組みもいるし、個人としての取り組みもいる。
つまりまあ、全体として取り組みがいるのだな。
私はいまは会社組織の人間じゃないので、あるとしたら仕事の組織になるか。
自分としては偏見とか持ってないつもりでいるけど、それはそれで自分に対する偏見で、自分の視点で物事を見るから偏見にしかならないと思う。
なのでまあ、自分の見方は常に偏見があることを意識しつつ、なるべく相手の意をくみ取るようにする、というところか。
うーん、経験がいるなぁ。


ダイバーシティーアンテナは、Wikipediaがよいだろう。

ダイバーシティ - Wikipedia

無線は比較的壊れやすいので、アンテナを複数持つことでよさそうな無線を使ったり、お互いに正しそうなところと間違ってそうなところを見比べたりするのだろう。
まあ、これも複数のアンテナ受信の意をくみ取る、と言えなくもないか。

2015年11月1日

[esp8266]自分でアップグレードしたいとき

「2C-ESP8266__SDK__Programming Guide__EN_v1.4.pdf」の「3.9. Upgrade (FOTA) APIs」に、FOTAでアップグレードするときのAPIが書かれている。

  • system_upgrade_userbin_check()
  • system_upgrade_flag_set()
  • system_upgrade_flag_check()
  • system_upgrade_start()
  • system_upgrade_reboot()

うしろに「_check」が付いているのは、GET系のAPIで、それ以外はなにがしかの動作を起こす。

 

system_upgrade_userbin_check()は、今動作しているuser.binが、UPGRADE_FW_BIN1かBIN2かを返す。
説明文には特に書かれていないけど、examples/at/at_upgrade.cの使い方を見ると、UPGRADE_FW_BIN1が取れたときには"user2.bin"を、UPGRADE_FW_BIN2が取れたときには"user1.bin"をHTTP GETしようとしているから、そうなんじゃなかろうか。

system_upgrade_flag_check()は、現在のアップグレード進行状況を取得するようだ。
ESPRESSIFのサーバを使うならば、アップグレードはsystem_upgrade_start()を使うとうまいことやってくれるようなのだが、自分で何とかしたいとなるとそのAPIが使えないため、ダウンロードして、FLASHに焼いて、というのを自分でやらんといかん。
そこまでは自力でできるのだが、「どっち側のパーティションから起動するか」という情報はSystem Paramが持っているため、そう簡単に変更できない。

それをやってくれるのが、system_upgrade_flag_set()とsystem_upgrade_reboot()のようだ。
読んだ感じでは、

  1. system_upgrade_flag_set()でUPGRADE_FLAG_FINISHをセットする
  2. system_upgrade_reboot()を呼び出す

とすると、新しい方のパーティションで再起動してくれるようだ。


もう少しできてくれないか、期待してしまう。
何かというと、

  • ファーム更新のダウンロードができた
  • ダウンロードしたデータを焼けた
  • FLAG_FINISHをセットして、upgrade_rebootした
  • 再起動したけど、正常に立ち上がらなかった!
  • やっぱり前のパーティションに戻す

赤文字で書いた、最後の2行だ。
せっかく2面持ってやってるんだから、失敗したら元に戻したくなるではないか。

ただ「正常に立ち上がらなかった」を判断するのは、なかなか難しそうだ。
何を持って「正常」と見なすのか。

ブート部がどうなっているか知らないけど、こういうやり方はできるんじゃないかと思う。

  1. 電源ON
  2. System Paramの起動パーティション情報を読む
  3. System ParamのUpgrade Flag情報を読む
  4. Upgrade Flagが「FINISH」だったら、起動パーティションの反対側で起動させる。
    そうでなければ、起動パーティション側で起動させる。
  5. ブートからアプリに切り替わる
  6. アプリの起動が安定した時点で、起動パーティション情報とUpgrade Flag情報を読む
  7. Upgrade Flagが「FINISH」だったら、「IDLE」に書き換える

6の「安定した時点」が、正常起動と見なすタイミングだ。
まあ、これだけだとどうにもならないので、いくつか細工がいる。

まず、WDTはいるだろう。
「起動しない」が固まるとかだったら、WDTでリセット掛けないといかんだろう。

それだけだと再起動を繰り返すだけになるので、再起動起動カウンタみたいなのがいるのかな。
何度か再起動したら、Upgrade Flagを「IDLE」に戻してあきらめる、と。

FLASHの書き換え可能回数もあるだろうから、書き換えを少なくしたいとは思うが、なんかそういうしくみがいるんじゃなかろうかと思う。
system_upgrade_reboot()は、新しいパーティションで再起動する、とは書かれているのだが、この時点でSystem Paramを更新するかどうかまで書かれていないので、もしかしたら・・・という気もするが。


ネットで調べたりしたが、このしくみを使わない人も多く見つかるので、もっと手軽なプラットフォームがあるんだったらそっちを使いたい、という気もする。
Arduinoでやってる人が多く見つかるんだけど、私はそんなにWROOM-02単体で動かしたいって方じゃないので、ATコマンドでホスト側から操作する程度のことができればよいから、なるべくWROOM-02は標準に近くしておきたいのだ。

まあ、標準の方が今ひとつ、というのはしばしばあるけどね・・・。

[hw][esp8266]use1とuser2

WROOM-02は、ESP8266+SPI-FLASHが搭載されたモジュールだ。
UART経由でATコマンドを使った制御もできるのだが、そうしないで動かすこともできる。

以下、「「2A-ESP8266__IOT_SDK_User_Manual__EN_v1.4.pdf」」を見ていこう。


5章の始めに、STEP 1と5でFLASHのサイズやマップが変わる、ということが書かれている。
この「STEP」は、スクリプトのgen_misc.shのSTEPだろう。

  • STEP 1: choose boot version(0=boot_v1.1, 1=boot_v1.2+, 2=none)
  • STEP 5: choose spi size and map

STEP1でnoneを選ぶと、5.1章の方、すなわちFOTAをサポートしない構成になる。
別にFOTAとか無くてもいいんだけどなぁ、と思うのだが、AT_v0.50のreadme.txtだと、どれもboot.binを焼くようになっているから、FOTAをサポートするのだろう。

 

領域の説明も書かれていた。

  • System param
    • 常にFLASHの最後16KBに割り当てられる
  • User param
    • IOT_DemoかATのときに使われるユーザパラメータ領域
    • ユーザが自分でアプリを作るなら、好きに使ってよい
  • User Data
    • 空き領域なので、好きに使ってよい
    • User1.binやUser2.binが最大サイズまで使っていない場合は、そこもUser Dataで使ってよい

 

さて、ATコマンドはサポートした方がやりやすいと思うのだが、ユーザアプリとどのように関係しているのだろうか?
推測だけど、bootのところはFLASHの前半(user1.bin)を起動するか後半(user2.bin)を起動するかが選べるようになっていて、user1.binにATコマンド用アプリが載っていて、user2.binはユーザが作ったアプリを載せる、みたいな想定じゃないだろうか。
ユーザアプリだけでよいなら、5.1章の構成にしてしまえばよい、と。

そういう気持ちで眺めてみよう。


5.2章によると、6番のFLASHメモリ構成はこうなっている。

image

User1.binもUser2.binも、最大が1MBくらいになっている。
私の予想では、ユーザプログラムは好き勝手なサイズにできるかと思ってたのだが・・・。

しかし、よく考えるとここのFLASHメモリはSPIだ。
だから、一度RAMに展開しないとプログラムとして実行できない。
外付けのRAMはWROOM-02には内容だから、ESP8266EXの内蔵RAM上に展開するのだろう。
esp_iot_sdk_v1.4.0/ld/eagle.app.v6.new.2048.ldでは、こうなっている。

MEMORY
{
  dport0_0_seg :                        org = 0x3FF00000, len = 0x10
  dram0_0_seg :                         org = 0x3FFE8000, len = 0x14000
  iram1_0_seg :                         org = 0x40100000, len = 0x8000
  irom0_0_seg :                         org = 0x40201010, len = 0xE0000
}

dramとあるから、Dynamic RAMのことかと思ったのだが、どうもData RAMっぽい感じだ。
その下のiramとかiromは、Instructionのiなんじゃなかろうか。
というのを、Wikiを見て思った。
Memory Map · esp8266/esp8266-wiki Wiki
アドレスの40200000hがSPI-FLASHをマッピングしたところになるみたいなのだけど、うん、さっぱりわからんね。
ともかく、一度RAMに展開しないと実行できないことには変わりが無いだろうから、FLASHの容量が増えたとしてもプログラムがそれだけ大きくできるというわけではない、ということだな。

こちらではWROOM-02のケースをはがした画像が載っているが、SPI-FLASHしか載ってないみたいだ。
「FM25Q16」というのが、それみたいだ。
こそっとDRAMが外付けしてある、ということはないみたい。
ねむいさんのぶろぐ | 技適マーク付きESP8266モジュール ESP-WROOM-02 を使ってみる

Wikiのトップページには、命令用RAMが64KB、データ用RAMが96KBとなっていた。
こちらではSPI-FLASHが25Q40となってるから、当時から大きくなったんですかね。
Home · esp8266/esp8266-wiki Wiki

 

ちなみに、5.1章のFOTAをサポートしない場合の4MByteマップは、こうなっている。

image

FOTA無しの場合でも、256KBは使用するようだ。


あとは、User1.binとUser2.binをどう使い分けるのかが気になる。

ありがちなのは、GPIOのどこかがHIかLOで切り替えるというやつなので、ピンがどうなっているか調べよう。
Pin definition · esp8266/esp8266-wiki Wiki
外れた。

では、一発正解がダメだったので、順番に見ていく。
まずは、ブートシーケンスから。
Boot Process · esp8266/esp8266-wiki Wiki
うーん、SPI-FLASHのどこを起動する、みたいなのはないな・・・。
また外れか。

そもそも、User1.binとUser2.binが切り替えられる、ということが間違ってるのかも。
この構成は、FOTAをサポートする場合、ということは、FOTAについて調べるのがよいか。

99 ESP8266 Flash Read/Write - Over the Air
「99C-ESP8266__OTA_Upgrade__EN_v1.6.pdf」によると、User1.binかUser2.binかを決めているのはSystem paramのようだ。
p.5そのままだが、それっぽく訳しておこう。

  1. まずFLASHに、boot.binとVersion 1.0.0のuser1.binを焼いておく。
    System paramのデフォルトはuser1.binから起動するようになっているので、電源ONするとUser1.binが起動する。
  2. サーバに、Version 1.0.1のuser1.binとuser2.binをアップロードする。
  3. サーバが「新しいソフトがあるよ」とPUSH通知する。
    デバイスがそれを受けとると、System paramのフラグをチェックして、user1.binで起動しているならuser2.binを、user2.binで起動しているならuser1.binをダウンロードする(ここでは、user2.binのダウンロードになる)。
  4. ダウンロードが終わったら、使用者にファーム更新をするかどうか確認する。
    更新を了解したら、System paramのフラグを書き換えてuser2.binからの起動にして、再起動する。

つまり、パーティションを2つに分けて、起動してない方に新しいファームを焼いて、起動するファームを反対側にして再起動、だ。
いわゆる(?)「2面持ち」みたいなやり方ですな。

なので、サーバにアップするときにはuser1.binもuser2.binも同時にアップする。
違いは配置するアドレスだけなのだけど、リロケータブルじゃないようなので、両方ビルドしないといかんみたい。

だから、UART経由でアップロードする場合はuser2.binがいらないのですな。
FOTAしない限りは切り替えないし、切り替えるときにはFLASHを書き換えるし。

 


なんとなく外側はわかったので、あとはどうやるとFOTAできるのか。

PDFのp.11に「http://iot.espressif.cn/#/help-en/」を見るように書いてある。
よくわからんが、うちのFirefoxからは見れなくて、Chromeだと見えた(Firefoxの方は、あれこれ制限を掛けて使ってるせいかも)。

Firefox
image

Chrome
image

 

まあ、そういうのはどうでもよいとして、PDFを見ている感じでは、このiot.espressif.cnのサイトにファームを置くと、いろいろAPIとかが用意されていて使えますよ、ということのように見える。
それが嫌だったら、spi_flash_erase_sector()とspi_flash_write()を組み合わせて、自分でやるしかないのだろうな。。。

esp_iot_sdk_v1.4.0/examples/IoT_Demo/include/user_config.hに、"iot.espressif.cn"という文字列があったし、AT v0.50の中にあったbinにもその文字列があったので、IoT_Demoをうまく流用すれば自前のサイトで同じようなことができるかもしれんな。
まあ、私にサーバ側のことができれば・・・という条件が付くのだが。