• 嵌入式驱动学习第三周——Linux内核中的继承思想


    前言

       我们知道Linux源码是C语言,而继承是面向对象的很重要的思想,Linux内核中也通过开发者的智慧实现了继承。

       嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程,未来预计四个月将高强度更新本专栏,喜欢的可以关注本博主并订阅本专栏,一起讨论一起学习。现在关注就是老粉啦!

    封装的思想

       在面向对象编程中,封装和继承其实是不分开的:封装就是为了更好地继承。我们将几个类共同的一些属性和方法抽取出来,封装成一个类,就是为了通过继承最大化地实现代码复用。通过继承,子类可以直接使用父类中的属性和方法。

       如Linux内核中的网卡设备,不同厂家的网卡、不同速度的网卡,以及相同厂家不同品牌的网卡,它们的读写操作基本上都是一样的,都通过标准的网络协议传输数据,唯一不同的就是不同网卡之间存在一些差异,如I/O寄存器、I/O内存地址、中断号等硬件资源不相同

       遇到这些设备,我们完全不必给每个类型的网卡都实现一个结构体。我们可以将各个网卡一些相同的属性抽取出来,构建一个通用的结构体net_device,然后通过一个私有指针,指向每个网卡各自不同的属性和方法,通过这种设计可以最大程度地实现代码复用。如Linux内核中的net_device结构体。

    继承实现方式

       可以通过内嵌结构体,即在子类中加入父类的结构体,然后就可以在子类基础上扩展自己的属性,同时子类也可以用父类的一些属性。

       使用私有指针,例如在net_device结构体定义中,我们可以看到一个私有指针成员变量:ml_priv。当我们使用该结构体类型定义不同的变量来表示不同型号的网卡设备时,这个私有指针就会指向各个网卡自身扩展的一些属性。

       当然最常见的还是private_data变量,private_data是一个结构体或类中的成员变量,用于指向该设备的私有数据。这个变量的作用是为了让驱动程序可以在设备和设备文件之间建立联系。

       需要注意的是,private_data变量不是内核中的全局变量,而是每个设备文件独有的。也就是说,每个设备文件都有自己独立的private_data变量,因此,不同的设备文件可以使用不同的私有数据,这样就使得驱动程序更加灵活。

       使用的时候一般是在open函数中就指定private_data变量为本设备文件:

    static int chrdevTest_open(struct inode *inode, struct file *filp) {
        filp->private_data = &chrdevTest;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4

       然后在需要的时候再取出来:

    struct chrdevTest_dev *dev = (struct chrdevTest_dev *)filp->private_data;
    
    • 1

    参考资料

       Linux驱动开发中private_data变量的理解

  • 相关阅读:
    MindsDB为许多不支持内置机器学习的数据库带来了机器学习功能
    MySql字符串拆分实现split功能(字段分割转列、转行)
    Day 85
    报表常用功能—插入公式以及父子格
    matlab去除图片上的噪声
    如何进行性能评估
    JS常用的函数
    倍福TwinCAT3--基于C++实现ADS通讯
    bean的生命周期分析(四)
    【栈】NowCoder-由两个栈组成的队列
  • 原文地址:https://blog.csdn.net/qq_43419761/article/details/136694016