Linux驱动程序-硬件访问笔记

寄存器与内存

他们的区别在哪里呢?

寄存器和RAM的主要不同在于寄存器操作有副作用LDD3上讲的sideeffect或者边际效果):当你读取某个地址时,可能导致该地址内容发生变化,比如很多设备的中断状态寄存器只要一读取,便自动清零。

内存与I/O

x86处理器中存在I/O空间的概念,I/O空间是相对内存空间而言的,他们是互相独立的地址空间,在32位的x86系统中,I/O空间大小为64k,内存空间大小为4G

ARMMIPSPowerPC只支持内存空间

只有x86IO空间

IO端口与IO内存

IO端口:当一个寄存器或者内存位于IO空间时,称为IO端口

IO内存:当一个寄存器或者内存位于内存空间时,称为IO内存

操作IO端口

步骤:

1)申请IO端口

核心函数:

structresource*request_region(unsignedlongfirst,unsignedlongn,constchar*name)

first

第一个IO端口的地址

n

要申请多少个IO

name

操作这个IO端口的设备名字

申请成功

返回非NULL

申请失败

返回NULL

系统中端口的分配情况记录在/proc/ioports中,如果不能分配需要的端口,可以来这里查看谁在使用!!

2)访问

IO端口可以分为8-位,16-位,32-位端口

在头文件<asm/io.h>

定义了内联函数来访问IO端口:

读字节端口(8位):unsignedinb(unsignedport)

写字节端口(8位):voidoutb(unsignedcharbyte,unsignedport)

读字节端口(16位):unsignedinw(unsignedport)

写字节端口(16位):voidoutw(unsignedshortword,unsignedport)

读字节端口(32位):unsignedinl(unsignedport)

写字节端口(32位):voidoutl(unsignedlongword,unsignedport)

3)释放

当用完一组IO端口(通常在驱动卸载时),应使用如下函数把它们返还给系统:

voidrelease_region(unsignedlongstart,unsignedlongn)

操作IO内存

步骤:

1)申请IO端口

核心函数:

structresource*request__mem_region(unsignedlongstart,unsignedlonglen,constchar*name)

start

IO内存的起始地址

len

长度为len字节的内存区

name

操作这个IO端口的设备名字

申请成功

返回非NULL

申请失败

返回NULL

系统中端口的分配情况记录在/proc/iomem中,如果不能分配需要的端口,可以来这里查看谁在使用!!

映射IO内存

2)映射IO内存

在申请了IO内存之前,仅仅是申请了物理地址。

在访问IO内存之前,必须进行物理地址到虚拟地址的映射

使用函数(常用):

void*ioremap(unsignedlongphys_addr,unsignedlongsize)

访问IO内存

3)访问IO内存

2.6内核

IO内存读,使用下列之一:

unsignedioread8(void*addr)

unsignedioread16(void*addr)\

unsignedioread32(void*addr)

写到IO内存,使用下列之一:

voidiowrite8(u8value,void*addr)

voidiowrite16(u16value,void*addr)

voidiowrite32(u32value,void*addr)

2.4内核

IO内存读,使用下列之一:

unsignedreadb(address)

unsignedreadw(address)

unsignedreadl(address)

写到IO内存,使用下列之一:

unsignedwriteb(unsignedvalue,address)

unsignedwritew(unsignedvalue,address)

unsignedwritel(unsignedvalue,address)

4)释放IO内存

步骤:

1voidiounmap(void*addr)

2void release_mem_region(unsignedlongstart,unsignedlonglen)

你可能感兴趣的:(linux)