现在的位置: 首页 > 综合 > 正文

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

2018年02月07日 ⁄ 综合 ⁄ 共 3796字 ⁄ 字号 评论关闭

寄存器与内存

他们的区别在哪里呢?

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

内存与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端口

核心函数:

struct resource *request_region(unsigned long first, unsigned long n, const char *name)

first

第一个IO端口的地址

n

要申请多少个IO

name

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

申请成功

返回非NULL

申请失败

返回NULL

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

2)访问

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

在头文件<asm/io.h>

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

读字节端口(8位):unsigned inb(unsigned port)  

写字节端口(8位):void outb(unsigned char byte, unsigned port)

读字节端口(16位):unsigned inw(unsigned port)  

写字节端口(16位):void outw(unsigned short word, unsigned port)

读字节端口(32位):unsigned inl(unsigned port)  

写字节端口(32位):void outl(unsigned long word, unsigned port)

3)释放

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

void release_region(unsigned long start, unsigned long n)

操作IO内存

步骤:

1)申请IO端口

核心函数:

struct resource *request__mem_region(unsigned long start, unsigned long len, const char *name)

start

IO内存的起始地址

len

长度为len字节的内存区

name

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

申请成功

返回非NULL

申请失败

返回NULL

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

映射IO内存

2)映射IO内存

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

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

使用函数(常用):

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

访问IO内存

3)访问IO内存

2.6内核

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

unsigned ioread8(void *addr)

unsigned ioread16(void *addr)\

unsigned ioread32(void *addr)

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

void iowrite8(u8 value, void *addr)

void iowrite16(u16 value, void *addr)

void iowrite32(u32 value, void *addr)

2.4内核

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

unsigned readb(address)

unsigned readw(address)

unsigned readl(address)

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

unsigned writeb(unsigned value, address)

unsigned writew(unsigned value, address)

unsigned writel(unsigned value, address)

4)释放IO内存

步骤:

1void iounmap(void *addr)

2void  release_mem_region(unsigned long start, unsigned long len)

寄存器与内存

他们的区别在哪里呢?

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

内存与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端口

核心函数:

struct resource *request_region(unsigned long first, unsigned long n, const char *name)

first

第一个IO端口的地址

n

要申请多少个IO

name

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

申请成功

返回非NULL

申请失败

返回NULL

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

2)访问

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

在头文件<asm/io.h>

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

读字节端口(8位):unsigned inb(unsigned port)  

写字节端口(8位):void outb(unsigned char byte, unsigned port)

读字节端口(16位):unsigned inw(unsigned port)  

写字节端口(16位):void outw(unsigned short word, unsigned port)

读字节端口(32位):unsigned inl(unsigned port)  

写字节端口(32位):void outl(unsigned long word, unsigned port)

3)释放

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

void release_region(unsigned long start, unsigned long n)

操作IO内存

步骤:

1)申请IO端口

核心函数:

struct resource *request__mem_region(unsigned long start, unsigned long len, const char *name)

start

IO内存的起始地址

len

长度为len字节的内存区

name

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

申请成功

返回非NULL

申请失败

返回NULL

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

映射IO内存

2)映射IO内存

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

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

使用函数(常用):

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

访问IO内存

3)访问IO内存

2.6内核

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

unsigned ioread8(void *addr)

unsigned ioread16(void *addr)\

unsigned ioread32(void *addr)

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

void iowrite8(u8 value, void *addr)

void iowrite16(u16 value, void *addr)

void iowrite32(u32 value, void *addr)

2.4内核

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

unsigned readb(address)

unsigned readw(address)

unsigned readl(address)

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

unsigned writeb(unsigned value, address)

unsigned writew(unsigned value, address)

unsigned writel(unsigned value, address)

4)释放IO内存

步骤:

1void iounmap(void *addr)

2void  release_mem_region(unsigned long start, unsigned long len)

抱歉!评论已关闭.