微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > [ARM笔记]设备IO端口和IO内存的访问

[ARM笔记]设备IO端口和IO内存的访问

时间:12-05 来源:互联网 点击:

设备通常会提供一组寄存器来用于控制设备、读写设备和获取设备状态,即控制寄存器、数据寄存器和状态寄存器。这些寄存器可能位于IO空间,也可能位于内存空间。当位于IO空间时,通常被称为IO端口,位于内存空间时,对应的内存空间成为IO内存。

1. Linux IO端口和IO内存访问接口

1.1 IO端口

在Linux设备驱动中,应使用Linux内核提供的函数来访问定位于IO空间的端口,这些函数包括如下几种:

(1)读写字节端口(8位宽)

unsigned inb(unsigned port);

void outb(unsigned char byte , unsigned port);

(2)读写字端口(16位宽)

unsigned inw(unsigned port);

void outw(unsigned char byte , unsigned port);

(3)读写长字端口(32位宽)

unsigned inl(unsigned port);

void outl(unsigned char byte , unsigned port);

(4)读写一串字

void insw(unsigned port , void *addr , unsigned long count);

void outsw(unsigned port , void *addr , unsigned long count);

(5)读写一串长字

void insl(unsigned port , void *addr , unsigned long count);

void outsl(unsigned port , void *addr , unsigned long count);

上述各函数中IO端口号port的类型高度依赖于具体的硬件平台,因此,只是写出了unsigned。

1.2 IO内存

在内核中访问IO内存之前,需首先使用ioremap()函数将设备所处的物理地址映射到虚拟地址。ioremap的原型如下:

void *ioremap(unsigned long offset , unsigned long size);

ioremap()与vmalloc()类似,也需要建立新的页表,但是它并不进行vmalloc()中所执行的内存分配行为。ioremap()返回一个特殊的虚拟地址,该地址可用来存取特定的物理地址范围。通过ioremap()获得的虚拟地址应该被iounmap()函数释放,其原型为:

void iounmap(void *addr);

在设备的物理地址被映射到虚拟地址之后,尽管可以直接通过指针访问这些地址,但是可以使用Linux内核的如下一组函数来完成设备内存映射的虚拟地址的读写,这些函数如下所示。

(1)读IO内存

unsigned int ioread8(void *addr);

unsigned int ioread16(void *addr);

unsigned int ioread32(void *addr);

与上述函数对应的较早版本的函数为(这些函数在Linux2.6中仍然被支持):

unsigned readb(address);

unsigned readw(address);

unsigned readl(address);

(2)写IO内存

void iowrite8(u8 value , void *addr);

void iowrite16(u16 value , void *addr);

void iowrite32(u32 value , void *addr);

与上述函数对应的较早版本的函数为(这些函数在Linux2.6中仍然被支持):

unsigned writeb(address);

unsigned writew(address);

unsigned writel(address);

(3)读一串IO内存

void ioread8_rep(void *addr , void *buf , unsigned long count);

void ioread16_rep(void *addr , void *buf , unsigned long count);

void ioread32_rep(void *addr , void *buf , unsigned long count);

(4)写一串IO内存

void iowrite8_rep(void *addr , void *buf , unsigned long count);

void iowrite16_rep(void *addr , void *buf , unsigned long count);

void iowrite32_rep(void *addr , void *buf , unsigned long count);

(5)复制IO内存

void memcpy_fromio(void *dest , void *source , unsigned int count);

void memcpy_toio(void *dest , void *source , unsigned int count);

(6)设置IO内存

void memset_io(void *addr , u8 value , unsigned in

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top