LED灯驱动
1、LED灯驱动原理
Linux下的任何外设驱动,最终都是要配置相应的硬件寄存器。本篇是对I.MX6ULL的IO进行配置,点亮LED,涉及到读写寄存器。
2、地址映射
Linux不能直接对寄存器物理地址进行读写操作,因为Linux会使能MMU,完成物理地址到虚拟地址的映射,物理地址和虚拟地址映射用到两个函数:ioremap和iounmap。
2.1、ioremap函数
该函数用于获取指定的物理地址空间对应的虚拟地址空间,定义在arch/arm/include/asm/io.h文件中,ioremap是个宏,定义如下:
#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
参数:
1、物理地址起始大小
2、要映射的字节数量
2.2、ioreunmap函数
1、卸载驱动时需要使用iounmap函数释放掉ioremap函数所做的映射,原型如下:
void iounmap (volatile void __iomem *addr)
2、该函数只有一个参数,就是要取消映射的虚拟地址空间的首地址。
3、I/O内存访问函数
1、这里的I/O是输入输出的意思,不是单片机的GPIO脚。Linux内核提高一组操作函数来对映射后的内存进行读写操作。
2、对寄存器操作的通用方法:读->改->写。
3.1、读操作函数
u8 readb(const volatile void __iomem *addr)
u16 readw(const volatile void __iomem *addr)
u32 readl(const volatile void __iomem *addr)
readb、readw、readl这三个函数分别对应8bit、16bit、32bit读操作,参数addr就是要读写的内存地址,返回值就是读取到数据。
3.2、写操作函数
void writeb(u8 value, volatile void __iomem *addr)
void writew(u16 value, volatile void __iomem *addr)
void writel(u32 value, volatile void __iomem *addr)
writeb、writew、writel这三个函数分别对应8bit、16bit、32bit写操作函数,参数value是写入的数值,addr是要写入的地址。
4、程序编写
4.1、驱动程序
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define LED_MAJOR 200 /* 主设备号 */
#define LED_NAME "xylink_led" /* 设备名字 */
#define LEDOFF 0 /* 关灯 */
#define LEDON