linux模块驱动之led(ioremap)
一:led内核驱动
(1)在编写led内核驱动时,我们首先要进行内核裁剪,因为友善之臂将LED灯的驱动默认加载到内核中,所以编写模块驱动程序前就要先把原先的LED灯驱动裁剪掉;
led驱动在源码里面的Device Drivers /Character devices目录下,进行完裁剪之后重新编译linux源码;
(2)ioremap()
define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
编写裸板驱动和编写模块驱动的区别在于,裸板程序直接操作的是物理内存,而模块程序操作 的是虚拟内存,模块程序要操作硬件,肯定是要通过物理地址来操作相应的寄存器的值。这时候,就是要通过ioremap()函数,实现物理地址(IO地址空 间)到虚拟地址的转换。
下面代码实现的是插入模块是:led灯全亮
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/sched.h> 4 #include <linux/io.h> 5 #include <linux/gpio.h> 6 #include <linux/kernel.h> 7 #include <linux/miscdevice.h> 8 #include <asm/uaccess.h> 9 #include <linux/ioport.h> 10 11 MODULE_LICENSE("GPL"); 12 MODULE_AUTHOR("bunfly"); 13 14 unsigned long gpio_virt; 15 unsigned long gpm4con; 16 unsigned long gpm4dat; 17 18 int bunfly_init() 19 { 20 //0x110002e0 0x110002e4 21 void __iomem *p; 22 p = request_mem_region(0x11000000, SZ_4K, "gpio");//注册内存的映射信息 23 if(NULL == p) { 24 printk("request faliure\n"); 25 return 1; 26 } 27 28 gpio_virt = ioremap(0x11000000, SZ_4K);//led物理地址到虚拟地址的映射 29 gpm4con = gpio_virt + 0x02e0 ; 30 gpm4dat = gpio_virt + 0x02e4; 31 32 *(unsigned long *)gpm4con &= ~0xffff; 33 *(unsigned long *)gpm4con |= 0x1111; 34 *(unsigned long *)gpm4dat = 0x0; 35 36 printk("this is bunfly_init\n"); 37 38 return 0; 39 } 40 41 void bunfly_exit() 42 { 43 printk("this is bunfly_exit\n"); 44 iounmap(gpio_virt); 45 release_mem_region(0x11000000, SZ_4K);//注销映射的虚拟内存 46 } 47 48 module_init(bunfly_init); 49 module_exit(bunfly_exit);
今天的重点内容就是ioremap()函数,理解模块驱动跟裸板驱动的不同,掌握物理内存到虚拟内存的映射关系;