阻塞型驅動設計

2021-08-06 05:37:41 字數 4264 閱讀 9470

阻塞型驅動設計

1.阻塞的必要性

當乙個裝置無法立刻滿足使用者的讀寫請

求時應當如何處理? 例如:呼叫read

時,裝置沒有資料提供, 但以後可能會

有;或者乙個程序試圖向裝置寫入資料,

但是裝置暫時沒有準備好接收資料。當

上述情況發生的時候,

驅動程式應當

(預設地)阻塞程序,使它進入等待(睡

眠)狀態,直到請求可以得到滿足

。a準備對b(驅動程式)讀取資料,b說現在還沒資料。請a先進候車室等待,b之後有了資料。b就將a喚醒。

2.核心等待佇列

在實現阻塞驅動的過程中,也

需要有乙個「候車室」來安排

被阻塞的程序「休息」,當喚

醒它們的條件成熟時,則可以

從「候車室」中將這些程序喚

醒。而這個「候車室」就是等

待佇列。

1、定義等待佇列

wait_queue_head_t my_queue

2、初始化等待佇列

init_waitqueue_head(&my_queue);

3、定義+初始化等待佇列

declare_wait_queue_head(my_queue);

3.進入等待佇列,睡眠

wait_event(queue,condition)

當condition(布林表示式)為真時,立即返回;否則讓程序

進入task_uninterruptible

模式的睡眠,並掛在queue參

數所指定的等待佇列上。

wait_event_interruptible(queue,condition)

當condition(布林表示式)為真時,立即返回;否則讓

程序進入

task_interruptible

的睡眠,並掛在queue引數

所指定的等待佇列上。

int wait_event_killable(queue, condition)

當condition(乙個布林表示式)為真時,立即返回;

否則讓程序進入

task_killable

的睡眠,並掛

在queue引數所指定的等待佇列上。

4.從等待佇列中喚醒程序

wake_up(wait_queue_t *q)

從等待佇列q中喚醒狀態為task_uninterruptible,

task_interruptible,task_killable

的所有程序。

wake_up_interruptible(wait_queue_t *q)

從等待佇列q中喚醒狀態為task_interruptible 的程序。

5.對按鍵程式進行改造

key.c

#include

<

linux

/module.h

>

#include

<

linux

/init.h

>

#include

<

linux

/miscdevice.h

>

#include

<

linux/fs

.h>

#include

<

asm/

uaccess.h

>

#include

<

linux/io

.h>

#include

<

linux

/irqreturn.h

>

#include

<

linux

/interrupt.h

>

#include

<

linux

/uaccess.h

>

#define gpfcon

(volatile unsigned long*)

0x56000050

#define gpfdat

(volatile unsigned long*)

0x56000054

unsigned

int*

gpio_data

;struct work_struct

*work1

;struct timer_list key_timer

;wait_queue_head_t key_q

;unsigned

intkey_num =0

;void key_timer_func

(unsigned long data

)elseif(

(key_val

&0x02)=

=0)elseif(

(key_val

&0x04)=

=0)elseif(

(key_val

&0x10)=

=0)wake_up(&

key_q

);                                 //喚醒程序

}void work1_func

(struct work_struct

*work

)irqreturn_t key_int

(int

irq,

void

*dev_id

)void key_hw_init()

intkey_open

(struct inode

*inode

,struct file

*filp

)ssize_t key_read

(struct file

*filp

,char __user

*buf

,size_t size

,loff_t

*pos

)struct file_operations key_fops =;

struct miscdevice key_miscdev =;

static

intbutton_init()

//按鍵初始化

key_hw_init()

;//註冊中斷處理程式

ret

=request_irq

(irq_eint0,&

key_int

,irqf_trigger_falling

,"tq2440key",0

);ret

=request_irq

(irq_eint1,&

key_int

,irqf_trigger_falling

,"tq2440key",0

);ret

=request_irq

(irq_eint2,&

key_int

,irqf_trigger_falling

,"tq2440key",0

);ret

=request_irq

(irq_eint4,&

key_int

,irqf_trigger_falling

,"tq2440key",0

);//

建立工作

work1

=kmalloc

(sizeof

(struct work_struct),

gfp_kernel);

init_work

(work1

,work1_func);

//初始化定時器

init_timer(&

key_timer);

key_timer

.function

=key_timer_func;/

/註冊定時器

add_timer(&

key_timer);

//初始化等待佇列

init_waitqueue_head(&

key_q

);                                //初始化等待佇列

return 0;}

static void button_exit()

module_init

(button_init);

module_exit

(button_exit);

0

給主人留下些什麼吧!~~

核心驅動 阻塞型驅動

1 定義 等待佇列頭部 wait queue head t key q 2 初始化 等待佇列頭部 init waitqueue head key q 3 等待事件發生 wait event key q,key num 4 喚醒等待事件 wake up key q 查詢按鍵狀態 key.c inclu...

linux裝置驅動(8)阻塞型IO

當驅動程式無法立即滿足請求,該如何響應?如當我們想要寫入的時候,裝置對應的緩衝區已滿,或者是當我們想要讀的時候當前緩衝區是空的。為了提高cpu的效率,我們的驅動程式應該阻塞等待該程序,將其置於休眠狀態直到請求可繼續。休眠 sleep 對於程序來講意味著什麼?當乙個程序被置入休眠時,他會被標記為一種特...

驅動開發之始,(四)阻塞型I O,程序休眠

在前面的章節中,我們講述了read和write方法。當資料不可用時,使用者呼叫read,或者使用者使用寫入資料,但輸出緩衝區已滿,驅動程式該如何相應呢?在這種情況下,驅動程式應該 預設 阻塞該程序,將其置入休眠狀態直到請求可繼續。1.休眠 sleep 當乙個程序被置入休眠時,它會被標記為一種特殊狀態...