*メモ [#p6ca7065]
USL-5Pのボタンの割り込みメモ
-ユーザプロセスへどうやってボタン割り込みを通知するか?~すこし考えてみる。~
--案1:割り込みハンドラでsignalを生成してユーザプロセスにボタン押下イベントを通知する。~
--案2:ユーザプロセスはselectで待ちうけ。割り込みハンドラは、その待ち受け解除する。~
結果的にボタンの押下イベントがユーザプロセスへ伝わる。~
-前者は、直感的で解りやすい。後者は、扱いやすい。?
*まず、前者の実装を行ってみる。 [#l731e969]
-カーネル内
--割り込み番号13までサポート。さらに、ボタン割り込みを登録。
#pre{{
void __init init_julian_IRQ(void)
{
int i;
for (i=5; i<&color(red){14};; i++)
make_julian_irq(i);
}
}}
--割り込みハンドラの登録。(2つの割り込みでハンドラを共有)
#pre{{
if (request_irq(IRQ_POWER, &color(red){sw_interrupt};, 0, "SHUTDOWNSWITCH", NULL)) {
printk(KERN_ERR "Unable to get IRQ 11.\n");
return 1;
}
if (request_irq(IRQ_BUTTON, &color(red){sw_interrupt};, 0, "USL-5P BUTTON", NULL)) {
printk(KERN_ERR "Unable to get IRQ 12.\n");
return 1;
}
}}
--割り込みハンドラ本体
#pre{{
static irqreturn_t &color(red){sw_interrupt};(int irq, void *dev_id, struct pt_regs *regs)
{
landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); // ボタンの読み出し
disable_irq(IRQ_BUTTON); // 割り込み禁止
disable_irq(IRQ_POWER); // 割り込み禁止
ctrl_outb(0x00, PA_PWRINT_CLR); // 割り込み線の解除?
if(landisk_btnctrlpid != 0){ // ユーザプロセスのPIDチェック
kill_proc(landisk_btnctrlpid, SIGUSR1, 1); // ユーザプロセスへシグナル送信
landisk_btnctrlpid = 0; // ハンドシェイク終了
}
return IRQ_HANDLED;
}
}}
--ユーザプロセスのPID受け渡し部分(ioctlルーチン)。~
#pre{{
case GIODRV_IOCSGIO_BTNPID:
landisk_btnctrlpid = data; // data: ユーザプロセスのPID
landisk_btn = 0;
if(irq_desc[IRQ_BUTTON].depth){
enable_irq(IRQ_BUTTON); // ボタン割り込み許可
}
if(irq_desc[IRQ_POWER].depth){
enable_irq(IRQ_POWER); // ボタン割り込み許可
}
break;
}}
-シグナルを受け取るユーザプロセス~
#pre{{
int main(int argc, char *argv[])
{
…省略…
pid = getpid();
if(signal(SIGUSR1, catch_SIGUSR1) == SIG_ERR){ // シグナルハンドラの登録
printf("failed to set signal handler.\n");
exit(0);
}
while(1){
catch_signal = 0; // ハンドシェイク開始
ioctl(fd, GIODRV_IOCSGIO_BTNPID, &pid); // 自身のPIDをセットする。
// (ボタン割り込み発生時、カーネルは本PIDへシグナルを発信する。)
while(catch_signal == 0){ // シグナル受信待ちループ
sleep(10); // シグナル受信時、sleepは即刻解除され、catch_SIGUSR1へ制御が移る。
}
// 以下シグナル(ボタン割り込み)を受け取った場合のみ実行される。
…省略…
}
}
static void catch_SIGUSR1(int sig) // シグナルハンドラ
{
catch_signal = 1;
}
}}
-うまく動作しているみたい。
*後者の実装 [#e2b1deee]
前者の実装で満足してしまったので、今後の課題とする。