割込み(2) - SEGAWA`s Web Site

割 込 み(2)
オペレーティングシステム
No.6
プログラムの記述(1)

制御プログラムを記述する言語
 Cの一部
プログラムの記述(2)

a=b;
 b(一般に式)の値を計算して,
変数aに格納する
プログラムの記述(3)

if (条件) { … }

条件が成立する(真)場合のみ,
{ … }の部分を実行する


条件 a = = b
aとbが等しいか?
条件 c
cが真か?(cが正しいか?)
プログラムの記述(3)


while (条件) { … }
①条件を調べる
②成立する場合は,{ … }を実行してから①に戻
る
③成立しない場合は,この先に進む
条件が成立する間(正しい間),
{ … }を繰り返し実行する
割込み処理の例
ちょっと難しいかも知れないが,
雰囲気は分かって欲しい
印刷処理
プリンタの制御
 想定するプリンタ
CPUがプリンタの速度に合わせると効率が悪くなる
 1文字ずつ印字
 現在あるかどうかは不明
割込みで,どのようにこのギャップを埋めるのか!?
 過去にはあった(使ったことがある)


プリンタの印字速度は遅いが,CPUの計算速度
は速い
プリンタの使い方



プログラムから,印字する1文字分のデータ(文
字コード)をプリンタに送る
プリンタに,(先に送ったデータの)印字開始を指
示する
 印字終了までに時間がかかる!
注意
プリンタが印字動作中に印字データを送ることは
できない(送っても無視される)
プ リ ン タ の 制 御 命 令(1)

send(PRINTER, date)

PRINTERにdata(データ,印字する文字の文
字コード)を送る手続き

複数のプリンタが接続されている場合は,
PRINTERの値により区別する。
しかし,この例ではプリンタは1台だけなので,
PRINTERは無視してかまわない。
プ リ ン タ の 制 御 命 令(2)

start(PRINTER)

PRINTERに既に送ってあるデータの
印字を開始させる手続き

印字には時間がかかるが,その終了を
待たずに手続きの呼び出し元に戻る
startの次を実行しているときは,
まだ印字中である
プ リ ン タ の 制 御 命 令(3)

busy(PRINTER)

PRINTERが動作中,つまり印字中なら真
(true),
そうでないなら偽(false)を返すプリンタの状
態を調べるための関数

プリンタは動作中にsendでデータを送られて
も受け取ることができないので,この関数で
状態をチェックする
割込みを用いないプログラム
印字データdata用意
send(PRINTER, data);
start(PRINTER);
while( busy(PRINTER) ) { ; }
印字データをプ
リンタに送る
このような部分が,
プログラム中に
たくさんある!
次の印字データ用意
プリンタがbusyの間(印字中
以下同様 の間),何もしないことを繰り
返す(印字の終了を待つ)
印字終了後,先に進む
start終了直後は,
プリンタは印字動作
中
プログラムとプリンタの動作
while( busy(PRINTER) ) { ; }

プリンタの動作中は,プログラムの実行が実質上止まる
割 込 み の 利 用(1)

印字終了で,プリンタが割込みをかけられる
 外部割込み
 “プリンタの印字終了”という事象により,割込
み発生
 利用者プログラムを中断
 割込み処理プログラムの実行
 その終了後,中断していた利用者プログラム
を再開
bufferが“空”かどうか
割 込 み の 利 用(2)
YESなら“空”,NOなら“印字データがある”



2つのプログラムから読み書きできる変数
empty:YESまたはNO(初期値はYES)
buffer:印字データを一時的に格納
割 込 み の 利 用(3)
emptyがNOであったら,
何もしないことを繰り返し続ける。
そのうちにemptyがYESになり,先
に進む
利用者プログラム
印字データdata用意
while(empty = = NO) { ; }
buffer = data; empty = NO;
if(not busy(PRINTER)) {
send(PRINTER, buffer);
start(PRINTER);
empty = YES;
}

プリンタがbusyでなけ
れば…
(印字中でなければ)
プリンタは動作中である
が,プログラムは先に進
む
割 込 み の 利 用(4)

プログラム中に,
青枠部分がたくさんあ
る
1文字目
2文字目
3文字目
割 込 み の 利 用(5)

割込み処理プログラム(利用者プログラムとは全
く別のところにある – OSの一部)
if(empty = = NO) {
send(PRINTER, buffer);
start(PRINTER);
empty = YES;
}
割 込 み の 利 用(6)
利用者プログラム
while(empty = = NO) { ; }
buffer = data; empty = NO;
if(not busy(PRINTER)) {
send(PRINTER, buffer);
start(PRINTER);
empty = YES;
}
1文字目が用意できた
empty は YES
印字データをbufferに
emptyをNOに
プリンタは動作中でないから,
busyではない
bufferのデータを送り,
プリンタをスタート
emptyをYESに
2文字目の用意を始める
(プリンタは印字中)
割 込 み の 利 用(7)
プリンタが1文字目を印字中に,
2文字目の用意ができたとする
割 込 み の 利 用(8)
利用者プログラム
while(empty = = NO) { ; }
buffer = data; empty = NO;
if(not busy(PRINTER)) {
send(PRINTER, buffer);
start(PRINTER);
empty = YES;
}
2文字目が用意できた
empty は YES
印字データをbufferに
emptyをNOに
プリンタは動作中なので,
実行しない
2文字目はbufferに入れたまま,
3文字目の用意
(プリンタは1文字目を印字中)
割 込 み の 利 用(9)
1文字目の印字
終了の割込み
割 込 み の 利 用(10)
if(empty = = NO) {
send(PRINTER, buffer);
start(PRINTER);
empty = YES;
}
割込み処理プログラム
emptyはNO
buffer中のデータ(2文字目)を
プリンタに送る
プリンタをスタート
emptyをYESに
3文字目を用意している
割り込まれたプログラムを再開
割 込 み の 利 用(11)
CPU(プログラム)とプリンタが同時に動作
効率がよくなる
一言でまとめると

CPU→プリンタ→CPU→プリンタ→…
と交互に動作するのではなく,

プリンタの動作中も,CPUは動作(処理)すること
により,CPUを無駄なく使う
補 足
とりあえず,今までのことを理解して欲しい
補 足(1)

何文字目かの印字データが用意できたとき
emptyがNOであったらどうなるか?
 buffer中に,直前の文字
 さらにその前の文字をプリンタが印字中
 つまり,印字される文字がたまってしまってい
る
そのうちに,印字終了の
 実際には,このような状態になることがほと
割込みが発生する!
んどである
補 足(2)
emptyがNOなので,ここで待つ!
while(empty = = NO) { ; }
buffer = data; empty =
NO;
if(not busy(PRINTER)) {
send(PRINTER,
buffer);
start(PRINTER);
empty = YES;
}
そのうちに,印字終了割込
みが発生する
if(empty = = NO) {
send(PRINTER,
buffer);
start(PRINTER);
empty = YES;
}
emptyがYESになる
補 足(3)



bufferを配列

参照 補足(1)
利用者プログラム中の印字関係の部分を手続
きにする
割込み禁止部分が必要
補 足(4)

割込みを用いないプログラムの変更
印字データdata用意
while( busy(PRINTER) ) { ; }
send(PRINTER, data);
start(PRINTER);
次回



割込み発生のタイミングにより,正しく処理
できなくなる場合がある
クリティカルレース
際どい部分(クリティカルセクション)