分配 I/O 内存并不是访问该内存之前唯一需要的步骤。您还必须确保内核可以访问此 I/O 内存。所以必须先建立一个映射。这就是ioremap函数的作用。
void *ioremap(unsigned long phys_addr, unsigned long size);
void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
void iounmap(void * addr);
该函数专门用于为 I/O 内存区域分配虚拟地址。
获取 I/O 内存的正确方法是通过为此目的提供的一组函数(通过 定义)。
要从 I/O 内存中读取,请使用以下方法之一:
unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);
这里,addr应该是从ioremap获取的地址,返回值是从给定的I/O内存中读取的。
有一组类似的函数用于写入 I/O 内存:
void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);
举个例子:
void __iomem *io = ioremap(PHYSICAL_ADDRESS, SZ_4K);
iowrite32(value, io);
另一方面,您可以在用户空间中这样做:
static volatile uint32_t *gpio = NULL;
int fd;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) return -1;
gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
if ((int32_t)gpio == -1) return -1;
*(gpio + n) = value;