内核提供的读写寄存器接口实现可移植性

来源:互联网 发布:只有粤语的电影软件 编辑:程序博客网 时间:2024/06/05 07:30

内核提供的读写寄存器接口实现可移植性

arm是IO与内存统一编址,其他平台如x86是IO与内存独立编址访问方式不一样,使用内核提供的寄存器读写接口writel\readl具有可移植性

在文章随笔–Linux字符设备驱动开发基础前面写的驱动在静态映射操作寄存器,都用#define rGPJ0CON *((volatile unsigned int *)GPJ0CON)的方式来访问寄存器,这样的做法在驱动中并不是很好,因为这样的做法在不同平台的情况下不具有可移植性。现在写的驱动是在ARM平台下去写的,ARM属于内存和IO统一编址的,在读写寄存器的时候即为进行IO操作,进行IO操作是和读写内存是一样的(IO也有个地址),这就叫统一编址。但是还有另外一些CPU(像x86)是非统一编址的,这种CPU在进行IO操作时的方法跟进行内存的读写的方法是不一样的。那么在这种情况下就有一种问题,如果写的驱动不仅要求在ARM下能够运行,还要求在X86下也要能够运行,如果还用#define rGPJ0CON *((volatile unsigned int *)GPJ0CON)的方式显然是不合适的,需要进行比较大的修改。我们要怎样才能够使他能够具有很强的移植性呢?——内核已经帮我们想好了办法,即内核提供访问寄存器的读写接口(函数),使用这些函数具有可移植性。其实现的原理就是用条件编译,如下比较:

blog007

代码示例(静态映射):

...#include <mach/regs-gpio.h>     //虚拟地址映射表#include <mach/gpio-bank.h> #include <linux/io.h>#include <linux/ioport.h>#define GPJ0CON     S5PV210_GPJ0CON#define GPJ0DAT     S5PV210_GPJ0DAT...    ...    writel(0x11111111, GPJ0CON);    writel(((0<<3) | (0<<4) | (0<<5)), GPJ0DAT);...

代码示例(动态映射):

#include <linux/io.h>#include <linux/ioport.h>...#define GPJ0CON_PA  0xe0200240  //要操作的寄存器的物理地址#define S5P_GPJ0REG(x)      (x)#define S5P_GPJ0CON         S5P_GPJ0REG(0)#define S5P_GPJ0DAT         S5P_GPJ0REG(4)static void __iomem *baseaddr;  // 寄存器的虚拟地址的基地址,用来保存 ioremap的返回值...    ...    if (!request_mem_region(GPJ0CON_PA, 8, "GPJ0BASE"))  //内存资源申请        return -EINVAL;    baseaddr = ioremap(GPJ0CON_PA, 8);    writel(0x11111111, baseaddr + S5P_GPJ0CON);    writel(((0<<3) | (0<<4) | (0<<5)), baseaddr + S5P_GPJ0DAT);...
0 0