MPLAB X IDEのSCLでデバッグ(3)

電子工作

PICマイコンの開発環境であるMPLAB X IDEに備わっているデバッグ用のプログラミング言語Stimulus Control Languageを使って、自作のPICプログラムをデバッグしてみる記録です。今回はプロセスとwaitについて調べてみます。

プロセス

デバッグ用のコードはprocessブロックに記述する。僕の趣味で、公式ユーザーズガイドとインデントの付け方が違っています。なんかSCLは懐かしのPascal言語っぽいので、Pascal流のインデント方式に統一しています。

process is
begin
    // プロセスをここに記述する。
end process;

testbenchブロックの中には、1個以上のprocessブロックを含む。2個以上のプロセスを記述する場合は並べて書けばよい。こんな感じ。processを1個も含まないからのtestbenchも一応許されるみたい。

testbench for "PIC16F1705" is
    process is
    begin
        // 1個目のプロセス
    end process;

    process is
    begin
        // 2個目のプロセス
    end process;
end testbench;

2つめのprocessブロックは1つ目のprocessブロックの実行が終了し次第実行されるようだ。ちなみにこのプロセスの動作はマニュアルに書いてないので、推測が入っています。

プロセスには名前を付けることができる。名前は任意で良いがtestbench中で重複してはならない。現在のバージョンではプロセス名自体に意味を持たないが、将来のバージョンで何かに使われるかもしれないらしい。
プロセス名の書き方は2種類ある。

プロセス名: process is
begin
    // プロセスの処理
end process プロセス名

またはこれ。プロセス名の後ろに"is"が付くか付かないかの違い。僕の趣味的には前者の方が好きかな。

プロセス名: is process is
begin
    // プロセスの処理
end process プロセス名

上の例では「プロセス名」と日本語で書いているが、実際に日本語が使えるかは今のところ不明。半角英文字だけにしておくのが無難かもしれない。

wait

ここからprocessブロックの中で記述する具体的な文が出てきます。まず命令実行を一時停止するwait文について。
SCLが普通の言語と違うのは、ループ構造を指定しなくてもprocessブロック内の文を上から順に実行し、一番下の文を実行するとまた先頭に戻って繰り返すということです。

process is
begin
    statement1
    statement2
    statement3
end

この例では、statement1→statement2→statement3と実行すると自動的に先頭に戻って再びstatement1から実行することになります。

そこでprocessブロックの実行を一時停止するか終了するにはwait文を実行する必要があります。もしprocessブロック中にwait文が無いとprocessブロックの実行が止まりません。これはデバッガがハングアップすることを意味ます。
ここでデバッガ内部の動作を見てみます。

シングルステップ
    (1) ユーザ命令を1つ実行する
    (2) 命令で必要としたサイクル数分に対して:
        (2-1) ストップウィッチを増分する
        (2-2) PICの内蔵モジュールを実行する
        (2-3) SCLプロセスを実行する

デバッガはユーザプログラムを1命令ずつ実行します。そして1目入れ実行するごとに、SCLのプロセスを実行するのですが、もしSCLプロセスが止まらなければ永遠に(2-3)の処理を続けてしまうため、次のユーザ命令を実行することができなくなります。そこでprocess中にwait文を挿入することによって、(2-3)から抜け出すタイミングを作ることができるのです。
予期しないハングアップを防ぐため、IDEがSCLを読み込む際にprocessブロック内のwait文有無をチェックし、もし無いとエラーとなるようになっています。

SIM004: Failed to parse SCL SCL022: Process contains neither a wait statement nor a sensitivity list line(#)

さて、wait文には4つの形式とその組み合わせの形式があります。

簡素Sait (Unadorned Wait)

プロセスを終了させます(現在のprocessブロックから抜けるということ)。

process is
begin
    wait;   // プロセスを終了する。
end process;

感度Wait (Sensitivity Wait)

値が変化するまで一時停止します。

wait on RD1;          // RD1ピンの状態が変化するまで待つ
wait on userVar;      // ユーザ定義変数userVarの値が変化するまで待つ
wait on STATUS;       // STATUSレジスタの値が変化するまで待つ
wait on PORTD.RD0;    // ポートDのRD0ピンの状態が変化するまで待つ

条件Wait (COndition Wait)

真偽値が真になるまで一時停止します。

wait until PORTA == 128;          // PORTAレジスタの値が128 (0x80)になるまで待つ
wait until RD1 == '1';            // RD1がHighになるまで待つ
wait until ADCON.ADON == '1';     // ADCONレジスタのADONビットが1になるまで待つ
wait until PC == 4;               // プログラムカウンタが4になるまで待つ。

タイムアウトWait (Timeout Wait)

指定した時間が経過するまで一時停止します。

wait for 10 ic;        // 10命令サイクル待つ
wait for 10 ms;        // 10ミリ秒待つ

組み合わせWait (Combined Wait)

タイムアウトWaitと、感度Waitまたは条件Waitを組み合わせていずれかが真になるまで一時停止することができます。要するに各種条件にタイムアウトを設定できるということですね。

wait on RD1 for 10 ms;            // RD1ピンが変化するか、10ミリ秒経過するまで待つ
wait until PC = 20 for 20 ic;     // プログラムカウンタが20になるか、20命令サイクル経過するまで待つ

SCL記事一覧

コメント

タイトルとURLをコピーしました