阻塞I/O、和硬件通行、延迟执行、定时器、中断

阻塞I/O

在用户空间调用read函数时,假如此时数据还不可用,则驱动程序应该阻塞该进

程,将其置入休眠状态直到数据请求可继续。简单的休眠机制有等待队列。等待

队列分两种,一种是简单的等待,另一种只等待限定的时间。

和硬件通信

每种外设都通过读写寄存器进行控制,也就是IO操作。

IO操作分两类,IO端口和IO内存。IO端口是针对X86结构(翻微机原理的书回忆下)。

这里说下IO内存,因为绝大多数嵌入式控制器采用的是这种方式。

驱动最重要的最用就是和硬件通信,驱动中IO需要注意的是:

1.所谓IO内存是指将外设的寄存器以及外设上的内存全部映射到IO地址空间的一种通

信方式。

2.内核运行在虚拟地址上,内核中的代码操作的是虚拟地址。而外设寄存器、内存等

是在物理地址上的,所以需要先将物理地址转换成为虚拟地址ioremap()后供内核代使

用。具体操作如下:
a.struct resource *request_mem_region(unsigned long start, undigned long len,

char *name)

b.void *ioremap(unsigned long phys_addr, unsigned long size)

c.访问io内存

a、b、c的具体解释如下:首先通过a步骤申请io内存(因为内核把IO内存当作一种资源),使得当前的进

程可以独占使用这片IO资源,此时得到的是物理IO地址。然后通过b映射,通过页表转换后变为虚拟地

址,以后程序就通过访问这个虚拟地址对外设寄存器进行操作。对外设寄存器的读写老方式是通过

writeb、writew、writel等,新方式是通过iowrite8、iowrite16、iowrite32。

具体理解可参考(LKD LDD)

延迟执行

1.忙等待

处理器利用率不高,死循环。并且需要延时的时间只能是内核时钟的整数倍。

2.schedule_timeout()

让任务休眠指定的时间后,再执行。

3.内核延时api如mdelay、udelay、ndelay等

上述api适合延时时间小于内核时钟片时。

4.使用内核定时器(软中断实现)

内核定时器

内核定时器是通过软中断实现的,内核时钟片中断之后会执行定时器软中断,进而

执行内核定时器,所以内核定时器是执行在软中断下半部的上下文中。需要注意的

是定时器在超时后就会自动撤销,但是可以通过mod_time等函数重新激活定时器

重复使用。

内核定时器的使用步骤如下。

1.定义一个内核定时器,并初始化相关数据

struct timer_list my_timer;

init_timer(my_timer)

my_timer.function = my_function(定时器中断处理程序)等

2激活定时器

add_timer(my_timer)

或者当定时时间到后再初始化这个定时器

mod_timer(&mod_timer, jiffies_delay)

需要注意的是,内核定时器处理程序运行在中断上下文中,所以对定时器中断处理程序

中的共享数据应该注意保护。

中断

Linux的中断分为中断上半部和下半部,并且执行的时候均处于中断上下文,上半部处于中断

上下文,下半部也处于中断上下文!中断上下文和进程上下文有区别!中断上下文是指内核处

于一种特殊状态,这种状态不能调度,当然就不能休眠(休眠可能导致调度)。因为内核调度的

基本单位是线程,并且依赖描述符thread_info,而中断上下文并没有代表他它的线程,所以一

旦认为调度或者休眠等导致中断处理程序失去了处理器,便调度不回来了!所以在中断上下文

中绝对不能休眠或者显示调度schedule()函数!

中断下半部的处理方法:

1.软中断(网卡收发)

2.tasklet

3.工作队列(不要和等待队列混淆)

tasklet也是基于软中断实现,所以中断下半部的实现方式本质上只有两种,一种是软中断,另一

种是工作队列。并且这两者的运行环境差别较大,软中断的运行处于中断上下文,而工作队列的

运行处于进程上下文。

下半部的软中断只有在非中断嵌套中且下半部未被禁止时才会触发,若中断嵌套(不同中断之间

的嵌套,同一中断号在执行中断处理程序的时候中断线被禁止了)则在中断最外层被触发。

此外,in_interrupt函数大多数情况下可以用作判断是否运行在中断上下文中,但是实际上它包

含了更多的信息,包括是否处于中断嵌套、下半部是否禁止等内容!

具体参见http://bbs.chinaunix.net/thread-2306027-1-1.html这个帖子

你可能感兴趣的:(阻塞I/O、和硬件通行、延迟执行、定时器、中断)