OSDN Git Service

First commitment for the BlackTank LPC1769.
[blacktank/blacktank.git] / README.2nd
1 ===============================================================
2  Natural Tiny Shell(NT-Shell)のポーティング事例。
3  LPCXpressoとTOPPERS/ASPで小規模組み込みシステムの開発を
4  もっと便利に!
5 ===============================================================
6
7 [はじめに]
8
9 前回VT100仮想端末を小規模組み込みシステムで実現するための
10 ライブラリを公開しました。
11
12 中には「これが何の役に立つのだろう?」と疑問に思われた方も
13 少なくないでしょう。
14 この手のツールは実際の開発作業が進むにつれて利便性を再認識
15 することが少なくありません。
16 (逆に言うと実際に開発作業で相当に困らないと不便な事に
17 気付かない事が多いのです。)
18
19 今回はLPCXpresso上でTOPPERS/ASPを動作させるシステムを実際に
20 開発するシステムと見立てて、Natural Tiny Shell(NT-Shell)を
21 ポーティングして活用した時のメリットについて御紹介します。
22
23
24 [TOPPERS/ASPでNatural Tiny Shell(NT-Shell)を使う]
25
26 今回はRTOS上にシェルを実装することでシステム開発をもっと
27 便利にしてみましょう。
28
29 題して「LPCXpressoとTOPPERS/ASPで小規模組み込みシステムの
30 開発をもっと便利に!」です。
31
32 小規模組み込みシステムでありがちな「この程度の規模だからいいや。」
33 と諦めている方におすすめです。
34 きちんと動作するデバッグ用シェルがあるだけでシステムが
35 見違えるように良くなったように感じます。
36 デバッグも楽しくなって作業効率が向上すること間違いなし!
37 是非皆さんも挑戦してみませんか?
38
39
40 [エコーバックを行わないようにする]
41
42 受信した文字列をエコーバックする設定を取り除きます。
43 TOPPERS/ASPでは受信した文字列をエコーバックすることが
44 できるようになっています。
45 Natural Tiny Shell(NT-Shell)を使用する時、エコーバックは
46 都合が悪いので設定を外します。
47 これはシリアルインターフェースドライバで行うことができます。
48
49 syssvc/serial.c の serial_opn_por 関数でIOCTL_ECHOの指定を取り除きます。
50 serial.cの240行目付近です。
51
52
53 /*
54  *  変数の初期化
55  *  エコーバックさせたい時にはIOCTL_ECHOを追加すると良い。
56  */
57 p_spcb->ioctl = (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
58
59
60 なぜ受信した文字列をそのまま返してはいけないかという話です。
61
62 システムに接続されたシリアル端末が送信してくるコードの中には
63 制御コードが含まれる事があります。
64 今回のシェルを設計実装した目的の1つは「制御コードをうまく
65 処理してシリアル端末ユーザに便利な機能を提供しよう」です。
66
67 受信したコードをそのまま送信した結果、シリアル端末上で制御コードが
68 解釈されてしまっては従来と何も変わらない事になってしまいます。
69 これを避ける為にエコーバックをしないようにします。
70
71 例えば、「おっ。上方向キーだな。じゃあ、過去のコマンドを表示して
72 あげよう。」といった具合です。
73
74 [システム]
75
76 今回のシステムは以下のようになっています。
77 実際に開発するシステムに見立てていると考えてみて下さい。
78
79 +----+               +--------------------+
80 |    | <----USB----> | LPCXpresso LPC1768 |
81 |    |               +--------------------+
82 |    |                          |
83 |HOST|                          |UART
84 | PC |                          |
85 |    |               +--------------------+
86 |    | <----USB----> | USB-UART Converter |
87 +----+               +--------------------+
88
89 システムと開発用ホストは2つのUSBで接続されています。
90
91 1つはLPCXpresso用でこれはLPCXpresso上のデバッガに接続されています。
92 実際に開発するシステムによってはここは他のデバッガに置き換わる事も
93 あるでしょう。
94
95 もう1つは開発対象システムのUARTをUSBで入出力するための変換器との接続です。
96 今回は秋月電子通商で販売されているFT2232Dを使った変換器を使用しました。
97
98 実際の接続した状態は以下のようになっています。
99
100
101 [内部タスクの構成]
102
103 今回の内部タスク構成を以下のようにしました。
104
105 * task_ledblink: LEDを一定間隔でトグルするLED点滅タスク
106 * task_ntshll: Natural Tiny Shellをフロントエンドとするシェルタスク
107
108
109 [LED点滅タスクを作る]
110
111 LED点滅タスクは一定時間間隔で動作しLEDの状態をトグルさせるタスクです。
112 点滅の間隔は100[ms]ですが、データキューから値を受け取って変化させる
113 ことができるようにしてあります。
114 外部からデータキュー経由で点滅の速度(正確にいうとタスクの動作間隔)
115 を変化させることができるようにしてあります。
116
117 void task_ledblink(intptr_t exinf)
118 {
119     syslog(LOG_NOTICE, "task_ledblink: Started.");
120
121     int ledspd = 100;
122     while(1)
123     {
124         uint_t value;
125         while (prcv_dtq(DTQ_LEDSPD, (intptr_t *)&value) == E_OK) {
126             if (value > 0) {
127                 ledspd = value;
128                 // syslog(LOG_NOTICE, "new value is %d.", value);
129             }
130         }
131         LPC_GPIO0->FIOPIN ^= ACTLED;
132         tslp_tsk(ledspd);
133     }
134 }
135
136
137 [シェルタスクを作る]
138
139 次にNatural Tiny Shell(NT-Shell)を組み込んだシェルタスクを立てます。
140 シェルタスクはUARTに対する入出力を管理しながら、ユーザの要求を
141 システムに伝達する役目を果たします。
142
143
144 void task_ntshell(intptr_t exinf)
145 {
146     syslog(LOG_NOTICE, "task_ntshell: Started.");
147     serial_opn_por(SIO_PORTID);
148
149     ntshell_execute(&parser,
150             &editor, &history,
151             func_read, func_write, func_cb);
152 }
153
154
155 ntshell_executeは処理を戻さない関数です。
156 UARTからの入出力関数を受け取って処理を行ないます。
157
158 今回の例ではfunc_readは以下のようになっています。
159
160
161 int func_read(void *buf, int cnt)
162 {
163     return serial_rea_dat(SIO_PORTID, buf, cnt);
164 }
165
166
167 同様にfunc_writeは以下のようになっています。
168
169
170 int func_write(const void *buf, int cnt)
171 {
172     return serial_wri_dat(SIO_PORTID, buf, cnt);
173 }
174
175
176 ユーザが操作を決定するとコールバック関数(上記ではfunc_cb)が
177 呼ばれるようになっています。
178 ユーザが入力を完了後、エンターキーを押した時の入力文字列が
179 渡されるようになっています。
180
181 ここでユーザの要求に応じて処理を行えば良い事になります。
182
183
184 int func_cb(const unsigned char *text)
185 {
186     // TODO 入力されたコマンドに応じて処理を行う。
187 }
188
189
190 ちなみに、この関数内部の実行スレッドはシェルタスクのスレッドです。
191 今回のアプリケーションでは以下のように実装してみました。
192 ntopt_compareはNatural Tiny Shellに含まれるユティリティ関数で、
193 文字列の比較を行うものです。
194
195
196 int func_cb(const unsigned char *text)
197 {
198     static int ledspd = 100;
199     if (ntopt_compare(text, "INTERVAL UP") == 0) {
200         if (ledspd < 500) {
201             ledspd++;
202             snd_dtq(DTQ_LEDSPD, (intptr_t)ledspd);
203         }
204     } else if (ntopt_compare(text, "INTERVAL DOWN") == 0) {
205         if (ledspd > 1) {
206             ledspd--;
207             snd_dtq(DTQ_LEDSPD, (intptr_t)ledspd);
208         }
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.");
213     } else {
214         if (ntopt_get_count(text) > 0) {
215             text_puts("\r\nUnknown command found. (HELP: display help.)");
216         }
217     }
218
219     return 0;
220 }
221
222
223 [実際に使ってみる]
224
225 実際に使用している様子を動画で御紹介します。
226 http://www.youtube.com/watch?v=4v47XPAijbE
227
228
229 [リソース]
230
231 今回は3千円で楽しめるARMマイコンとRTOSの世界(TOPPERS/ASP on LPCXpresso
232 LPC1768)のプロジェクトに小規模組み込みシステムデバッグ用シェル
233 Natural Tiny Shell (NT-Shell)を追加する形で作業しました。
234
235
236 [まとめ]
237
238 ターゲットに対して対話型で操作要求ができるとちょっとした確認をする
239 時に非常に便利です。
240 今回はLPCXpresso(Cortex-M3搭載)でRTOS(TOPPERS/ASP)を動作させるという
241 比較的小さな組み込みシステムでの応用例を示しました。
242
243 システム内部の値を外部から変更することは当然デバッガなどでも可能です。
244 しかし、ちょっとしたパラメータを変更したい場合や複数のパラメータを
245 同時に変更したい時には不便です。
246
247 対話型のシェルインターフェースがあれば、開発ホスト並の利便性を確保する
248 ことも可能になります。
249
250
251 [補足]
252 念の為補足しておくと、LEDの点灯間隔を変化させるという行為が主眼では
253 ありません。
254 おそらく点灯間隔を変えるための実装にはもっと相応しいものがあるでしょう。
255
256 今回はあくまでシステム内部の挙動をシェルを介して変化させるという
257 ところに視点をおいてあります。
258 今回の実装では点灯間隔が狭くなるにつれてプロセッサの使用率も
259 相当上がります。
260 システムがどの程度の負荷を許容するのかを外部でパラメータを変更させながら
261 見ることもできるでしょう。
262
263
264 [連絡先]
265  このプロジェクトに関するお問い合せは下記までお願いします。
266
267  Shinichiro Nakamura
268
269  shinta.main.jp@gmail.com
270  http://shinta-main-jp.blogspot.com/
271