在以前的文章中,有一篇
基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号
在那篇文章中,具体可以参考。那时候我使用了简单的字符设备驱动框架,最终的ID号通过read方法可将ID读取出来,但是,这样做就太麻烦啦,有没有更简单的方法呢?其实有,这种方法称作IO地址的映射,而今天我们要说的是IO地址的动态映射方法,静态映射就太简单了,直接调用相应的接口,配置相应的寄存器,设置状态就可以实现。接下来看看驱动代码:
#if 0 . io地址: . 静态映射: //这个头文件与平台相关,不同平台对应不同的gpio.h,也就是有不同的配置信息 arch/arm/mach-exynos/include/mach/gpio.h gpio ==> S3C64XX_GPx(n) EXYNOS4X12_GPM0() EXYNOS4_GPD0() int gpio_request(gpio, "name"); 申请; void gpio_free(gpio); 撤销; int gpio_direction_output(gpio, dat); 配置为输出, 输出1/0; int gpio_direction_input(gpio); 配置为输入, 输入1/0; int s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(con)); 配置为con; void gpio_set_value(gpio, dat); 输出1/0; int gpio_get_value(gpio); 输入1/0; irqnum = gpio_to_irq(gpio); gpio <==> irqnum MACH_TYPE_TINY4412 /* Initial IO mappings */ static struct map_desc exynos_iodesc[] __initdata = { { .virtual = (unsigned long)S5P_VA_CHIPID, .pfn = __phys_to_pfn(EXYNOS_PA_CHIPID), .length = SZ_4K, .type = MT_DEVICE, }, }; . 动态映射: virt = ioremap(phys, size); //vmalloc_area iounmap(virt); //将虚拟地址转化为32位整型数 ioread32(virt); iowrite32(val, virt); //将虚拟地址转化为16位整型数 ioread16(); iowrite16(); //将虚拟地址转化为8位整型数 ioread8(); iowrite8(); #endif #include <linux/module.h> #include <linux/fs.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/atomic.h> #include <linux/types.h> #include <linux/interrupt.h> #include <linux/kthread.h> #include <linux/slab.h> //和IO相关的头文件 #include <linux/io.h> //板子ID的物理地址 0x10000000 -----> 通过4412的手册查询到 #define CHIP_ID 0x10000000 int test_init(void) { int ret; unsigned int *virt = NULL; printk("test init\n"); //将CHIP_ID的物理地址映射成虚拟地址,分配4个字节的大小给它 virt = ioremap(CHIP_ID, 4); //如果映射完成之后,virt指针为空,返回错误码 if(IS_ERR_OR_NULL(virt)) { ret = -EIO; goto ERROR_map; } //打印虚拟地址 printk("virt = %p\n", virt); //打印物理地址 printk("CHIP_ID = %x\n", CHIP_ID); //将虚拟地址转化为32位整型数 printk("*virt = %x\n", ioread32(virt)); //解除地址映射 iounmap(virt); return 0; ERROR_map: return ret; } void test_exit(void) { printk("test exit\n"); } module_init(test_init); module_exit(test_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("yangyx"); MODULE_VERSION("1.1");
时间: 2024-10-25 10:16:17