[質問] 12thステップ command.c の send_use() と send_write() の char* pについて

73 views
Skip to first unread message

TOKIKO OTA

unread,
Dec 9, 2013, 4:24:42 AM12/9/13
to kozos_t...@googlegroups.com
お世話になっています。
大変わかりやすい本で、私でもなんとかようやく12thステップまでたどり着くことが出来ました。
 
ここに来て行き詰まったことが生じたため、ご質問させていただきます。
 
12thステップ、command.cのsend_use()とsend_write()でコンソールドライバに渡す、
char* pなのですが、send_use()の場合は、
 
p[0] = '0';
p[1] = CONSDRV_CMD_USE;
p[2] = '0' + index;
 
send_write()の場合は、
 
p[0] = '0';
p[1] = CONSDRV_CMD_WRITE;
memcpy(&p[2], str, len);
 
となっています。ここがいまひとつわかりません。(テキストp473)
・p[0]に'0'を代入したのか。
・send_use()のp[2]はindexをそのまま代入するのではなく、なぜ'0'+indexなのか。
という疑問です。
 
ちなみに、コマンドスレッドから依頼を受けるコンソールドライバの処理でも、consdrv_main()
の中のループ分の中で、メッセージを受け取った後、
 
index = p[0] - '0';
 
という式で、シリアルの番号を抜き出していますが、(テキストp472)
 
・なぜp[2]ではなく、p[0]なのか?
・ここで‐'0'をするならなぜ最初からindexそのものを代入しなかったのか
 
というのも疑問に思っています。
 
初心者で周りに聞く人がいないため、はまってしまって抜け出せない状態です。
なにかヒントになるアドバイスをいただければと思っています。
 
よろしくお願いします<(。_。)>””

SAKAI Hiroaki

unread,
Dec 9, 2013, 5:42:41 AM12/9/13
to kozos_t...@googlegroups.com, ko...@kozos.jp
筆者の坂井です.

まず consdrv はコンソールの管理データベースを持っています.
これは consdrv.c で以下のように定義されています.

static struct consreg {
kz_thread_id_t id; /* コンソールを利用するスレッド */
...
} consreg[CONSDRV_DEVICE_NUM];

これは拡張性のために,複数のコンソールを管理できるようになっています.
が,実際には CONSDRV_DEVICE_NUM の定義は「1」になっていて,
コンソールは1個だけの利用になっています.

p[0] に入れているのは,利用する管理データベースの番号です.
現状でコンソールはひとつだけなので,固定で'0'を入れることで
0番を指定しています.

p[2] に入れているのは,実際に利用するシリアルポートの番号で,
これはシリアル関連のデバイスドライバ(serial.c)の利用の際の,
シリアルポートの指定のためのものです.

つまり,send_use()で

p[0] = '0';
p[1] = CONSDRV_CMD_USE;
p[2] = '0' + index;

のようにしているのは,

・0番のコンソールを利用する (p[0]による指定)
・0番のコンソールは,0番のシリアルポートに接続する (p[2]による指定)

という意味になります.「コンソール番号」と「シリアルポート番号」の
2つの指定があるわけです.シリアルポートは実際に出力される物理的な
ポート番号,コンソールは仮想的な(抽象的な)出力デバイス,という感じです.

例えばコンソールの出力先は実際にはUSBシリアルに出力したりとか,
そういう可能性もあるので,このような抽象層を1枚入れているわけです.


あと,なぜ '0' + index のようにしていて,そもそも index をそのまま代入
しないのか? ですが,実際そのとおりで,indexを直接代入してしまっても
構わないかと思います.'0'を加えることで文字コードにしているのは,
デバッグのためです.以下のような理由があります.

1つ目の理由は,デバッグ出力などしたときに,そのまま文字として出力できる.
(この理由のために,CONSDRV_CMD_USE なども文字として定義しています)
2つ目の理由は,indexをそのまま入れてしまうと0x00が格納されてしまい,
値がきちんと設定されているのか,それとも初期化でゼロクリアしたときの値が
そのまま残ってしまっているのかが判別しにくい.

安定して動作した今となっては,indexをそのまま入れてもいいような気はしますね.



<6517bfd2-7f05-4419...@googlegroups.com>の記事において
ota.t...@gmail.comさんは書きました。
>> --
>> このメールは Google グループのグループ「KOZOS友の会」の登録者に送られています。
>> このグループから退会し、メールの受信を停止するには、kozos_tomonok...@googlegroups.com にメールを送信します。
>> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
>>

TOKIKO OTA

unread,
Dec 9, 2013, 8:27:00 PM12/9/13
to kozos_t...@googlegroups.com, ko...@kozos.jp
坂井さん
 
丁寧なご回答ありがとうございました。
 
シリアルポートだけでなく、コンソールの番号も指定していることと
その理由も大変よくわかり、すっきりました。
 
また、'0' + indexの理由も大変よくわかりました。
デバッグ用に入れている文字ということは、ここは'0'でなくてほかの文字でもokなのですね!
確かに0を代入している場合は、正しく代入できているのか確認するのが難しいですね。
 
これからの仕事で役に立ちそうな知識です。参考になりました。
 
これでようやく1冊の本をやり遂げることができました。
本の説明が丁寧でわかりやすかったので、挫折せずにここまで来れました。
今後これが生かせるように、さらに勉強して行こうと思います。
 
ありがとうございました。
 
Reply all
Reply to author
Forward
0 new messages