LDD3學習筆記(9) 高階字元驅動操作

2021-08-25 23:55:10 字數 4024 閱讀 5493

1、ioctl介面

ioctl驅動方法有和使用者空間版本不同的原型:

int(*ioctl)(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg);

2、阻塞i/o

阻塞程序,使它進入睡眠直到請求可繼續。

當乙個程序被置為睡眠,它被標識為處於乙個特殊的狀態並且從排程器的執行佇列中去除,直到發生某些事情改變了那個狀態。乙個睡著的程序將不被任何cpu排程,因此不會執行,乙個睡著的程序已被擱置到系統的一邊,等待以後發生事件。

3、參考和總結

#include

宣告用來定義ioctl命令的巨集定義.當前被包含.

_ioc_nrbits

_ioc_typebits

_ioc_sizebits

_ioc_dirbits

ioctl命令的不同位段所使用的位數.還有4個巨集來指定mask和4個指定shift,但是它們

主要是給內部使用._ioc_sizebit是乙個要檢查的重要的值,因為它跨體系改變.

_ioc_none

_ioc_read

_ioc_write

"方向"位段可能的值."read"和"write"是不同的位並且可相或來指定read/write.這些值是基

於0的.

_ioc(dir,type,nr,size)

_io(type,nr)

_ior(type,nr,size)

_iow(type,nr,size)

_iowr(type,nr,size)

用來建立ioclt命令的巨集定義.

_ioc_dir(nr)

_ioc_type(nr)

_ioc_nr(nr)

_ioc_size(nr)

用來解碼乙個命令的巨集定義.特別地,_ioc_type(nr)是_ioc_read和_ioc_write的

or結合.

#include

intaccess_ok(inttype,constvoid*addr,unsignedlongsize);

檢查乙個使用者空間的指標是可用的.access_ok返回乙個非零值,如果應當允許訪問.

verify_read

verify_write

access_ok中type引數的可能取值.verify_write是verify_read的超集.

#include

intput_user(datum,ptr);

intget_user(local,ptr);

int__put_user(datum,ptr);

int__get_user(local,ptr);

用來儲存或獲取乙個資料到或從使用者空間的巨集.傳送的位元組數依賴sizeof(*ptr).常規的版本

呼叫access_ok,而常規版本(__put_user和__get_user)假定access_ok已經被呼叫了.

#include

定義各種cap_符號,描述乙個使用者空間程序可有的能力.

intcapable(intcapability);

返回非零值如果程序有給定的能力.

#include

typedefstructwait_queue_head_t;

voidinit_waitqueue_head(wait_queue_head_t*queue);

declare_wait_queue_head(queue);

linux等待佇列的定義型別.乙個wait_queue_head_t必須被明確在執行時使用

init_waitqueue_head或者編譯時使用devlare_wait_queue_head進行初始化.

voidwait_event(wait_queue_head_tq,intcondition);

intwait_event_interruptible(wait_queue_head_tq,intcondition);

intwait_event_timeout(wait_queue_head_tq,intcondition,inttime);

intwait_event_interruptible_timeout(wait_queue_head_tq,intcondition,inttime);

使程序在給定佇列上睡眠,直到給定條件值為真值.

voidwake_up(structwait_queue**q);

voidwake_up_interruptible(structwait_queue**q);

voidwake_up_nr(structwait_queue**q,intnr);

voidwake_up_interruptible_nr(structwait_queue**q,intnr);

voidwake_up_all(structwait_queue**q);

voidwake_up_interruptible_all(structwait_queue**q);

voidwake_up_interruptible_sync(structwait_queue**q);

喚醒在佇列q上睡眠的程序._interruptible的形式只喚醒可中斷的程序.正常地,只有乙個互斥等待者被喚醒,但是這個行為可被_nr或者_all形式所改變._sync版本在返回之前不重新排程cpu.

#include

set_current_state(intstate);

設定當前程序的執行狀態.task_running意味著它已經執行,而睡眠狀態是

task_interruptible和task_uninterruptible.

voidschedule(void);

選擇乙個可執行的程序從執行佇列中.被選中的程序可是當前程序或者另外乙個.

typedefstructwait_queue_t;

init_waitqueue_entry(wait_queue_t*entry,structtask_struct*task);

wait_queue_t型別用來放置乙個程序到乙個等待佇列.

voidprepare_to_wait(wait_queue_head_t*queue,wait_queue_t*wait,intstate);

voidprepare_to_wait_exclusive(wait_queue_head_t*queue,wait_queue_t*wait,intstate);

voidfinish_wait(wait_queue_head_t*queue,wait_queue_t*wait);

幫忙函式,可用來編碼乙個手工睡眠.

voidsleep_on(wiat_queue_head_t*queue);

voidinterruptible_sleep_on(wiat_queue_head_t*queue);

老式的不推薦的函式,它們無條件地使當前程序睡眠.

#include

voidpoll_wait(structfile*filp,wait_queue_head_t*q,poll_table*p);

將當前程序放入乙個等待佇列,不立刻排程.它被設計來被裝置驅動的poll方法使用.

intfasync_helper(structinode*inode,structfile*filp,intmode,structfasync_struct**fa);

乙個"幫忙者",來實現fasync裝置方法.mode引數是傳遞給方法的相同的值,而fa指標指向乙個裝置特定的fasync_struct*.

voidkill_fasync(structfasync_struct*fa,intsig,intband);

如果這個驅動支援非同步通知,這個函式可用來傳送乙個訊號到登記在fa中的程序.

intnonseekable_open(structinode*inode,structfile*filp);

loff_tno_llseek(structfile*file,loff_toffset,intwhence);

nonseekable_open應當在任何不支援移位的裝置的open方法中被呼叫.這樣的裝置應當使

用no_llseek作為它們的llseek方法.

LDD3讀書筆記(第3章 字元驅動)

include dev t dev t 是用來在核心裡代表裝置號的型別.int major dev t dev int minor dev t dev 從裝置編號中抽取主次編號的巨集.dev t mkdev unsigned int major,unsigned int minor 從主次編號來建立...

LDD3學習筆記(20) 網路驅動

include 定義structnet device和structnet device stats的標頭檔案,包含了幾個其他網路驅動需要的頭 檔案.structnet device alloc netdev intsizeof priv,char name,void setup structnet ...

LDD3 讀書筆記 之 第 3 章 字元驅動

本章介紹了下面符號和標頭檔案.struct file operations 和 struct file 中的成員的列表這裡不重複了.include dev t dev t 是用來在核心裡代表裝置號的型別.int major dev t dev int minor dev t dev 從裝置編號中抽取...