一:led内核驱动

  (1)在编写led内核驱动时,我们首先要进行内核裁剪,因为友善之臂将LED灯的驱动默认加载到内核中,所以编写模块驱动程序前就要先把原先的LED灯驱动裁剪掉;

  led驱动在源码里面的Device Drivers /Character devices目录下,进行完裁剪之后重新编译linux源码;

  linux模块驱动之led(ioremap)_物理地址

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