このページの2つのバージョン間の差分を表示します。
次のリビジョン | 前のリビジョン | ||
mas1xx_devel:nuttx_firmware:start [2024/02/29 13:19] – 作成 admin | mas1xx_devel:nuttx_firmware:start [2024/02/29 14:20] (現在) – admin | ||
---|---|---|---|
行 1: | 行 1: | ||
====== NuttX のファームウェア開発 ====== | ====== NuttX のファームウェア開発 ====== | ||
+ | |||
+ | \\ | ||
+ | |||
+ | {{https:// | ||
MA-S1xx シリーズは Linux のほかに、OS として[[https:// | MA-S1xx シリーズは Linux のほかに、OS として[[https:// | ||
行 8: | 行 12: | ||
* 2秒でアプリケーションが起動 | * 2秒でアプリケーションが起動 | ||
* PPP 接続をする場合、LTE module 起動まで 18 秒ほど、PPPは 20 秒ほどで接続完了 | * PPP 接続をする場合、LTE module 起動まで 18 秒ほど、PPPは 20 秒ほどで接続完了 | ||
+ | * => 動作している時間を Linux と比べて非常に短くできるため、バッテリー駆動の時間を大幅に延ばすことが可能 | ||
* 高速シャットダウン(Filesystem を unmount するだけ) | * 高速シャットダウン(Filesystem を unmount するだけ) | ||
* ちいさいファームウェアサイズ (0.5 MiB 〜 2MiB 程度) | * ちいさいファームウェアサイズ (0.5 MiB 〜 2MiB 程度) | ||
+ | |||
+ | 実際のファームウェアサイズの例はこのようなサイズ感です。 | ||
+ | |||
+ | [参考] | ||
+ | |||
+ | < | ||
+ | nuttx$ ls -l uImage | ||
+ | -rw-rw-r-- 1 user user 1706160 | ||
+ | </ | ||
+ | |||
+ | このファームウェアでは、下記のような処理を行っています。 | ||
+ | |||
+ | * RTC Alarm で定期的に起動して、下記処理を行う | ||
+ | * RS485 接続のセンサーに電源を供給 | ||
+ | * センサーの起動を待ち、独自プロトコルのセンサーからデータを取得 | ||
+ | * eMMC にデータを保存 (1) | ||
+ | * 送信するタイミングの場合、下記を追加で行う | ||
+ | * LTE module の電源を投入 | ||
+ | * LTE module が起動したら、PPP 接続の設定を行い、LTE 網に Attach されるのを待つ | ||
+ | * LTE 網に Attach されたら、PPP 接続を行う | ||
+ | * PPP 接続完了後、(1) で保存されたデータを読み込み、JSON 形式にして SORACOM Funk へ送信する | ||
+ | * HTTP Response Header にある日時情報を利用して、RTC へ時刻同期を行う | ||
+ | * HTTP Response Body の情報を見て、RTC Alarm のインターバルを変更する | ||
+ | * 上記処理完了後、RTC Alarm の設定を行い、Filesystem を unmount 後、shutdown する | ||
+ | |||
+ | \\ | ||
上記のメリットに加えて、[[https:// | 上記のメリットに加えて、[[https:// | ||
行 15: | 行 46: | ||
* Nim の各種モジュールを使用して簡単にアプリケーションを作成可能 | * Nim の各種モジュールを使用して簡単にアプリケーションを作成可能 | ||
* Python で開発するのと同じ程度の記述量で RTOS のアプリケーションを作成可能 | * Python で開発するのと同じ程度の記述量で RTOS のアプリケーションを作成可能 | ||
+ | * C 言語にコンパイルされるため、Python や microPython などと比較して超高速で処理が可能 | ||
+ | * C 言語の関数をバインディングモジュールを作る必要がなく簡単に呼び出すことが可能 | ||
+ | * Nim のモジュールにない、NuttX 独自の関数を簡単に使用することができる | ||
となっています。 | となっています。 | ||
\\ | \\ | ||
+ | |||
+ | ===== Nim での記述例 ===== | ||
+ | |||
+ | RTOS 向けとは思えないほどの少ないコードで記述できます。 | ||
+ | |||
+ | \\ | ||
+ | |||
+ | ==== SORACOM Harvest に bool 値の配列を JSON で送信する ==== | ||
+ | |||
+ | <codify nim> | ||
+ | import std/ | ||
+ | import std/ | ||
+ | import std/json | ||
+ | import std/osproc | ||
+ | import std/ | ||
+ | |||
+ | proc post_harvest(data: | ||
+ | let client = newAsyncHttpClient() | ||
+ | defer: client.close() | ||
+ | client.headers = newHttpHeaders({" | ||
+ | let body = %* {" | ||
+ | echo $body | ||
+ | try: | ||
+ | let resp = await client.request(" | ||
+ | httpMethod = HttpPost, body = $body) | ||
+ | echo &" | ||
+ | let resp_headers = resp.headers | ||
+ | for key, val in resp_headers.pairs: | ||
+ | echo &" | ||
+ | except: | ||
+ | let errmsg = getCurrentExceptionMsg() | ||
+ | echo &" | ||
+ | </ | ||
+ | |||
+ | \\ | ||
+ | |||
+ | ==== Modbus-RTU でデータを取得 ==== | ||
+ | |||
+ | <codify nim> | ||
+ | import std/ | ||
+ | import std/ | ||
+ | import std/times | ||
+ | import nim_asyncmodbus | ||
+ | |||
+ | proc get_data(mb: | ||
+ | echo "--- Input Status" | ||
+ | let hregs = await mb.read_input_bits(address, | ||
+ | echo &" | ||
+ | echo hregs | ||
+ | try: | ||
+ | await post_harvest(hregs) | ||
+ | except: | ||
+ | let errmsg = getCurrentExceptionMsg() | ||
+ | echo &" | ||
+ | |||
+ | proc mb_task() {.async.} = | ||
+ | let mb = newModbusRtu("/ | ||
+ | echo "mb instanciated." | ||
+ | discard mb.set_slave(2) | ||
+ | echo " | ||
+ | discard mb.connect() | ||
+ | echo " | ||
+ | |||
+ | for i in 0 ..< 2: | ||
+ | let time_start = now() | ||
+ | await mb.get_data(2) | ||
+ | let time_end = now() | ||
+ | let elapsed = time_end - time_start | ||
+ | echo &" | ||
+ | await sleepAsync(100) | ||
+ | mb.close() | ||
+ | </ | ||
+ | |||
+ | \\ | ||
+ | |||
+ | ===== 開発方法 ===== | ||
+ | |||
+ | * [[.nuttx_development_detail: | ||
+ | |||