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()函数,理解模块驱动跟裸板驱动的不同,掌握物理内存到虚拟内存的映射关系;

 

posted @ 2015-09-12 13:56  zhangwju  阅读(1123)  评论(0编辑  收藏  举报