前回はSPI接続だったので、今回はUARTです。UARTなどいつもprintfデバッグで使ってるとも思ったのですが、マジメに確かめてみるといろいろあり。前回同様、OSはMbed OS v6.15、開発環境はオンラインのKeil Stucio Cloudです。ターゲットボードはST社のNucleo-F401REです。
※「モダンOSのお砂場」投稿順Indexはこちら
Keil Studio Cloudは、CMSISとMbed用のオンライン環境です。しかし、古いMbedオンラインコンパイラ環境からの移行を促しているだけあって、主たるターゲットはMbed OS6のようです。Mbed OS2のビルドもできることは確かめてありますが、OS2はOS6のベアメタルへ移行してね、という思し召しを感じます。
さて、OS2の時代には、以下のようなインスタンス xxx を作ってUART接続をやれていました。
Serial xxx(UARTの端子…
そのSerialクラスは printfもメソッドとして抱えていたので
xxx.printf(…
みたいな書き方でUARTに出力をたれ流せてました。USBシリアルに関してはインスタンス名を pc などとするのが定番でした。pc.printf(なんちゃら)という感じ。
しかしOS5だか、OS6だかになって Serial というクラスは廃止されてしまったみたいです。OS6のSerial(UART) APIsをみると以下の2つのクラスが存在します。
しかしご存じのとおり、USBシリアルに対してはユーザコードでインスタンスを生成しなくても
-
- printf
- putchar
- getchar
などの関数が即使用可能です(いつの頃からか?)mbed.hをインクルードしておけばとりあえず使える「デバッグの友」であります。ただし通信条件は、
-
- 9600ボー
- 8ビット、ノンパリティ、ストップ1ビット
がデフォルト設定で、この辺をいじりたければ BufferedSerial とか使え、ということになってくるのだと思います。知らんけど。
まずは OS6で、printf、putchar, getcharの動作確認
いつもやっていることだからチョロイということでやり始めてツボにはまってしまいました。オンライン環境の Keil Studio Cloud でのビルドであるので、パソコンを変えた(ようやくWindows10機からWindows11機に更新)ことなど関係ないだろ~と高をくくってました。しかし、
Keil Studio Cloudは、オンライン環境からの書き込みやデバッグも可
です。便利になった分、パソコン側もちゃんと設定しないとダメなのでした。手元にあるST社製のNucleo-F401REを接続した場合、以下のようでした。
-
- USBシリアルポートとしては認識される。通信もできる
- 接続すれば、ストレージデバイスとして認識され、BINファイルの書き込みもできる
しかし、ST-Link Debug ドライバは使えない状態です。このため、Keil Studio Cloudから接続しようとしても Flash に書き込み不可、デバッグも不可でした。
ST社の以下のページからST-Linkのドライバをダウンロードしてインストールしたところ問題解決。しかし不安点ありです。ターゲットOSにWindows11がまだ含まれてない、という1点です。ですから真似するのは自己責任でお願いいたします。
環境が変わるといろいろあるね。といって、実際のプログラムは短いです。
#include "mbed.h" int main() { int count = 0; while (true) { printf("Count: %d\n", count++); char kin = getchar(); putchar(kin); putchar('\n'); } }
getchar()は入力を待ってくれるので、何か入力しないと止まったままになります。9600ボー、8N1設定のTeraTermに接続して動作させているところが以下に。
BufferedSerialを使う
上記のprintf、getchar相当の動作をBufferedSerialを使ってやってみることにいたしました。Bufferedの方が「いろいろやってくれる」ので楽そうなので。ガチでクリティカルな制御が必要な人はUnbefferedということですかね。これまた知らんけど。
まったく同じことでは意味がないので、こちらではボーレートを115200まで上げてます。
#include "mbed.h" static BufferedSerial serial_port(USBTX, USBRX); char buf[128]; int main() { int count = 0; serial_port.set_baud(115200); serial_port.set_format(8, BufferedSerial::None, 1); //8bit NO-Parity STOP1 while (true) { uint32_t ncnt = sprintf(buf, "Count: %d\n", count++); serial_port.write(buf, ncnt); if (uint32_t num=serial_port.read(buf, sizeof(buf))) { serial_port.write(buf, num); } } }
動作しているところが以下に。バグだあ。入力文字をエコーバックした後に、改行しなければならないのを忘れてます。トホホ。
まあ動いているみたいだからいいか。
Keil Studio Cloudのシリアルモニタ
一応、シリアルポートは動かせたものの、引っかかっている事柄がもう1件ありです。
Keil Studio Cloudのシリアルモニタが動いてくれない
Flash書き込みもデバッグもでき、TeraTermでは通信できるというのに、Keil Studio Cloudのシリアルモニタ起動してもなしのツブテっす。勿論TeraTermは止めてあるし、ボーレートもあわせました。でもだめ。しかし以下のページをみて気づいたことがあります。
1か所引用させていただきます。
By default, Keil Studio automatically detects any board with a WebUSB-enabled CMSIS-DAP interface
インタフェースがCMSIS-DAPご指定だあ。もしかして ST-LINKは対象外。それとも何か設定すれば使えるようになるの? TeraTermできるからそんなにほじくらなくてもいいか?