解决一个驱动代码解耦合问题

之前解决的项目LCD设备兼容问题,在 a.c 文件里面定义了一个变量,然后在 b.c 里面使用 extern声明引用这个变量,通过这种方法可以在b.c中使用在a.c 里面初始化的变量。

但是这中情况就会引起一个问题,就是驱动代码之间耦合了,这也违背了驱动代码 高内聚、低耦合的思想。

所以,这篇文章就是讨论解决这个问题的。

之前写的文章

LCD驱动兼容

1、先说说问题产生的本质

在 a.c 驱动文件中,我会根据 dts 文件的配置挂载一个platform 驱动,这个驱动获取dts文件的 gpio口信息,申请gpio口,并赋值给 g_lcm_power变量。

代码如下

dts文件

 panel: panel@0 {compatible = "hx8279d";gpio_lcd_pwr_en = <&pio 47 0>;status = "okay";};

驱动文件

static const struct of_device_id lcm_platform_of_match[] = {{.compatible = "hx8279d",.data = 0,}, {/* sentinel */}
};MODULE_DEVICE_TABLE(of, platform_of_match);static int lcm_platform_probe(struct platform_device *pdev)
{const struct of_device_id *id;enum of_gpio_flags flags;int ret;struct device_node *node = pdev->dev.of_node;PRINTFx("[Kernel/LCM] lcm_platform_probe() enter\n");id = of_match_node(lcm_platform_of_match, pdev->dev.of_node);if (!id)return -ENODEV;g_lcm_power = of_get_named_gpio_flags(node, "gpio_lcd_pwr_en", 0, &flags);if (!gpio_is_valid(g_lcm_power)) {dev_err(&pdev->dev, "invalid en gpio%d\n", g_lcm_power);}ret = devm_gpio_request(&pdev->dev, g_lcm_power, "gpio_lcd_pwr_en");if (ret) {dev_err(&pdev->dev,"failed to request GPIO%d for relay-en-gpio\n",g_lcm_power);return -EINVAL;}return 0;
}static struct platform_driver lcm_driver = {.probe = lcm_platform_probe,.driver = {.name = "hx8279d",.owner = THIS_MODULE,.of_match_table = lcm_platform_of_match,},
};static int __init lcm_init(void)
{PRINTFx("[Kernel/LCM] lcm_init() probe enter\n");/*if (platform_driver_register(&lcm_driver)) {PRINTFx("LCM: failed to register this driver!\n");return -ENODEV;}*/return 0;
}static void __exit lcm_exit(void)
{platform_driver_unregister(&lcm_driver);
}late_initcall(lcm_init);
module_exit(lcm_exit);
MODULE_AUTHOR("mediatek");
MODULE_DESCRIPTION("LCM display subsystem driver");
MODULE_LICENSE("GPL");

a.c 文件 和 b.c 文件的只能执行一个lcm 驱动,具体执行哪个驱动是在lk判断硬件接了哪一个硬件模组,所以我们在实现驱动代码的时候,a.c驱动文件和b.c驱动文件都需要具备注册上述说的那个 power gpio代码,用来控制模组的电源。

我的解决办法是

在 a.c 驱动文件中,我会根据 dts 文件的配置挂载一个platform 驱动,这个驱动获取dts文件的 gpio口信息,申请gpio口,并赋值给 g_lcm_power变量。

因为a.c的platform驱动我是默认每次开机都会加载。

在b.c驱动文件中,我使用 extern int g_lcm_power;来声明这个变量,这样做之后,如果在lk识别到b.c的驱动,这个变量也可以正常使用。

2、什么是高内聚、低耦合?

什么是高内聚、低耦合?

这是之前写的一篇文章,我觉得解释的比较不错了。

3、如何解决这样的问题?

如何解决,也就是说我们要对驱动代码进行解耦合。

因为我们代码中就只对一个对GPIO口的控制,如果脱离DTS的注册,直接在驱动文件里面对这个GPIO口进行操作的话,理论上就可以解决耦合的问题了。

这部分可以去查一下下面这个函数

gpio_direction_output

测试看看如果在不申请的情况下是否可以使用。

第二种情况就还是使用dts来匹配

dts改成如下

 panel: panel@0 {/*compatible = "hx8279d";*/gpio_lcd_pwr_en = <&pio 47 0>;status = "okay";};

在 a.c 和 b.c 驱动中,同时使用如下代码申请gpio口,linux的dts是一个很不错组织结构,也有很多函数来获取dts中的文件。

想研究dts的同学,可以看看这个目录下的内容,对大家调试非常有帮助。

static void lcm_init_power(void)
{struct device_node *panel_nd;int ret;enum of_gpio_flags flags;PRINTFx("[Kernel/LCM] lcm_init_power() enter\n");/*查找整个dts文件,找到panel,前面是NULL就是让这个函数查找整个dts*/panel_nd = of_find_node_by_name(NULL, "panel");if(!panel_nd){PRINTFx("Can't file panel_nd node\n");return;}/*获取gpio_lcd_pwr_en属性信息*/g_lcm_power = of_get_named_gpio_flags(panel_nd, "gpio_lcd_pwr_en", 0, &flags);PRINTFx("1212121g_lcm_power=%d\n", g_lcm_power);if (!gpio_is_valid(g_lcm_power)) {PRINTFx("invalid en gpio%d\n", g_lcm_power);return;}ret = gpio_request( g_lcm_power, "gpio_lcd_pwr_en");if (ret) {PRINTFx("failed to request GPIO%d for relay-en-gpio\n",g_lcm_power);return;}PRINTFx("[Kernel/LCM] lcm_init_power() end\n");return;
#ifndef BUILD_LKPRINTFx("[Kernel/LCM] lcm_init() enter\n");
#endif
}

推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

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

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

相关文章

STM32——DMA

STM32——DMA 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 DMA 是为CPU分担数据转移的工作。因为DMA的存在CPU才被解放出来&#xff0c;它可以在 DMA 转移数据的过程中同时进行数据运算、响应中断&#xff0c;大大提高效率。 1、DMA工作分析 数据传…

YOLOv8改进 | 主干篇 | 利用SENetV1改进网络结构 (ILSVRC冠军得主)

一、本文介绍 本文给大家带来的改进机制是SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型&#xff0c;而是一个可以和现有的任何一个模型相结合的模块(可以看作是一…

搭建Servlet在线视频

这个视频flash上传及在线播放&#xff0c;搞了我一天了&#xff0c;总算有点成果&#xff0c;但还有一些疑问没有解决&#xff0c;现在发这篇随笔&#xff0c;为的就是交流视频在线上传和观看的一些问题。 在线编辑器使用FCKEditor&#xff0c;首先是修改FCKEditor的配置文件&a…

操作系统——内存管理例题

1、关于分配策略例题 case1&#xff1a;某系统的空闲分区见下表&#xff0c;如有下列作业&#xff1a;96KB&#xff0c;20KB&#xff0c;200KB&#xff0c;分别采用首次适应算法和最佳适应算法来处理这些作业序列&#xff0c;哪种算法能满足该作业序列请求&#xff1f; 分区号…

STM32中C语言知识点:初学者必看,老鸟复习(长文总结)

说在前面的话一位初学单片机的小伙伴让我推荐C语言书籍&#xff0c;因为C语言基础比较差&#xff0c;想把C语言重新学一遍&#xff0c;再去学单片机&#xff0c;我以前刚学单片机的时候也有这样子的想法。其实C语言是可以边学单片机边学的&#xff0c;学单片机的一些例程中&…

STM32——ADC

STM32——ADC 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、ADC指标 有 18 个通道&#xff0c;可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行 &#xff1b;ADC的结果可以左对齐或右对齐方式存储在 16…

时间复杂度和空间复杂度,一看就懂,面试前必过一遍

一、定义时间和空间是程序的一个硬性指标&#xff0c;一个用来衡量 代码执行的速度 &#xff0c;一个用来衡量 存储空间的大小程序 数据结构 算法时间复杂度&#xff1a;就是执行程序的快慢&#xff0c;速度越快&#xff0c;时间复杂度就越好。空间复杂度&#xff1a;就是执…

数据结构——排序【仅用于考试】

1、简介 排序&#xff0c;是重新排列表中的元素&#xff0c;使表中的元素满足按关键字有序的过程 稳定性&#xff1a;选取两个元素Ri<Rj&#xff0c;经过排序算法之后&#xff0c;仍为Ri<Rj 不稳定的排序&#xff1a;【简单选择排序&#xff0c;快速排序&#xff0c;堆…

[UWP]做个调皮的BusyIndicator

1. 前言 最近突然想要个BusyIndicator。做过WPF开发的程序员对BusyIndicator应该不陌生&#xff0c;Extended WPF Toolkit 提供了BusyIndicator的开源实现&#xff0c;Silverlight Toolkit也有一个&#xff0c;这次想要把这个控件移植到UWP中。 2. 先说点正经的 2.1 BusyIndica…

STM32——I2C

STM32——I2C 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、I2C协议 I 2 C &#xff08;Inter-Integrated Circuit&#xff09;协议是由 Philips 公司开发的&#xff0c;由于它具备引脚少、硬件实现简单、可扩展性强、不需要如 USART、CAN 的外部…

C语言发展简史

1、起源C 语言最早的原型是 ALGOL 60 1963 年&#xff0c;剑桥大学将其发展成为 CPL(Combined Programing Language)。1967 年&#xff0c;剑桥大学的 Matin Richards 对 CPL 语言进行了简化&#xff0c;产生了 BCPL 语言。1970 年&#xff0c;美国贝尔实验室(Bell Labs)的 Ken…

STM32——EEPROM

STM32——EEPROM 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、I2C接口读写EEPROM&#xff08;AT24C02&#xff09; ——主模式&#xff0c;分别用作主发送器和主接收器。通过查询事件的方式来确保正常通信。 1、I 2C接口初始化 与其他对GPIO 复用…

Linus Torvalds谈ECC内存的重要性 痛斥英特尔正在扼杀它

新年假期&#xff0c;Linus Torvalds在邮件列表中发表的一篇火热的帖子引发技术社区关注&#xff0c;人们借此讨论ECC内存的重要性&#xff0c;Torvalds在文章中抨击了英特尔在这方面的”坏政策”&#xff0c;因为特定的市场细分使ECC内存不那么普及。Linus认为&#xff0c;纠错…

加密和解密算法的兩個實現

最近一段時間,集團加強了資安方面的管理,所有敏感的配置字節都必須經過加密處理,把最近用到的幾個加解密類整理了一下,以做備忘. 其實這兩個類實現的方法差不多,只是有些細微區別: 對稱加密演算法類 SymmetricMethodHelperusing System;using System.IO;using System.Security.…

47.leetcode36_valid_suduko

1.题目分析 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character .. A partially filled sudoku which is valid. Note: A valid Sudoku board (partia…

STM32——SPI接口

STM32——SPI接口 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、SPI协议【SerialPeripheral Interface】 串行外围设备接口&#xff0c;是一种高速全双工的通信总线。在ADC/LCD等与MCU间通信。 1、SPI信号线 SPI 包含 4 条总线&#xff0c;SPI 总…

这两种printf()函数重定向方法,太实用了

作者&#xff1a;echobright原文链接&#xff1a;https://blog.csdn.net/qq_29344757/article/details/75363639在前面学习了STM32的串口编程&#xff0c;通过USART1向计算机的串口调试助手打印数据&#xff0c;或者接收计算机串口调试助手的数据&#xff0c;接下来我们可以实现…

浅析Linux 64位系统虚拟地址和物理地址的映射及验证方法

前言有好久没更新了&#xff0c;这段时间发生了挺多大喜事哈。但是也还是有挺久没更新了&#xff0c;不得不意识到自己是个小菜鸡&#xff0c;就算是小菜鸡也要做一只快乐小菜鸡。就算更新慢但是我依然会持续更新&#xff0c;因为更文使我快乐。虚拟内存先简单介绍一下操作系统…

C语言指针:从底层原理到花式技巧,用图文和代码帮你讲解透彻

一、前言二、变量与指针的本质三、指针的几个相关概念四、指向不同数据类型的指针五、总结一、前言如果问C语言中最重要、威力最大的概念是什么&#xff0c;答案必将是指针&#xff01;威力大&#xff0c;意味着使用方便、高效&#xff0c;同时也意味着语法复杂、容易出错。指针…

ARM

ARM 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 1 、ARM处理器的特点 ARM 处理器具有耗电少&#xff0c;功能强大&#xff0c;16 位/32 位双指令集等众多优点。主要有以下六个主要特点&#xff1a; ① 体积小、低功耗&#xff0c;低成本和高性能&am…