メモ&Tips
.
メモ&Tips
Information
本ページは私家版のため、誤り等あればご指摘ください。
なるべく更新を心がけていますが、最新の情報に追従していないことがあります。
mbed RTOSの情報はmbed RTOS の メモ&Tipsへ
エェェェェンベッドの小ネタ (by Tedd OKANO) もどうぞ
mbed の読みは?
- mbed : エンベッド
- テンション高めの時は「エェェェンベッド!」
- Keil : カイル
- CMSIS : スィムシス
- Cortex : コーテックス
参考: ARMのよみもの:mbedシリーズ バックナンバー:第1回:「mbedをご存知ですか?」
Arduinoとはどう違う?
どのmbedボードがおすすめ?
Platforms を見るとたくさんの素晴らしい仲間が増えました。
初めてmbedに触れるなら LPC1768 (青) または LPC11U24 (黄)にすべきです。
「箱を開けてから10分以内に Hello World」が体験できます。
他のボードより価格は高いですが、mbedチップによるUSBストレージ機能(2MBのファイルシステムとしても使える)があり格段に便利です。
他のボードの mbed interface でも、ドラッグ&ドロップによるプログラム書き込みが実現されていますが、全く同じではなく、 プログラム書き込み後にリセットがかかるため、USBが切断されシリアルを使っていたりするととても煩わしいことになります。
ボードごとのクセ
自分のプログラムは公開されているの?
コンパイラの画面で作ったプログラムは、 Publishしない限り他人には見えません。
逆に、Publishされていないプログラムは検索しても出てきません。
デバッガはないの?
ブラウザとUSB機器をリンクする技術がまだないため、クラウドコンパイラからはデバッグできません。
printfでプログラムの流れを追う、printfデバッグをすることになります。
最近はmbedチップが CMSIS DAP というインターフェースに対応するようになり、対応しているデバッガからデバッグできるようになりました。
プログラムのエクスポート機能と組み合わせると、開発環境に合わせたプロジェクトファイルを出力できます。
ソフトリセット
extern "C" void mbed_reset(); : mbed_reset();
NVIC_SystemReset();
シリアル(USBシリアル)からはbreakを送るとリセットされる。(TeraTermの場合 [Alt]+[B])
CPUのクロック
現在のCPUのクロックは SystemCoreClock という変数に入っています。
printf("%d Hz\r\n", SystemCoreClock);
クロックの変更は Power management - 省電力化 などを参照。
DigitalIn/Outを配列にする
C++のClassであるDigitalIn/Outは、引数付きのコンストラクタのため、配列として定義する場合は記述方法に注意が必要。
DigitalOut pin[5] = {p15, p16, p17, p18, p19};
複数の引数がある場合。
Class配列、引数付きコンストラクタの宣言方法。
I2C i2c[2] = { I2C(p9, p10), I2C(p28, p27) };
プログラムが書き込めなくなった(LPC1768, LPC11U24)
mbedのドライブをフォーマットしてみてください。
その後、USBの抜き差し(電源OFF/ON)で、初期状態に戻ります。
プログラムが書き込めなくなり fail.txt が出現した
何らかの理由でプログラムの書き込みが失敗した後、この状態になってしまうようです。
CPUに内蔵されているBootloaderモードで起動して、別のプログラムを書き込めば復活します。
参照:"SWD ERROR" と書かれた fail.txt が現れた (by mio)
メインのCPUへの電源が切れていて、mbed HDKだけが動作している場合にもこの状態になります。
プログラムが動かなくなった、でも何かを外すと動いた
マイコンボードのI/Oポートに、何かを繋いだ後に電源を入れると、 それまで動いていたプログラムが動かなくなる。外すと動くようになる。
ブートローダー内臓のマイコンの場合、ブートローダーモードを設定するためのピンが たまたま繋いだものによってLowまたはHighに固定されてしまい、 ユーザーのプログラムではなく、ブートローダーを起動してしまっていることがあります。
マイコンのマニュアルでピンの機能を確認してみましょう。
例: LPC1114・LPC824のISP、NucleoのBOOT0等
gccなどで自分でコンパイルしたプログラムが動かない
もしかするとアドレス 0x0000001C (割り込みベクタ7)に Check Sum が埋め込まれていないからかもしれません。(LPC1768、LPC11U24など)
割り込みベクタ0~6 をもとに計算(総和の 2の補数?)したチェックサムを、ベクタ7へ書き込んでおきます。
プログラムをプロテクト(読出し禁止・書込み禁止)したい
Code Read Protection (CRP)を有効にします。(LPC1768、LPC11U24など)
プログラムを書き込む際、アドレス 0x000002FC に次のコードを埋め込む
CRP1 | 0x12345678 | SWD,JTAG無効、ISP有効、読出し制限、Flash書込みセクタ0制限 |
---|---|---|
CRP2 | 0x87654321 | CRP1に加え、Flash書込み制限 |
CRP3 | 0x43218765 | CRP2に加え、ISPピン無効、※危険 |
プルアップが有効にならない
I/Oポートによってはオープンドレインとなっているピンがあり、もともとプルアップの機能が備わっていません。
例: LPC11U24 の p28, p27
また、割込みに使用できないピンもあります。
例: LPC1768 の p19, p20
マイコンのマニュアルでピンの機能を確認してみましょう。
未定義のレジスタ(メモリ)を操作する
メモリ アドレス
(*(volatile uint32_t*)0xe000ed24) = 0x0123;
または
#define MYREG (*(volatile uint32_t*)0xe000ed24) MYREG = 0x0123;
CPUレジスタ
register int _R0 __asm("r0"); register unsigned int _MSP __asm("msp"); register unsigned int _PSP __asm("psp"); i = _MSP;
便利なコンパイラ組み込み関数
何もしない(CPUサイクルだけ消費する)
__NOP();
ビット順序を反転する
ret = __RBIT(val);
ビッグエンディアン値とリトルエンディアン値を変換する
ret = __REV(val); ret = __REV16(val);
コンパイルオプション
コード最適化を変更
#pragma O3 #pragma Otime
- 参照: https://developer.mbed.org/users/MACRUM/notebook/offline_compiler_1/
- 参照: http://todotani.cocolog-nifty.com/blog/2011/04/lpcxpresso-lp-1.html
CPUの違いによる分岐
LPC1768 と LPC11U24、どちらのCPUでもコンパイルできるプログラムを書くには、 コンパイル時にシンボル定義(-Dオプション? #defineと同じ効果)されている値で処理を分けるとよいでしょう。
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) : mbed LPC1768 のときのコード : #elif defined(TARGET_LPC11U24) : mbed LPC11U24 のときのコード : #elif defined(TARGET_KL25Z) : mbed FRDM KL25Z のときのコード : #endif
または、対応していないCPUの場合、コンパイルエラーを出力する。
#if !defined(TARGET_LPC1768) #error This code is only for LPC1768. #endif
その他のCPUについて何が#defineされているかは https://github.com/mbedmicro/mbed/blob/master/workspace_tools/targets.py の labels を参照するとよいと思う。
ファームウェア更新
mbedのUSB端子(USBストレージ・PCシリアル)を制御しているファームウェアの更新方法。
http://mbed.org/handbook/Firmware
- 上記ページからダウンロードできるファームウェア mbedMicrocontroller_00000.if をmbedのUSBストレージ(USBメモリ)へ書き込む。
- いったんmbedの電源を切り、再度電源を入れる(power-cycle)とファームウェアが書き換えられる。
- 念のため、もう一度電源をoff/onする。
- ユーザーのプログラムを書き込む。
Ethernet の MTU (Maximum Transmission Unit)
古いmbedのドライバーは約700バイトまでしかサポートしていなかった。
v29より1500バイトをサポートする。
勝手にLEDがチカチカする
それはこんなふうですか?
内部でエラーが起きたことを表している。
例えば、バッファあふれなどでスタックを破壊してしまった時や、I2SやSPIなどの機能のないピンを使って初期化しようとしたときなどに起こる。
PCシリアルに何かメッセージが出力されているかもしれない。(Serialが未初期化の時は9600bps)
error("文字列") を呼ぶか、main() を return -1 で抜けて、わざとこの状態にすることもできる。
参考:Debugging
mbed を作る
Eagle CAD のデータなどが公開されている。
USBインターフェースの部分はないが、LPC Xpresso等からJTAG書き込みをすれば同じように使える。
LANのリンクLED
EthernetのPHYチップから出力されているリンクとリンク速度のLED用端子は、LPC1768の P1_25 P1_26 にそれぞれ接続されている。
DigitalIn link(P1_25); DigitalIn speed(P1_26);
EthernetNetIf の動的初期化
EthernetNetIf *eth; eth = new EthernetNetIf; or eth = new EthernetNetIf(ipaddr, netmask, gateway, nameserver); eth->setup();
割込みの禁止・許可
__disable_irq(); __enable_irq();
書きこんだファイルはどれが有効?
ファイルのタイムスタンプが最新の .bin ファイルが実行される。
最後に書き込んだファイルか、またはタイムスタンプを更新すればいい。(UNIX or Macなら touch コマンド)
Mac OS上でも使えるか
青・黄以外のmbedへファイルを書き込む際は、 単純にドラッグ&ドロップすると管理ファイルまでコピーされてしまうので、 「cp -X」コマンドでファイルをコピーするといいでしょう。
OSX Yosemite (10.10) で若干の不具合があるようです。
参照:/users/okano/notebook/mbed-on-yosemite/
BSD上でも使えるか
BSDでもmountできます。
エンディアン
リトルエンディアンか、ビッグエンディアンか確認した。
// http://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3 #include "mbed.h" union tag_uEndian { int in; /* 4Byte */ unsigned short sh[2]; /* 2Byte×2 */ unsigned char ch[4]; /* 1Byte×4 */ }; int main() { union tag_uEndian En; En.in = 0x12345678; printf("INPUT is 0x%x\n",En.in); printf("short is 0x%x, 0x%x\n",En.sh[0],En.sh[1]); printf(" char is 0x%x, 0x%x, 0x%x, 0x%x\n",En.ch[0],En.ch[1],En.ch[2],En.ch[3]); return 0; }
結果、リトルエンディアンだった。
INPUT is 0x12345678 short is 0x5678, 0x1234 char is 0x78, 0x56, 0x34, 0x12
コンパイルエラー、その原因と対策は?
ARMの「RVCT 3.1 Build Tools - Errors and Warnings」に、エラーやワーニングに対する解決指南が書かれている。
USBシリアルは?
- Windows用ドライバ: http://mbed.org/handbook/Windows-serial-configuration
- XPの場合、新しいmbedごとにインストールが必要
- Mac OS X: /dev/tty.usbmodem
- Linux: /dev/ttyACM
CGIやPHPへのHTTP POST
デフォルトではPOSTデータが Content-type: text/html になっており、サーバ側でPOSTデータとして扱われない。
application/x-www-form-urlencoded と指定する。
#include "HTTPClient.h" : HTTPClient http; HTTPText data("application/x-www-form-urlencoded"); : data.puts("key=val&key=val..."); : http.post(URI, data, NULL); :
スーパークールボタン
初期のウェブサイトの写真では、LPC1768のリセットボタンはこんな青色のものでした。
理想
しかし、実際に購入すると無愛想な金属枠のボタンです。
現実
誰もこの青色ボタンのmbedを見たことがありませんでした。
それはいつしか「スーパークールボタン」と呼ばれるようになりました。
あるとき伝説のボタンが発見されるのです。
https://twitter.com/ytsuboi/status/322353074024882176
https://twitter.com/toyowata/status/474798718609141761
青色の部分は薄膜のゴムでいい感じ。 どうやらすでにディスコンのもよう。
そして、初期型のmbedが日本へ!
https://twitter.com/toyowata/status/527988989324959744
しかも LPC2368
番外:ARM界隈の漢字表記
https://twitter.com/search?q=%E5%89%A3%E6%A9%8B%E5%B1%8B&src=typd
- 剣橋屋 : ARM
- 剣橋一門 : ARMシリーズ
- 南蛮屋 : NXP
- 自由定規 : Freescale
- コムシス : STM
- 聖荷西屋 : Atmel
- 瑞薩 : ルネサス
ネタまとめ (by Tedd OKANO)
Please log in to post comments.