一、地址映射
1、Linux驱动开发也可以实现操作寄存器来实现功能,但是没办法直接对寄存器的物理地址进行读写操作,但是可以通过MMU来实现。
2、MMU:内存管理单元。老版本的Linux要求处理器必须带有MMU,常说STM32不能跑Linux是因为没有MMU,但是比较新的的H7系列其实是可以跑的,新版本的Linux已经可以不要求带有MMU。MMU主要的功能有: 1)实现虚拟地址到物理地址的映射 2)内存保护 等功能。在Linux中操作是虚拟地址,所以首先是拿到物理地址并将其转换成虚拟地址。
3、关于地址的映射这里我们用到两个函数:ioremap函数和iounmap函数。首先是ioremap函数:ioremap(cookie,size),cookie是需要映射的物理地址的首地址,size是映射的内存空间大小。然后是iounmap函数:iounmap (volatile void __iomem *addr),函数参数就是需要取消映射的虚拟地址空间首地址。
二、驱动程序编写
1、初始化时钟和IO端口。
2、编写驱动接口函数。
3、编写应用程序。
三、测试
1、加载驱动到开发板,通过写1写0控制led亮灭。
retvalue = copy_from_user(databuf, buf, count);
led_switch(databuf[0]);
#define LEDOFF 0
#define LEDON 1
/*led打开关闭函数*/
static void led_switch(unsigned char sta) {
unsigned int val = 0;
if (sta == LEDON) {
val = readl(GPIO1_DR);
val &= ~(1 << 3); /*清零打开led灯*/
writel(val, GPIO1_DR);
val = readl(GPIO1_DR);
val &= ~(1 << 3); /*清零打开led灯*/
writel(val, GPIO1_DR);
} else if (sta == LEDOFF) {
val = readl(GPIO1_DR);
val |= (1 << 3);
writel(val, GPIO1_DR);
}
}
/lib/modules/4.1.15 # ./ledAPP /dev/led 0
/lib/modules/4.1.15 # ./ledAPP /dev/led 1