20:54-22:01 20p
使用I/O 内存
用来和设备通讯的主要机制是通过内存映射的寄存器和设备内存
I/O 内存是简单的一个象 RAM 的区域
不管是否需要 ioremap 来存取 I/O 内存, 不鼓励直接使用 I/O 内存的指针。 而应该用封装过的函数或宏。这是为了安全和可移植性的考虑。
I/O 内存分配和映射
I/O 内存区必须在使用前分配.分配内存区的接口是( 在 <linux/ioport.h> 定义):
struct resource*request_mem_region(unsigned long start, unsigned long len, char *name);
分配后还必须设置一个映射. 这是ioremap 函数的功能,
从 ioremap 返回的地址不应当直接引用; 相反,应当使用内核提供的accessor函数
存取I/O 内存
从 I/O 内存读, 使用下列之一:
unsigned intioread8(void *addr);
unsigned intioread16(void *addr);
unsigned intioread32(void *addr);
这里, addr 应当是从 ioremap获得的地址(也许与一个整型偏移); 返回值是从给定 I/O 内存读取的.
有类似的一系列函数来写 I/O 内存:
void iowrite8(u8 value,void *addr);
void iowrite16(u16value, void *addr);
void iowrite32(u32value, void *addr);
像I/O内存一样使用端口
有些硬件既某些版本使用端口,某些版本使用I/O内存。内核通过一个函数可以把端口映射到内存从而统一使用I/O内存的方式来访问。
void*ioport_map(unsigned long port, unsigned int count);
这个函数重映射 count I/O端口和使它们出现为 I/O 内存.
第十章中断处理
设备必须有一种方法使处理器知道有事情发生了。
这种方法就是中断.一个中断就是一个信号,当需要处理器的注意时,设备便发出这个信号给处理器。
中断处理,从本质上讲,它们与其他的代码并行地运行. 因此, 它们不可避免地引起并发问题和对数据结构和硬件的竞争
安装一个中断处理
模块在使用中断前,需要先请求中断通道,使用完毕后需要释放它。
在<linux/interrupt.h>, 实现中断注册接口:
intrequest_irq(unsigned int irq,
irqreturn_t (*handler)(int,void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
调用 request_irq 的正确位置是当设备第一次打开时, 而不是 在设备初始化时,在硬件被指示来产生中断前. 因为如果初始化占用了中断号,但是没有实际用到的话,就浪费了。
自动检测IRQ号
内核函数来检测
unsigned longprobe_irq_on(void);
自己实现检测
快速和慢速处理
快速中断(那些使用 SA_INTERRUPT被请求的)执行时禁止所有在当前处理器上的其他中断。
慢速中断,则允许其他中断。