1. H8マイコンでWEBサーバを立ち上げる
  2. WEBサーバプログラムをシリアル転送ツール、または、sendコマンドを使って内蔵ROMディスクに転送します。
    内蔵ROMディスクに書き込むには、モード7/FWE有効の設定にしなければいけません。
    WEBサーバの実行ファイル http
    WEBサーバのソースファイル http.c
    MESはモード5で動作しますので、モード5にしてWEBサーバを起動します。
    /rom0/http &
    WEBサーバのプログラムは内蔵ROMディスク上にあるので、 絶対パスでWEBサーバを指定して起動します。

    (1) 内蔵ROMディスク(rom0)上でWEBサーバを立ち上げる

    内蔵ROMディスクに書き込むには、モード7/FWE有効の設定にしなければいけません。
    HTML文書や画像ファイルなどをシリアル転送ツール、または、sendコマンドを使って内蔵ROMディスクに転送します。
    起動は上記のとおりに起動します。
    そうすると、転送しておいたHTML文書や画像ファイルを外部のブラウザから見ることができます。
    (2) RAMディスク(ram0)上でWEBサーバを立ち上げる
    RAMディスクはマイコン起動直後の状態では何もファイルが存在しない空の状態です。
    また、電源を切ったり、リセットをすると内容がすべて消えてしまいます。
    モード5のMESが起動した状態でtftpコマンドを使って、tftpサーバにあるHTML文書や画像ファイルをRAMディスクへ転送します。
    WEBサーバを起動は以下のようにします。
    /rom0/http /ram0/ &
    WEBサーバのプログラムは内蔵ROMディスク上にあるので、絶対パスでWEBサーバを指定して起動します。
    また、デフォルトでWEBサーバは内蔵ROMディスクへアクセスをするので、RAMディスクに対してアクセスさせるにはオプションでramディスクを指定します。
    (3) 外付ROMディスク/AT24C1024(se0)上でWEBサーバを立ち上げる
    外付ROMディスク/AT24C1024を最初に使う場合はコマンドライン上で以下のように必ずフォーマットをしてください。
    format se0
    フォーマットは最初に一度だけ行えばいいです。
    起動直後のカレントフォルダはRAMディスクになっているので、以下のように外付ROMディスク/AT24C1024にカレントフォルダを移動します。
    cd /se0/
    モード5のMESが起動した状態でtftpコマンドを使って、tftpサーバにあるHTML文書や画像ファイルをRAMディスクへ転送します。
    WEBサーバを起動は以下のようにします。
    /rom0/http /se0/ &
    WEBサーバのプログラムは内蔵ROMディスク上にあるので、絶対パスでWEBサーバを指定して起動します。
    また、デフォルトでWEBサーバは内蔵ROMディスクへアクセスをするので、外付ROMディスク/AT24C1024に対してアクセスさせるにはオプションで外付ROMディスク/AT24C1024を指定します。

  3. WEBサーバのカスタマイズ
  4. WEBサーバは、オプションでカレントフォルダ、ポート番号、デフォルトのファイル名を指定できます。
    WEBサーバの起動時の書式は以下のとおりとなっています。
    http [カレントフォルダ] [ポート番号] [/=デフォルトのファイル名]
    オプションを指定しない場合のカレントフォルダは /rom0/ 、ポート番号は80、デフォルトのファイル名は、index.html となっています。
    例えば、WEBサーバのポート番号を8080番ポートにしたい場合は、以下のように起動します。
    /rom0/http 8080
    デフォルトのファイル名は、ブラウザ上でファイル名を指定しない場合に呼び出されるファイル名のことを指します。
    例えば、デフォルトのファイル名を main.html に変更したい場合は、以下のように起動します。
    /rom0/http /=main.html
  5. H8マイコンでCGIプログラムを作る
  6. (1)入出力のしくみ
    (a) フォームからの入力

    フォームから送信されたデータは、WEBサーバーを通じてCGIプログラム に渡されます。
    データの経路は、GETメソッドとPOSTメソッドがありますが、ここではGETメソッドを使います。
    その指定は、FORMタグのMETHODをGETにします。
    その場合、データの文字列はCGIプログラムの引数argv[1]にセットされます。
    従って、これをプログラムで読むためには、argv[1]をcgi_value()で対応する変数の値を取り出せば良いわけです。

    (b) ブラウザへの出力

    printf()などで標準出力に書き込めば、WEBサーバーを通じて、ユーザーのブラウザにデータが送られます。
    標準出力では、HTMLフォーマットのテキストを出力します。

    (2)とりあえずフォームを作ってみる

    左図のようなHTML文書で簡単なフォームを作ります。
    そして、データをCGIプログラムで読み込み、受け取ったままのデータをブラウザに表示してみましょう。
    ブラウザから入力データがどのように送られてくるのかを見てください。
    <html><body>
    <form action="program">
    <p>
    Subject<input type="text" name="sub"><br>
    Mail<input type="text" name="mail"><br>
    <input type="submit" value="submit">
    <input type="reset" value="reset"><br>
    </p>
    </form>
    </body></html>
    上に示したフォームのためのHTML文書です。
    フォームから2つのデータを受け取って、
    programというCGIプログラムを起動します。
    GETメソッドを指定しているので、
    データの文字列はOPTIONにセットされます。
    #include <mes.h>

    int main(int argc, char **argv) {
    char text[80];

    printf("<html><body>");
    cgi_value(argv[1], "sub", text, 79);
    printf("<p>Subject is %s</p>\n", text);
    cgi_value(argv[1], "mail", text, 79);
    printf("<p>Mail is %s</p>\n", text);
    printf("</body></html>");
    }
    このプログラムは、HTML文書を出力しているだけです。
    フォームの環境変数は引数argv[1]に渡されます。
    cgi_value()でargv[1]の中に含まれる変数に対応する値
    を取り出します。
    その値を含めてprintf()でHTML文書を出力しています。

    (3)CGIプログラムのコンパイル
    CGIプログラムは普通のユーザプログラムです。
    コンパイルは、MES付属の統合開発環境で行うか、以下のようにコマンドラインで行います。

    h8300-hms-gcc -mh -mint32 -r -fno-common -o program program.c

    コンパイルしたCGIプログラムをマイコンへ転送します。
    (4)CGIプログラムのテスト
    このままWEBサーバでフォームから実行する前に、コマンド上で動作させてみましょう。
    CGIプログラムで出力したHTML文書とともに環境変数argv[1]の値が出力されれば成功です。
    以下にコマンド上での実行例を示します。
    argv[1]の値はコマンドライン上で指定します。
    MES >program
    <html><body><p>Subject is </p>
    <p>Mail is </p>
    </body></html>
    MES >program sub=CGIProgram&mail=mituiwa%40linet.gr.jp
    <html><body><p>Subject is CGIProgram</p>
    <p>Mail is mituiwa@linet.gr.jp</p>
    </body></html>
    MES >

    フォームからの入力は
    フィールド名1=値1&フィールド名2=値2・・・
    というようにエンコードされて、サーバーに渡されるのです。
    それぞれの変数は & で区切られます。
    変数名と値は = で区切られます。
    環境変数はスペースが許されていないのでスペースは + で表記されます。
    特殊な記号については %16進数 で表記されます。
    (5)CGIプログラムの実行
    それでは、WEBサーバ上でCGIプログラムを実行させて、結果をブラウザで見てみましょう。
    あらかじめ、WEBサーバである http をマイコンに転送しておき、IPアドレスも設定しておきましょう。
    まず、WEBサーバを実行します。
    MES >http &
    次に外部のパソコン上のブラウザからマイコンに対してアクセスしてみましょう。
    そして、以下のように入力欄に適当に文字列を入力して送信します。

    そうするとCGIプログラムが起動され、以下のように入力欄に入力した文字列を含めて表示されます。
  7. ブラウザでマイコン制御
  8. マイコン制御をするには、ブラウザから何らかの入力を受付けて、その入力内容に従って制御を行います。
    入力の受付けは、HTML文書では、<form>タグ中の<input>タグで記述をします。
    入力内容の種類にしてもその種類がいくつか存在しています。
    代表的なものとして、文字列入力を受付けるもの、単にON/OFFを1ビット単位で指定するチェックボックス、多肢択一で指定するラジオボタンなどがあります。
    まず、どのようなフォーマットで入力を受け付けるかを決めて、それをHTML文書のかたちにします。
    例えば、LCD文字出力とLED点滅制御を行う場合は、以下のようなHTML文書にします。

    <html>
    <body>
    <input type="text" name="lcd"><br>
    LED1<input type="checkbox" name="led1" value="on">
    LED2<input type="checkbox" name="led2" value="on">
    <input type="submit" value="submit"><br>
    </body>
    </html>

    上のHTML文書を単純に出力するCGIプログラムは以下のプログラムです。

    #include <mes.h>

    int main(int argc, char **argv) {
    printf("<html><body><p><big>LED control CGI sample</big></p>");
    printf("<form><p>");
    printf("LCD<input type=\"text\" name=\"lcd\"><br>");
    printf("LED1<input type=\"checkbox\" name=\"led1\" value=\"on\">");
    printf("LED2<input type=\"checkbox\" name=\"led2\" value=\"on\">");
    printf("<input type=\"submit\" value=\"submit\"><br>");
    printf("</form></body></html>");
    }

    次に呼び出すHTML文書を自分自身に指定するには、<from>タグのactionオプションで指定します。
    また、チェックボックスの内容を前回に指定した内容をそのまま反映させるようにさせます。
    それらを追加修正したCGIプログラムは以下のプログラムです。

    #include <mes.h>
    #include <string.h>

    int main(int argc, char **argv) {
    char led1[4], led2[4], check[8], lcd[82];

    strcpy(check, "checked");
    cgi_value(argv[1], "led1", led1, 3);
    cgi_value(argv[1], "led2", led2, 3);
    cgi_value(argv[1], "lcd", lcd, 80);
    printf("<html><body><p><big>LED control CGI sample</big></p>");
    printf("<form action=\"%s\"><p>", argv[0]);
    printf("LCD<input type=\"text\" name=\"lcd\"><br>");
    printf("LED1<input type=\"checkbox\" name=\"led1\" value=\"on\"> %s>",
    (led1[0] == 'o') ? check : "");
    printf("LED2<input type=\"checkbox\" name=\"led2\" value=\"on\"> %s>",
    (led2[0] == 'o') ? check : "");
    printf("<input type=\"submit\" value=\"submit\"><br>");
    printf("</form></body></html>");
    }

    そして、入力内容に応じたLCD出力制御とLED点滅制御を行うようにして完成させます。
    完成したCGIプログラムは以下のプログラムです。
    制御対象のボードは、秋月電子のH8/3069Fネットワークボード付属のマザーボードです。

    #include <mes.h>
    #include <string.h>
    #define P4DR (*(volatile unsigned char *)0xffffd3)
    #define LED1 64
    #define LED2 128

    int main(int argc, char **argv) {
    char led1[4], led2[4], check[8], lcd[82];
    unsigned char bits;
    int fd;

    strcpy(check, "checked");
    cgi_value(argv[1], "led1", led1, 3);
    cgi_value(argv[1], "led2", led2, 3);
    cgi_value(argv[1], "lcd", lcd, 80);
    printf("<html><body><p><big>LED control CGI sample</big></p>");
    printf("<form action=\"%s\"><p>", argv[0]);
    printf("LCD<input type=\"text\" name=\"lcd\"><br>");
    printf("LED1<input type=\"checkbox\" name=\"led1\" value=\"on\" %s>",
    (led1[0] == 'o') ? check : "");
    printf("LED2<input type=\"checkbox\" name=\"led2\" value=\"on\" %s>",
    (led2[0] == 'o') ? check : "");
    printf("<input type=\"submit\" value=\"submit\"><br>");
    printf("</form></body></html>");

    fd = open("lcd0", 0);
    write(fd, lcd, strlen(lcd));
    close(fd);
    bits = (led1[0] == 'o') ? LED1 : 0;
    bits |= (led2[0] == 'o') ? LED2 : 0;
    P4DR = bits;
    }

    上のプログラムをコンパイルして、マイコンに転送します。
    そして、WEBサーバを立ち上げるとブラウザからCGIプログラムを呼び出して実行させることができます。
    そうすると以下の図のように入力フォームが表示されます。



    それぞれの入力フォームに上図のように入力をして、フォームを送信します。
    そうすると、アドレスとともに入力内容を合わせて送信されます。
    送信結果が以下の図のようになるとともにLCDに入力内容が表示され、LEDに点滅結果が反映されます。