【转】Linux嵌入式系统开发之Led开发---驱动篇
时间:2010-11-08
来源:互联网
作者:☆&寒 烟☆
“小涛哥,你给我说说昨天那个Led驱动吧,我知道咋用程序点亮它了,可是调用的是驱动,我就是一个命令,感觉不知道究竟怎么弄的..”小王央求道。
“这样啊, 那也行,要不咱们这样以后,就讲一次应用,然后就讲与之相关的驱动开发,趁着应用的热度,顺便把驱动学了…”我想想说。
“好好,那今天就开始昨天的那个Led驱动程序开发吧…”
首先需要说明的是LED设备是个字符设备,这就和咱们本博客的linux设备驱动开发里的字符设备驱动关联起来了,不懂,就自己去看了,开始今天的重点内容.在mini24
40中LED链接线使用引脚GPB5~8外接4个LED,操作方法是:
1)引脚功能设为输出。 2)要点亮LED,令引脚输出为0. 3)要熄灭LED,令引脚输出为1.
好了下边,给出详细的源码注释:
复制代码
小王,上面的代码看清楚了吗,那么怎么使用呢,使用方法有两种(假设保存为leds_control.c):
方法一:
将代码放到内和drivers/char目录下,在drivers/char/Makefile中增加一行obj-m += leds_control.o,然后在内核根目录下执行make modules,就可以生成模块drivers/char/leds_control.ko。
方法二:
直接在当前驱动源码目录下,建立Makefile文件,内容如下:
CROSS=arm-linux-
#依赖的内核源代码目录,不一定是当前系统的,要是开发板系统源码的目录
KERNELDIR = /opt/linux-2.6.32.2
PWD := $(shell pwd)
.PHONY:
<tab>modules clean
obj-m += leds_control.o
modules:
<tab>$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
<tab>rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
然后执行make,可以看到在当前目录下也会生成leds_control.ko.
OK,小王,看到没,通过以上两不,生成了leds_control.ko,下面就用ftp下载到开发板上,用:
insmod ./leds_control.ko
mknod /dev/leds_control c 150 0
就建好了驱动模块和设备节点,应用程序调用那就是上一篇的事了…
“嗯,我明白了,你这样一说,我几乎都明白了,led的前前后后的工作模式,不要和你说了,我也抓紧时间调调我的自己LED驱动”小王娇气的说。
“小涛哥,你给我说说昨天那个Led驱动吧,我知道咋用程序点亮它了,可是调用的是驱动,我就是一个命令,感觉不知道究竟怎么弄的..”小王央求道。
“这样啊, 那也行,要不咱们这样以后,就讲一次应用,然后就讲与之相关的驱动开发,趁着应用的热度,顺便把驱动学了…”我想想说。
“好好,那今天就开始昨天的那个Led驱动程序开发吧…”
首先需要说明的是LED设备是个字符设备,这就和咱们本博客的linux设备驱动开发里的字符设备驱动关联起来了,不懂,就自己去看了,开始今天的重点内容.在mini24
40中LED链接线使用引脚GPB5~8外接4个LED,操作方法是:
1)引脚功能设为输出。 2)要点亮LED,令引脚输出为0. 3)要熄灭LED,令引脚输出为1.
好了下边,给出详细的源码注释:
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <asm/irq.h>
- #include <mach/regs-gpio.h>
- #include <machhardware.h>
- #include <linux/gpio.h>
-
- #define DEVICE_NAME "leds_control" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
- #define LED_MAJOR 231 /* 主设备号 */
- #define IOCTL_LED_ON 0 /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
- #define IOCTL_LED_OFF 1
-
- static unsigned long led_table [] = { /* 用来指定LED所用的GPIO引脚 */
- S3C2410_GPB(5),
- S3C2410_GPB(6),
- S3C2410_GPB(7),
- S3C2410_GPB(8),
- };
-
- static unsigned int led_cfg_table [] = { /* 用来指定GPIO引脚的功能:输出 */
- S3C2410_GPIO_OUTP,
- S3C2410_GPIO_OUTP,
- S3C2410_GPIO_OUTP,
- S3C2410_GPIO_OUTP,
- };
-
- //应用程序对设备文件/dev/leds执行open(...)时,就会调用s3c2410_leds_open函数
- static int s3c2410_leds_open(struct inode *inode, struct file *file)
- {
- int i;
- for (i = 0; i < 4; i++) {
- // 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能
- s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
- }
- return 0;
- }
-
- //应用程序对设备文件/dev/leds执行ioclt(...)时,就会调用s3c2410_leds_ioctl函数
- static int s3c2410_leds_ioctl(
- struct inode *inode,
- struct file *file,
- unsigned int cmd,
- unsigned long arg)
- {
- if (arg > 4) {
- return -EINVAL;
- }
- switch(cmd) {
- case IOCTL_LED_ON:
- // 设置指定引脚的输出电平为0
- s3c2410_gpio_setpin(led_table[arg], 0);
- return 0;
-
- case IOCTL_LED_OFF:
- // 设置指定引脚的输出电平为1
- s3c2410_gpio_setpin(led_table[arg], 1);
- return 0;
-
- default:
- return -EINVAL;
- }
- }
-
- //字符设备驱动程序的核心,当应用程序操作设备文件时所调用的open、read、write等函数,最终会调用这个结构中指定的对应函数
- static struct file_operations s3c2410_leds_fops = {
- .owner = THIS_MODULE,
- .open = s3c2410_leds_open,
- .ioctl = s3c2410_leds_ioctl,
- };
-
- //执行“insmod s3c2410_leds.ko”命令时就会调用这个函数
- static int __init s3c2410_leds_init(void)
- {
- int ret;
-
- /* 注册字符设备驱动程序
- * 参数为主设备号、设备名字、file_operations结构;
- * 这样,主设备号就和具体的file_operations结构联系起来了,
- * 操作主设备为LED_MAJOR的设备文件时,就会调用s3c24xx_leds_fops中的相关成员函数
- * LED_MAJOR可以设为0,表示由内核自动分配主设备号
- */
- ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c2410_leds_fops);
- if (ret < 0) {
- printk(DEVICE_NAME " can't register major number\n");
- return ret;
- }
- printk(DEVICE_NAME " initialized\n");
- return 0;
- }
-
- //执行”rmmod s3c24xx_leds.ko”命令时就会调用这个函数
- static void __exit s3c2410_leds_exit(void)
- {
- unregister_chrdev(LED_MAJOR, DEVICE_NAME);/* 卸载驱动程序 */
- }
-
- module_init(s3c2410_leds_init); /* 指定驱动程序的初始化函数和卸载函数 */
- module_exit(s3c2410_leds_exit);
方法一:
将代码放到内和drivers/char目录下,在drivers/char/Makefile中增加一行obj-m += leds_control.o,然后在内核根目录下执行make modules,就可以生成模块drivers/char/leds_control.ko。
方法二:
直接在当前驱动源码目录下,建立Makefile文件,内容如下:
CROSS=arm-linux-
#依赖的内核源代码目录,不一定是当前系统的,要是开发板系统源码的目录
KERNELDIR = /opt/linux-2.6.32.2
PWD := $(shell pwd)
.PHONY:
<tab>modules clean
obj-m += leds_control.o
modules:
<tab>$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
<tab>rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
然后执行make,可以看到在当前目录下也会生成leds_control.ko.
OK,小王,看到没,通过以上两不,生成了leds_control.ko,下面就用ftp下载到开发板上,用:
insmod ./leds_control.ko
mknod /dev/leds_control c 150 0
就建好了驱动模块和设备节点,应用程序调用那就是上一篇的事了…
“嗯,我明白了,你这样一说,我几乎都明白了,led的前前后后的工作模式,不要和你说了,我也抓紧时间调调我的自己LED驱动”小王娇气的说。
作者: cu_Cbear 发布时间: 2010-11-08
有点意思!!!!顶楼主
作者: xuyun1227 发布时间: 2010-11-09
QUOTE:
有点意思!!!!顶楼主
xuyun1227 发表于 2010-11-09 13:15
xuyun1227 发表于 2010-11-09 13:15
写的有意思,我借点光,哈哈
作者: cu_Cbear 发布时间: 2010-11-09
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28