1 ===============================================================
2 Natural Tiny Shell(NT-Shell)のポーティング事例。
3 LPCXpressoとTOPPERS/ASPで小規模組み込みシステムの開発を
5 ===============================================================
9 前回VT100仮想端末を小規模組み込みシステムで実現するための
12 中には「これが何の役に立つのだろう?」と疑問に思われた方も
14 この手のツールは実際の開発作業が進むにつれて利便性を再認識
16 (逆に言うと実際に開発作業で相当に困らないと不便な事に
19 今回はLPCXpresso上でTOPPERS/ASPを動作させるシステムを実際に
20 開発するシステムと見立てて、Natural Tiny Shell(NT-Shell)を
21 ポーティングして活用した時のメリットについて御紹介します。
24 [TOPPERS/ASPでNatural Tiny Shell(NT-Shell)を使う]
26 今回はRTOS上にシェルを実装することでシステム開発をもっと
29 題して「LPCXpressoとTOPPERS/ASPで小規模組み込みシステムの
32 小規模組み込みシステムでありがちな「この程度の規模だからいいや。」
34 きちんと動作するデバッグ用シェルがあるだけでシステムが
36 デバッグも楽しくなって作業効率が向上すること間違いなし!
42 受信した文字列をエコーバックする設定を取り除きます。
43 TOPPERS/ASPでは受信した文字列をエコーバックすることが
45 Natural Tiny Shell(NT-Shell)を使用する時、エコーバックは
47 これはシリアルインターフェースドライバで行うことができます。
49 syssvc/serial.c の serial_opn_por 関数でIOCTL_ECHOの指定を取り除きます。
55 * エコーバックさせたい時にはIOCTL_ECHOを追加すると良い。
57 p_spcb->ioctl = (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
60 なぜ受信した文字列をそのまま返してはいけないかという話です。
62 システムに接続されたシリアル端末が送信してくるコードの中には
64 今回のシェルを設計実装した目的の1つは「制御コードをうまく
65 処理してシリアル端末ユーザに便利な機能を提供しよう」です。
67 受信したコードをそのまま送信した結果、シリアル端末上で制御コードが
68 解釈されてしまっては従来と何も変わらない事になってしまいます。
69 これを避ける為にエコーバックをしないようにします。
71 例えば、「おっ。上方向キーだな。じゃあ、過去のコマンドを表示して
77 実際に開発するシステムに見立てていると考えてみて下さい。
79 +----+ +--------------------+
80 | | <----USB----> | LPCXpresso LPC1768 |
81 | | +--------------------+
85 | | +--------------------+
86 | | <----USB----> | USB-UART Converter |
87 +----+ +--------------------+
89 システムと開発用ホストは2つのUSBで接続されています。
91 1つはLPCXpresso用でこれはLPCXpresso上のデバッガに接続されています。
92 実際に開発するシステムによってはここは他のデバッガに置き換わる事も
95 もう1つは開発対象システムのUARTをUSBで入出力するための変換器との接続です。
96 今回は秋月電子通商で販売されているFT2232Dを使った変換器を使用しました。
98 実際の接続した状態は以下のようになっています。
103 今回の内部タスク構成を以下のようにしました。
105 * task_ledblink: LEDを一定間隔でトグルするLED点滅タスク
106 * task_ntshll: Natural Tiny Shellをフロントエンドとするシェルタスク
111 LED点滅タスクは一定時間間隔で動作しLEDの状態をトグルさせるタスクです。
112 点滅の間隔は100[ms]ですが、データキューから値を受け取って変化させる
114 外部からデータキュー経由で点滅の速度(正確にいうとタスクの動作間隔)
115 を変化させることができるようにしてあります。
117 void task_ledblink(intptr_t exinf)
119 syslog(LOG_NOTICE, "task_ledblink: Started.");
125 while (prcv_dtq(DTQ_LEDSPD, (intptr_t *)&value) == E_OK) {
128 // syslog(LOG_NOTICE, "new value is %d.", value);
131 LPC_GPIO0->FIOPIN ^= ACTLED;
139 次にNatural Tiny Shell(NT-Shell)を組み込んだシェルタスクを立てます。
140 シェルタスクはUARTに対する入出力を管理しながら、ユーザの要求を
144 void task_ntshell(intptr_t exinf)
146 syslog(LOG_NOTICE, "task_ntshell: Started.");
147 serial_opn_por(SIO_PORTID);
149 ntshell_execute(&parser,
151 func_read, func_write, func_cb);
155 ntshell_executeは処理を戻さない関数です。
156 UARTからの入出力関数を受け取って処理を行ないます。
158 今回の例ではfunc_readは以下のようになっています。
161 int func_read(void *buf, int cnt)
163 return serial_rea_dat(SIO_PORTID, buf, cnt);
167 同様にfunc_writeは以下のようになっています。
170 int func_write(const void *buf, int cnt)
172 return serial_wri_dat(SIO_PORTID, buf, cnt);
176 ユーザが操作を決定するとコールバック関数(上記ではfunc_cb)が
178 ユーザが入力を完了後、エンターキーを押した時の入力文字列が
181 ここでユーザの要求に応じて処理を行えば良い事になります。
184 int func_cb(const unsigned char *text)
186 // TODO 入力されたコマンドに応じて処理を行う。
190 ちなみに、この関数内部の実行スレッドはシェルタスクのスレッドです。
191 今回のアプリケーションでは以下のように実装してみました。
192 ntopt_compareはNatural Tiny Shellに含まれるユティリティ関数で、
196 int func_cb(const unsigned char *text)
198 static int ledspd = 100;
199 if (ntopt_compare(text, "INTERVAL UP") == 0) {
202 snd_dtq(DTQ_LEDSPD, (intptr_t)ledspd);
204 } else if (ntopt_compare(text, "INTERVAL DOWN") == 0) {
207 snd_dtq(DTQ_LEDSPD, (intptr_t)ledspd);
209 } else if ((ntopt_compare(text, "HELP") == 0)
210 || (ntopt_compare(text, "?") == 0)) {
211 text_puts("\r\nINTERVAL UP : Task interval time increase.");
212 text_puts("\r\nINTERVAL DOWN : Task interval time decrease.");
214 if (ntopt_get_count(text) > 0) {
215 text_puts("\r\nUnknown command found. (HELP: display help.)");
225 実際に使用している様子を動画で御紹介します。
226 http://www.youtube.com/watch?v=4v47XPAijbE
231 今回は3千円で楽しめるARMマイコンとRTOSの世界(TOPPERS/ASP on LPCXpresso
232 LPC1768)のプロジェクトに小規模組み込みシステムデバッグ用シェル
233 Natural Tiny Shell (NT-Shell)を追加する形で作業しました。
238 ターゲットに対して対話型で操作要求ができるとちょっとした確認をする
240 今回はLPCXpresso(Cortex-M3搭載)でRTOS(TOPPERS/ASP)を動作させるという
241 比較的小さな組み込みシステムでの応用例を示しました。
243 システム内部の値を外部から変更することは当然デバッガなどでも可能です。
244 しかし、ちょっとしたパラメータを変更したい場合や複数のパラメータを
247 対話型のシェルインターフェースがあれば、開発ホスト並の利便性を確保する
252 念の為補足しておくと、LEDの点灯間隔を変化させるという行為が主眼では
254 おそらく点灯間隔を変えるための実装にはもっと相応しいものがあるでしょう。
256 今回はあくまでシステム内部の挙動をシェルを介して変化させるという
258 今回の実装では点灯間隔が狭くなるにつれてプロセッサの使用率も
260 システムがどの程度の負荷を許容するのかを外部でパラメータを変更させながら
265 このプロジェクトに関するお問い合せは下記までお願いします。
269 shinta.main.jp@gmail.com
270 http://shinta-main-jp.blogspot.com/