Seeed松岡です。
シリアルポートからマイコンへ、ちょっとした設定がしたいときって結構ありますよね。わたしは結構な頻度であります。測定間隔を変更したいとか、Wi-Fi SSID/パスワードを設定したいなど。そんなときはいつも過去に作ったコンソールっぽいシェルっぽいコードをコピペしていました。これで動きはするので問題は無いのですが、同じコードがいろんなところに複製されてイヤだなぁと毎回感じていました。
SWEST25に参加したとき、NT-Shellという便利そうなライブラリを使っている方がいました。試してみようと思います。(結果的に3つのライブラリを試すことになりました。😅)

NT-Shell
CuBeatSystemsのNatural Tiny Shell。略称はNT-Shell。小規模組み込みシステム用のシェルライブラリです。Webサイトが英語ですが日本人が開発していて、Interface 2013年1月号に日本語記事があります。
Seeed Studio XIAO ESP32C3 + Arduino IDEで実装したのがこちらです。
カーソルを移動して再編集だけでなく、入力履歴の呼び出し、入力補完ができます。思っていたより高機能ですね。

実装はいくつかハマりましたが、わかってしまえば簡単でした。
NT-ShellライブラリはWebサイトからダウンロードして自身のプロジェクトに入れます。
NT-ShellライブラリはGitHubからダウンロードしてArduino IDEに追加すれば利用できるようになります。
シリアルポートとのつなぎは、シリアルポートへの読み書き用のserial_read()とserial_write()を用意してntshell_init()で設定します。このとき、serial_read()は指定されたバイト数cntを受信するまでブロッキングが必須なので間違えないように。
くわえて、NT-Shellが提供しているコマンドテキスト解析を使うようにします。user_callback()を用意してntshell_init()で設定します。
コマンドが入力されると(コマンドテキスト解析後にuser_callback()でntopt_parse()に渡した)usrcmd_ntopt_callback()が呼び出されるので、引数に応じた処理を実装します。
最後に、ntshell_execute()を繰り返し呼び出せばOKです。ntshell_execute()はブロッキング関数なので他に並行して実行する処理があるとき(たとえば、LEDの点滅)は、RTOS使って別スレッドにしてください。
MicroShell
NT-Shellをもっと小さくした(8bitマイコンが対象!?)MicroShellというのがありました。開発者はNT-Shellと同じ。
Seeed Studio XIAO ESP32C3 + Arduino IDEで実装したのがこちらです。
カーソルを移動して再編集できます。NT-Shellよりは機能が少ないですが、必要十分と思います。

実装は簡単でした。
MicroShellライブラリはWebサイトからダウンロードして自身のプロジェクトに入れます。(ここからコピーするのもいいかも。)
シリアルポートとのつなぎは、シリアルポートへの読み書き用のutx()とurx()を用意してmicroshell_init()で設定します。このとき、urx()はブロッキングが必須なので間違えないように。
そして、プロンプト表示Serial.print()、コマンドテキスト取得microshell_getline()、コマンド実行mscmd_executeを順に実行します。microshell_getline()はブロッキング関数なので他に並行して実行する処理があるとき(たとえば、LEDの点滅)は、RTOS使って別スレッドにしてください。
marcinbor85/microshell
MicroShellについて調べているときに、Marcin Borowicz氏のMicroShellというのを発見しました。非ブロッキングで作られていて、ファイルシステムっぽいディレクトリツリーを構築できます。
Seeed Studio XIAO ESP32C3 + Arduino IDEで実装したのがこちらです。
lsでファイルやディレクトリの一覧を見て、catで中身を見るあたり、Linuxを意識したシェルのようです。ディレクトリツリーが使えるので複雑なデータの操作を実装しやすそうな感じがします。

実装は簡単でした。
marcinbor85/microshellライブラリはArduino IDEのライブラリマネージャで追加します。ちょー簡単。あ、でもバージョンがちょっと古いっぽいので、最新を使いたいならGitHubから取りましょう。

具体的なところは今回のコードをご参照ください。ポイントは、ファイルに対する操作をush_file_descriptorに定義してush_node_mount()でディレクトリツリーに追加しているところです。
まとめ
- NT-Shell、MicroShell、marcinbor85/microshellのどれでも、Arduino IDEで利用できる。
- 操作をシンプルにするときはNT-Shell、高機能にするときはmarcinbor85/microshellがよさそう。
- RTOS使わずに並行処理したいときは、marcinbor85/microshell。(NT-Shellでも実現は可能。(*1))
| ライブラリ | Arduino利用 | 高機能(<=>シンプル) | 非ブロッキング | 特記 |
|---|---|---|---|---|
| NT-Shell | ○ | △ | ×(*1) | 日本語記事あり。 |
| MicroShell | △ | × | × | サイズが小さい。 |
| marcinbor85/microshell | ○ | ○ | ○ | ディレクトリツリー。 |
*1 ... NT-Shellを少し変更すれば、非ブロッキング化が可能。サンプルはこちら。
変更履歴
| 日付 | 変更者 | 変更内容 |
|---|---|---|
| 2024/2/12 | 松岡 | 作成 |