2015/11/30

[mbed]STM32F4の内蔵FLASHに書込む

STM32のPeripheral Driverではなく、mbedで使えるライブラリで書込むのだ。

Nucleo_flash - a mercurial repository | mbed

 

ポイントは、FLASH_Erase_Sector()ではアドレス値ではなくセクタ番号を、HAL_FLASH_Program()ではセクタ番号ではなくアドレス値を渡すところか。
まあ、消すときはセクタまるまるだし、書込むときは途中からでもできるからなのだろうけど、消せずに悩んでた。

FLASHの後半は、128KBセクタしかないので、ちょっと使いづらいかも。
でも、STM32F4はFLASHが大きいので、前半しか使わないのももったいない、というときによいのか。
STM32F411REでしか試してないので、他はよくわからん。
F4系は同じAPIだからよいかもしれんが、F1とかF0は別のAPIを呼ぶことになるから、どうだろうね。
mbed-srcをエクスポートして、関連するソースファイルを見てみるのがよいと思う。

[mbed]アイコンの括弧

これの続き?だ。
hiro99ma blog: [mbed]faviconに見るmbed

image

mbedのfaviconは括弧だなぁ、と思っていたが、他のページを見たらこういうのもあった。

ARM Technology Symposia 2015 Japan
image

image

 

ARM mbed Enabled | mbed
image

 

他にもあるかもしれないが、こういう括弧で囲むことで強調するような意味があるのかもしれない。

それなら、Keynote Speechは文字ごと囲んでないというのが気になるのだけど、同じページに複数強調するものがあると気が散るせいかも。

 

 

ええい、体調がすっきりしなくて、記事まですっきりせんわ(いつものことか?)!

2015/11/29

R-R間隔を測りたい (1)

胸が痛むとかじゃないのだけど、なんか、変な感じがすることがある。
なんとなく脈を取ってみると、ちょうどそのときに心拍が抜けている感じがする。
いわゆる不整脈ってやつなのだろう。

心電図的にいえば、R波が出てないか、遅れているか、そんなのだろう。
P波がどうとかは、さすがにわからん。
少々なら良いのだけど、手で測っている間にわかってしまうから、そこそこ発生頻度が高いように思う。

ミネソタコードの本があったので見てたけど、波形を見てるわけじゃないので、当然わからん。
それに、あんまり素人診断はしたくないものだ。

とりあえず、本当に心拍が抜けるなり遅れるなりしているのかを知りたい。
スマホのアプリに心拍を測るやつがあった。
カメラのレンズに指を当てて、赤血球の酢け方を見ているのかな?
それっぽい出方をしているように見えるんだけど、なんか微妙だ。
冷え性なのも影響があるのかも。

 

そういうわけで、座ってるかどうかを計測する方法を探っていたが、あっちは中断だ。
R-R間隔でもなんでもいいけど、脈の間隔を(安く)測る方法を探ってみよう。
医療目的じゃなくて、販売目的でもなくて、私が満足するためだけに。

もうすぐ健康診断もあるので、そちらはお気遣いなきよう。。。


カメラだとやりづらいだろうから、こういうセンサーを使った方がよいのか。
Amazon.co.jp: 【UMKTOKYO】Arduino センサー/モジュールHeartbeat Sensor Detector Module (AD-039心拍センサー)×5個: 家電・カメラ

こういうセンサもあるようだ。
心拍 - スイッチサイエンス

ウェアラブルなやつは心拍数を計測する機能があったりするけど、ちょっと違うのだ。
心拍の間隔をそれぞれ知りたいだけなのだ。
R-R間隔を記録しそうなのもあるけど、ちょっとお高い。

まあ、もう少し探してみますかね。

2015/11/28

[arm]TrueSTUDIO Lite

今のところ、nRF51822にせよmbedにせよ、あまりコンパイルには困っていない。
ただ、よいツールで無料のものがあれば使ってみたいとは思う。

探していて、TrueSTUDIOというものがあったので、インストールした。
http://timor.atollic.com/

インストール後に気付いたが、Nordicのチップに対応しているわけではないようだ。
まあ、GCCでやるときもNordicを指定してるわけじゃないからなんとかなるだろう。

製品版は、AICさんが代理店?になっているようだ。
http://www.aicp.co.jp/products/atollic.shtml


image

インストールは、退屈だから省略。

立ち上げると、Eclipseだ。
バージョンは、4.3みたい。

プロジェクトを作るときか、作った後かはわからないが、ここからターゲットの設定ができる。
(ここでは、Cプロジェクトだけ作って後から設定している。)

image

Nordicはないのだけど、たぶん種類さえ設定すればよいだろう。

image

設定するとリンカスクリプトのテンプレートを作ってくれる。
だけど、チップの情報が何もないのでアドレスやら何やらは自分で入れないといけない。
ざーっと設定のダイアログを見たが、値を入れるようなところを見つけられなかった。
NUCLEOなんかを指定すると値が入ったリンカスクリプトを作ってくれたので、どこかに情報を持ってるのだろうねぇ。

 

SVDにも対応していると書いてあったので、nRF51.svdなどを設定すれば何かできそうなのだが・・・。

image

デバイス定義ファイルの方に、nRF51 SDKに入っていたnrf51.svdを指定すると、SFRsウィンドウにレジスタが出てきた。

image

うん、見えそうだ。


感想としては、mbed compilerがエクスポート形式として準備してくれたら使ってみたいな、というところだ。
nRF51はもう環境作っているし、デバッグしてもブレークポイントで止めて値を見る、以上のことはやらない(止めてから動かしても例外が発生するので)し。

STM32CubeMXはTrueSTUDIO形式のプロジェクトを作ってくれるので、うちだとKeilの32KB制限があるからちょうどよいかも。

image

[android]AndroidStudioのProtocol family unavailableはFirewallだった

久しぶりにAndroidStudioを起動させた。
アップデート通知があったので、何も考えずに更新させた。
妙にエラーが発生すると思ったら、どうもメジャーバージョンが変わるらしい。
しまった・・・Nightlyなのもチェックするようにしていたままだったみたい。

 

image

せっかくだから、Customにしてみよう。

image

うちは壁紙が真っ黒なので、白い方にしておこう。

 

image

これは、今のSDKインストールと同じ場所になってくれてる。
AVDは、もういいや。

 

image

Finishすると、なんかコンポーネントのダウンロードが始まった。
インストール済みってあったのになぁ。

image

途中でこんなダイアログも出てきたが、リトライすると進んだ。
最後までいったけど、出てきたログを見ると、SDKのフォルダを移動しようとしたけど使用中だったから上書きしました、ということのようだ。

Installing Archives:
  Preparing to install archives
  Installing SDK Platform Android 6.0, API 23, revision 2
  Failed to rename directory C:\Winappli\android-sdk\platforms\android-23 to C:\Winappli\android-sdk\temp\RemotePlatformPkgInfo.old01.
SDK Manager: failed to install
-= Warning ! =-
A folder failed to be moved. On Windows this typically means that a program is using that folder (for example Windows Explorer or your anti-virus software.)
Please momentarily deactivate your anti-virus software or close any running programs that may be accessing the directory 'C:\Winappli\android-sdk\platforms\android-23'.
When ready, press YES to try again.
Note: you  can use --force to override to yes.
[y/n] =>
  Installing Android SDK Build-tools, revision 23.0.2
    Installed Android SDK Build-tools, revision 23.0.2
  Done. 1 package installed.
Installing Archives:
  Preparing to install archives
  Installing SDK Platform Android 6.0, API 23, revision 2
    Installed SDK Platform Android 6.0, API 23, revision 2
  Done. 1 package installed.
Android SDK is up to date.

Finishすると、いつものダイアログが出てきた。

 

image

 

ドキュメントフォルダを見ると、また1つ増えていた。
消せない気持ちもわかるのだが、増えていくばかりなのもねぇ。

image


以前、1.5で読込んでいたBLEアプリのプロジェクトを開いたが・・・やはり失敗した。
Gradle sync failedだ。
Protocol family unavailable、と出てきているが、はてさて。

今までの経験から、だいたいこういうファイルを見るとよさそうだ。

  • gradle/wrapper/gradle-wrapper.properties
  • app/build.gradle

ただ、まずはウィザードでアプリをつくり、その設定ファイルをまねするのがよい、というのが1.5にしたときの教訓なので、実践しよう。
ウィザードで作ったアプリも、Protocol family unavailableだ・・・。

 

ネットで検索すると、ファイアウォールうんたらと出てくる。
うちは、Windows 10 Firewall Controlというやつを制御に入れている。
Windowsの標準ファイアウォールがもうちょっと細かく動いてくれる感じだと思ってる。
その通信を見ると、java.exeの通信が遮断されていた。
Outgoing Onlyじゃなくて、両方有効にしないとダメみたい。

許可すると、普通に動いた。

 

せっかくなので、設定ファイルも全部消してやりなおしたら、Preview2.0だけできた。
まあ、それでいいじゃろう。

[勉]bitconを使えるようにしてみよう (2)

続き。
いちおう、知らない言葉を調べるシリーズの一環として行ってる。

前回は、とりあえずビットコインを使えるようにするにはビットコイン・ウォレットってものを用意せんといかんみたい、というところまでだった。
今日は、パソコンにビットコイン・ウォレットのアプリをインストールしてみる。


うちのパソコンは、Windows7 64bit版。
ダウンロードしたのは、electrum-2.5.4.exe。

スプラッシュ画面やウィザード画面よりも先に、VC++のランタイムライブラリエラーが発生!
どうしようもないのでOKボタンを押すと、進んだ。

新しいウォレットを作るか、インポートするかを聞かれる。
それと、ウォレットの種類。
悟コインをはがしてインポートするのもよさそうだが、後からでもできそうなので、新規で作ってみよう。
種類は、標準で。

そうすると、ウォレットのseedを文字で入力するよう求められた。
と思ったら、入力を求めてるわけじゃなくて、表示している単語を覚えておくように要求されているのだ。
seed? 種?
たぶん、このキーワードで一意な値を生成できるようになっているのだろう。
念のため、ここでインストーラを終了させてもう一度ここまで進めると、別の単語が表示されていた(数も違う)。
「公開するな」「ウェブサイトに載せるな」「印刷するな」と、とにかくこれが重要なのはわかった。
どういう風に使うのかはわからんけど、いっそのこと日本語とかが出てきた方がよさそうな気もする。

次に進めると、「ほんとにseedを覚えているか心配だから、もういっぺん入力してみなされ」という画面になる。
大切なんだねぇ。

次はパスワード。
ただ、このパスワードは必須というわけではなさそうだ。
パスワードを入力しないと暗号化しないぞ、ということらしい。
何を暗号化するかというと、wallet keys。
さっきのはseedだったから、それともまた違うということか。。
まあ、暗号化しない理由もないので、入力しておく。

次が、トランザクションとアドレスの情報を取ってくるリモートサーバの選択らしい。
自動か手入力か。
手入力できないから自動で選んでもらうけど、いいのかな?
そして、うちのパソコンはファイアウォールアプリが入ってるから、そろそろ警告されそう。
(警告のときはアクセスが遮断されるので、リトライできないタイプのインストーラだとやり直しになってしまう。。)

えいっ

予想に反して、何も出てこなかった。
え、終わり??
image

Not connectedと書いてあるから、未接続なんだろう。
ファイアウォールは作動しなかったような。。。
あ、インストールの最初辺りに有効にしたけど、あれがそのままのようだ。
つまりこのexeファイルは、インストーラじゃなくて本体なんだ。

 

右下の赤いボタンを押すと、それっぽい選択画面が出てきた。

image

さっき、自動を選んだつもりだったが、チェックされてないな・・・。
チェックして、OKすると、緑色になった。

image

これで、終わりみたい。

メニューの「File > New/Resotre」を選ぶと、またウィザードっぽいダイアログが出てきた。
インポートしたかったら、ここから選べばよいのだろう。

これで、私もビットコイナー(そういう呼び方かは知らんが)だ!


で?

ここにアドレスを載せておけば、世界中の人から振込とか来たりするんだろうか?
いや・・・買い物するわけじゃないから、そういうわけじゃないだろう。

銀行で考えると、こういうことができる。

  • お金を振り込む
  • お金を引き出す

振り込む手段としては、ATMに現金を突っ込んだり、他の人から振り込んでもらったり。
引き出すときは、現金として使いたいときだから、窓口に行くかATMに行くかだろう。

 

ビットコインのはじめ方 - ビットコインの解説 | Bitcoin日本語情報サイト
ここら辺に載ってた。
今日やったのは「①ウォレット(財布)を作る」に当たるな。
そして「②ビットコインを手に入れる」が、お金を振り込むという動作になるか。
引き出すというのは、取引所で日本円とかに変換してもらって、銀行口座に振り込んでもらうとかか。

すぐには理解できそうにないので、今回はここまで。

2015/11/27

[mbed]faviconに見るmbed

あまり本質に関係ない記事を書いて今日を終えよう。
mbedのサイトが、いろいろ変わりつつある。

私が見たときはこういうサイトだった。

image

 

ただ、昨年にmbedを買ったとき見たのは、こんな感じのサイトだったと思う。
(これはdeveloperのページ。)

image

 

なので、1年も経てばページくらい変わるよなあ、という気持ちでいたのだけど、mbedのメジャーバージョンが変わろうとしているところらしく、mbed OSだのyottaだのも、新しい方のmbedでの話みたいだ。

というのはさておくとして、以前との最近のではfaviconが違うんだ、ということに気付いたので記録を残しておこう。


前のfavicon。

image

うちのFirefoxのブックマーク画像だけど、濃い青に黒い丸と四角と点々があるアイコンだ。

 

image

こっちが、最近のfavicon。
薄い緑というか、青というかに白い線だ。
HTMLの色でいえば、#159AB5らしい。

image この色

mbedのページだと、カギ括弧。
mbed Device Connectorだと「ARM」は見えるけど、「ARM mbed」なのかな。

 

mbed forumのfaviconは違う」とか「mbed Developer Blogのfaviconは、白じゃなくてちょっとグレーっぽいけど、圧縮のせいか?」とか、いろいろあるようだけど、落ちもなく記事はこれで終わりだ。

[勉]bitcoinを使えるようにしてみよう (1)

よそのオフィスに行ったら、ビットコインのコインをいただいた。
こんなの。

image

ビットコインをリアルに体感できる悟コイン
「さとりコイン」と読むようだ。
こちらが、供給?元。
フィジカル・ビットコイン「悟 Satori」

練習用かなー、と思ったが、ちゃんとビットコインが入っているらしい。
ほほぅ。


ビットコイン、というのは、なんとなくしか知らない。
仮想通貨だ、というくらいか。

このコインには0.001単位のビットコインが使えるとのこと。
ビットコインの単位は、BTC、のようだ。
これで「ビットコイン」と読んでよいようだ。
http://bitcoin-mania.hatenablog.com/entry/2014/01/22/050548
1BTCが最小じゃなくて、1億分の1BTCが一番小さいらしい。
いくらだよ。

1BTCの値段は、取引所で違うようだ。
海外のお金を換金するのと同じイメージなのかな?
https://www.btcbox.co.jp/
ここを見ると、今の時間だと44,219円となっているので、1BTCがそういう値段なのだろう。
だから、このコインには今日だと44.2円分くらいの価値があるということになる。

無料でもらってきたけど、よかったのかなぁ。
まあ、もらった分の宣伝?にはなるかもしれないので、それで許してもらおう。


ただ、持っているだけではどうしようもない。

海外旅行から帰ってきたおじさんが、あまった海外の通貨をおみやげでくれたようなものだ。
モノとしてあるから「わー、おもしろい」と思って眺めておくも良し、コインの耐タンパ?されたシールをはがせば使うための情報が入っているらしい。

 

じゃあ、使う前提として、何を用意したらよいか調べよう。

まず、コインをはがすと、QRコードに秘密鍵が書いてある紙が出てくるそうだ。
だから、QRコードを読めるツールはいるな。

これを、ビットコイン・ウォレットというものに移し込むとよいらしい。
銀行振込みたいに手数料がいる(振り込む額から引かれるようだ)タイプ「粋-ピング」と、そのまま使うタイプ「インポート」があるようだ。

じゃあ、後者の方が引かれなくていいやん、と思うのだが、QRコードが残っていると他の人に同じことをされて、これを他の口座に振り込みされてしまうと消えてしまうらしい。
しかも、後者の機能が使えるところは少ないらしい。


よくわからんが、口座を作らんといかんということはわかった。
作ったら、そこの機能として、振り込んだりできるというしくみだと思う。

ビットコインの保管(ウォレット比較) | Bitcoin日本語情報サイト
・・・だんだん、めんどくさくなってきた。
とりあえず「口座」と書いてきたが、銀行みたいな管理してくれる機関はない、ということらしい。
口座に相当するものが、ビットコイン・ウォレット、と呼ぶもののようだ。

このビットコイン・ウォレット、長いから「ウォレット」と略すようだが、ローカルに作るか、ネット上に作るかみたい。
上記サイトでは、

  • パソコン上
  • インターネット上
  • モバイル上
  • ハードウェア

にウォレットを作るというか、ウォレットを管理するというかに分かれていた。

「紙ってなによ?」と思ったが、たぶん今回もらってきた悟コインも、このジャンルになりそうだ。
紙といっても、紙幣という意味じゃなくて、どっちかといえば紙にパスワードを書いて保存しておくようなものかしら。

リンク先には、バックアップとは異なる、と書いてあるけど、バックアップは「情報が消えても復活できるように」が目的で、まだ本物のビットコインはネット上に残っているからかね。
バックアップは「インポート」と同じことなのかもしれん。


パソコン上に作るタイプの説明があった。
デスクトップウォレット仕様・機能徹底比較 - ビットコインの保管 | Bitcoin日本語情報サイト
これを書いているときは、2015年9月21日が最終更新になっている。
2ヶ月前だから、まあそれほど変わらんだろう。
Electrumってのが軽いらしいから、それをインストールしてみよう。

[nrf51]WRITEの戻り値は考慮が必要?

Characteristicへの書き込みの時、アプリで戻り値を決めようとしている。
nRF51822 S110のシーケンスだと、これだ。
GATTS Write Request with Authorization

エラーにするだけだからなんでもいいだろうと思っていたのだけど、ものによってはsd_ble_gatts_rw_authorize_reply()でNRF_ERROR_INVALID_PARAMを返しているようだ。

「ようだ」というのは、同じ操作をしても値によってはエラーにならなかったからだ。
別の要因で発生した可能性もあるんだけど、そこまでは調べ切れてない。

まず、仕様としてそういうことがありうるのかどうかを見ていこう。


Core_v4.2.pdf [Vol 3, Part G 4.9.3 Write Characteristic Value]でも、シンプルなシーケンスだ。
image

戻り値のError Codeは、Attribute Protocolで規定してあるとのこと。
[Vol 3, Part F 3.4.1.1 Error Response]に表があった。
ここを見る限りでは、WRITEのときはこの値を返してはいけない、ということはないように見える。

ただ、変えそうとしていたのがBLE_GATT_STATUS_ATTERR_INVALIDとかBLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTEDだから、あまり行儀がよくない値という気もする。

前者の場合、値が「0x0100」となっている。
PDFの値を見ると、0x01~となっているし、nRF51のエラー値はその値に0x0100をORしたような値なので、返してはいけない値だったのかも。
後者の場合は、別にClientにエラーを返してもよい気はする。


表を見てて気付いたけど、アプリ側でエラーにするときは0x80~0x9Fにすべきなのかも。
いやー、でもなぁ。。。

答えが出ないまま終わってしまった。

2015/11/24

[nrf51]サイズ0のCharacteristicにしたい

メモ。

動作中に、可変サイズにしているCharacteristicのサイズを0にしたい。

 

sd_ble_gatts_value_set()

  • 第3パラメータにNULL設定
    • NRF_ERROR_INVALID_ADDR
  • ble_gatts_value_tのp_valueとlenに0設定
    • NRF_ERROR_INVALID_ADDR
  • ble_gatts_value_tのp_valueには非NULL値を、lenに0設定
    • OK

 

そうなのねぇ。

2015/11/23

[c/c++]extern "C"の復習

あまりやらないけど、extern "C"するときがある。
なんとなく、extern "C"で囲みすぎているような気がするので、復習しておこう。


なにもなし

  1: //main.c
  2: #include "test.h"
  3: int main()
  4: {
  5:     func_test(10);
  6: 
  7:     return 0;
  8: }
  1: //test.h
  2: #ifndef TEST_H__
  3: #define TEST_H__
  4: void func_test(int a);
  5: #endif /* TEST_H__ */
  1: //test.c
  2: #include <stdio.h>
  3: void func_test(int a)
  4: {
  5:     printf("%s(%d)\n", __func__, a);
  6: }

$ g++ -c main.cpp
$ g++ -c test.c
$ g++ -o tst test.o main.o
$ nm test.o
00000000 T __Z9func_testi
00000008 r __ZZ9func_testiE8__func__
$ nm main.o
         U __Z9func_testi

gccは、特に拡張子を見分けたりはしないようだ。


test.hにextern "C"

  1: //test.h
  2: #ifndef TEST_H__
  3: #define TEST_H__
  4: extern "C" {
  5: void func_test(int a);
  6: }
  7: #endif /* TEST_H__ */

$ g++ -o tst test.o main.o
main.o:main.cpp:(.text+0x16): `func_test' に対する定義されていない参照です
$ nm test.o
00000000 T __Z9func_testi
00000008 r __ZZ9func_testiE8__func__
$ nm.main.o
         U _func_test

結局のところ、extern "C"はオブジェクト生成するときの指示になる。
だから、test.hをincludeしているmain.cppは「func_test()はC系の名前なんだ」と思ってオブジェクトを作るけど、test.cはtest.hをincludeしていないので、コンパイラがg++だからC++系の名前でオブジェクトを作る。
だから、リンクしようとしても名前が合わなくて、エラーになる。


じゃあ、両方つける?

  1: //test.c
  2: #include <stdio.h>
  3: extern "C" {
  4: void func_test(int a)
  5: {
  6:     printf("%s(%d)\n", __func__, a);
  7: }
  8: }

これは、うまくいく。
いくけどさぁ。。。


単に、test.cの行儀が悪いだけ、という気もするが、もうちょっと考えてみよう。

まず、staticな関数じゃないのに、ヘッダファイルに関数定義を作らないのはどういうときか?
思いつくパターンとしては、

  • ざざっと急いで作ったので、1つのソースファイルにまぜこぜした機能が入ってしまった
  • なんか気持ち悪いので、とりあえずソースファイルを小分けすることにした
  • 小分けすると、共通で使うわけではないが、機能的には別ファイルに置いた方がよい関数が出てきた
  • うーん・・・
  • ヘッダファイルには書かずに、使うソースがexternすることにしてしまえ!

といった感じだろうか?
弱い非公開関数、みたいなイメージだ。

「そんなのするべきじゃない」というのは簡単なのだけど、まあ、ここではそういう話はしない。
そういうパターンがあるかも、くらいにしておく。

 

そもそも、関数を参照する方はプロトタイプ宣言みたいに前方参照するものがいるけど、定義しているところは自分が本物だから何も言われないのだよなぁ。
もし、関数定義しているところも宣言を読まないといけないのだったら、「ヘッダに書きましょう」で終わるんだけどねぇ。
やるんだったら、内部参照用のヘッダファイルを別に定義して、そっちをソースファイルはincludeするようにするのかな。

そういうわけで、私の場合はこうしておこう。

  • 公開することになる関数のプロトタイプ宣言は、必ず書く
  • 公開することになるプロトタイプ宣言は、ヘッダファイルに書く
  • 公開範囲を制限したいときは、ヘッダファイルを分割する
  • 非公開関数のプロトタイプ宣言は、そのときの気分で
    • お仕事用の時は、ちゃんとするよ!
  • ソースファイルをincludeしたりする人は、もう知らん
    • 単体テストの時とか、めんどくさくてやったりするけど、例外ってことで

 

まあ、今回のtest.cでincludeを書いていないのは、本当に書き忘れていただけなんだけどね・・・。

WireShark2.0からUSBPcapが取り込まれたので、TIスニファを試す

出ましたね、WireShark2.0。
ネットワークプロトコルアナライザー「Wireshark」がメジャーアップデート - 窓の杜

インストール中に気付いたが、USBPcapがとうとう取り込まれることになった。
以前のこんなめんどくさいことをしなくてもよくなるんではなかろうか。

 

これと同じように、TIのBLEドングルの通信を吸い取ってみよう。
hiro99ma blog: [ble]どうせならWireSharkで直接パケットを見られないだろうか
環境は、Windows7 64bit SP1 + WireShark v2.0.0だ。


起動すると、こんな画面が出てくる。
(最初は日本語で出てたけど、さっき見たら英語になってたので、キャプチャし直した。)

image

下に、キャプチャとなるデバイスの一覧が出ているようだ。
USBPcapというのがいくつもあるが、これがUSBPcapCMD.exeを実行したときに出てくる一覧と一致しているようだ。
どれにTIのドングルが入っているかわからないので、手当たり次第に開いたら、3番に入っていた。

ダイアログを出すときは、歯車のアイコンの方をクリックする。
ただ、ここで期待するデバイスを選択しても、データは配下のものを全部取ってくるようだ。

image

ここで「開始」とすると、おお、キャプチャーが始まった!
というスクリーンショットを撮ろうとしたのだが、プロファイルを変更しようとしたら異常終了してしまった・・・。

異常終了したときは、タスクマネージャーを確認しておこう。
どういうときかわからないが、USBPcapCMD.exeが残ったままで、しかも高負荷になっていることがあるのだ。

 

気を取り直して、もう一度。

image

ドングルの制御ができるわけじゃないから、TIのスニファを起動させている。
選択している箇所が、Advertisingのデータらへんだ。

 

で、左側のリストに緑色のがあるが、そこはUSBMSで、MassStorageのパケット。
mbedを接続しているのだけど、同じPcap3につながっているから見えてしまうのだ。
これは、フィルタで「usb.device_address == xx」を指定するのがよいだろう。
実際に取ったパケットから選択するのが楽だな。

image

 

あとは、MassStorageみたいに動的な解釈をしてくれればよし、なのだが。
hiro99ma blog: [ble]CC2540 USB Dongleから直接WireSharkで見る
記憶から抜けていたが、ここでLUAを作っていたらしい。
そのまま使うと動かなかったのだが、どこかの時点でDissectorTableが変わったようで、変更したら動いた。

https://sites.google.com/site/hiro99ma/ble/files/ble_cc2540dongle.lua?attredirects=0&d=1

image

Advertisingだってことがわかるし、Flagsの解析もしてくれるので、CSS.pdfを見なくて済むな。

2015/11/22

[mbed][nrf51]RAMが32KB向け

mbed OSをnRF51 DK向けにビルドできたので、とりあえずうちのnRF51822に焼いてみた。
ピン番号が違うくらいだから、そこに割り当てたら動くんじゃなかろうか。

・・・動かない。
LEDとUART出力を行うようなのだけど、どちらも動かん。

 

MAPファイルを見ると、こうなっていた。

Name             Origin             Length             Attributes
FLASH            0x0001c000         0x00024000         xr
RAM              0x20002800         0x00005800         xrw

そして、targetのgithubページにはこう書いてあった。

image

32KBって、RAMのことだろう。
nRF51822で32KBのRAMって、QFACかCFACしかない。
うちのは、16KBなのだ。
22KB強って、ちょっとなぁ。
OS使うから、このくらいはしょうがないということか。

 

あと、SoftDeviceはS130が混ぜ込まれたHEXファイルが作られてた(入ってないのもできてる)。

[mbed][nrf51]もう一度nRF51822ビルドを!

なんとなく文化の日っぽくやってきたが、全然関係なかった。

https://github.com/ARMmbed/mbed-os
ここを見ていて、やっぱり対象となるターゲットにnRF51822が入っていることがわかった。
ターゲットの指定方法が悪かったように思うので、もう一度やり直すことにした。


まずは、書いてある通りにやろう。
やるのだが、yottaをもう一度インストールし直すことにした。
「pip install yotta -U」とやったけど、エラーになったのでねぇ。
Windowsだったからか、インストールした時期が悪かったのか。。

それをやってから、まずはblinkyサンプルを取り直す。

> git clone https://github.com/ARMmbed/example-mbedos-blinky
> cd example-mbedos-blinky
> yotta target nrf51kd-gcc
> yotta build

いろいろwarningが出たが、進んだ!
128番まであるようで、こういうので終わった。

[128/128] Linking CXX static library ym/ble/source/ble.a

えっ、ライブラリ・・・?
githubを見ると、source/example-mbedos-blinkyらしいが・・・

build/nrf51dk-gcc/source/example-mbedos-blinkyってのがあるな。
hexファイルもある。
こ、これか・・・、ごくり。

 

焼いて試したいところだが、うちにあるmbedのnRF51822ってBLE Nanoだけで、この子がDKと同じもので動けるとはちょっと考えにくい。
なので、ちょっと動かすのは保留だ。

だが、nRF51用のmbed OSでもビルドできたぞ!ということで満足した。

2015/11/21

[arm]Cortex-MでもLLVMを使ってみたかったが、失敗した

静的解析のことを調べていたら、LLVMが出てきた。
そういえば、Objective-CのときはLLVMだったよなぁ、と薄い記憶しかない。
が、Interface誌の2015年3月号に特集もあったので、あれから半年以上経っているのでもっと使えるようになっているはず。

そう、私だってCortex-MでLLVMしてみたいのだ。


うちの環境は、Windows7 64bitがメインなので、ここで使いたい。
Cortex-Mのビルドはcygwinを使っているが、コンパイラはGCC ARM EmbeddedからWin32版を落としているので、同じような感じになるのかな?

 

How To Build On ARM

ここがLLVMのページにある説明のだが、クロスコンパイルについては「NOT tailored」ということで、まだ整備されていないと読めばよいのか。
つまり、ここに書いてある説明は、ARM上でARMのビルドをするセルフコンパイルについてということだろう。

あまり気にしてなかったけど、LLVMとClangって別々なのですな。
Wikipediaで見ると、「ClangはLLVM上で動作することを意図している」とあり、

  • LLVM : バックエンド
  • Clang : C/C++/Objective-C/Objective-C++向けコンパイラフロントエンド

となっている。

コンパイルのフロントエンドとバックエンドってなんじゃろう、と思ってInterface誌を見ると、フロントエンドがソースファイルを解析して、バックエンドがバイナリに変換する、といっているようだ。
フロントエンドとバックエンドの間は「中間言語」がインターフェースになっていて、フロントエンドが何言語用であっても中間言語にさえ変換しておけば、あとはバックエンドが中間言語をうまいこと処理してくれるということだろう。
確か、GCC4から大きく変わりましたよー、というアナウンスがあったときも同じようなことを言ってたように思う。

そうなると、クロスコンパイルで差し替えになるのは、ClangというよりもLLVMの方になるのかな?
まあ、そこら辺はやっていけばわかるだろう。


How To Cross-Compile Clang/LLVM using Clang/LLVM
Cross-compilation using Clang

クロスコンパイルについてはこちらを、ということだ。
上のリンクは、LLVM/Clang自体をクロスコンパイルしてセルフビルドできるようにしているのかな?
下のリンクは「using Clang」だから、こちらが私の思うクロスコンパイルの方だ。
「Clang 3.8」となっているが、正式リリースされているのは3.7みたい(2015/11/21)。

ARMのサポートは全部じゃない、とあるが、Interface誌ではLLVM3.5からthumbのオブジェクトも一気に吐いてくれると書いてあるので、とりあえずLLVM3.5以降ならよいのかな?
ダウンロードページに、64bit用Windows向けのプレビルド版LLVM3.7.0があるので、それをインストールしてみよう。
"c:\Program Files\LLVM"に入るが、まあいいだろう。

こんなソースをコンパイルしてみた。

hello.c

  1: volatile int a;
  2: 
  3: int main(void)
  4: {
  5:     int i;
  6:     
  7:     for (i=0; i<10; i++) {
  8:         a += i;
  9:     }
 10:     
 11:     return 0;
 12: }

特に何かするわけでもないが、最適化されて中身が空っぽということはないだろう。

>clang hello.c
/usr/bin/ld: unrecognised emulation mode: i386pep
Supported emulations: i386pe
clang.exe: error: linker command failed with exit code 1 (use -v to see invocation)

えっ。
ldは、cygwinにパスを通してある方のが呼ばれているようだけど、そもそもなんでclangがldを呼び出すのだろう?
インストールされているパスを見ると、lld.exeというのがあり、これはLLVM Linkerらしい。
じゃあ、これを呼び出せばよいのに。。。

LLVM Clang の Windows へのインストールと使い方 | プログラマーズ雑記帳
こちらを読むと、どうもWindowsで動かすときには「gcc互換」と「VisualStudio互換」があるらしい。
gcc互換の場合はMinGWを使うらしく、includeファイルなどもそっちを使うとのこと。
うぅ・・・。

c++ - (clang / llvm-mc / lld) hello world (x86-64 windows & linux) - Stack Overflow
こっちも、lld開発者の人が「clang to use lld is to make a symlink to lld named ld」と書いているので、ldを使っているように読める。

でもねぇ。lld.exeって30MBもあるのだよ。
もうちょっと小さくてもいいやん、と思ってしまう。

 

では、と-cをつけてオブジェクトだけ生成させて確認する。

>clang -c hello.c

これでhello.oができる。
できるのだが、gccで生成したobjectファイルと構成が違うようなのだ。
cygwinのfileコマンドで見ても、gccの方は「MS Windows COFF Intel 80386 object file」と読むのだが、llvmの方は単なるデータファイルとしてみてしまう。
だから、ld.exeを呼び出してもダメだったんじゃなかろうか?
バイナリエディタで見ると、同じようなものは含んでいそうだけど、頭の方が違うので構造が違うんだろうな。

 

めんどくさくなってきたので、cygwinのLLVM/Clangをインストールした。
こちらは3.5.2だった。

$ clang -o hello hello.c

普通にコマンドができた。

$ clang -c hello.c
$ file hello.o

COFFファイルになっている。
うーん。

Windows版のclangとMinGWのldで動くとするならば、MinGWのldで認識できるオブジェクトをclangが生成しているということだろう。
cygwinのfileコマンドも、データベースから参照しているだけだと思うので、それに入っていなければわからないだろうし。
そういうのは、後で考えよう。


では、cygwin上でCortex-M用にビルドしてみよう。

$ clang -target arm-eabi -mcpu=cortex-m0 hello.c
error: unable to create target: 'No available targets are compatible with this triple, see -version for the available
      targets.'
1 error generated.

あら。。。
-versionでターゲットを見て見ろ、と。

$ clang -version
clang: error: unknown argument: '-version'
clang: error: no input files

エラーになるやん!

$ clang -v
clang version 3.5.2 (tags/RELEASE_352/final)
Target: i386-pc-windows-cygnus
Thread model: posix

このTargetの中にARMも追加されればよいのだろうか?
Windows版ではこう出てきた。

>clang -v
clang version 3.7.0 (tags/RELEASE_370/final)
Target: x86_64-w64-windows-gnu
Thread model: posix

うーん・・・・・・・・・。

Thieves of BeagleBoard: ARMクロスコンパイル用clang
こちらを見ると、llvmをビルドしているようなので、私もそうしよう。


http://llvm.org/releases/download.html#3.7.0

ここから、いりそうな気がするものをダウンロード。

  • LLVM
  • Clang
  • compiler-rt
  • LLD
  • LLDB

LLVMを解凍して、その中のtoolsフォルダ内に残りを解凍。
解凍した後、フォルダ名は変更するみたい(Interface誌を見て)。
そして、どこかに作業用のフォルダを掘って、そこに移動して、cmakeをたたく。

$ cd tools
$ 適当に解凍してリネーム
$ cd ..
$ mkdir build
$ cd build
$ cmake -Wno-dev ..

-Wno-devは、警告がうっとうしいので入れただけで、特に意味はない。
私の環境では、SWIGとlibxml2がなかったので、それも入れてやり直した。
Ocamlも見つからないと言われたけど、インストールしたんだけどなぁ。
そこは無視したが、最後に「done」と出てきたのでよしとする。

「done」したけど、どうしていいのかわからん・・・。
http://llvm.org/docs/CMake.html
ここを見ると、--buildしているので、まねしよう。

$ cmake --build .

時間がかかりそう。
オプションで、ビルド対象のターゲットを指定できるみたいだから、それをした方がよかったのかも。
それと、今回はnRF51822で使うつもりだから、C++はいらないのだな。


えーっと、約3時間半ビルドして、エラーが発生しました。。。

  1: Scanning dependencies of target lldbTarget
  2: [ 71%] Building CXX object tools/lldb/source/Target/CMakeFiles/lldbTarget.dir/ABI.cpp.o
  3: /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/source/Target/ABI.cpp:1:0: 警告: -fPIC はターゲットでは無視されます (全てのコー ドは位置非依存です)
  4:  //===-- ABI.cpp -------------------------------------------------*- C++ -*-===//
  5:  ^
  6: In file included from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Target/Process.h:13:0,
  7:                  from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Core/ValueObject.h:33,
  8:                  from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Core/ValueObjectConstResult.h:17,
  9:                  from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/source/Target/ABI.cpp:13:
 10: /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Host/Config.h:39:2: エラー: #error undefined platform
 11:  #error undefined platform
 12:   ^
 13: In file included from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Core/Communication.h:23:0,
 14:                  from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Target/Process.h:28,
 15:                  from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Core/ValueObject.h:33,
 16:                  from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Core/ValueObjectConstResult.h:17,
 17:                  from /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/source/Target/ABI.cpp:13:
 18: /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Host/HostThread.h:45:5: エラー: ‘HostNativeThread’ does not name a type
 19:      HostNativeThread &GetNativeThread();
 20:      ^
 21: /cygdrive/e/Temp/llvm-3.7.0.src/tools/lldb/include/lldb/Host/HostThread.h:46:11: エラー: ‘HostNativeThread’ does not name a type
 22:      const HostNativeThread &GetNativeThread() const;
 23:            ^
 24: cc1plus: 警告: 認識できないコマンドラインオプション "-Wno-deprecated-register" です
 25: tools/lldb/source/Target/CMakeFiles/lldbTarget.dir/build.make:62: ターゲット 'tools/lldb/source/Target/CMakeFiles/lldbTarget.dir/ABI.cpp.o' のレシピで失敗しました
 26: make[2]: *** [tools/lldb/source/Target/CMakeFiles/lldbTarget.dir/ABI.cpp.o] エラー 1
 27: CMakeFiles/Makefile2:29330: ターゲット 'tools/lldb/source/Target/CMakeFiles/lldbTarget.dir/all' のレシピで失敗しました
 28: make[1]: *** [tools/lldb/source/Target/CMakeFiles/lldbTarget.dir/all] エラー 2
 29: Makefile:149: ターゲット 'all' のレシピで失敗しました
 30: make: *** [all] エラー 2

うーん、undefined platformが効いてるのかな。
tools/lldb/include/lldb/Host/Config.hを見てみよう。

__APPLE__
__ANDROID_NDK__
__linux__ || __GNU__
__FreeBSD__ || __FreeBSD_kernel__ || __OpenBSD__ || __NetBSD__
__MINGW__ || __MINGW32__
_MSC_VER

えっ、cygwinって__GNU__は持ってないの??

それに、LLDBってLLVMのシンボリックデバッガらしいではないか。
なくてもよいんでないか?
tools/CMakeLists.txtの最後にlldbが入ってるけど・・・

lldbフォルダを別の名前にして、ビルドし直し。


あれから5時間経ちました・・・。
CPUにもメモリにもタスクマネージャー上は余裕があるのだけど、ディスクがぐりぐり動いていて、そしてエラーです。

[ 67%] Linking CXX executable ../../../../bin/clang.exe
../../../../lib/libclangStaticAnalyzerCheckers.a(VLASizeChecker.cpp.o): シンボルを読み込むことができませんでした: Memory exhausted
collect2: エラー: ld はステータス 1 で終了しました
tools/clang/tools/driver/CMakeFiles/clang.dir/build.make:309: ターゲット 'bin/clang-3.7.exe' のレシピで失敗しました
make[2]: *** [bin/clang-3.7.exe] エラー 1
CMakeFiles/Makefile2:19960: ターゲット 'tools/clang/tools/driver/CMakeFiles/clang.dir/all' のレシピで失敗しました
make[1]: *** [tools/clang/tools/driver/CMakeFiles/clang.dir/all] エラー 2
Makefile:149: ターゲット 'all' のレシピで失敗しました
make: *** [all] エラー 2

ディスクの空きもあるのだけど、とりあえずPCを再起動しないと身動きが取れないです。
くそう、こっちも失敗かー。

[c/c++]静的解析ツールを探そう (1)

コンパイルが終わらないので、その間に静的解析ツールでも使ってみよう。
先に書いておくが、今回はInferをWindowsで動かすのはあきらめた。

  • Infer
    • 「分離理論」というものでやってる
    • ポインタを追うのが他の静的ツールよりも得意らしい
    • モバイル向けっぽいことを書いてあるけど、何がだろう?
  • Cppcheck
    • C++でも使える
  • Splint
    • LINTの中のLINTというイメージ(私の中で)

 

やってみる対象は、こちら。
https://github.com/hirokuma/nrf51822v10_bds_sample

ほとんどnRF51 SDKのサンプルなのだけど、まあよかろう。
GCCのビルドでは、-Wallくらいしかつけていないが警告は出ていない。

-DBOARD_BVMCN5102 -DSWI_DISABLE0 -DSOFTDEVICE_PRESENT -DNRF51 -DS110 -DBLE_STACK_SUPPORT_REQD -Wall -Werror -O0 -ggdb -Wno-error=format -mcpu=cortex-m0 -mthumb -mabi=aapcs --std=gnu99 -mfloat-abi=soft -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums


Inferを試そうと、インストール方法のページを見た。
https://github.com/facebook/infer/blob/master/INSTALL.md#install-the-dependencies
うーん・・・、LinuxとMacOSはコンパイル済みのバイナリがあるけど、Windowsについては単語すら出てこない。
cygwinならLinuxと似たような環境でできるんじゃなかろうか、ということで、試すだけ試そう。

gccが4.7.2以上、Pythonが2.7以上なのはよいとして、opamってのも必要らしい。
cygwinのインストーラには、大文字でも小文字でもOPAのものがなかった。

cygwinでinfer入れた人いないの?と検索したら、こちらが出てきた。
http://fbinfer.com/support.html#faq
まあ、サポートしてないならないでもいいので、どこでダメになるか見てみよう。

cygwinとopamで検索すると、Ocamlが出てきた。
opamというのは、Ocamlのパッケージ管理ツールみたいだ。
Ubuntuのapt-get、pythonのpipみたいなものか。

Ocamlのインストールページを見る。
https://ocaml.org/docs/install.html
ここから、Ocaml on Windowsのページに飛んで、そこのインストーラをダウンロードするサイトに飛ぼうとすると、Firefoxが「危険!」と警告してきた。
gallium.inria.frというサイトがよろしくないらしい。

「君子、危うきに、近寄らず!」

私はその場を立ち去った。
まあ、君子かどうかは別として、そこまでしてWindowsで試さなくとも、というところだ。
今回はInferを見送って、Linuxを立ち上げるときに試そう。


次は、CppCheck。
これはCygwinのインストーラからでもインストールできるので楽だ。

CppCheckのよいところは、とりあえず解析してくれるところだ。

$ cppcheck --enable=all .
Checking main.c...
[main.c:178]: (style) The scope of the variable 'err_code' can be reduced.
Checking main.c: BLE_DFU_APP_SUPPORT...
1/3 files checked 63% done
Checking services/ble_adconvert_service.c...
2/3 files checked 90% done
Checking services/service_if.c...
3/3 files checked 100% done
[main.c:97]: (style) The function 'assert_nrf_callback' is never used.
[services/ble_adconvert_service.c:172]: (style) The function 'ble_adconvert_service_advalue_set' is never used.
[services/service_if.c:78]: (style) The function 'bluetooth_adc_send' is never used.
(information) Cppcheck cannot find all the include files (use --check-config for details)

インクルードパスとか、マクロの定義とかまったく与えていないのに、とりあえず調べてくれている。
うん、確かに「assert_nrf_callback」はいきなり出てくるから未使用とみなされて仕方ないし。
世話好きなおっちゃんが「うーん、わからんこともあるけど適当にやってみるわ」っていう印象。
悪い意味じゃなくてですな。

ここで引数にインクルードパスなどを設定していくのもよいが、せっかく「--check-configで詳細を見れるよ」って書いてあるので、見てみよう。

  1: $ cppcheck --enable=all --check-config .
  2: Checking main.c...
  3: [main.c:27]: (information) Include file: <stdint.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
  4: [main.c:28]: (information) Include file: <string.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
  5: [main.c:29]: (information) Include file: "nordic_common.h" not found.
  6: [main.c:30]: (information) Include file: "nrf.h" not found.
  7: [main.c:31]: (information) Include file: "app_error.h" not found.
  8: [main.c:32]: (information) Include file: "ble.h" not found.
  9: [main.c:33]: (information) Include file: "ble_hci.h" not found.
 10: [main.c:34]: (information) Include file: "ble_srv_common.h" not found.
 11: [main.c:35]: (information) Include file: "ble_advdata.h" not found.
 12: [main.c:36]: (information) Include file: "ble_advertising.h" not found.
 13: [main.c:37]: (information) Include file: "ble_conn_params.h" not found.
 14: [main.c:38]: (information) Include file: "boards.h" not found.
 15: [main.c:39]: (information) Include file: "softdevice_handler.h" not found.
 16: [main.c:40]: (information) Include file: "app_timer.h" not found.
 17: [main.c:41]: (information) Include file: "device_manager.h" not found.
 18: [main.c:42]: (information) Include file: "pstorage.h" not found.
 19: [main.c:43]: (information) Include file: "app_trace.h" not found.
 20: [main.c:44]: (information) Include file: "bsp.h" not found.
 21: [main.c:45]: (information) Include file: "bsp_btn_ble.h" not found.
 22: [main.c:46]: (information) Include file: "service_if.h" not found.
 23: 1/3 files checked 63% done
 24: Checking services/ble_adconvert_service.c...
 25: [services/ble_adconvert_service.h:6]: (information) Include file: <stdint.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
 26: [services/ble_adconvert_service.h:7]: (information) Include file: <stdbool.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
 27: [services/ble_adconvert_service.h:8]: (information) Include file: "ble.h" not found.
 28: [services/ble_adconvert_service.h:9]: (information) Include file: "ble_srv_common.h" not found.
 29: [services/ble_adconvert_service.h:10]: (information) Include file: "app_util_bds.h" not found.
 30: [services/ble_adconvert_service.c:4]: (information) Include file: <string.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
 31: [services/ble_adconvert_service.c:5]: (information) Include file: "nordic_common.h" not found.
 32: [services/ble_adconvert_service.c:6]: (information) Include file: "ble_srv_common.h" not found.
 33: [services/ble_adconvert_service.c:7]: (information) Include file: "app_util.h" not found.
 34: [services/ble_adconvert_service.c:8]: (information) Include file: "app_util_bds.h" not found.
 35: 2/3 files checked 90% done
 36: Checking services/service_if.c...
 37: [services/service_if.h:16]: (information) Include file: <stdint.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
 38: [services/service_if.h:17]: (information) Include file: "ble.h" not found.
 39: [services/service_if.c:4]: (information) Include file: <stdint.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
 40: [services/service_if.c:5]: (information) Include file: "app_error.h" not found.
 41: [services/service_if.c:6]: (information) Include file: "app_trace.h" not found.
 42: 3/3 files checked 100% done

たくさんある・・・。
まあ、何も指定していないので、当たり前だ。

 

まずは、Makefileを書き換える。
インクルードパスだけの変数と、マクロ定義だけの変数を作るようにするのだ。
そうしておくと、それをCppCheckに渡すことができる。
-Wallなんかは、CppCheckが理解できないので、分離するのだ。

そうして整理した結果をgithubにコミットした。

$ make check
Checking ../../../main.c...
[../../../main.c:178]: (style) The scope of the variable 'err_code' can be reduced.
1/3 files checked 63% done
Checking ../../../services/ble_adconvert_service.c...
2/3 files checked 90% done
Checking ../../../services/service_if.c...
3/3 files checked 100% done
[../../../main.c:97]: (style) The function 'assert_nrf_callback' is never used.
[../../../services/ble_adconvert_service.c:172]: (style) The function 'ble_adconvert_service_advalue_set' is never used.
[../../../services/service_if.c:78]: (style) The function 'bluetooth_adc_send' is never used.
(information) Cppcheck cannot find all the include files (use --check-config for details)

システム側のインクルードパスは、もう気にしないことにした。
本当は、コンパイラオプションから自動的に-Iを生成できればと思ったのだけど、うまくいかなかったのだ。


splintも、cppcheckと同じ文法でいけるかなー、と、何も考えずに試した。

$ make splint
Splint 3.1.2 --- 15 Sep 2012

../../../../../components/device/nrf51.h:146:40:
    #warning Not supported compiler type
  Preprocessing error. (Use -preproc to inhibit warning)
   In file included from ../../../../../components/device/nrf.h:44,
                 from ../../../main.c:30
../../../../../components/device/nrf51.h:1191:40:
    #warning Not supported compiler type
../../../../../components/libraries/trace/app_trace.h:47:29:
    Invalid character in macro parameter name
   In file included from ../../../main.c:43
../../../../../components/libraries/trace/app_trace.h:47:29:
    Parameter list for #define is not parseable
../../../../../components/libraries/trace/app_trace.h:48:28:
    Invalid character in macro parameter name
../../../../../components/libraries/trace/app_trace.h:48:28:
    Parameter list for #define is not parseable
../../../../../components/libraries/trace/app_trace.h:49:29:
    Invalid character in macro parameter name
../../../../../components/libraries/trace/app_trace.h:49:29:
    Parameter list for #define is not parseable
Preprocessing error for file: /cygdrive/e/Prog/BLE/nRF51_SDK_10.0.0_dc26b5e/proj
    ects/bds_test/main.c
*** Cannot continue.
Makefile:264: ターゲット 'splint' のレシピで失敗しました
make: *** [splint] エラー 1

まあ、そんなもんか。

コンパイラの種類が違う、というのは、gccじゃなくてsplintだから仕方なかろう。
「Invalid character」は、こういうので出ていた。

#define app_trace_init(...)

これはapp_trace.hの47行目だが、改行位置は28桁目になっている。
ファイルは0x0D/0x0Aで保存しているので、「改行は0x0A」という指摘なのか。
まあ、main.cが処理されなかったので、意味はないのだけどね。


いろいろ調べて疲れたので、今回はここまで。

2015/11/19

[c/c++]他の静的解析ツールを探したい(無料の)

AdLintを使って、ツールのエラーが出ないところまで確認した。
つまり、まだ指摘の内容は何も見ていないままだった。

そろそろ仕事でのソースもコンパイルできるようになってきたので、まずは通そうと動かした。
が・・・ちょっと結果がつらい。
警告がたくさん出て、それを抑止する設定もあるのだけど、エラーの抑止ができない。
書き方が悪いのかもしれないが、サンプルが少ないのでよくわからない。

「インクルードガードがない」という指摘が出ていたのでヘッダを見たが、入っていた。
しばし考えたが、指摘された行はソースの先頭コメントと次のコメントの狭間だった。

/***
*
なんちゃら
*/

/***
*
なんとか
*
*/

2番目の「/***」でインクルードガードがない、といわれているので、そういう解析の仕方をしてるみたいだ。

無視していけばよいのだろうが、もうちょっと実績とサンプルが多くないと、疑う箇所が多すぎてつらい。
そういう感じの人が多くて、なかなかこういう静的解析ツールというのは無料だと品質が上がらないのだろう。
協力はしたいのだが、すまん、というところだ。

 

CppCheckは以前使って、なんとなく指摘が少なすぎたのでやめていたのだが、もう一度見直そうと思う。
あと、inferというのがあるのを知った。
FacebookがOSS化した静的プログラム解析ツールinferを試してみた - def yasuharu519(self):
これも試したい。
前のInterface誌の特集で、Clangのプラグイン?みたいなものあるとかだったので、そういうのもいいなぁ。

品質を上げるには時間と金がかかるが、自分でバランスを判断するとなるとつらいものがあるな。

2015/11/18

[mbed]medにcmsis-driverはなさそうだ

mbedで、内蔵FLASHにデータを書き込みたいと思った。
EEPROMとかないので、内蔵FLASHでいいや、くらいの選択だ。

出てきたのは、LocalFileSystem
サンプル通り書いてみたが、コンパイルが通らない。。。
ターゲットを、NUCLEO-F411REからLPCに変更すると、通った。
そうですか、そういうことですか。。。

STM32F411では内蔵FLASHの実行中書き込みができないためかと思ったが、PDFを見るとそうではない。
セクタが8つにわかれていて、消去はセクタ単位にしかできないけれどもできそうだ。

ならば誰かライブラリを作っているだろうと検索したけど、探し方が悪いのかもしれないが出てこない。
ネットで探すと、こちらの方がF401REで試されてた。
開発状況
CubeMXを使われているので、私も同じ感じでやってみて、Keil使って書き込みができることを確認できた。

 

そうなると、元情報を見ながら作りたいと思うではないか。
STM32のPeripheral Libraryじゃなかろうかと思い、stm32f4_dsp_stdperiph_lib.zipをダウンロードした。
いまは「STM32F4xx_DSP_StdPeriph_Lib_V1.6.1」というバージョンだ。
この中に「FLASH_Program」というサンプルがあったので、それを見ながら作った。
が、mbedコンパイラではコンパイルエラーになる。

上のサイトの人は「HAL_FLASH_Unlock」みたいな関数だけど、STMのライブラリは「FLASH_Unlock」という感じで、HAL_というプレフィクスがない。
mbedの方からmbed-srcをダウンロードして少し見たが、mbedではF4とかF1とかを吸収しようとして、間にHALを入れているような感じがする。
かといって、ヘッダファイルが共通なわけでもないから何とも言えないし、単にHAL_がついただけじゃなくて使い方が少し違ったりフラグクリアしてくれたりと、何かしら作っている感じがする。

なので、結局プログラムの作りとしては、サイトの人が作っているのと同じような感じになった。


「こういう違いを吸収するのって、CMSISがやってるんじゃなかったっけ?」ということで検索すると、CMSIS-DriverにFlash Interfaceがあった。

mbed-srcを「ARM_Flash_ProgramData」で検索したが引っかからなかったので、mbedにはCMSIS-Driverに相当する部分は無いんじゃなかろうか?という気がした。
まあ、STMのライブラリにも入ってないし、どういう状況なのかわからん。
CMSISのトップページでは、各社がHALを提供したら、アプリがHALかCMSIS-Driverを呼び出すようになってるから、どっちでもいいってことかなぁ。
image

CMSISに対応していてもいてなくてもいいので、mbedのコンパイラでビルドできればいいや、と思ってしまうので、実はARMのドライバ部分はCMSISじゃなくてmbedで吸収しようとしてたりして、と思わなくもない。

2015/11/17

NUCLEO-F411REの別USARTはPA11とPA12

NUCLEO-F411REのPA2とPA3を、USBシリアルからではなく普通のUSARTとして使おうとしていた。

そうなると、ST-Link側と切断しないといかん。
それには、裏側にあるジャンパというかハンダ付けブリッジというか、SBなんとかっていうのをショートさせたり外したりしないといけない。

DM00105823というPDFに載っているのだが、こういうことをやる。

  • SB13とSB14がそれぞれショートしているので、はずす
  • SB62とSB63がオープンになっているので、ショートさせる

 

ただ、これだとデバッグしづらいので、他のピンが空いているからそこのUSARTを代わりにつなぎたい。
PDFにはF103RBの例が載っているのだが、これはF411REには当てはまらない。
(どうせ同じだろう、とやってみて、失敗・・・)。

 

調べるのが面倒なのでネットで検索すると出てきた。
https://developer.mbed.org/users/JackB/notebook/nucleo-f411re---usart-on-arduino-header-d0rx-d1tx/
これの最初に書かれているのは、PDFのと同じだ。
最後に、F411REではUSART6を使う、というところが追加されている。

CN10の12ピンとCN3のRXピン、CN10の14ピンとCN3のTXピンを空中で配線すればよい、とある。
ふんふん、とつなぎ、ソースも「Serial pc(PA_11, PA_12)」みたいにした。
が、何も出てこず。

いろいろ調べたが、こうだった。

  • USART6のTX ・・・ PA11 ・・・ CN10の14ピン
  • USART6のRX ・・・ PA12 ・・・ CN10の12ピン

惜しい! TXとRXが逆だ。
USARTのTXはCN3のRXと、USARTのRXはCN3のTXと接続しないといかんので、

  • CN10の14ピンを、CN3のRXとつなぐ
  • CN10の12ピンを、CN3のTXとつなぐ

で動いた。

悩んだわぁ。

2015/11/16

Bluetooth Developer Studioの記事が少ない

みんな、Bluetooth Developer Studioを使ってるかい?

しーん・・・

というくらいに、ネットで検索しても出てこない。
まだ出たばかりとは言え、もうちょっと「使ってみました」な記事があってもよい気がする。

原因としては、まずWindows用のアプリということがあるだろう。
なんとなくだけど、BLEはiOSがこなれているらしいから、Macの人が多いんじゃないかと思う。
DotNetでできてるようだから、Mono(だっけ)とかで移植が進んでいるかもしれない。
ただ、機能として「Bluetoothのドングルでテストする」というものが載っている感じがするので、そういうのは難しいのだろうな。

他には、過去の資産を使っている、とかか。
BDSを使うとプラグインでソースを自動的に作ってくれるのだが、良くも悪くも自動生成なので、今のソースの構成から動きを変更することになるだろう。
それは、ちょっとコストが高すぎる。
新規で作っていいや、というときにしか使わないだろう。

やっぱり、こういうのは使う人が増えないと、心配で使えないだろう。
そう、今の私のように・・・。


ツールの出来は、最後は自動生成されたソースがどうかにかかってくると思う。
いま、nRF51822向けに使っているのだが、不明なところが多々ある。
そういう情報を探したいのだけど、検索しても使っている人が見つからない、という状況だ。

たぶん、ツールは問題ないのだろうと思うが、プラグインに改良の余地がありそうだ。
プラグインはJavaScriptやテンプレートファイルで作られている。
標準ではAndroid用などのプラグインがついていて、nRF51822はNordicのサイトにある。
Readme含めても8ファイルで、テンプレートが4ファイル。
こういうファイルを作れば、自分に合ったコードを自動生成させることもできるだろう。
実際、githubにiOS用のを作ってる人もいたし。

 

そんなわけで、文章が散漫になってしまったが、プラグインが重要だ、ということで終わろう。
ツールとプラグインの連携がよくわからないのだ。
ツールでここを変えると、ソースではこうなる、みたいなところがないと、ちょっとつらい。

また、自動生成してそのままビルドして通ったが、動かしていると死んでしまった、とか。
私が遭遇したのは、CharacteristicのフォーマットをVARIABLEにしたときに、スマホから書込むと死んでしまったのだ。
Authありだとか、READ無しだとか、ちょっと変なCharacteristicではあったが、ローカル変数でuint8_arrayを確保し、そのまま初期化もメモリ割り当てもせずに書き込みデータをコピーしようとして、死んでいた模様。

今回はローカル変数にコピーする必要がなかったため、その辺りをがさっと削除した。
そう考えると、自動生成したソースはなるべく加工せずに使うよりも、既存を残しつつ変更していって、BDSの方に変更が入ったら自動生成したソースをマージする、というやり方の方がよさそうだ。

そういう、「こういう風に使うのがよさそうだ」という情報が調べたいのですよ、私は!
「だったら自分で調べて書こうよ」と思われそうだけど、まだまだnRF51のことがわかってないし、BLEもわかってないので嘘を書いてしまいそうで怖くて。。。
でもまあ、間違ったことを書いていると「ここ違うよ」と教えてくれる方もあると思うので、ぼちぼち書いていきますかね。

[nrf51]特定CHへのAdvertisingを止める(デバッグ)

探すのに時間がかかったので、メモ。

nRF51 SDKでは、Advertisingするチャネルを抑制するオプションがある。
デバッグ用途以外で使うことはないと思うが、1つのスニファで捕捉したいときは楽なのだ。


components/ble/ble_advertising/ble_advertising.c
ble_advertising_start()

// http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s110.api.v8.0.0%2Fstructble__gap__adv__ch__mask__t.html&resultof=%22ble_gap_adv_ch_mask_t%22
#ifdef BLE_GAP_ADV_DISABLE37
    adv_params.channel_mask.ch_37_off = 1;
#endif  //BLE_GAP_ADV_DISABLE37
#ifdef BLE_GAP_ADV_DISABLE38
    adv_params.channel_mask.ch_38_off = 1;
#endif  //BLE_GAP_ADV_DISABLE38
#ifdef BLE_GAP_ADV_DISABLE39
    adv_params.channel_mask.ch_39_off = 1;
#endif  //BLE_GAP_ADV_DISABLE39

 

こんな感じにして、マクロを適当に使う。

[勉][py]やむを得ず覚えるpython (6)

やむを得ずといいながらも6回続けてきたこのコーナー。
今回で終わりにします。

実装するには不十分だけど、「うわっ、python知らないから無理」というところは脱したかなと思う。
あとは、他の言語と同じように、知らないことが出てきたら調べていけばいいだろう。


複数ファイル

sys.stderr.write()なんかは、他で実装された機能を使っている。
importで読込んだような感じはするのだが、まずは自分で複数作って試そう。

 

06.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: functionA()

06a.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: def functionA():
  4:     print("This is functionA.");

$ ./06.py
Traceback (most recent call last):
  File "./06.py", line 3, in <module>
    functionA()
NameError: name 'functionA' is not defined

同じフォルダに06.pyと06a.pyを置いたのだが、それだけではダメだ。
では、importを追加してみよう。

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import 06a
  4: 
  5: 06a.functionA()

$ ./06.py
  File "./06.py", line 3
    import 06a
            ^
SyntaxError: invalid syntax

嘘つき!
みんな、ファイル名をimportしてクラスっぽくすれば呼び出せるって言ってるのに。

06.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import f06a
  4: 
  5: f06a.functionA()

$ mv 06a.py f06a.py
$ ./06.py
This is functionA.

薄々、そんなことじゃないかと思っていたが、数字で始まる名前はクラスとか変数名とかで使えないから、importするものとしても使えない、ということのようだ。

あとですね、これを実行すると「f06a.pyc」というファイルが自動的に作られていた。

image

勝手に作るものなのか?
.pycファイルを作成する方法メモ - かせきのうさぎさん
.pycファイルを作成させない方法メモ - かせきのうさぎさん
作るものらしい。

コンパイルしたものらしいから、じゃあ元ファイルがなくても実行できるのか?

$ rm f06a.py
$ ./06.py
This is functionA.

できるんだ。

お互いを呼び出すような関係にはできる?

f06.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import f06a
  4: 
  5: def functionB():
  6:     print("This is functionB.")
  7: 
  8: if __name__ == "__main__":
  9:     f06a.functionA()

f06a.py

  1: #!/usr/bin/python
  2: # coding: utf-8
  3: import f06
  4: 
  5: def functionA():
  6:     f06.functionB()
  7:     print("This is functionA.")

$ ./f06.py
This is functionB.
This is functionA.

特にないようだ。
ただ、f06.pyに__name__=="__main__"のif文がないと、こうなる。

$ ./f06.py
Traceback (most recent call last):
  File "./f06.py", line 3, in <module>
    import f06a
  File "/cygdrive/e/Prog/python/study/f06a.py", line 3, in <module>
    import f06
  File "/cygdrive/e/Prog/python/study/f06.py", line 9, in <module>
    f06a.functionA()
AttributeError: 'module' object has no attribute 'functionA'

たぶん、

  • 06.pyの3行目のimportで、06a.pyを読込み始める
  • 06a.pyの3行目のimportで、06.pyを読込み始める
  • 06.pyの3行目のimportはもう読込み始めているのでスルーする
  • 地の文の「f06a.functionA()」にたどり着くが、まだ06a.pyの読込みは3行目で止まっているので「functionAはないよ」というエラーを出す

ということじゃなかろうか。


あとは、タプルとかC/C++の言語仕様にはないものがあるが、出てきたときに調べればいいだろう。

なんとなく満足したので、終了!