`
mmdev
  • 浏览: 12928612 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

LDD3学习笔记(9):高级字符驱动操作

 
阅读更多
1、ioctl接口

ioctl驱动方法有和用户空间版本不同的原型:

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

2、阻塞I/O

阻塞进程,使它进入睡眠直到请求可继续。

当一个进程被置为睡眠,它被标识为处于一个特殊的状态并且从调度器的运行队列中去除,直到发生某些事情改变了那个状态。一个睡着的进程将不被任何CPU调度,因此不会运行,一个睡着的进程已被搁置到系统的一边,等待以后发生事件。

3、参考和总结

#include<linux/ioctl.h>

声明用来定义ioctl命令的宏定义.当前被<linux/fs.h>包含.

_IOC_NRBITS

_IOC_TYPEBITS

_IOC_SIZEBITS

_IOC_DIRBITS

ioctl命令的不同位段所使用的位数.还有4个宏来指定MASK4个指定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<asm/uaccess.h>

intaccess_ok(inttype,constvoid*addr,unsignedlongsize);

检查一个用户空间的指针是可用的.access_ok返回一个非零值,如果应当允许存取.

VERIFY_READ

VERIFY_WRITE

access_oktype参数的可能取值.VERIFY_WRITEVERIFY_READ的超集.

#include<asm/uaccess.h>

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<linux/capability.h>

定义各种CAP_符号,描述一个用户空间进程可有的能力.

intcapable(intcapability);

返回非零值如果进程有给定的能力.

#include<linux/wait.h>

typedefstruct{/*...*/}wait_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<linux/sched.h>

set_current_state(intstate);

设置当前进程的执行状态.TASK_RUNNING意味着它已经运行,而睡眠状态是

TASK_INTERRUPTIBLETASK_UNINTERRUPTIBLE.

voidschedule(void);

选择一个可运行的进程从运行队列中.被选中的进程可是当前进程或者另外一个.

typedefstruct{/*...*/}wait_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<linux/poll.h>

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方法.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics