- 1、本文档共29页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
;目录;前一节我们在设计简单字符驱动程序时,跳过了一个重要的问题:当一个设备无法立刻满足用户的读写请求时应当如何处理? 例如:调用read时没有数据可读, 但以后可能会有;或者一个进程试图向设备写入数据,但是设备暂时没有准备好接收数据。应用程序通常不关心这种问题,应用程序只是调用read 或write 并得到返回值。驱动程序应当(缺省地)阻塞进程,使它进入睡
眠,直到请求可以得到满足。;在阻塞型驱动程序中,Read实现方式如下:
如果进程调用read,但设备没有数据或
数据不足,进程阻塞。当新数据到达后,
唤醒被阻塞进程。;在阻塞型驱动程序中,Write实现方式如下:
如果进程调用了write,但设备没有足够的空
间供其写入数据,进程阻塞。当设备中的数
据被读走后,缓冲区中空出部分空间,则唤
醒进程。
;阻塞方式是文件读写操作的默认方式,但
应用程序员可通过使用O_NONBLOCK
标志来人为的设置读写操作为非阻塞方式
(该标志定义在linux/fcntl.h中,在打
开文件时指定)。
;如果设置了O_NONBLOCK标志,read
和write的行为是不同的。如果进程在没
有数据就绪时调用了read,或者在缓冲
区没有空间时调用了write,系统只是简
单地返回-EAGAIN,而不会阻塞进程。
;实例分析;什么是Poll方法,功能是什么?
系统调用(用户空间) 驱动(内核空间)
Open Open
Close Release
Read Read
Write Write
Ioctl Ioctl
lseek llseek
Select Poll
;Select系统调用;Select系统调用;Select系统调用;Select系统调用;Select系统调用;Select系统调用;Select系统调用;Poll方法;Poll方法;POLLIN
如果设备可被不阻塞地读, 这个位必须设置.
POLLRDNORM
这个位必须设置, 如果正常数据可用来读. 一个可读的设备返回( POLLIN|POLLRDNORM ).
POLLRDBAND
这个位指示带外数据可用来从设备中读取. 当前只用在 Linux 内核的一个地方( DECnet 代码 )并且通常对设备驱动不可用.
POLLPRI
高优先级数据(带外)可不阻塞地读取. 这个位使 select 报告在文件上遇到一个异常情况, 因为 selct 报告带外数据作为一个异常情况.;用来指示操作的几个标志;static unsigned int mem_poll(struct file *filp,poll_table *wait)
{
struct scull_pipe *dev =filp-private_data;
unsigned int mask =0;
/* 把进程添加到等待队列*/
poll_wait(filp,dev-inq,wait);
/*返回掩码*/
if (有数据可读)
mask = POLLIN |POLLRDNORM;/*设备可读*/
return mask;
}
;unsigned long 变量, 它被声明做 volatile 。在 32-位平台上 HZ 是 1000 时, 计数器只是每 50 天回绕一次。
你需要读取当前的计数器, 无论何时你的代码需要计算一个将来的时间戳。
#include linux/jiffies.h
unsigned long j, stamp_1, stamp_half, stamp_n;
j = jiffies; /* read the current value */
stamp_1 = j + HZ; /* 1 second in the future */
stamp_half = j + HZ/2; /* half a second */
stamp_n = j + n * HZ / 1000; /* n milliseconds */ ;#include linux/jiffies.h
int time_after(unsigned long a, unsigned long b);
int time_before(unsigned long a, unsigned long b);
int time_after_eq(unsigned long a, unsigned long b);
int time_before_eq(unsigned long a, unsigned long b);
Unsigned long timeout = jiffies+3*Hz;
While(time_before(jiffies,
文档评论(0)