led子系统之实战篇(实际led驱动编写)
2015-10-14 15:52
417 查看
led驱动应该是linux驱动中是最简单的一个,下面实际讲解关于led驱动编写的过程。
早期的led驱动实际上在/dev/led生成文件,当led成为一个单独的子系统时,我们要用到led的子系统以及相关的函数
每个平台上的注册函数都是不一样的,但是实际上我们的目的嗾使一样的,那就是使用户空间的能够访问到这些device,其实关键有几步需要注意
1. 定义dirver,比如我们是spmi总线上的,一般有spmi_driver,有的平台是挂在paltform总线上的,就是使用platform_driver定义的,并且对内部的元素进行填充或者是初始化;
2.调用总线驱动注册函数,当总线上已经存在相同的name(一般)device已经挂载上,那么当driver注册的时候会遍历所有总线上的device,当找到相同的时,这个相同取决于总线的match函数,一般比较的是name,相同时返回1,然后调用驱动中的probe函数
3.在probe函数中,我们要针对led_classdev 的变量进行初始化,一般初始化的的brightness_set,brightness_get,name,其中name是实际生成的leds下的子目录的名字。
4.调用led_classdev_register(struct device *parent, struct led_classdev *led_cdev)函数,则大功告成。
当然了1,2步骤可以不用的,我们完全可以将led_classdev_register函数的调用放在其他的比如lcd背光的probe函数中,或者是按键的probe函数中,我们要的只是在用户空间能生成对应的访问接口。
可以看到在class/leds下有calr_wang_led的目录,我们仅仅需要访问的是brightness,输入echo 255 > brightness 然后cat brightness ,看看是不是255。
早期的led驱动实际上在/dev/led生成文件,当led成为一个单独的子系统时,我们要用到led的子系统以及相关的函数
#include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/spmi.h> 头文件不说了
static struct led_classdev led_cdev; //直接定义led_classdev的变量
<pre name="code" class="cpp">static void carl_wang_led_set(struct led_classdev *led_cdev, enum led_brightness value) { led_cdevbrightness = value; //赋值操作,当对led的文件写时会调用这个函数,剩余的操作和平台相关</span> } static enum led_brightness carl_wang_led_get(struct led_classdev * led_dev) { return led_cdev.brightness; //读取操作,当cat时会调用 } static int carl_wang_led_probe(struct spmi_device *dev ) { int ret; led_cdev.brightness_set = carl_wang_led_set; //函数指针赋值 led_cdev.brightness_get = carl_wang_led_get; led_cdev.name = "carl_wang_led"; //在sys/class/leds/ 生成carl_wang_led的目录 /* register our new led device */ ret = led_classdev_register(&dev->dev, &led_cdev); //led class 的注册 if (ret < 0) { dev_err(&dev->dev, "led_classdev_register failed\n"); return ret; } return 0; } static int carl_wang_led_remove(struct spmi_device * dev) { led_classdev_unregister(&led_cdev); return 0; } #ifdef CONFIG_OF static struct of_device_id spmi_match_table[] = {{ .compatible = "qcom,leds-qpnp",},{ },}; #else# define spmi_match_table NULL #endif static struct spmi_driver carl_wang_led_driver = { .probe = carl_wang_led_probe, //device和device_driver匹配到后调用的函数 .remove = carl_wang_led_remove, .driver = { .name = "qcom,leds-qpnp", //spmi总线上一定要有与之对应的相同name(名字)的device .owner = THIS_MODULE, .of_match_table = spmi_match_table, //和name的作用一样,用于匹配device和device_driver的凭证},}; static int __init qpnp_led_init(void) { return spmi_driver_register(&carl_wang_led_driver); //高通平台专有的spmi的总线注册驱动的函数 }module_init(qpnp_led_init); static void __exit qpnp_led_exit(void) {spmi_driver_unregister(&carl_wang_led_driver);}module_exit(qpnp_led_exit); MODULE_AUTHOR("carl_wang@unicair"); MODULE_DESCRIPTION("carl_wang LED driver"); MODULE_LICENSE("GPL");
每个平台上的注册函数都是不一样的,但是实际上我们的目的嗾使一样的,那就是使用户空间的能够访问到这些device,其实关键有几步需要注意
1. 定义dirver,比如我们是spmi总线上的,一般有spmi_driver,有的平台是挂在paltform总线上的,就是使用platform_driver定义的,并且对内部的元素进行填充或者是初始化;
2.调用总线驱动注册函数,当总线上已经存在相同的name(一般)device已经挂载上,那么当driver注册的时候会遍历所有总线上的device,当找到相同的时,这个相同取决于总线的match函数,一般比较的是name,相同时返回1,然后调用驱动中的probe函数
3.在probe函数中,我们要针对led_classdev 的变量进行初始化,一般初始化的的brightness_set,brightness_get,name,其中name是实际生成的leds下的子目录的名字。
4.调用led_classdev_register(struct device *parent, struct led_classdev *led_cdev)函数,则大功告成。
当然了1,2步骤可以不用的,我们完全可以将led_classdev_register函数的调用放在其他的比如lcd背光的probe函数中,或者是按键的probe函数中,我们要的只是在用户空间能生成对应的访问接口。
可以看到在class/leds下有calr_wang_led的目录,我们仅仅需要访问的是brightness,输入echo 255 > brightness 然后cat brightness ,看看是不是255。
相关文章推荐
- iOS学习笔记11-Xcode启动基本介绍
- Jenkins之全局配置
- vertical-align各属性对比
- ubuntu开机自启动脚本编写
- 理解 python 装饰器
- hadoop-2.7.1 datanode
- 高端内存永久映射分析
- 深入理解Android之Gradle
- spring中注解的实现原理,帮助理解@autowired @resource区别
- Android游戏开发学习②焰火绽放效果实现方法
- 11g RAC LBA load balancing advisory
- [Android UI] graphics
- Unity3D研究院之手游开发中所有特殊的文件夹
- Myeclipse 全局搜索的时候报错problems encountered during text search
- WIN 系统操作快捷键大全
- Chrome浏览器扩展开发系列之十七:扩展中可用的chrome.events API
- tchar
- Android SDK国内镜像
- OOM(out_of_memory) killer分析
- opengl es学习笔记3(EGL使用流程,EGL命令)