DUICUO

RT-Thread の FinSH を使用してハードウェアをプログラミングします。

[[344778]]

モノのインターネット(IoT)の普及に伴い、ハードウェアプログラミングはますます一般的になっています。RT-Threadを使用すると、FinSHを使用してLinuxコマンドラインからデバイスと通信できます。

RT-Threadは、モノのインターネット(IoT)デバイスをプログラミングするためのオープンソースのリアルタイムオペレーティングシステムです。FinSHはRT-Threadのコマンドラインコンポーネントであり、コマンドラインからデバイスと通信するためのユーザーインターフェースを提供します。主にデバッグやシステム情報の表示に使用されます。

通常、開発デバッグではハードウェアデバッガとprintfログを使用してログを表示します。しかし、これらの2つの方法は実行中のコンテンツから抽象化されたものであり、解析が難しい場合があるため、あまり役に立たない場合があります。しかし、RT-Threadはマルチスレッドシステムであるため、実行中のスレッドの状態を知りたい場合や、システムの現在の状態を手動で制御したい場合に役立ちます。マルチスレッドであるため、対話型シェルが提供され、デバイスに直接コマンドを入力したり、関数を呼び出して必要な情報を取得したり、プログラムの動作を制御したりすることができます。LinuxやBSDなどの最新のオペレーティングシステムに慣れている人にとっては当たり前のことかもしれませんが、ハードウェアハッカーにとっては、エラーの痕跡を取得するためにシリアルケーブルを直接回路基板に接続することよりもはるかに贅沢なことです。

FinSHには2つのモードがあります。

  • C 言語インタープリタのパターンは c スタイルと呼ばれます。
  • 従来のコマンドラインモードは、msh (モジュール シェル) と呼ばれます。

Cインタプリタモードでは、FinSHはほとんどのC言語式を解析・実行し、関数呼び出しを使用してシステム関数やグローバル変数にアクセスできます。また、コマンドラインから変数を作成することもできます。

msh モードでは、FinSH は Bash などの従来のシェルと同様に動作します。

GNUコマンド標準

FinSHの開発において、コマンドラインアプリケーションを開発する前に、GNUコマンドライン標準に精通しておく必要があることを学びました。この標準プラクティスのフレームワークは、インターフェースに親しみやすさをもたらし、開発者が快適かつ効率的に使用できるようにします。

完全な GNU コマンドは 4 つの主要部分で構成されます。

  1. コマンド名 (実行可能ファイル): コマンドライン プログラムの名前。
  2. サブコマンド: コマンド プログラムのサブ機能の名前。
  3. オプション: サブコマンド機能の構成オプション。
  4. パラメーター: サブコマンド機能の構成オプションに対応するパラメーター。

これはどのコマンドでも確認できます。Gitを例に挙げてみましょう。

  1. git reset -- hard HEAD ~ 1

これは次のように分類できます。

GNUコマンドライン標準

実行コマンドはgit 、サブコマンドはreset 、使用されるオプションは--head 、パラメーターはHEAD~1です。

次に別の例を示します。

  1. systemctl enable -- now firewalld

実行可能コマンドはsystemctl 、サブコマンドはenable 、オプションは--now 、パラメーターはfirewalldです。

RT-Threadを使ってGNU標準準拠のコマンドラインプログラムを書きたいと想像してみてください。FinSHには必要なものがすべて揃っており、コードを期待通りに実行できます。さらに、この準拠性のおかげで、お気に入りのLinuxプログラムを安心して移植できます。

エレガントなコマンドラインプログラムを書く

以下は、RT-Thread 開発者が日常的に使用する RT-Thread コマンドの例です。

  1. usage : env . py package [- h ] [-- force - update ] [-- update ] [-- list ] [-- wizard ]
  2.                       [-- upgrade ] [-- printenv ]
  3. optional arguments :
  4.   - h , -- help show this help message and exit
  5.   -- force - update force update and clean packages , install or remove the
  6. packages by your settings in menuconfig
  7.   -- update update packages , install or remove the packages by your
  8. settings in menuconfig
  9.   -- list           list target packages
  10.   -- wizard create a new package with wizard
  11.   -- upgrade upgrade local packages list and ENV scripts from git repo
  12.   -- printenv print environmental variables to check

ご覧の通り、LinuxやBSDで既に実行しているほとんどのPOSIXアプリケーションと同様に、見た目も動作も馴染み深いものとなっています。誤った構文や不適切な構文を使用した場合のサポートも提供し、長いオプションと短いオプションの両方をサポートしています。この汎用的なユーザーインターフェースは、Unix端末を使ったことがある人なら誰でも馴染みのあるものになるでしょう。

オプションの種類

オプションには多くの種類があり、長さに応じて 2 つの主要なカテゴリに分けられます。

  1. 短いオプション: pkgs -h-hオプションのように、ハイフンとそれに続く文字で構成されます。
  2. 長いオプション: 2 つのハイフンとそれに続く単語または文字で構成されます (例: scons- --target-mdk5--targetオプション)。

これらのオプションは、パラメータがあるかどうかによって 3 つのタイプに分類できます。

  1. パラメータなし: このオプションにはパラメータを指定できません。
  2. パラメータは必須です: オプションの後にはパラメータが続く必要があります。
  3. オプション パラメータ: オプションにはパラメータを指定できますが、必須ではありません。

ほとんどのLinuxコマンドと同様に、FinSHのオプション解析は非常に柔軟です。スペースやイコール記号を区切り文字として使うことでオプションと引数を区別することも、オプション自体を抽出して、それに続く内容を引数と見なす(つまり、区切り文字を一切使わない)こともできます。

  • wavplay -v 50
  • wavplay -v50
  • wavplay --vol=50

optparseを使用する

コマンドラインプログラムを書いたことがある方なら、おそらくご存知でしょうが、一般的に、お使いの言語には optparse と呼ばれるライブラリまたはモジュールが用意されています。これは、コマンドの一部として入力されたオプション( -v--verboseなど)を、コマンドの残りの部分と共に解析できるようにするためにプログラマーに提供されています。これにより、コード内でサブコマンドや引数からオプションを取得できるようになります。

FinSH のコマンドを記述する場合、 optparseパッケージは次の形式を想定しています。

  1. MSH_CMD_EXPORT_ALIAS ( pkgs , pkgs , this is test cmd .);

オプションを実装するには、長い形式、短い形式、または両方の形式を使用できます。例:

  1. static struct optparse_long long_opts [] =
  2. {
  3.     { "help"         , 'h' , OPTPARSE_NONE }, // Long command: help, corresponding to short command h, without arguments.
  4.     { "force-update" ,   0 , OPTPARSE_NONE }, // Long comman: force-update, without arguments
  5.     { "update"       ,   0 , OPTPARSE_NONE },
  6.     { "list"         ,   0 , OPTPARSE_NONE },
  7.     { "wizard"       ,   0 , OPTPARSE_NONE },
  8.     { "upgrade"     ,   0 , OPTPARSE_NONE },
  9.     { "printenv"     ,   0 , OPTPARSE_NONE },
  10.     { NULL ,   0 , OPTPARSE_NONE }
  11. };

オプションを作成したら、各オプションとそのパラメータのコマンドと説明を書き留めます。

  1. static void usage ( void )
  2. {
  3. rt_kprintf ( "usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]\n" );
  4. rt_kprintf ( " [--upgrade] [--printenv]\n\n" );
  5. rt_kprintf ( "optional arguments:\n" );
  6. rt_kprintf ( " -h, --help show this help message and exit\n" );
  7. rt_kprintf ( " --force-update force update and clean packages, install or remove the\n" );
  8. rt_kprintf ( " packages by your settings in menuconfig\n" );
  9. rt_kprintf ( " --update update packages, install or remove the packages by your\n" );
  10. rt_kprintf ( " settings in menuconfig\n" );
  11. rt_kprintf ( " --list list target packages\n" );
  12. rt_kprintf ( " --wizard create a new package with wizard\n" );
  13. rt_kprintf ( " --upgrade upgrade local packages list and ENV scripts from git repo\n" );
  14. rt_kprintf ( " --printenv print environmental variables to check\n" );
  15. }

次のステップは解析です。まだ機能は実装していませんが、解析されたコードのフレームワークは同じです。

  1. int pkgs ( int argc , char ** argv )
  2. {
  3. int ch ;
  4. int option_index ;
  5. struct optparse options ;
  6. if ( argc == 1 )
  7. {
  8. usage ();
  9. return RT_EOK ;
  10. }
  11. optparse_init (& options , argv );
  12. while (( ch = optparse_long (& options , long_opts , & option_index )) != - 1 )
  13. {
  14. ch = ch ;
  15. rt_kprintf ( "\n" );
  16. rt_kprintf ( "optopt = %c\n" , options . optopt );
  17. rt_kprintf ( "optarg = %s\n" , options . optarg );
  18. rt_kprintf ( "optind = %d\n" , options . optind );
  19. rt_kprintf ( "option_index = %d\n" , option_index );
  20. }
  21. rt_kprintf ( "\n" );
  22. return RT_EOK ;
  23. }

関数のヘッダーファイルは次のとおりです。

  1. # include "optparse.h"
  2. # include "finsh.h"

次に、コンパイルしてデバイスにダウンロードします。

出力

ハードウェアハッカー

ハードウェアプログラミングは難しそうに思えるかもしれませんが、IoT(モノのインターネット)の台頭により、ますます一般的になりつつあります。Raspberry Piですべてのハードウェアが動作できるわけではありませんし、動作させるべきでもありません。しかし、RT-ThreadではFinSHを使うことで、使い慣れたLinuxの感覚を維持できます。

ベアメタルでのコーディングに興味がある場合は、RT-Thread を試してみるとよいでしょう。