1、浅谈linux驱动3linux系统下led驱动浅谈linux驱动(3)-linux系统下led驱动2012年02月21日 23:13:52首先我提一下我过程中遇到的一些问题。1.led驱动模块的编译2.led驱动内核模块的安装3.开发板nand的意外处理4.当前linux kerner版本与led内核模块版本的一致性接下来我来谈谈具体我做的一个过程看原理图之前我先略微的讲下什么上拉电阻下拉电阻,下面会用到上拉是将不确定的信号通过一个电阻与电源相连,固定在高电平。下拉是将不确定的信号通过一个电阻与地相连,固定在低电平。上拉是对器件注入电流,下拉是对器件导出电流,当一个接有上拉电阻的I/O端口设置
2、为输入状态的时候,它的常态为高电平,可用于检测低电平的输入。首先看LED的原理图从上面的原理图可以得知,LED与CPU引脚的连接方法如下,低电平点亮。LED1-GPM0LED2 -GPM1LED3-GPM2LED4-GPM3s3c6410包含GPA,GPB,GPC.GPQ17组I/O端口,我这里也没有读完上s3c6410的datasheet,主要看了下led的寄存器的三个功能GPMCON用来设置端口功能,(00表示输入,01表示输出,10表示特殊功能,11表示保留不用),GPMDAT用来读/写数据,GPMPUD用来决定是否内部使用上拉电阻,某位为0时,相应引脚无内部上拉,某位为1时候,相应引脚
3、内部上拉)。s3c6410_leds.c程序代码/#include /*包涵内核中的多个头文件,以下头文件都是内核当中已经存在的*/#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEVICE_NAME leds /*定义设备名字为leds*/#define LED_MAJOR 231 /*定义led主设备号为231*/ static unsigned long led_tab
4、le = S3C64XX_GPM(0), S3C64XX_GPM(1), S3C64XX_GPM(2), S3C64XX_GPM(3),; static unsigned int led_cfg_table = S3C64XX_GPM_OUTPUT(0), S3C64XX_GPM_OUTPUT(1), S3C64XX_GPM_OUTPUT(2), S3C64XX_GPM_OUTPUT(3),;/*这里IOCTL的工作大概分两个步骤,定义命令,执行命令,但大家会发现这里并有defineIOCTL,但是我们会发现下面的case0,case1,这里其实是直接用定义为了数字,比如0表示灯灭,1表示灯亮
5、*/static int s3c6410_leds_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) unsigned long tmp; switch(cmd) case 0: case 1: if (arg 4) return -EINVAL; tmp = _raw_readl(S3C64XX_GPMDAT); if(cmd) tmp &= (1arg); else tmp |= (1arg); _raw_writel(tmp,S3C64XX_GPMDAT);/ gpio_
6、set_value(led_tablearg, !cmd); return 0; default: return -EINVAL; /*struct file_operations函数来定义我们能进行哪些操作,比如IOCTL*/static struct file_operations s3c6410_leds_fops = .owner = THIS_MODULE, .ioctl = s3c6410_leds_ioctl,;/*大家可以上去看一下s3c6410_leds_ioctl的定义*/ static struct cdev cdev_leds;struct class * my_cla
7、ss; static int _init s3c6410_leds_init(void) /*函数初始化,配置I/O口的模式*/ int ret; unsigned long tmp; int i; dev_t devno; printk(KERN_NOTICE enter s3c6410_leds_initn); devno = MKDEV(LED_MAJOR,0); ret = register_chrdev_region(devno,1,DEVICE_NAME);/*注册LED设备*/ ret = 0; if(ret0) printk(KERN_NOTICE can not regist
8、er led device); return ret; cdev_init(&cdev_leds,&s3c6410_leds_fops); cdev_leds.owner = THIS_MODULE; ret =cdev_add(&cdev_leds,devno,1); if(ret) printk(KERN_NOTICE can not add leds device); return ret; my_class = class_create(THIS_MODULE,my_class); if(IS_ERR(my_class) printk(Err: Failed in creating c
9、lassn); return -1; device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME); /gpm0-3 pull up tmp = _raw_readl(S3C64XX_GPMPUD); tmp &= (0xFF); tmp |= 0xaa; _raw_writel(tmp,S3C64XX_GPMPUD); /gpm0-3 output mode tmp = _raw_readl(S3C64XX_GPMCON); tmp &= (0xFFFF); tmp |= 0x1111; _raw_writel(tmp,S3
10、C64XX_GPMCON); /gpm0-3 output 0 tmp = _raw_readl(S3C64XX_GPMDAT); tmp |= 0x10; _raw_writel(tmp,S3C64XX_GPMDAT); /printk(S3C64XX_GPMCON is %xn,_raw_readl(S3C64XX_GPMCON); /printk(S3C64XX_GPMDAT is %xn,_raw_readl(S3C64XX_GPMDAT); /printk(S3C64XX_GPMPUD is %xn,_raw_readl(S3C64XX_GPMPUD); printk(DEVICE_
11、NAME initializedn); return 0; static void _exit s3c6410_leds_exit(void) /*模块卸载函数,大家可以参考我前一篇字符设备驱动*/ cdev_del(&cdev_leds); /*删除字符设备结构体*/ unregister_chrdev_region(MKDEV(LED_MAJOR,0),1); /*释放设备号*/ printk(KERN_NOTICE s3c6410_leds_exitn); module_init(s3c6410_leds_init);/*首先从这里开始分析,这里是驱动程序的初始化函数*/ module_
12、exit(s3c6410_leds_exit); MODULE_LICENSE(GPL);因为我这里不想直接编译进内核,所以采取内核模块加载的方式把led的内核模块加载进内核,那么我这里就要自己写一个简单的makefilemakefile这里相对来说还是比较简单的,这个可以当做一个模板,因为需要修改的仅仅是obj -m :=s3c6410_leds.o 我的C文件就是s3c6410_leds.c .还有就是修改KDIR的路径,改成当前内核源码的路径。然后我make,结果出错了我看了我下makefile是没问题的,但是看到出错信息里面提示的makefile的第一个字母M是大写Makefile,然
13、后我改了下。结果好了接下来我用nfs共享目录来进行led驱动模块向内核进行加载结果是这样不能加载,错误提示里面显示不能创建一个类然后我cat /proc/devices 查看了下,我内核里原本已经有一个LED的驱动了既然这样吧,我决定重新编译个内核,没有led驱动的内核,make menuconfig里面在device drivers里面的char类驱动设备里面把led的驱动设置为M。然后保存退出,编译,make zImage然后把新的内核烧到板子上去接下来再试试加载内核模块好了,终于加载上去了。这里有一个要注意的,你的LED内核模块版本和当前板子上跑的linux系统的内核的版本需要一致才行。如图这是查看的板子上linux内核的版本这是查看的编译的LED驱动模块的版本OK,都是linux2.6.28.6.我早上细看了下内核配置,如图选上这个应该就能解决不同版本的模块的问题了.但不知道是否会出现BUG。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1