驱动框架入门——以LED为例

发布者:Joyful444Life最新更新时间:2025-01-14 来源: cnblogs关键字:驱动框架  LED 手机看文章 扫描二维码
随时随地手机看文章

一、什么是驱动框架?

 

数据结构,这些是驱动框架的直接表现。

 

Linux/init.h中。

 

  • 这个宏的功能是:将其声明的函数放到一个特定的段:.initcall4.init。

 

(2)分析module_init宏,可以看出它将函数放到了.initcall6.init段中。

  • module_init

  •       __initcall

  •             device_initcall

  •                  __define_initcall('6',fn,6)

 

(3)内核在启动过程中,需要按照顺序执行很多事情。内核如何实现按照先后顺序去做很多初始化操作?

 

  • 内核的解决方案就是将内核启动时要调用的所有函数归类,然后每个类按照一定的次序去调用执行。

  • 这些分类名就叫.initcalln.init,n的值从1到8。

  • 内核开发者在编写内核代码时只要将函数设置合适的级别,链接的时候,这些函数就会被放入特定的段,内核启动时再按照(内核链接脚本中指定的)段顺序去依次执行各个段即可。内核链接脚本(编译之后才有)在arch/arm/kernel/vmlinux.lds中。

 

(4)经过分析可以看出,subsys_initcall和module_init的作用是一样的,只不过前者所声明的函数要比后者在内核启动时的执行顺序更早。

 

3、led_class_attrs

 

(1)什么是attribute?

 

  • 对应将来/sys/class/leds/目录里的内容,一般是文件和文件夹。

  • 这些文件其实就是sysfs开放给应用层的一些操作接口(非常类似于/dev/目录下的那些设备文件,对这些设备文件的操作API,对应file_operations里面的函数)。

 

(2)attribute有什么用?

 

  • 让应用程序可以通过/sys/class/leds/目录下面的属性文件来操作驱动进而操作硬件设备。

 

(3)attribute其实是另一条驱动实现的路线(不再有c_dev相关的函数操作),有区别于之前讲的file_operations那条线。

 

 

4、led_classdev_register设备注册函数

 

 

  • led_classdev_register函数创建一个属于leds这个类的一个设备,其实就是去注册一个设备。

  • 这个函数是led驱动框架中,内核开发者提供给SoC厂家驱动开发者的一个注册驱动的接口。

  • 当使用led驱动框架去编写驱动的时候,这个led_classdev_register函数的作用类似于之前使用file_operations方式去注册字符设备驱动时的register_chrdev函数。

  • 之前使用file_operations方式时,在sys/class目录下创建一个类,然后再创建属于这个类的一个设备。

5、led_classdev结构体

 

  • 在leds.h文件中

 

 

四、在内核中添加或去除某个驱动

1、去除九鼎移植的LED驱动

(1)九鼎移植的驱动(在应用层的接口)在/sys/devices/platform/x210-led/目录下,有led1、led2、led3、led4四个设备文件,各自管理一个led。

 

  • echo 1 > led1可以点亮其中的led1;

 

(2)要去掉九鼎自己移植的led驱动,要在make menucofig中去掉选择项,然后重新make得到zImage,然后重启时启动这个新的zImage即可。

 

  • 新的内核启动后,如果/sys/devices/platform/目录下已经没有了x210-led这个目录,就说明我们去掉这个驱动成功了。

 

(3)为什么make menuconfig就能去掉这个驱动?

 

  • 理解make menuconfig的功能。

 

2、添加led驱动框架支持

当前内核中没有LED驱动框架,要去添加它。(/sys/class目录下没有此类,因此要去添加此类)

 

  • 主要是menuconfig的操作。

 

3、sysfs中的内容分析

4、后续展望:完成leds-x210.c





五、基于驱动框架写led驱动1

1、分析

(1)参考哪里?  drivers/leds/leds-s3c24xx.c文件

(2)关键点?led_classdev_register函数

2、动手写led驱动模块

代码如下

注意设备注册函数、设备注销函数

 

  1. #include      // module_init  module_exit  

  2. #include            // __init   __exit  

  3. #include   

  4. #include   

  5. #include   

  6. #include   

  7. #include   

  8. #include   

  9.   

  10.   

  11.   

  12. #define GPJ0CON     S5PV210_GPJ0CON  

  13. #define GPJ0DAT     S5PV210_GPJ0DAT  

  14.   

  15. static struct led_classdev mydev;           // 定义结构体变量  

  16.   

  17.   

  18. // 这个函数就是要去完成具体的硬件读写任务的  

  19. static void s5pv210_led_set(struct led_classdev *led_cdev,enum led_brightness value)  

  20. {  

  21.     printk(KERN_INFO 's5pv210_led_setn');  

  22.       

  23.     // 在这里根据用户设置的值来操作硬件  

  24.     // 用户设置的值就是value  

  25.     if (value == LED_OFF)  

  26.     {  

  27.         // 用户给了个0,希望LED灭  

  28.         writel(0x11111111, GPJ0CON);  

  29.         writel(((1<<3) | (1<<4) | (1<<5)), GPJ0DAT);  

  30.     }  

  31.     else  

  32.     {  

  33.         // 用户给的是非0,希望LED亮  

  34.         writel(0x11111111, GPJ0CON);  

  35.         writel(((0<<3) | (0<<4) | (0<<5)), GPJ0DAT);  

  36.     }  

  37. }  

  38.   

  39.   

  40. static int __init s5pv210_led_init(void)  

  41. {  

  42.     // 用户insmod安装驱动模块时会调用该函数  

  43.     // 该函数的主要任务就是去使用led驱动框架提供的设备注册函数来注册一个设备  

  44.     int ret = -1;  

  45.       

  46.     mydev.name = 'myled';//设备的名字  

  47.     mydev.brightness = 255;   

  48.     mydev.brightness_set = s5pv210_led_set;  

  49.       

  50.     ret = led_classdev_register(NULL, &mydev);  

  51.     if (ret < 0) {  

  52.         printk(KERN_ERR 'led_classdev_register failedn');  

  53.         return ret;  

  54.     }  

  55.       

  56.     return 0;  

  57. }  

  58.   

  59. static void __exit s5pv210_led_exit(void)  

  60. {  

  61.     led_classdev_unregister(&mydev);  

  62. }  

  63.   

  64.   

  65. module_init(s5pv210_led_init);  

  66. module_exit(s5pv210_led_exit);  

  67.   

  68. // MODULE_xxx这种宏作用是用来添加模块描述信息  

  69. MODULE_LICENSE('GPL');                          // 描述模块的许可证  

  70. MODULE_AUTHOR('aston <1264671872@qq.com>');       // 描述模块的作者  

  71. MODULE_DESCRIPTION('s5pv210 led driver');       // 描述模块的介绍信息  

  72. MODULE_ALIAS('s5pv210_led');                    // 描述模块的别名信息  



 

 

六、基于驱动框架写led驱动2

1、代码实践

(1)调试

(2)分析

 

 

 

  • 我们写的驱动确实工作了,被加载了,/sys/class/leds/目录下确实多出来了一个表示设备的文件夹。

  • 文件夹里面有相应的操控led硬件的2个属性brightness和max_brightness。

  • led-class.c中brightness方法有一个show方法和store方法,这两个方法对应用户在/sys/class/leds/myled/brightness目录下直接去读写这个文件时实际执行的代码。

  • 当我们show brightness时,实际就会执行led_brightness_show函数。

  • 当我们echo 1 > brightness时,实际就会执行led_brightness_store函数。

(3)show方法实际要做的就是读取LED硬件信息,然后把硬件信息返回

  • 因此show方法和store方法会去操控硬件;

  • 但是led-class.c文件又属于驱动框架中的文件,它本身无法直接读取具体硬件,因此在show和store方法中使用函数指针的方式调用了struct led_classdev结构体中的相应的读取/写入硬件信息的方法。

(4)struct led_classdev结构体中的实际用来读写硬件信息的函数,就是我们自己写的驱动文件leds-s5pv210.c中要提供的。

 

2、添加硬件操作

 

七、基于驱动框架写led驱动3

1、在驱动中将4个LED分开

(1)好处

 

  • 驱动层实现对各个LED设备的独立访问,并向应用层展示出4个操作接口led1、led2、led3、led4,这样应用层可以完全按照自己的需要对LED进行控制。

  • 驱动的设计理念:不要对最终需求功能进行假定(不能假定用户进行什么操作,比如是几个led一起操作还是一个操作而已?),而应该只是直接的对硬件的操作。

  • 有一个概念就是:机制和策略的问题。在硬件操作上驱动只应该提供机制(具体实现)而不是策略(方法、主意、解决方案)。策略由应用程序来做。

 

(2)如何实现

 

  1. #include      // module_init  module_exit  

  2. #include            // __init   __exit  

  3. #include   

  4. #include   

  5. #include   

  6. #include   

  7. #include   

  8. #include   

  9.   

  10.   

  11.   

  12. #define GPJ0CON     S5PV210_GPJ0CON  

  13. #define GPJ0DAT     S5PV210_GPJ0DAT  

  14.   

  15. static struct led_classdev mydev1;          // 定义结构体变量  

  16. static struct led_classdev mydev2;          // 定义结构体变量  

  17. static struct led_classdev mydev3;          // 定义结构体变量  

[1] [2] [3] [4]
关键字:驱动框架  LED 引用地址:驱动框架入门——以LED为例

上一篇:tiny210V2 Uboot kernel filesystem 烧写和启动
下一篇:INPUT输入子系统——按键

推荐阅读最新更新时间:2026-03-25 11:25

标准化接口将统一 新能源车充电国标发布倒计时
    新能源汽车用户再也不用为充电兼容问题所烦恼。日前,在国家信息中心主办的全国汽车信息发布会上,北京市科委双新处处长许心超表示,“充电国标的修 订工作已基本完成,开始征求意见,并有望在今年8月正式发布”。昨日,许心超在接受北京商报记者采访时表示,此次充电国标的核心在于将新能源汽车充电桩规 范化、一致化,且不同车型充电插口将统一,并采用标准化的充电桩。    充电桩将实现标准化       此前由于是不同品牌新能源车而出现充电桩电压、功率不同导致充不进电的情况,对此,许心超表示,充电国标也将在充电桩的兼容性上做出调整,具体表现在统一充电插口尺寸以及通信协议标准,即保证不同品牌的新能源车都能与同一充电桩正常连接,进行充电
[汽车电子]
中国家电巨头联盟推影音标准化接口
  中国TCL通讯、海信(HISENSE)、康佳(KONKA)、海尔(HAIER) 长虹(CHANGHONG)、创维(SKYWORTH)、上广电(SVA)、熊猫(PANDA)与寰宇芯连(SYNERCHIP)等大厂,日前共同宣布成立影音标准化接口(DIVA,Digital Interface for Video and Audio)推广组织,以建立下一代交互式数字电视与家庭消费性电子产品的网络标准接口。   除了可传输未压缩的影音数据之外,DIVA技术还结合高速双向数据传输频宽,让用户可以通过自家的数字电视来联接、配置与控制家中的各种消费性电子设备。由于消费者使用愈来愈多的电子娱乐装置及数字家电,DIVA标准化接口将有助于提升并简
[焦点新闻]
丰田合成开发可在车内投射动态图案的LED灯组照明
据外媒报道,丰田合成株式会社(Toyoda Gosei Co., Ltd.)开发出一种可在车内投射动态图案光的LED灯组。该产品应用于丰田汽车公司旗下雷克萨斯RZ1纯电动汽车。 图片来源: 丰田合成 近年来,为了提升车内空间体验,人们对与音乐或感应器(例如接近提示)联动的照明需求日益增长。为了满足这些需求,丰田合成利用其独有的光学工程技术,开发出将精细图案板集成到LED灯中的照明系统,从而在车内投射出生动的光影图像。如今,该公司通过切换三盏灯,实现了车门内饰板上流畅优美的光影动画效果,有助于营造轻松舒适的车内空间。 雷克萨斯RZ还采用了丰田合成公司开发的新型方向盘,这是一款“线控转向系统专用方向盘”,可兼容下一代转向系
[汽车电子]
丰田合成开发可在车内投射动态图案的<font color='red'>LED</font>灯组照明
LED产业百花怒放ISE 2026,聚积科技驱动LED应用不设限
LED 显示器持续扩张应用可能性;终端客户在重要活动、场域使用LED显示屏的比例越来越高,应用已贴近日常生活。商用背光、车用显示与照明领域,亦使用LED技术来提升显示器HDR显示效果与提供更好的驾车体验,聚积科技以驱动芯片的角色积极参与LED技术不被设限的新型应用。 图1. 聚积科技在ISE 2026展出达芬奇系列驱动芯片 ISE 2026展览中,聚积科技在LED显示屏领域提出“人人都是摄影师”的主轴,因应社群与个人自媒体盛行时代,LED显示屏作为重要的视觉媒介,拍摄需求已不仅限于专业摄影,要让一般人用手机把显示屏拍得好看,企业主的精心制作的广告素材才能得到“病毒营销式”扩散。 达芬奇系列创造无可取代的氛围感,体验强
[电源管理]
<font color='red'>LED</font>产业百花怒放ISE 2026,聚积科技<font color='red'>驱动</font><font color='red'>LED</font>应用不设限
Melexis 推出了高度可配置、无代码的 LIN LED 驱动
Melexis 推出了高度可配置、 无代码 的 LIN LED 驱动器。凭借其预定义的、经过验证的功能和直观的图形用户界面,它旨在从根本上简化各种背景的工程师的动态 RGB-LED 汽车环境照明应用的开发。 Melexis 推出了高度可配置、 无代码 的 LIN LED 驱动器。凭借其预定义的、经过验证的功能和直观的图形用户界面,它旨在从根本上简化各种背景的工程师的动态 RGB-LED 汽车环境照明应用的开发。 该MLX80124的独特创新使工程师无需编写或编译任何代码即可配置行为。相反,GUI 提供对可配置参数的访问。其结果是简化、高效的工作流程,减少了开发时间,并消除了对嵌入式软件开发专业知识的需求。 作为一款智
[汽车电子]
Melexis 推出了高度可配置、无代码的 LIN <font color='red'>LED</font> <font color='red'>驱动</font>器
【STM32 HAL库】GPIO:按键和LED
文章内容偏向HAL库的移植和使用,以个人观点及了解为主,若与事实不符,则以www.st.com、www.stmcu.org.cn等平台为准。 使用的软件: VSCode(1.36版,带C/C++ IntelliSense插件) Keil MDK(5.26版) 芯片:STM32H743ZIT6(Nucleo-H743平台,B-01版) 所使用的库:STM32Cube_FW_H7_V1.3.0,下载地址:https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-softw
[单片机]
【STM32 HAL库】GPIO:按键和<font color='red'>LED</font>
实测干货分享|如何使用AFG和万用表测试LED 驱动器的调光线性度?
随着LED灯珠技术的发展,相较于传统的模拟调光技术,数字调光技术在近几年得到了长足的发展。现如今在灯具市场里有成千上万种调光产品可供选择,在调光驱动选择上我们需要考虑到这些要素:调光平滑度,调光深度,在调光过程中是否有可感知的频闪和纹波。 为了达到调光输出的超细平滑度,首先得了解每个调光等级之间的差别。 在每个调光等级间,如果差别越小,则调光越平滑。这样就能在整个调光过程中实现无极调光,如下图所示。 以客户实测场景为例 本文案例是一个客户需要快速测量PWM调光时的输出电流线性度和平滑度,进而再进积分球测试亮度线性度。被测器件是一款集成度极高,具备恒压或恒流输出的双模式BUCK和无极性接入的载波二总线芯片。同时客户又担心这种具备
[测试测量]
STM32G431 LED实验教程详解
一、实验目的 1.使用STM32CubeMX、Keil5调试验证LED灯、KEY例程,下载代码实验板实物验证。(验证HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)函数); 2.新建4个花式的流水灯花式(8个LED)程序,下载代码试验实验板验证。(调用HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)函数,ODR的操作); 3.采用按键查询模式,新建4个按键对应4个花式的流水灯(8个LED)程序,下载代码试验实验板验证。(调用HAL_GPIO_ReadP
[单片机]
STM32G431 <font color='red'>LED</font>实验教程详解
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved