• 知识整理Linux驱动框架概念之LED

    • 何谓驱动框架
    • LED驱动框架分析
      • 内核驱动框架中LED的基本情况
      • LED驱动框架源码
    • 基于驱动框架写LED驱动
    • 在硬件操作上驱动只应该提供机制而不是策略
    • 总结LED驱动开发

知识整理–Linux驱动框架概念之LED

驱动框架也用模块这种’机制’实现,为了在不需要的时候也能够卸载

何谓驱动框架

什么是驱动框架,为什么需要驱动框架,基于驱动框架写驱动有什么优势

驱动编程协作要求:(1)接口标准化;(2)尽量降低驱动开发者难度

什么是驱动框架:标准化的驱动实现``统一管控系统资源,维护系统稳定

(1)内核中驱动部分维护者针对每个种类的驱动设计一套成熟的、标准的、典型的驱动实现,并把不同厂家的同类硬件驱动中相同的部分抽出来自己实现好,再把不同部分留出接口给具体的驱动开发工程师来实现,这就叫驱动框架。

譬如LED 亮灭肯定都会有,这就是同类硬件的相同部分,用内核开发工程师开发的这套成熟的、标准的、典型的驱动去实现。
A厂家的LED能调亮度,B厂家的LED就只有亮灭,那A厂家的调亮度就是同类硬件的不同部分,驱动工程师就要在基本的驱动实现上去添加

(2)内核维护者在内核中设计了一些统一管控系统资源的体系,这些体系让内核能够对资源在各个驱动之间的使用统一协调和分配,保证整个内核的稳定健康运行。譬如系统中所有的GPIO就属于系统资源,每个驱动模块如果要使用某个GPIO就要先调用特殊的接口先申请,申请到后使用,使用完后要释放。又譬如中断号也是一种资源,驱动在使用前也必须去申请。其他比如框架中的设备锁等。这些也是驱动框架的组成部分

(3)一些特定的接口函数、一些特定的数据结构,这些是驱动框架的直接表现。

驱动框架这个概念单靠文字说明很难理解,应在实际驱动编程中去体会上面的这几点

LED驱动框架分析

内核驱动框架中LED的基本情况

开始一件事,不盲目,简单分析后再去分析源码。像分析uboot和kernel先看地图(Makefile)那样

相关文件:
(1)drivers/leds目录,这个目录就是驱动框架规定的LED这种硬件的驱动应该待的地方。
(2)led-class.c和led-core.c,这两个文件加起来属于LED驱动框架的第一部分,这两个文件是内核开发者提供的,他们描述的是内核中所有厂家的不同LED硬件的相同部分的逻辑。必要的需要花时间的就是内核提供的led-class.c和led-core.c文件。
(3)leds-xxxx.c,这个文件是LED驱动框架的第2部分,是由不同厂商的驱动工程师编写添加的,厂商驱动工程师结合自己公司的硬件的不同情况来对LED进行操作,使用第一部分提供的接口来和驱动框架进行交互,最终实现驱动的功能。

我自己学习使用的开发板是九鼎厂商生产的s5pv210,内核源码树为其提供的linux+qt的kernel
其(九鼎移植的内核)led驱动没有使用内核推荐的led驱动框架,文件放在放在drivers/char/led/x210-led.c

案例分析驱动框架的使用:
(1)以leds-s3c24xx.c为例。leds-s3c24xx.c中通过调用led_classdev_register来完成LED驱动的注册,而led_classdev_register是在drivers/leds/led-class.c中定义的。所以其实SoC厂商的驱动工程师是调用内核开发者在驱动框架中提供的接口来实现自己的驱动的。
(2)驱动框架的关键点就是:分清楚内核开发者提供了什么,驱动开发者自己要提供什么

典型的驱动开发行业现状:
(1)内核开发者对驱动框架进行开发和维护、升级,对应led-class.c和led-core.c
(2)SoC厂商的驱动工程师对设备驱动源码进行编写、调试,提供参考版本,对应leds-s3c24xx.c
(3)做产品的厂商的驱动工程师以SoC厂商提供的驱动源码为基础,来做移植和调试

LED驱动框架源码

涉及到的文件:led-core.c和led-class.c

经过基本分析经过基本分析,发现LED驱动框架中内核开发者实现的部分主要是led-class.c。
led-class.c就是一个内核模块,对led-class.c分析应该从下往上,遵从对模块的基本分析方法。
为什么LED驱动框架中内核开发者实现的部分要实现成一个模块?因为内核开发者希望这个驱动框架是可以被装载/卸载的。

subsys_initcall
点击这里:linux内核段属性机制(以subsys_initcall和module_init为例)

leds_init

类的创建。leds_init除了对class结构体变量进行赋值,还做了class_create,所以到开发板下 ls /sys/class可以看到多了一个类leds,但是里面是空的。里面的用来与应用层进行交互的文件是驱动程序要去创建的,这就是驱动工程师要做的(用提供的接口去创建)

led_class_attrs:
(1)attribute是什么,对应将来/sys/class/leds/xxx目录里的内容,一般是文件和文件夹。这些文件其实就是sysfs开放给应用层的一些操作接口(非常类似于/dev/目录下的那些设备文件)
(2)attribute有什么用,作用就是让应用程序可以通过/sys/class/leds/xxx目录下面的属性文件来操作驱动进而操作硬件设备。
(3)attribute其实是另一条驱动实现的路线。有区别于之前讲的file_operations那条线。不同设备驱动实现走的路不一定,像这边的led走的是attribute,而LCD走的是file_operations

leds_class(class结构体):
以下文件在/include/linux/device.h

struct class {const char      *name;struct module       *owner;struct class_attribute      *class_attrs;struct device_attribute     *dev_attrs;struct kobject          *dev_kobj;int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);char *(*devnode)(struct device *dev, mode_t *mode);void (*class_release)(struct class *class);void (*dev_release)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct kobj_ns_type_operations *ns_type;const void *(*namespace)(struct device *dev);const struct dev_pm_ops *pm;struct class_private *p;
};

唤醒(resume)、挂起(suspend):

led_classdev_register

属于某一类的设备的创建。分析可知,led_classdev_register这个函数其实就是去创建一个属于leds这个类的一个设备。其实就是去注册一个设备。所以这个函数其实就是led驱动框架中内核开发者提供给SoC厂家驱动开发者的一个注册驱动的接口
当使用led驱动框架去编写驱动的时候,这个led_classdev_register函数的作用类似于驱动程序使用file_operations方式去注册字符设备驱动时的register_chrdev函数。

led_classdev:
以下文件在/include/linux/leds.h

struct led_classdev {const char      *name;int          brightness;int          max_brightness;int          flags;.../* Set LED brightness level *//* Must not sleep, use a workqueue if needed */void        (*brightness_set)(struct led_classdev *led_cdev,enum led_brightness brightness);/* Get LED brightness level */enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);...struct device       *dev;struct list_head     node;          /* LED Device list */const char      *default_trigger;   /* Trigger to use */...
};

基于驱动框架写LED驱动

实践之前需要确认内核是否添加led驱动框架支持(通过make menuconfig配置,设置成功后到开发板下ls /sys/class可以看到多了一个类leds 但是里面是空的)

一般不从零开始写,参考哪里? drivers/leds/leds-s3c24xx.c;
思路/关键点:led_classdev_register,我们之前写的led驱动,直接看的是内核里面提供的操作接口,譬如register_chardev,cdev结构体等那些
仍然是驱动模块,module_init(XXX),insmod时会去调用XXX去注册,在xxx模块安装函数中去使用专用的接口

注:以前看注册成功与否,cat     /proc/devices去看信息变化。现在要看/sys/class/leds 如果注册成功该目录下会多一些文件

示例程序leds-s5pv210.c:

现象:
第1:写的驱动能够工作了,被加载了,/sys/class/leds/目录下多出来了一个表示设备的文件夹。文件夹里面有相应的操控led硬件的2个属性brightness和max_brightness
第2:led-class.c中brightness方法有一个show方法和store方法,这两个方法对应用户在/sys/class/leds/myled/brightness目录下直接去读写这个文件时实际执行的代码。
show brightness ...时,实际就会执行led_brightness_show函数
echo 1 > brightness时,实际就会执行led_brightness_store函数

show方法实际要做的就是读取LED硬件信息,然后把硬件信息返回给用户即可。所以show方法和store方法必须能够操控硬件。但led-class.c文件属于驱动框架中的文件,本身无法直接读取具体硬件,因此在show和store方法中使用函数指针的方式调用了struct led_classdev结构体中的相应的读取/写入硬件信息的方法(在linux/leds.h中,写驱动就一定要包含这个头文件和对应的led_classdev结构体类型变量。当有多个个同类设备(即多个led_classdev结构体类型变量)它是怎么判段的呢?–不难,文章不想写太长,自行分析)(算了还是写一下吧,都整理出来了)。
struct led_classdev结构体中的实际用来读写硬件信息的函数,就是驱动文件leds-s5pv210.c中要提供的(如示例程序)。

分析echo 1 > b brightness 是如何传递的:

在硬件操作上驱动只应该提供机制而不是策略

在驱动中将4个LED分开,使应用层可以完全按照自己的需要对LED进行控制

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

驱动的设计理念:不要对最终需求功能进行假定,而应该只是直接的对硬件的操作。有一个概念就是:机制和策略的问题。在硬件操作上驱动只应该提供机制而不是策略。策略由应用程序来做。比如有人要造反,提供枪支弹药这就是机制;比如马克思主义,没有枪支弹药,但是有策略

将4个LED分开程序:
leds-s5pv210.c

总结:LED驱动开发

不是很复杂的一个框架,多分析思考;关键点:细节另外,要明白写的驱动如何与框架结合(即应用到硬件是怎样的一条路线)

整理--Linux驱动框架概念之LED相关推荐

  1. Linux驱动——mmc概念与框架(一)

    Linux驱动--mmc概念与框架(一) 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客: Linux MMC framewo ...

  2. 4.驱动框架入门之LED

    1.何谓驱动框架 1.1.驱动是谁写的 (1)驱动开发工程师 (2)内核维护者 1.2.驱动编程协作要求 (1)接口标准化 (2)尽量降低驱动开发者难度 1.3.到底什么是驱动框架 (1)内核中驱动部 ...

  3. Linux驱动框架及详述(详细教程)

    Linux驱动框架及详述(详细教程) 1.前言 2.驱动程序的分类 3.设备驱动程序功能 4.驱动的基本框架 5.Hello驱动的编写 6.字符设备(LED)驱动程序编写实例 6.1 定义file_o ...

  4. linux用户空间flash驱动,全面掌握Linux驱动框架——字符设备驱动、I2C驱动、总线设备驱动、NAND FLASH驱动...

    原标题:全面掌握Linux驱动框架--字符设备驱动.I2C驱动.总线设备驱动.NAND FLASH驱动 字符设备驱动 哈~ 这几天都在发图,通过这种方式,我们希望能帮大家梳理学过的知识,全局的掌握Li ...

  5. Linux驱动框架之framebuffer驱动框架

    1.什么是framebuffer? (1)framebuffer帧缓冲(一屏幕数据)(简称fb)是linux内核中虚拟出的一个设备,framebuffer向应用层提供一个统一标准接口的显示设备.帧缓冲 ...

  6. linux驱动:二、LED灯驱动编写

    一.地址映射 在正式编写驱动前需要先简单了解一下 MMU 这个神器,MMU 全称叫做 Memory Manage Unit,也就是内存管理单元.在老版本的 Linux 中要求处理器必须有 MMU,但是 ...

  7. Linux驱动框架之misc类设备驱动框架

    1.何为misc设备 (1)misc中文名就是杂项设备\杂散设备,因为现在的硬件设备多种多样,有好些设备不好对他们进行一个单独的分类,所以就将这些设备全部归属于 杂散设备,也就是misc设备,例如像a ...

  8. Linux驱动框架与杂项字符设备框架介绍

    1. Linux下驱动框架介绍 1.1 驱动框架分类 Linux下驱动框架分为3大类型: 字符设备 --------- 块设备 存储设备 SD 硬盘 网络设备 网卡 无线 有线 字符设备和块设备都会生 ...

  9. linux驱动(一):linux驱动框架

    编写linux驱动先看一下驱动框架是什么样子的. 驱动编写和应用层编写有什么区别呢? (一)首先 入口函数的问题.应用层编写我们的入口就是main函数,但在驱动编写时不是这样的,有两种情况, 1.缺省 ...

  10. Linux驱动框架之v4l2视频驱动框架解析

    1.简介 v4l2是专门为linux设备设计的一套视频框架,其主体框架在linux内核,可以理解为是整个 linux 系统上面的视频源捕获驱动框架.其广泛应用在嵌入式设备以及移动端.个人电脑设备上面, ...

最新文章

  1. ANDROID_MARS学习笔记_S01_011ProgressBar
  2. 视频编解码的理论和实践2:Ffmpeg视频编解码
  3. ios 字符串转数组_ES6中常用的数组操作-必须收藏
  4. Curator实现分布式锁的基本原理-createsTheLock
  5. scrapy_redis项目配置
  6. 打算开源一个低代码平台,包含【工作流,业务流,财务,APQC】。技术站 React,typescript,java,mysql
  7. Centos7下载文件恢复工具 extundelete
  8. 计算机编程语言排行榜—TIOBE世界编程语言排行榜(2021年08月份最新版)
  9. besiege机器人_《围攻》双脚机器人制作图文教程 双脚机器人怎么制作
  10. Fuchsia编译与真机安装
  11. 国产系统下的DES,SM4工具,银河麒麟V10桌面系统,飞腾芯片
  12. File和MultipartFile互转
  13. php 搜索引擎包含哪些技术,浅谈三大搜索引擎爬虫性感 B-G-B
  14. Spark Streaming控制每秒消费数据的速度
  15. Ubuntu18.0.4仿Mac界面
  16. Android开发之集成Twitter登陆以及分享,文后有源码。
  17. 实现微信自动发送/回复信息_Android版微信7.0.15
  18. iOS各个版本的特性和差别
  19. DNS原理及局域网DNS劫持实验
  20. 华为WLAN射频资源管理

热门文章

  1. Flink中水位线/Periodic周期水印/Punctuated每个事件水印实现原理/ PunctuatedWatermarks/PeriodicWatermarks
  2. 单片机中断程序详解(转)
  3. 【CTF】明御攻防实验平台 crypto 鸡藕椒盐味 wp--海明校验码
  4. 华为路由器基本使用命令
  5. Could not instantiate the executor. Make sure a planner module is on the classpath
  6. (转载)重新编译SJF2410以适应NM9805并口卡(PCMICIA接口)
  7. 数据可视化平台Superset 简介
  8. 方程检验格式图片_eviews的异方差检验ppt课件
  9. python数据类型转换、将数值转换为以万为单位的数_如何把Excel表格中金额为元的数转换成以万元为单位...
  10. @Qualifier注解 的理解和使用