本文共 2955 字,大约阅读时间需要 9 分钟。
本文将介绍在EXYNOS4412平台上实现对LED灯开关的控制
首先定义命令在led.h文件中
#define LED_MAGIC 'L'#define LED_ON _IO(LED_MAGIC,1)#define LED_OFF _IO(LED_MAGIC,0)
LED2对应控制寄存器为GPL2
LED3对应控制寄存器为GPK1 接下来编写led控制驱动程序#include#include #include #include #include #include "led.h"#define GPL2CON 0x11000100 //GPL2CON寄存器的物理地址#define GPL2DAT 0x11000104 //GPL2DAT寄存器的物理地址#define GPK1CON 0x11000060//GPK1CON寄存器的物理地址#define GPK1DAT 0x11000064//GPK1DAT寄存器的物理地址static int *pgpl2con;static int *pgpl2dat;static int *pgpk1con;static int *pgpk1dat;struct cdev cdev;dev_t devno;int led_open(struct inode *node, struct file *filp){ pgpl2con = ioremap(GPL2CON,4);//将物理地址转化为虚拟地址 pgpl2dat = ioremap(GPL2DAT,4); pgpk1con = ioremap(GPK1CON,4); pgpk1dat = ioremap(GPK1DAT,4); writel((readl(pgpl2con)& ~(0xf<<0)) |(0x1<<0),pgpl2con); //led2对应GPL2寄存器的第0位,将其写0x1配置为输出模式 writel((readl(pgpk1con)& ~(0xf<<4)) |(0x1<<4),pgpk1con); // led3对应GPK1寄存器的第0位,将其写0x1配置为输出模式 return 0;}long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ switch (cmd) { case LED_ON: writel(readl(pgpl2dat) |(0x1<<0), pgpl2dat); //led2对应GPL2寄存器的第0位,将其写0x1配置为高电平 writel(readl(pgpk1dat) |(0x1<<1), pgpk1dat); //led2对应GPk1寄存器的第0位,将其写0x1配置为高电平 printk("OPEN is success\n"); break; case LED_OFF: writel(readl(pgpl2dat) &(~(0x1<<0)), pgpl2dat); //led2对应GPL2寄存器的第0位,将其0x1取反为0配置为低电平 writel(readl(pgpk1dat) &(~(0x1<<1)), pgpk1dat); //led2对应GPK1寄存器的第0位,将其0x1取反为0配置为低电平 printk("close is success\n"); break; default: return -EINVAL; }}/*文件操作结构体*/static struct file_operations led_fops ={ .open = led_open, .unlocked_ioctl = led_ioctl,};/*设备驱动模块加载函数*/static int led_init(){ cdev_init(&cdev,&led_fops);*初始化cdev结构*/ alloc_chrdev_region(&devno, 0 , 1 , "myled"); /* 注册字符设备 */ cdev_add(&cdev, devno, 1); return 0;}static void led_exit(){ cdev_del(&cdev); /*注销设备*/ unregister_chrdev_region(devno,1);/*释放设备号*/}module_init(led_init);module_exit(led_exit);
应用程序
led_app.c#include#include #include #include #include "led.h"#include int main(int argc,char *argv[]){ int fd; int cmd; if(argc<2) { printf("please input second para\n"); return 0; } cmd = atoi(argv[1]); fd = open("/dev/myled0",O_RDWR); if(cmd ==1) ioctl(fd,LED_ON); if(cmd==0) ioctl(fd,LED_OFF); return 0;}
编写Makefile,通过make编译该驱动程序生成led.ko文件。
使用arm-none-linux-gnueabi-gcc led_app.c -o led_app -static编译应用程序文件,使用 tftp将led.ko ,led_app下载到开发板中 [root@iTOP-4412]# insmod led.ko [root@iTOP-4412]# mknod /dev/myled0 c 249 0 [root@iTOP-4412]# ./led_app 0 [ 26.834348] close is success [root@iTOP-4412]# ./led_app 1 [ 31.561757] OPEN is success