RT-Threadは、モノのインターネット(IoT)デバイスのプログラミングに使用されるオープンソースのリアルタイムオペレーティングシステムです。 FinSHはRT-Threadのコマンドラインコンポーネントであり、ユーザーがコマンドラインからデバイスに接続できるようにする一連の操作インターフェイスを提供します。これは主に、システム情報のデバッグまたは表示に使用されます。
通常、開発デバッグはハードウェアデバッガーとprintf
を使用して表示されます ログ。ただし、場合によっては、これら2つの方法は、実行中のものから抽象化されており、解析が難しいため、あまり役に立たないことがあります。ただし、RT-Threadはマルチスレッドシステムであり、実行中のスレッドの状態や手動制御システムの現在の状態を知りたい場合に役立ちます。マルチスレッドであるため、インタラクティブシェルを使用できるため、コマンドを入力したり、デバイスで直接関数を呼び出して必要な情報を取得したり、プログラムの動作を制御したりできます。 LinuxやBSDなどの最新のオペレーティングシステムにしか慣れていない場合、これは普通に思えるかもしれませんが、ハードウェアハッカーにとって、これは非常に贅沢であり、エラーを垣間見るためにシリアルケーブルをボードに直接配線することとはかけ離れています。
FinSHには2つのモードがあります:
- Cスタイルと呼ばれるC言語通訳モード
-
msh
と呼ばれる従来のコマンドラインモード (モジュールシェル)
C言語解釈モードでは、FinSHは、ほとんどのC言語を実行する式を解析し、関数呼び出しを使用してシステム上の関数とグローバル変数にアクセスできます。コマンドラインから変数を作成することもできます。
msh
で モードでは、FinSHはBashなどの従来のシェルと同様に動作します。
GNUコマンド標準
その他のLinuxリソース
- Linuxコマンドのチートシート
- 高度なLinuxコマンドのチートシート
- 無料のオンラインコース:RHELの技術概要
- Linuxネットワーキングのチートシート
- SELinuxチートシート
- Linuxの一般的なコマンドのチートシート
- Linuxコンテナとは何ですか?
- 最新のLinux記事
FinSHを開発していたとき、コマンドラインアプリケーションを作成する前に、GNUコマンドライン標準に精通する必要があることを学びました。この標準的な慣行のフレームワークは、インターフェースに親しみをもたらすのに役立ち、開発者がそれを使用するときに快適で生産的であると感じるのに役立ちます。
完全なGNUコマンドは、次の4つの主要部分で構成されています。
- コマンド名(実行可能ファイル): コマンドラインプログラムの名前
- サブコマンド: コマンドプログラムのサブ関数名
- オプション: サブコマンド機能の構成オプション
- 引数: サブコマンド関数の構成オプションに対応する引数
これは、どのコマンドでも実際に動作していることがわかります。 Gitを例にとると:
git reset --hard HEAD~1
これは次のように分類されます:
実行可能コマンドはgit 、サブコマンドはリセット 、使用されるオプションは-head 、引数は HEAD〜1 。
別の例:
systemctl enable --now firewalld
実行可能コマンドはsystemctl 、サブコマンドは有効です 、オプションは-now 、引数は firewalld 。
RT-Threadを使用してGNU標準に準拠するコマンドラインプログラムを作成するとします。 FinSHには必要なものがすべて揃っており、期待どおりにコードを実行します。さらに良いことに、このコンプライアンスに頼ることができるので、お気に入りのLinuxプログラムを自信を持って移植できます。
これは、RT-Thread開発者が毎日使用するコマンドを実行するRT-Threadの例です。
usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]
[--upgrade] [--printenv]
optional arguments:
-h, --help show this help message and exit
--force-update force update and clean packages, install or remove the
packages by your settings in menuconfig
--update update packages, install or remove the packages by your
settings in menuconfig
--list list target packages
--wizard create a new package with wizard
--upgrade upgrade local packages list and ENV scripts from git repo
--printenv print environmental variables to check
お分かりのように、見慣れたものであり、LinuxまたはBSDですでに実行されている可能性のあるほとんどのPOSIXアプリケーションのように動作します。誤った構文または不十分な構文が使用され、長いオプションと短いオプションの両方がサポートされ、一般的なユーザーインターフェイスがUnix端末を使用したことのある人なら誰でも知っている場合にヘルプが提供されます。
オプションの種類
オプションにはさまざまな種類があり、長さによって2つの主要なカテゴリに分類できます。
- 短いオプション: 1つのハイフンと1つの文字で構成されます(例:
-h
)pkgs -h
のオプション - 長いオプション: 2つのハイフンと単語または文字で構成されます(例:
--target
)scons- --target-mdk5
のオプション
これらのオプションは、引数があるかどうかによって、3つのカテゴリに分類できます。
- 引数なし: オプションの後に引数を続けることはできません
- 引数を含める必要があります: オプションの後には引数が続く必要があります
- オプションの引数: オプションの後の引数は許可されていますが、必須ではありません
ほとんどのLinuxコマンドに期待されるように、FinSHオプションの解析は非常に柔軟です。区切り文字としてスペースまたは等号に基づいて、またはオプション自体を抽出し、それに続くものが引数であると想定することによって(つまり、区切り文字がまったくない)、オプションを引数と区別できます。
-
wavplay -v 50
-
wavplay -v50
-
wavplay --vol=50
optparseの使用
コマンドラインアプリケーションを作成したことがある場合は、一般に、optparseと呼ばれる選択した言語用のライブラリまたはモジュールがあることをご存知かもしれません。オプション( -v など)ができるようにプログラマーに提供されます または--verbose )コマンドの一部として入力されたものは解析できます コマンドの残りの部分に関連して。これは、コードがサブコマンドまたは引数からオプションを認識するのに役立ちます。
FinSHのコマンドを作成する場合、optparse
パッケージは次の形式を想定しています:
MSH_CMD_EXPORT_ALIAS(pkgs, pkgs, this is test cmd.);
長い形式または短い形式、あるいはその両方を使用してオプションを実装できます。例:
static struct optparse_long long_opts[] =
{
{"help" , 'h', OPTPARSE_NONE}, // Long command: help, corresponding to short command h, without arguments.
{"force-update", 0 , OPTPARSE_NONE}, // Long comman: force-update, without arguments
{"update" , 0 , OPTPARSE_NONE},
{"list" , 0 , OPTPARSE_NONE},
{"wizard" , 0 , OPTPARSE_NONE},
{"upgrade" , 0 , OPTPARSE_NONE},
{"printenv" , 0 , OPTPARSE_NONE},
{ NULL , 0 , OPTPARSE_NONE}
};
オプションを作成したら、各オプションとその引数のコマンドと手順を記述します。
static void usage(void)
{
rt_kprintf("usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]\n");
rt_kprintf(" [--upgrade] [--printenv]\n\n");
rt_kprintf("optional arguments:\n");
rt_kprintf(" -h, --help show this help message and exit\n");
rt_kprintf(" --force-update force update and clean packages, install or remove the\n");
rt_kprintf(" packages by your settings in menuconfig\n");
rt_kprintf(" --update update packages, install or remove the packages by your\n");
rt_kprintf(" settings in menuconfig\n");
rt_kprintf(" --list list target packages\n");
rt_kprintf(" --wizard create a new package with wizard\n");
rt_kprintf(" --upgrade upgrade local packages list and ENV scripts from git repo\n");
rt_kprintf(" --printenv print environmental variables to check\n");
}
次のステップは解析です。その関数をまだ実装することはできませんが、解析されたコードのフレームワークは同じです:
int pkgs(int argc, char **argv)
{
int ch;
int option_index;
struct optparse options;
if(argc == 1)
{
usage();
return RT_EOK;
}
optparse_init(&options, argv);
while((ch = optparse_long(&options, long_opts, &option_index)) != -1)
{
ch = ch;
rt_kprintf("\n");
rt_kprintf("optopt = %c\n", options.optopt);
rt_kprintf("optarg = %s\n", options.optarg);
rt_kprintf("optind = %d\n", options.optind);
rt_kprintf("option_index = %d\n", option_index);
}
rt_kprintf("\n");
return RT_EOK;
}
関数ヘッドファイルは次のとおりです。
#include "optparse.h"
#include "finsh.h"
次に、コンパイルしてデバイスにダウンロードします。
ハードウェアハッキング
プログラミングハードウェアは恐ろしいように思えるかもしれませんが、IoTではますます一般的になっています。すべてがRaspberryPiで実行できる、または実行する必要があるわけではありませんが、RT-Threadを使用すると、FinSHのおかげで使い慣れたLinuxの感覚を維持できます。
ベアメタルでのコーディングに興味がある場合は、RT-Threadを試してみてください。