我正在研究rasberry pi board。是否可以直接访问GPIO物理地址 从Linux内核空间使用inb(),outb()......?如果是的话怎么样?。
GPIO寄存器地址链接 第90页 http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
谢谢
答案 0 :(得分:10)
是
ioremap
readl/writel
来操纵物理内存。请注意ARM处理器在未对齐访问时会出错。 Linux处理得很好,但性能下降。
微小的例子:
void __iomem *regs = ioremap(0xdead0000, 4);
pr_info("0xdead0000: %#x\n", readl(regs));
iounmap(regs);
答案 1 :(得分:5)
在访问内存之前,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;