linux总线设备驱动程序框架

简介: linux总线设备驱动程序框架

传统写法:上下分层


image.png


典型的如字符设备驱动。


  • 预先分配GPIO


  • 注册file_operations


  • 使用ioremap映射寄存器,操作寄存器


这种写法的缺点:


  • 硬件绑定很死


  • 不适合扩展


总线模型:左右分离


image.png


  • 把固定的硬件资源放到平台结构中


  • 把固定的驱动程序放到paltform_driver结构中


  • 设备与驱动程序通过bus联系起来(这里的总线是一个虚拟的概念)


struct platform_device led_device; <====> struct platform_driver led_drv;
struct platform_device btn_device; <====> struct platform_driver btn_drv;
struct platform_device lcd_device; <====> struct platform_driver lcd_drv;


这种写法的优缺点:


  • 方便扩展


  • 对于每一个单板都需要提供一个平台,重复的代码太多,从而有了后续的设备树驱动模型(此处暂不研究)


设备与driver是如何匹配上的


相关结构


struct platform_device {
    const char  *name;    //名称
    int     id;
    bool        id_auto;
    struct device   dev;
    u32     num_resources;
    struct resource *resource;
    const struct platform_device_id *id_entry;
    char *driver_override;      //Driver name to force a match
    /* MFD cell pointer */
    struct mfd_cell *mfd_cell;
    /* arch specific additions */
    struct pdev_archdata    archdata;
};
struct platform_driver {
    int (*probe)(struct platform_device *);     //匹配成功后被调用
    int (*remove)(struct platform_device *);
    void (*shutdown)(struct platform_device *);
    int (*suspend)(struct platform_device *, pm_message_t state);
    int (*resume)(struct platform_device *);
    struct device_driver driver;                //{.name = "xxx"}
    const struct platform_device_id *id_table;  //能支持的设备,一个driver可能支持多个设备
};
struct bus_type platform_bus_type = {
    .name       = "platform",
    .dev_attrs  = platform_dev_attrs,
    .match      = platform_match,               // 判断(dev,drv)是否匹配,若匹配,则调用drv->probe
    .uevent     = platform_uevent,
    .pm     = &platform_dev_pm_ops,
};


内核里面有一个虚拟总线(平台总线类型),其上挂着两个链表,左边是设备链表,右边是驱动链表。当我们去注册平台设备时,这个平台设备就会加入左边的链表;当我们去注册一个平台driver时这个平台driver就会加入右边的链表。


这些结构体加入链表后,就会马上和对方的链表的成员一一比较,如果有匹配上的就调用平台驱动的probe函数,来处理dev。


  • 如果platform_device.driver_override存在,则比较platform_device.driver_override和platform_driver.driver.name


  • 如果platform_driver id_table 不为空,比较platform_device.name和platform_driver.driver.name


  • 最后比较platform_device.name 和 platform_driver.driver.name


image.png


函数调用关系


platform_device_register
platform_device_add
    device_add
        bus_add_device // 放入链表
        bus_probe_device  // probe枚举设备,即找到匹配的(dev, drv)
            device_initial_probe
                __device_attach
                    bus_for_each_drv(...,__device_attach_driver,...)
                        __device_attach_driver
                            driver_match_device(drv, dev) // 是否匹配
                            driver_probe_device         // 调用drv的probe
platform_driver_register
__platform_driver_register
    driver_register
        bus_add_driver // 放入链表
            driver_attach(drv)
                    bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
                        __driver_attach
                            driver_match_device(drv, dev) // 是否匹配
                            driver_probe_device         // 调用drv的probe


总结


对于Linux总线设备驱动框架只是一个简单的认识,后续还需要深入学习,如有错误,敬请谅解。

相关文章
|
2天前
|
存储 Linux
深入了解Linux设备管理:字符、块和网络设备文件
深入了解Linux设备管理:字符、块和网络设备文件
10 0
|
13天前
|
Linux
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
|
13天前
|
Linux 程序员 芯片
【Linux驱动】普通字符设备驱动程序框架
【Linux驱动】普通字符设备驱动程序框架
|
23天前
|
存储 编解码 Linux
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(二)
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(二)
21 1
|
23天前
|
存储 Linux C语言
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(一)
【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架(一)
20 0
|
23天前
|
Linux 芯片
Linux 驱动开发基础知识——查询方式的按键驱动程序_编写框架(十三)
Linux 驱动开发基础知识——查询方式的按键驱动程序_编写框架(十三)
12 2
|
16小时前
|
Linux
Linux的top命令是什么,如何使用
【6月更文挑战第30天】Linux的top命令是什么,如何使用
6 1
|
1天前
|
Linux 数据处理
探索Linux下的readlink命令:解析符号链接的利器
`readlink`命令在Linux中用于揭示符号链接的指向,显示它们所链接的实际文件或目录的路径。它可以显示简洁的绝对路径(-f),处理循环链接(-e),或不加换行符输出(-n)。例如,查看`link.txt`指向:`readlink link.txt`;获取绝对路径:`readlink -f link.txt`。使用时要注意链接是否存在、权限问题和可能的循环链接。
|
1天前
|
Linux 数据处理
探索Linux下的readelf命令:深入了解ELF文件
`readelf`是Linux下分析ELF文件的命令行工具,用于查看文件头、节区、符号表等信息。支持可执行文件、共享库等多种类型。常用选项有`-h`(文件头)、`-l`(程序头)、`-S`(节区)、`-s`(符号表)、`-r`(重定位)和`-d`(动态节区)。结合其他工具如`objdump`,能深入理解二进制文件,助力开发和调试。
|
1天前
|
Linux
常用的Linux系统命令及其使用技巧
常用的Linux系统命令及其使用技巧