drv_open関数分析
ピンを外部トリガー割り込みソースとして構成します。
(1)ピンラベル-void * dev_id
(2)高感度エッジ-符号なし長いirqflags
(3)割り込みラベル-符号なしint irq;
(4)割り込みタイプ-irq_handler_tハンドラー
(5))デバイス名-constchar * devname
上記のパラメーターは、Linuxカーネルのrequest_irq
関数によって設定されます。
[1]request_irq
関数呼び出し
request_irq(IRQ_EINT0, buttons_irq, IRQT_BOTHEDGE, "S2", &pins_desc[0]);
[2]request_irq
関数内部処理:setup_irq
関数を呼び出して割り込みを初期化します。
その中で、
irq =(3)割り込みラベル-unsigned int irq = IRQ_EINT0アクション-
>ハンドラー=(4)割り込み発生後に呼び出される関数-irq_handler_tハンドラー=ボタン_irqアクション-
>フラグ=(2)センシティブエッジ-符号なし長いirqflags = IRQT_BOTHEDGE
action-> name =(5)デバイス名-const char * devname = "S2"任意の値をとる
action-> next = NULL;
action-> dev_id =(1)ピンラベル-void * dev_id =&pins_desc [0]任意の値を選択できます。目的は、アンインストールするドライバーを決定することです。
int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
{
...
retval = setup_irq(irq, action);
...
}
[3]setup_irq
関数内部処理:set_type
関数処理を使用します
int setup_irq(unsigned int irq, struct irqaction *new)
{
...
if (desc->chip && desc->chip->set_type)
desc->chip->set_type(irq,new->flags & IRQF_TRIGGER_MASK);
...
}
その中で、desc->chip
どこで定義されていますか?
arch\arm\plat-s3c24xx\irq.c\void __init s3c24xx_init_irq(void)
、[1]IRQ_EINT0
で定義されているように、desc-> chipはs3c_irq_eint0t4に対応します。
void __init s3c24xx_init_irq(void)
{
...
/* external interrupts */
for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
irqdbf("registering irq %d (ext int)\n", irqno);
set_irq_chip(irqno, &s3c_irq_eint0t4);
set_irq_handler(irqno, handle_edge_irq);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
irqdbf("registering irq %d (extended s3c irq)\n", irqno);
set_irq_chip(irqno, &s3c_irqext_chip);
set_irq_handler(irqno, handle_edge_irq);
set_irq_flags(irqno, IRQF_VALID);
}
...
}
ビューのs3c_irq_eint0t4
定義:
static struct irq_chip s3c_irq_eint0t4 = {
.name = "s3c-ext0",
.ack = s3c_irq_ack,
.mask = s3c_irq_mask,
.unmask = s3c_irq_unmask,
.set_wake = s3c_irq_wake,
.set_type = s3c_irqext_type,
};
[4]set_type
関数=s3c_irqext_type
関数
前の呼び出しコードは次のとおりです。
new->flags=action->flags = (2)敏感沿-unsigned long irqflags=IRQT_BOTHEDGE
desc->chip->set_type(irq,new->flags & IRQF_TRIGGER_MASK);
関数の定義は次のとおりです。
s3c_irqext_type(unsigned int irq, unsigned int type)
{
...
if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
{
gpcon_reg = S3C2410_GPFCON;
extint_reg = S3C24XX_EXTINT0;
gpcon_offset = (irq - IRQ_EINT0) * 2;
extint_offset = (irq - IRQ_EINT0) * 4;
}
...
/* Set the external interrupt to pointed trigger type */
switch (type)
{
case IRQT_NOEDGE:
printk(KERN_WARNING "No edge setting!\n");
break;
case IRQT_RISING:
newvalue = S3C2410_EXTINT_RISEEDGE;
break;
case IRQT_FALLING:
newvalue = S3C2410_EXTINT_FALLEDGE;
break;
//与前面request_irq函数调用一致
case IRQT_BOTHEDGE:
newvalue = S3C2410_EXTINT_BOTHEDGE;
break;
case IRQT_LOW:
newvalue = S3C2410_EXTINT_LOWLEV;
break;
case IRQT_HIGH:
newvalue = S3C2410_EXTINT_HILEV;
break;
default:
printk(KERN_ERR "No such irq type %d", type);
return -1;
}
}
2つのdrv_close関数分析
機能目的:割り込みソースを解放する
- free_irq関数呼び出し
irq=(3)中断标号-unsigned int irq = IRQ_EINT0
dev_id = (1)引脚标号-void *dev_id = &pins_desc[0]
free_irq(IRQ_EINT0, &pins_desc[0]);
free_irq関数の定義:
void free_irq(unsigned int irq, void *dev_id)
3つのbuttons_irq割り込みサービス機能分析-ウェイクアップ機能
- 関数宣言の形式:
static irqreturn_t buttons_irq(int irq, void *dev_id)
注:ここでdev_id
関数を確認できます:割り込みソースを決定します - 戻り値:
return IRQ_RETVAL(IRQ_HANDLED);
- ウェイクアップ機能:
wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */
4つのdrv_read関数分析-スリープ関数:
- スリープ関数呼び出し
/* 如果没有按键动作, 休眠 */
wait_event_interruptible(button_waitq, ev_press);
- 睡眠機能プロトタイプ
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \ //condition数值为0的时候休眠
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
- パラメータ宣言
[1] ev_pressパラメーター:
/* 中断事件标志, 中断服务程序将它置1:表示唤醒
third_drv_read将它清0:表示休眠 */
static volatile int ev_press = 0;
[2] button_waitqパラメーター:
キューにぶら下がっているプロセスを表します
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
5ドライブテスト1
アプリプログラムが読み取り機能を実行する場合:割り込み機能が発生しない場合はスリーププロセスが実行され
、割り込みが発生する場合はプロセスが起動されます
-
開発ボードがドライバーをロードした後に
drv_open
関数を呼び出す方法は?
exec 5</dev/buttons
意味:デバイスの電源を入れ、/dev/buttons
5に配置します注:次の図に示されているシェルプロセス番号は770
/ proc / 770 / fdです。fd—これは、現在のプロセスによって開かれた各ファイルのファイル記述子を含むディレクトリです。これらのファイル記述子は、実際のファイルを指します。リンク;シェルプロセスによって開かれたドライバー/ dev / buttonsの
実行効果:
-
close関数を呼び出しますか?
実施した:exec 5<&-
6ドライブテスト2
- テストプログラムの実行(バックグラウンドでの実行):./ app&
図からわかるように、ドライバーとテストプログラムはバックグラウンドで実行されます。その中で、テストプログラムはスリープ状態(S)にあり
、各プロセスによって占有されているCPUリソースを表示します。top
コマンド(終了するにはctrl + c)