HDL-GT/LCD研究記録


1. ブロック図

 HDL-GT/LCDのブロック図を示します。

Visio

 上図は推測によるもので、不足や誤りがあるかも知れません。たとえば上図では、装置全体への電源供給をUSB Hubの外側から分岐させていますが、CP2102もレギュレータの機能を内蔵しているので、もしかしたら本当はCP2102の中から分岐させるべきかも知れません。そのような不明点はあるものの、HDL-GT/LCDを外部から制御するときに意識する構成は、おおよそこのとおりだと思います。


2. モード

HDL-GT/LCDは、三種類の動作モードを持っています。停止も含めると、四種類のモードとなります。これら四種類のモードと、モード遷移の様子を、下図に示します。

Visio

 青色の丸が、モードを表します。赤色の文字は、モード遷移の契機です。黄色の四角は、モード遷移に伴ってHDL-GT/LCDが実行する処理を示します。たとえば、

「HDL-GT/LCDが入力可能モードのときに、NASから"@HELLO"を受信すると、NASへ"@ACK"を送信して、入力可能モードになる。」
というふうに読んでください。

 上図には、モード遷移に関係の無いコマンド等は示していません。たとえば、"@HANTEN"コマンドは、どのモードでも受け付けられて、画面表示を反転しますが、モードは変化しません。このように、モード遷移に関係の無いコマンド等は、上図には示していません。

 次に、四種類のモードそれぞれの、動作内容を説明します。

2-1. 停止

 HDL-GT/LCDがNASに接続されていない状態です。電源が供給されていないので、HDL-GT/LCDは何も処理を行いません。

2-2. 入力不可モード

 HDL-GT/LCDのボタンが押されても、何も起きません。表示専用モードといったところです。

2-3. 入力可能モード

 HDL-GT/LCDのボタンが押されると、NASへ文字列を送信します。UP(+)ボタンが押されると、"@SW,1"を送信します。DOWN(-)ボタンが押されると、"@SW,2"を送信します。ENTERボタンが押されると、"@SW,3"を送信します。CANCELボタンが押されると、"@SW,4"を送信します。

2-4. ログ表示モード

 ログをスクロール表示します。UP(+)ボタンが押されると上スクロール、DOWN(-)ボタンが押されると下スクロールします。UP(+)ボタンやDOWN(-)ボタンが押されたときに、NASへは何も送信しません。CANCELボタンが押されると、NASへ"@BACK"を送信して、自動的に入力可能モードになります。

 モード遷移は、HDL-GT/LCDの内部だけの状態変化であることに注意してください。画面表示を見ても、現在のモードを判断することはできません。たとえば、ログ表示モードでCANCELボタンが押されると、HDL-GT/LCDは入力可能モードになりますが、画面にはログを表示したままです。画面表示が変わるのは、明示的に画面を書き換えるコマンド("@TITLE"等)を受信したときや、画面変化を伴うイベント(11分間コマンド受信無し等)が発生したときです。


3. コマンド

 HDL-GT/LCDは、NASから送られてくるコマンドを受信して、様々な動作を行います。コマンドには、"@"で始まる「制御コマンド」と、"%"または"#"で始まる「描画コマンド」の二種類があります。

3-1. 制御コマンド

 制御コマンドは、"@"で始まって、改行で終了します。改行は、CR("\r")またはLF("\n")またはCR+LF("\r\n")のどれでも構いません。HDL-GT/LCDは、どれでも一つの改行と見なします。簡単のために、以降の例では、"\n"に統一して説明することにします。

"@HELLO\n"
正しく、"@HELLO"コマンドとして受け付けます。

 "@"から改行までの間に、"@"または"%"または"#"の文字が現れると、そこからあらためてコマンドの解釈を始め、"@"または"%"または"#"以前の文字列を捨てます。

"@HELLO@HANTEN\n"
"@HELLO"の後に改行が無いため、"@HELLO"コマンドとは見なしません。"@HELLO"の後の"@"から、あらためてコマンドの解釈を始め、"@HANTEN"コマンドとして受け付けます。

 ただし特例として、"@LOG"コマンドの場合のみ、"@"または"%"または"#"が現れても、そのまま継続します。

"@LOG,One@Two%Three#Four\n"
正しく、"@LOG,One@Two%Three#Four"コマンドとして受け付け、"One@Two%Three#Four"というログ文字列を記録します。

 コマンド名とパラメータは、英大文字または数字で指定してください。英小文字や記号等は受け付けません。

"@led,1,ON\n"
コマンド名に英小文字を含んでいるので不正です。
"@LED,1,On\n"
パラメータに英小文字を含んでいるので不正です。

 ただし特例として、"@LOG"コマンドの場合のみ、パラメータに英小文字や記号等を含んでいても受け付けます。

"@LOG,#include <stdio.h>\n"
正しく、"@LOG,#include <stdio.h>"コマンドとして受け付け、"#include <stdio.h>"というログ文字列を記録します。

 HDL-GT/LCDは、正しい制御コマンドを受信すると、制御コマンドごとに定められた応答を送信します。制御コマンドごとに定められた応答の詳細は、コマンドリファレンスを参照してください。

"@HELLO\n"
正しい"@HELLO"コマンドへの応答として、"@ACK"を送信します。
"@HELLO@HANTEN\n"
送信者の意図とは違っているかも知れませんが、HDL-GT/LCDから見ると、正しい"@HANTEN"コマンドです。従って、正しい"@HANTEN"コマンドへの応答として、"@ACK"を送信します。

 HDL-GT/LCDは、コマンド名は正しいがパラメータが誤っている制御コマンドを受信すると、"@NAK"を送信します。

"@LED,5,ON\n"
"@LED"コマンドの最初のパラメータは、1〜4の数字でなくてはなりません。従って、"@NAK"を送信します。
"@LED,1,On\n"
パラメータに英小文字を含んでいるので不正です。従って、"@NAK"を送信します。

 HDL-GT/LCDは、コマンド名が不正な制御コマンドを受信すると、何も送信せず、単純に無視します。

"@LDE,5,On\n"
"@LDE"というコマンドは無いので、何も送信せず、単純に無視します。パラメータも誤っていますが、それ以前にコマンド全体を無視するので、"@NAK"を送信しません。

 制御コマンドが、一文字づつゆっくり送られてきた場合、文字と文字の間隔が5秒間以上空いていると、それ以前に受信した文字列を捨てて、次の文字からあらためてコマンドの解釈を始めます。

"@←1秒間→H←2秒間→E←3秒間→L←4秒間→L←1秒間→O←2秒間→\n"
正しく、"@HELLO"コマンドとして受け付けます。
"@HEL←6秒間→LO\n"
"@HEL"を捨てて、"LO\n"と見なします。ただし、"LO\n"というコマンドは無いので、HDL-GT/LCDはこれを無視します。

3-2. 描画コマンド

 描画コマンドは、"%"または"#"で始まって、488バイト分の16進数文字列、すなわち、976文字の16進数文字列を受け取って、終了します。最後に改行は不要であることに注意してください。"%"と"#"の違いは、16進数文字列のエコーバックの有無だけです。以降では、まず"%"で始まる描画コマンドについて説明し、その後で"#"で始まる描画コマンドについて説明します。

"%12345678…9ABCDEF0" ("12345678…9ABCDEF0"は976文字)
正しく、描画コマンドとして受け付けます。

 描画コマンドは、途中の任意の位置に、空白(" ")またはカンマ(",")または改行("\r"または"\n")を含むことができます。HDL-GT/LCDは、これらの文字を単純に無視します。以降では、これらの文字を「区切り文字」と呼ぶことにしますが、見た目だけの区切りであって、コマンド解釈上は意味を持たないことに注意してください。簡単のために、以降の例では、","に統一して説明することにしますが、代わりに他の区切り文字を使ったり、混在して使っても同じ結果となります。

"%12,34,56,78…9A,BC,DE,F0" ("12,34,56,78…9A,BC,DE,F0"は、区切り文字を除いて976文字)
正しく、描画コマンドとして受け付けます。
"%1,2,3,4…D,E,F,0" ("1,2,3,4…D,E,F,0"は、区切り文字を除いて488文字)
16進数文字列の長さが不足のため、受け付けません。区切り文字で区切っても、1桁で1バイトとは見なさないことに注意してください。
"%1,234,,5678…9ABC,,,DEF,,,,0" ("1,234,,5678…9ABC,,,DEF,,,,0"は、区切り文字を除いて976文字)
正しく、描画コマンドとして受け付けます。

 "%"で始まって、976文字の16進数文字列を受け取るまでの間に、16進数文字と区切り文字以外の文字が現れると、不正な描画コマンドと見なして、それまでに受信した文字列を捨てます。そして、次の文字からあらためてコマンドの解釈を始めます。

"%1234X5678…"
"X"を受信した時点で、不正な描画コマンドと見なして、"%1234X"を捨てます。そして、"5"からあらためてコマンドの解釈を始めます。ただし、"5678…"というコマンドは無いので、HDL-GT/LCDはこれを無視します。

 16進数文字列は、英大文字または数字で指定してください。英小文字は受け付けません。

"%123456789abcdef0…"
"a"を受信した時点で、不正な描画コマンドと見なして、"%123456789a"を捨てます。そして、"b"からあらためてコマンドの解釈を始めます。ただし、"bcdef0…"というコマンドは無いので、HDL-GT/LCDはこれを無視します。

 HDL-GT/LCDは、正しい描画コマンドを受信すると、応答として、"@ACK"を送信します。

"%12345678…9ABCDEF0" ("12345678…9ABCDEF0"は976文字)
正しく、描画コマンドとして受け付けます。最後の"0"を受信したときに、"@ACK"を送信します。

 HDL-GT/LCDは、不正な描画コマンドを受信すると、応答として、"@NAK"を送信します。

"%1234X5678…"
"X"を受信した時点で、不正な描画コマンドと見なして、"@NAK"を送信します。そして、"%1234X"を捨てて、"5678…"と見なします。ただし、"5678…"というコマンドは無いので、HDL-GT/LCDはこれを無視します。

 描画コマンドが、一文字づつゆっくり送られてきた場合、文字と文字の間隔が1秒間以上空いていると、それ以前に受信した文字列を捨てて、次の文字からあらためてコマンドの解釈を始めます。

"%←0.7秒間→1←0.8秒間→2←0.9秒間→3…E←0.99秒間→F←0.999秒間→0" ("123…EF0"は976文字)
正しく、描画コマンドとして受け付けます。最後の"0"を受信したときに、"@ACK"を送信します。
"%12←1.1秒間→34…"
"2"を受信した後、1秒間経過した時点で、不正な描画コマンドと見なして、ただちに"@NAK"を送信し、"%12"を捨てます。その後、"34…"を受信しますが、"34…"というコマンドは無いので、HDL-GT/LCDはこれを無視します。

 以上、"%"で始まる描画コマンドについて説明しました。次に、"#"で始まる描画コマンドについて説明します。"#"で始まる描画コマンドは、16進数文字列を一文字受信するたびに、その文字をエコーバックします。

"#12345678…ABCDEF0" ("12345678…ABCDEF0"は976文字)
"#"を受信したときは、何も送信しません。"1"を受信すると、"1"を送信します。"2"を受信すると、"2"を送信します。以降同様に繰り返し、最後の"0"を受信すると、"0"を送信します。そして、"@ACK"を送信します。

 区切り文字も、そのままエコーバックします。

"#1 2,3\r4…\n0" ("1 2,3\r4…\n0"は、区切り文字を除いて976文字)
"#"を受信したときは、何も送信しません。"1"を受信すると、"1"を送信します。" "を受信すると、" "を送信します。以降同様に繰り返し、"2"、","、"3"…"\n"、"0"を送信します。そして、"@ACK"を送信します。

 "#"で始まって、976文字の16進数文字列を受け取るまでの間に、16進数文字と区切り文字以外の文字が現れたときの扱いは、"%"で始まる描画コマンドと同様です。不正と判断した文字もエコーバックし、それ以降の文字はエコーバックしません。

"#1234X5678…"
"#"を受信したときは、何も送信しません。"1"を受信すると、"1"を送信します。以降同様に繰り返し、"2"、"3"、"4"を送信します。"X"を受信すると、"X"を送信します。そして、"@NAK"を送信します。"5678…"は、既に描画コマンドの一部とは見なさないので、エコーバックしません。

4. 応答と通知

 HDL-GT/LCDがNASへ送信する文字列は、「応答」と「通知」に分類できます。

4-1. 応答

 応答とは、HDL-GT/LCDがNASから受信したコマンドを解釈し、実行した結果として、HDL-GT/LCDがNASへ送信する文字列です。コマンドに同期的であると言えます。NASの立場から見ると、HDL-GT/LCDへコマンドを送信した直後に応答が送られてくるので、送られてくるタイミングが予期できます。

 応答には、既に説明したように、コマンドを正しく受け付けたことを示す"@ACK"、パラメータが誤っていることを示す"@NAK"があります。その他に、"@CON"コマンドに対する応答として、"@CON,数値"があります。制御コマンドごとに定められた応答の詳細は、コマンドリファレンスを参照してください。

 HDL-GT/LCDは、応答の文字列の末尾に改行を付けて送信します。改行は、CR+LF("\r\n")です。たとえば、HDL-GT/LCDがNASから"@HELLO"コマンドを受信し、"@ACK"応答を送信する場合は、厳密には以下のような文字列を送受信します。

 HDL-GT/LCD   ←   "@HELLO\n"   ←   NAS 
 →   "@ACK\r\n"   → 

 "#"で始まる描画コマンドがエコーバックする、16進数文字、区切り文字、不正な文字も、応答の一種と見なせます。なぜなら、コマンドに同期的だからです。ただし、HDL-GT/LCDは、エコーバック文字の末尾には改行を付けずに送信する点が、"@ACK"や"@NAK"等とは異なります。たとえば、HDL-GT/LCDがNASから"#12…F0"コマンドを受信し、エコーバック文字と"@ACK"応答を送信する場合は、厳密には以下のような文字列を送受信します。

 HDL-GT/LCD   ←   "#"   ←   NAS 
 ←   "1"   ← 
 →   "1"   → 
 ←   "2"   ← 
 →   "2"   → 
 … 
 ←   "F"   ← 
 →   "F"   → 
 ←   "0"   ← 
 →   "0"   → 
 →   "@ACK\r\n"   → 

4-2. 通知

 通知とは、HDL-GT/LCDが自分で判断して、NASへ送信する文字列です。ユーザーがHDL-GT/LCDのボタンを押したときや、NASとの通信が長時間途絶えたときに、HDL-GT/LCDがNASへ通知を送信します。コマンドに非同期であると言えます。NASの立場から見ると、通知はいつ送られてくるか予期できないので、どんなタイミングで通知が送られてきても正しく処理できるよう、待ち受けておかなくてはなりません。

 通知には、HDL-GT/LCDが入力可能モードのときにユーザーがボタンを押したことを示す"@SW,1"、"@SW,2"、"@SW,3"、"@SW,4"、HDL-GT/LCDがログ表示モードのときにユーザーがCANCELボタンを押しHDL-GT/LCDが入力可能モードになったことを示す"@BACK"、NASからHDL-GT/LCDへ11分間コマンドが送られずHDL-GT/LCDが自動的に入力不可モードになったことを示す"@TITLE"があります。"@BACK"と"@TITLE"については、本ページの上で示したモード遷移の図も参照してください。

 HDL-GT/LCDは、通知の文字列の末尾に改行を付けて送信します。改行は、CR+LF("\r\n")です。たとえば、HDL-GT/LCDが"@SW,1"通知を送信する場合は、厳密には以下のような文字列を送信します。

 HDL-GT/LCD   →   "@SW,1\r\n"   →   NAS 

 もう一度モード遷移の図を見て、"@TITLE"コマンドの応答に注目してください。"@TITLE"コマンドを正しく受け付けたことを示す応答は、"@ACK"と"@TITLE"の二行です。他のコマンドへの応答が一行("@ACK"または"@NAK"または"@CON,数値")であることに較べると、"@TITLE"への応答だけが二行で、特殊です。なぜ、このような仕様になったのでしょうか。僕は、次のように推測しました。"@TITLE"コマンドへの直接の応答は、"@ACK"だけと考えます。続く"@TITLE"の送信は、HDL-GT/LCDが入力不可モードになったことを示す通知であると考えるのです。つまり、11分間コマンドが送られてこなかったときにHDL-GT/LCDが送信する"@TITLE"も、"@TITLE"コマンドを実行した結果としてHDL-GT/LCDが送信する"@TITLE"も、どちらも共通の意味で、HDL-GT/LCDが入力不可モードになったことを示す通知であると考えるのです。そのように考えれば、一見不思議な"@TITLE"コマンドへの応答仕様も、納得できるのではないでしょうか。

 HDL-GT/LCDをPCに接続して、PCからHDL-GT/LCDを制御するプログラムを作成する場合、通知の扱いには注意が必要です。通知は、あらゆるタイミングで送られてくる可能性があるからです。たとえば、"@HELLO"コマンドを送信して、"@ACK"応答を確認するプログラムを作成するとしましょう。単純に考えると、以下のように作成できそうです。


/* 一行送信サブルーチン */
void send_line(const char* p) {
	...
}
/* 一行受信サブルーチン */
int read_line(char* p) {
	...
}
/* "@HELLO"コマンドを送信して、"@ACK"応答を確認する */
void hello_ack() {
	...
	send_line("@HELLO");
	read_line(buf);
	while(!read_line(buf)) { } /* 何か受信するまで待つ */
	if(!strcmp(buf, "@ACK")) {
		/* 成功 */
	} else {
		/* 失敗 */
	}
	...
}

 意図した通りならば、HDL-GT/LCDとPCの間では、以下のような文字列が送受信されるはずです。

 HDL-GT/LCD   ←   "@HELLO\n"   ←   PC 
 →   "@ACK\r\n"   → 
 ところがもし、PCが「send_line("@HELLO");」を実行するのと同時か直前のタイミングで、ユーザーがHDL-GT/LCDのボタンを押したとしたら、どうなるでしょう。HDL-GT/LCDは、"@HELLO"コマンドを受信するのと同時か直前に、"@SW,1"通知を送信します。その後、"@HELLO"コマンドを受信して、"@ACK"応答を送信します。この場合、HDL-GT/LCDとPCの間では、以下のような文字列が送受信されます。一行受信サブルーチン

 HDL-GT/LCD   ←   "@HELLO\n"   ←   PC 
 →   "@SW,1\r\n"   → 
 →   "@ACK\r\n"   → 
    または    
 HDL-GT/LCD   →   "@SW,1\r\n"   →   PC 
 ←   "@HELLO\n"   ← 
 →   "@ACK\r\n"   → 

 いずれにせよ、"@ACK"よりも先に"@SW,1"がPCに届くので、「read_line(buf);」の結果は"@SW,1"となり、プログラムは失敗と判断してしまいます。

 このような問題を避けるために、PCからHDL-GT/LCDを制御するプログラムを作成する場合は、応答と通知を分けて扱うのが良いと思います。一行受信サブルーチンの中で、応答と通知を分別して、通知はグローバル変数にカウントアップするのです。一行受信サブルーチンは、応答だけを返すようにします。


int sw_1;	/* "@SW,1"通知の受信カウンタ */
int sw_2;	/* "@SW,2"通知の受信カウンタ */
int sw_3;	/* "@SW,3"通知の受信カウンタ */
int sw_4;	/* "@SW,4"通知の受信カウンタ */
int back;	/* "@BACK"通知の受信カウンタ */
int title;	/* "@TITLE"通知の受信カウンタ */
/* 改良版一行受信サブルーチン */
int read_line(char* p) {
	char buf[100];
	for(;;) {
		if(!read_line_from_com(buf)) { /* COMポートから1行受信する */
			return 0; /* 未受信 */
		}
		if(!strcmp(buf, "@SW,1")) {
			sw_1++;
		} else if(!strcmp(buf, "@SW,2")) {
			sw_2++;
		} else if(!strcmp(buf, "@SW,3")) {
			sw_3++;
		} else if(!strcmp(buf, "@SW,4")) {
			sw_4++;
		} else if(!strcmp(buf, "@BACK")) {
			back++;
		} else if(!strcmp(buf, "@TITLE")) {
			title++;
		} else {
			strcpy(p, buf);
			return 1; /* 応答を受信した */
		}
	}
}

 先ほど、"@TITLE"コマンドに対してHDL-GT/LCDが送信する"@TITLE"も、通知と見なすと良い、という話をしました。いま示した改良版一行受信サブルーチンに、さっそくその利点が現れています。受信した"@TITLE"はすべて通知と見なすことにしたので、常にグローバル変数にカウントアップするだけで済みます。もし、"@TITLE"応答と"@TITLE"通知の両方を考慮していたら、"@TITLE"コマンドを送信した直後であるかどうかによって、受信した"@TITLE"の意味を区別する必要が生じ、もっと複雑なサブルーチンになっていたかも知れません。


5. ログ

 HDL-GT/LCDは、20文字×99件のログを記録しています。HDL-GT/LCDがNASから"@SHOW,LOG"コマンドを受信すると、ログ表示モードになります。ログ表示モードでは、HDL-GT/LCDがユーザーのボタン入力を判断して、ログをスクロール表示します。NASからのコマンド指示無しに動作するという点で、もっとも高機能なモードであると言えます。

 NASの立場から見ると、ログをスクロール表示する処理はすべてHDL-GT/LCDにおまかせなので、その動作内容を詳しく知る必要はありません。以下に、ログ表示モードの挙動を説明しますが、NASや、PCからHDL-GT/LCDを制御するプログラムを作成する場合は、特に意識する必要はありません。HDL-GT/LCDのエミュレータ等を作成する場合に、参考にしてください。

 ログ表示モードでは、20文字×100行の仮想画面を使います。全100行の内容は、最上行が1番古いログ、上から2行目が2番目に古いログ、以下同様に繰り返して、上から99行目すなわち下から2行目が最新のログとなっています。最下行の内容は、"--- syslog end"という文字列に固定です。

1行目 1番古いログ
2行目 2番目に古いログ
3行目 3番目に古いログ
4行目 4番目に古いログ
5行目 5番目に古いログ




94行目 5つ前のログ
95行目 4つ前のログ
96行目 3つ前のログ
97行目 2つ前のログ
98行目 1つ前のログ
99行目 最新のログ
100行目 --- syslog end

 HDL-GT/LCDが"@SHOW,LOG"コマンドを受信して、ログ表示モードになった直後のスクロール位置は、最下行を含む4行分です。下の表で、緑色の部分が、HDL-GT/LCDの画面に見えていると考えてください。

1行目 1番古いログ
2行目 2番目に古いログ
3行目 3番目に古いログ
4行目 4番目に古いログ
5行目 5番目に古いログ




94行目 5つ前のログ
95行目 4つ前のログ
96行目 3つ前のログ
97行目 2つ前のログ
98行目 1つ前のログ
99行目 最新のログ
100行目 --- syslog end

 UP(+)ボタンを押すと、一行上へスクロールします。一行上へスクロールした様子を、以下に示します。

1行目 1番古いログ
2行目 2番目に古いログ
3行目 3番目に古いログ
4行目 4番目に古いログ
5行目 5番目に古いログ




94行目 5つ前のログ
95行目 4つ前のログ
96行目 3つ前のログ
97行目 2つ前のログ
98行目 1つ前のログ
99行目 最新のログ
100行目 --- syslog end

 ユーザーがUP(+)ボタンを何度も押して、スクロールを繰り返すと、最上行を含む4行分まで、スクロール位置が変化します。

1行目 1番古いログ
2行目 2番目に古いログ
3行目 3番目に古いログ
4行目 4番目に古いログ
5行目 5番目に古いログ




94行目 5つ前のログ
95行目 4つ前のログ
96行目 3つ前のログ
97行目 2つ前のログ
98行目 1つ前のログ
99行目 最新のログ
100行目 --- syslog end

 最上行を含む4行分を表示しているときに、さらにUP(+)ボタンを押しても、何も変化しません。同様に、DOWN(-)を押すと、一行下へスクロールします。最下行を含む4行分を表示しているときに、さらにDOWN(-)ボタンを押しても、何も変化しません。ここまでは、おおよそ直観どおりの挙動だと思います。

 HDL-GT/LCDが"@LOG"コマンドを受信すると、パラメータの文字列を最新のログとして記録し、元々のログはひとつづつ古い方へずれます。そして、元々1番古かったログを捨てます。入力不可モードや入力可能モードで"@LOG"コマンドを受信した場合は、前述の処理はHDL-GT/LCDの内部だけで行って、画面表示は更新しません。それに対して、ログ表示モードで"@LOG"コマンドを受信した場合は、画面のログ表示もリアルタイムに更新する点が異なります。

 ログ表示モードで"@LOG"コマンドを受信した場合、画面のログ表示を更新する方法は、"@LOG"コマンドを受信したときのスクロール位置によって異なります。もし、スクロール位置が最下行を含む4行分だった場合は、スクロール位置はそのままで、ログ内容を更新します。

1行目 1番古いログ
2行目 2番目に古いログ
3行目 3番目に古いログ
4行目 4番目に古いログ
5行目 5番目に古いログ




94行目 5つ前のログ
95行目 4つ前のログ
96行目 3つ前のログ
97行目 2つ前のログ
98行目 1つ前のログ
99行目 最新のログ
100行目 --- syslog end
    →    
1行目 元々2番目に古かったログ
2行目 元々3番目に古かったログ
3行目 元々4番目に古かったログ
4行目 元々5番目に古かったログ
5行目 元々6番目に古かったログ




94行目 元々4つ前だったログ
95行目 元々3つ前だったログ
96行目 元々2つ前だったログ
97行目 元々1つ前だったログ
98行目 元々最新だったログ
99行目 いま受信した最新のログ
100行目 --- syslog end

 もし、スクロール位置が最上行を含む4行分だった場合も、スクロール位置はそのままで、ログ内容を更新します。

1行目 1番古いログ
2行目 2番目に古いログ
3行目 3番目に古いログ
4行目 4番目に古いログ
5行目 5番目に古いログ




94行目 5つ前のログ
95行目 4つ前のログ
96行目 3つ前のログ
97行目 2つ前のログ
98行目 1つ前のログ
99行目 最新のログ
100行目 --- syslog end
    →    
1行目 元々2番目に古かったログ
2行目 元々3番目に古かったログ
3行目 元々4番目に古かったログ
4行目 元々5番目に古かったログ
5行目 元々6番目に古かったログ




94行目 元々4つ前だったログ
95行目 元々3つ前だったログ
96行目 元々2つ前だったログ
97行目 元々1つ前だったログ
98行目 元々最新だったログ
99行目 いま受信した最新のログ
100行目 --- syslog end

 それら以外の場合は、ログ内容を更新すると共に、自動的に一行上へスクロールします。従って、見た目の画面表示は変化しません。

1行目 1番古いログ
2行目 2番目に古いログ
3行目 3番目に古いログ
4行目 4番目に古いログ
5行目 5番目に古いログ




94行目 5つ前のログ
95行目 4つ前のログ
96行目 3つ前のログ
97行目 2つ前のログ
98行目 1つ前のログ
99行目 最新のログ
100行目 --- syslog end
    →    
1行目 元々2番目に古かったログ
2行目 元々3番目に古かったログ
3行目 元々4番目に古かったログ
4行目 元々5番目に古かったログ
5行目 元々6番目に古かったログ




94行目 元々4つ前だったログ
95行目 元々3つ前だったログ
96行目 元々2つ前だったログ
97行目 元々1つ前だったログ
98行目 元々最新だったログ
99行目 いま受信した最新のログ
100行目 --- syslog end

6. キープアライブタイマ

 HDL-GT/LCDは、11分間コマンドが送られてこないと、画面に「LANDISK NOT FOUND!」と表示して、"@TITLE"通知を送信し、自動的に入力不可モードになります。

 HDL-GT/LCDは、本来、LANDISKシリーズのNASに接続して使うものです。NASにHDL-GT/LCDを接続すると、NASの内蔵OSがHDL-GT/LCDに対して、定期的にコマンドを送り続けます。NASがHDL-GT/LCDに何も指示することが無い場合も、ダミーとして、約1秒間ごとに"@HELLO"コマンドを送り続けます。HDL-GT/LCDは、定期的にコマンドが送られてくるのを見て、NASが正常に動作していることを確認します。11分間コマンドが送られてこないと、HDL-GT/LCDは、NASが故障などの原因で停止したと判断します。そして、画面に「LANDISK NOT FOUND!」と表示して、ユーザーに注意を促します。11分間という時間に、明確な理由は無いようです。

 HDL-GT/LCDの内部で、11分間を計測しているタイマを、「キープアライブタイマ」と呼ぶことにします。キープアライブタイマが11分に達し、前述の動作を引き起こすことを、「キープアライブタイムアウト」と呼ぶことにします。NASからコマンドが送られてきて、キープアライブタイマが0秒に戻って計測を再開することを、キープアライブタイマの「リセット」と呼ぶことにします。

 キープアライブタイムアウトを発生させないためには、11分間以内の時間間隔で、定期的にキープアライブタイマをリセットしなくてはなりません。キープアライブタイマをリセットする要因を、以下に示します。

 キープアライブタイマをリセットする要因は、以上で全部です。以下のような要因では、キープアライブタイマをリセットしないことに注意してください。

 ユーザーがボタンを押しても、キープアライブタイマをリセットしない理由は、次のように考えれば納得できると思います。キープアライブタイマは、本来、NASが正常に動作していることを確認するためのものです。ユーザーがHDL-GT/LCDのボタンを押すことと、NASが正常に動作しているか否かは、無関係です。だから、ユーザーがボタンを押しても、キープアライブタイマをリセットしないのです。

 HDL-GT/LCDが、でたらめな文字列や、コマンド名が不正な制御コマンドを受信しても、キープアライブタイマをリセットしない理由は、次のように考えれば納得できると思います。キープアライブタイマは、本来、NASが正常に動作していることを確認するためのものです。でたらめな文字列を受信しただけでは、NASが正常に動作しているとは認められません。少なくともコマンド名が正しければ、NASが正常に動作していると認めても良いでしょう。

 キープアライブタイムアウトが発生したあとで、自動的にキープアライブタイマをリセットしないという仕様は、すなわち、キープアライブタイムアウトは周期イベントではないということを意味します。たとえば、NASからコマンドが送られてこない状態が数時間続いた場合でも、キープアライブタイムアウトが発生するのは、最初の11分間経過時点の一度だけです。22分間経過時点や、33分間経過時点では、キープアライブタイムアウトは発生しません。最初の11分間経過時点で、キープアライブタイムアウトが発生した瞬間に、キープアライブタイマが停止するからです。その後、コマンドを受信してキープアライブタイマをリセットすると、再びキープアライブタイマが動き出します。

 既に説明したように、HDL-GT/LCDは、キープアライブタイムアウトが発生すると、画面に「LANDISK NOT FOUND!」と表示します。さらに、"@TITLE"通知を送信し、自動的に入力不可モードになります。画面に「LANDISK NOT FOUND!」と表示するのは、ユーザーに注意を促すためとわかるのですが、"@TITLE"通知を送信して入力不可モードになるのは、何のためでしょうか。理由はよくわからないのですけれど、たとえば次のように推測してみました───NASの内蔵OSが何らかの理由(?)で意図的にしばらくHDL-GT/LCDとの通信を中断し、その間もUSBシリアルドライバは有効であったとします。もし、HDL-GT/LCDが入力可能モードのまま画面に「LANDISK NOT FOUND!」と表示する仕様であったとして、この表示を見たユーザーがあわててHDL-GT/LCDのボタンを無闇に押してしまいました。NASの内蔵OSのUSBシリアルドライバの入力バッファには、"@SW,1"等の通知がたくさん溜まってゆきます。NASの内蔵OSがHDL-GT/LCDとの通信を再開し、入力バッファをフラッシュせずにHDL-GT/LCDからの受信を行うと、溜まっていた通知を一気に読み取ってしまいます。それが、偶然にもHDL-GT/LCDのメニュー操作に一致してしまい、NASのIPアドレス等を設定変更してしまいました・・・こんな悲劇を避けるために、キープアライブタイムアウトが発生した後は余計なボタン通知を送信しないよう、入力不可モードに切り替えるのではないかと思います。"@TITLE"通知を送信するのは、HDL-GT/LCDが入力不可モードに遷移したことを、NASが追跡できるための最低限の情報を残しておくためではないでしょうか───かなり弱い推測ですね(^^; 理由はよくわからない、というのが本当のところです。


7. コマンドリファレンス

 ※のちほど追記する予定です。(2007/12/20)


Thu Dec 20 19:20:49 JST 2007 Naoyuki Sawa (nsawa@piece-me.org)