2016/05/15

[nrf]nRF5 SDK for Eddystoneは動くのか? (15) - 16KBでは無理

EIDをSlotに割り当てようとするとAndroidアプリのログにエラーが返ってくる件だが、どうもnRF51822側が最初の要因になっているようだ。

RTTでログを取っていると、EIDのconfigure後にSESが固まってしまった。
JLinkを抜くと動き出したので、何か邪魔しているようだ。
なので、RTTを全部消して動かすと、HardFaultが発生していた。。。

 

SESにはMMDというトレースするようなデバッグができるようなのだが、nRF51ではサポートしていないらしい。
コールスタックを見ると、0x20001350が直前なので、これはRAMアドレスだ。

image

examplesにあるble_app_hrsのgcc Linker Scriptを見ると、RAMの開始は0x20002080にして最初の方はSoftDeviceが使うように空けている。
S130 v2.0.0のリリースノートを読むと、最低でも4.9KB(0x13C8)は使うようになっている。

いま使っているEddystoneサンプルは、Linker ScriptをSESが自動生成してくれるようで、Output Filesに入っていた。
それには、RAMが0x20000000からになっている。
まあ、これは__vectors_ram_load_start__が0x20002080になっているから、いいのかな?

となると、コールセンターに出ているアドレスはSoftDeviceが管理している領域でよいだろう。
とはいえ、いくらSoftDeviceでもRAMにコードを書いて実行するとは考えづらい。

 

ということは・・・スタック不正でHardFaultしたのか?
もしかして、RAMが足りてない??
EIDでごにょごにょするということは、楕円曲線暗号の処理を行うのだろう。
それがどのくらいRAMを必要としているかは、把握していない。
スタックは4KBでやってるのだけど、さて、どうしたらよかろうか。

 

S130ではsd_ble_enable()でSoftDeviceが使用するRAMサイズを処理するようになったが、APIはsoftdevice_enable()の中で呼ぶようになったようだ。
呼んだ後の、戻り値であるble_enable_paramsを見てみよう。

image

attr_tab_sizeは、Attribute Tableのサイズだろう。
これを、SoftDeviceが使う4.9KBに加えたサイズが、実際に使用するサイズになるはず。

0x13C8 + 0x580 = 0x1948

nRF51822_xxAAはRAMが16KBだから、

0x4000 – 0x1948 = 0x26B8

9KBくらいがアプリとして使えるRAMサイズだろう。
たぶん、静的な変数の領域が足りなければリンカがエラーを出してくれるだろうし、ヒープは使わないので、スタックサイズをもっと増やせばよいはずだ。

 

いや・・・そうなのだろうか。
スタックの領域は、RAM領域の後ろからずんずん増えるだけだと思う。
静的変数の領域が足りない、というリンカのエラーは「スタックがこれだけ使うはずだから、それと重なりますよ」というエラーになるはず。
動的にスタックサイズが足りないからといって、HardFaultは発生しないんじゃないだろうか。それで発生するんだったら、コールスタックでももう少しそれっぽいアドレスになっているはず。

ということは、単純にRAMが足りなくて、スタックが静的変数の領域を侵してしまったと考えるのが妥当か。

HardFaultが発生したときのStackPointerは0x20002AF0だった。
MAPファイルを見ると、BSS領域の終わりは0x20003118だ。
うん、ダメだね。


そういうわけで、残念ながらEphemeral IDを16KBのRAMで試すのは無理そうだ。

タイマが多いせいか、それがけっこうRAMを消費しているようだ。
しかし、タイマを減らしても足りないだろう。
暗号化周りもけっこうRAMを使っている感じがする。

幸い、RAMの後ろの方に暗号化関係のメモリが配置されているようで、普通に使う分には大丈夫のようだ。
スタックも、そこまで使ってないのだろう。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。