(五)Linux设备驱动模型介绍

五.linux设备驱动模型 站在设备驱动这个角度分析,设备驱动模型是如何构建出来,起到什么作用,认识它并在写驱动的时候去利用设备驱动模型 目录 一.linux 设备驱动模型简介 1.1、 什么是设备驱动模型 1.2、 为什么需要设备驱动模型 1.3、 驱动开发的2个点 二.设备驱动模型的底层架构 2.1、kobject结构体 2.2、kobj_type结构体 2.3、kset结构体 三.总线式设备驱... 阅读详情

本系列导航
(一)初识Linux驱动
(二)Linux设备驱动的模块化编程
(三)写一个完整的Linux驱动程序访问硬件并写应用程序进行测试
(四)Linux设备驱动之多个同类设备共用一套驱动
(五)Linux设备驱动模型介绍
(六)Linux驱动子系统-I2C子系统
(七)Linux驱动子系统-SPI子系统
(八)Linux驱动子系统-PWM子系统
(九)Linux驱动子系统-Light子系统
(十)Linux驱动子系统-背光子系统
(十一)Linux驱动-触摸屏驱动

1. Linux设备驱动模型产生背景

我们知道,同一个LED灯,在不同的硬件平台上,可能接在不同的GPIO上面,那么你针对某个平台写的LED驱动就不适应于另外一个平台,这个时候从新移植驱动到新的平台还是很麻烦的。但是对于这两个平台的LED驱动基本都是相同的,唯有操作的GPIO不同,比如控制方法一样(亮/灭/闪烁等),硬件的gpio接口不一样。所以为了减小移植驱动的工作量,就提出了总线、设备、驱动的这种设备模型,把驱动相同的部分代码提取出来,作为公共部分(平台驱动driver),而与平台相关的单独放在一起(叫做平台设备device),然后通过一个叫做平台总线的东西将他们关联在一起这样,对于同样的设备在不同平台上的驱动只需要修改平台相关的部分即可。

2. Linux设备驱动模型简单介绍

Linux设备驱动模型之bus、device、driver模型,将驱动划分为三个部分–总线(bus)、设备(device)、驱动(driver),总线可以是物理上存在的总线,比如i2c_bus、spi_bus等,也可以是物理上不存在而虚拟出来的总线(platform_bus),设备代码和驱动代码都挂在(通过指针)对应的总线上面,由总线来统一管理他们,总线如果发现它下面挂的驱动和挂在它下面的设备相匹配,那么就会调用驱动里面相应的函数,来获取设备里面相应的硬件信息,从而来初始化硬件设备。简而言之,这三个东西就是对应三个结构体,那么按照这个模型,写驱动,其实就是填充对应的结构体:

struct bus_type {
    const char  *name;            //bus的名字
    const char  *dev_name;
    struct device  *dev_root;
    struct device_attribute *dev_attrs; /* use dev_groups instead */
    const struct attribute_group **bus_groups;
    const struct attribute_group **dev_groups;
    const struct attribute_group **drv_groups;
    
    int (*match)(struct device *dev, struct device_driver *drv);   //device和driver的匹配函数
    ...
};
struct device {
    struct device  *parent;
    struct device_private *p;
    struct kobject kobj;
    const char  *init_name; /* initial name of the device */
    const struct device_type *type;
    struct bus_type *bus;  /* type of bus device is on */     //表示这个device挂在哪个bus下面
    struct device_driver *driver; /* which driver has allocated this device */
    void  *platform_data; 
    struct device_node *of_node; /* associated device tree node */
 ...
};
struct device_driver {
    const char  *name;        //driver的名字
    struct bus_type  *bus;       //表示这个driver挂在哪个bus下面
    struct module  *owner;
    const char  *mod_name; /* used for built-in modules */
    const struct of_device_id *of_match_table;
    
    int (*probe) (struct device *dev);
    int (*remove) (struct device *dev);
    void (*shutdown) (struct device *dev);
    int (*suspend) (struct device *dev, pm_message_t state);
    int (*resume) (struct device *dev);
    const struct dev_pm_ops *pm;
    ...
};

bus_dev_drv模型是一个泛型的概念,根据具体的总线,就会衍生出具体的总线模型,比如i2c总线模型,spi总线模型,platform虚拟总线模型,那么接下来具体讲的就是platform总线模型,后续再说I2C等总线模型:
有些驱动(LED、PWM等)没有挂在具体的总线上面,但是也想使用bus_dev_drv模型,那么就需要虚拟一个bus,我们称为platform_bus_type,那么对应的设备称之为platform_device,继承于或者说派生于struct device结构体(面向对象思想),对应的驱动称之为platform_driver,继承于或者说派生于struct device_driver结构体:

struct bus_type platform_bus_type = {
    .name  = "platform",
    .dev_groups = platform_dev_groups,
    .match  = platform_match,        //用来匹配platform_device和对应的platform_driver
    .uevent  = platform_uevent,
    .pm  = &platform_dev_pm_ops,
};
struct platform_device {
    const char *name;   //platform_device的名字
    int  id;
    bool  id_auto;
    struct device dev;  //表示platform_driver是继承于(用面向对象思想,不严谨,但便于理解)device_driver
    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 *);   //如何platform总线探测到它下面挂的某个driver和device匹配,那么就会调用对应的drv下面的probe函数
    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;   //表示platform_driver是继承于(用面向对象思想,不严谨,但便于理解)device_driver
    const struct platform_device_id *id_table;
    bool prevent_deferred_probe;
};

下面我们重点分析下platform_match函数,看bus是如何进行device和driver的匹配的:

static int platform_match(struct device *dev, struct device_driver *drv)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct platform_driver *pdrv = to_platform_driver(drv);
    
    //如果探测到是设备树的格式,那么就按照设备树的方式匹配(后续再说设备树)
    /* Attempt an OF style match first */
    if (of_driver_match_device(dev, drv))
        return 1;
        
    //如果drv里面id_table选项初始化了,那么就按照match_id的方式进行匹配,后面再讲
    /* Then try to match against the id table */
    if (pdrv->id_table)
        return platform_match_id(pdrv->id_table, pdev) != NULL;
        
    //如果上面的匹配方式都没有探测到,那么就用最简单的名字进行匹配,其实就是比较    platform_device->name和platform_driver->drv->name
    //如果这两个name一样,那么就代表传进来的device和driver是对应同一个设备的,接下来就会调用driver的probe函数去操作device了
    /* fall-back to driver name match */
    return (strcmp(pdev->name, drv->name) == 0);
}

3. 平台总线框架工作流程

编写代码,从两个部分入手–device和driver
device:

  1. 分配并设置一个platform_device结构体
  2. 将这个platform_device结构体注册到platform_bus上面 – platform_device_register
  3. 注册成功后,platform_bus会去遍历这个bus上面的所以platform_driver,如果某个platform_driver里面的name和当前注册的这个platform_device的name一样(其实就是执行platform_match函数),那么就调用这个platform_driver里面的probe函数。

driver:
4. 分配并设置一个platform_driver结构体
5. 将这个platform_driver结构体注册到platform_bus上面 – platform_driver_register
6. 注册成功后,platform_bus会去遍历这个bus上面的所以platform_device,如果某个platform_device里面的name和当前注册的这个platform_driver的name一样(其实就是执行platform_match函数),那么就调用这个platform_driver里面的probe函数。

图析:
在这里插入图片描述

4. 代码实例

paltform_device代码:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>

static struct platform_device hello_device = {
    .name = "hello device",
};

static int hello_init(void)
{
    printk("%s : %d platform_device_registered\n", __func__, __LINE__);
    
    platform_device_register(&hello_device);
    return 0;
}

static void hello_exit(void)
{
    printk("%s : %d platform_device_unregistered\n", __func__, __LINE__);
    
    platform_device_unregister(&hello_device);
}

MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);

paltform_driver代码:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/platform_device.h>

int hello_probe(struct platform_device * pdev)
{
    printk("%s : %d match ok, probed\n", __func__, __LINE__);
    return 0;
}

int hello_remove(struct platform_device * pdev)
{
    printk("%s : %d platform_driver has been removed\n", __func__, __LINE__);
    return 0;
}

static struct platform_driver hello_driver = {
    .driver = {
        .name = "hello device",
    },
    
    .probe = hello_probe,
    .remove = hello_remove,     //device和driver匹配成功后,当device或者driver中的任意一个被从bus中卸载后,就会立马执行这个remove函数
};

static int hello_init(void)
{
    printk("%s : %d platform_driver_has been registered\n", __func__, __LINE__);
    
    platform_driver_register(&hello_driver);
    return 0;
}

static void hello_exit(void)
{
    printk("%s : %d platform_driver_has been unregistered\n", __func__, __LINE__);
    
    platform_driver_unregister(&hello_driver);
}

MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);

测试:

  1. 分别用Makefile将platform_device和platform_driver编译成对应的ko文件
  2. 分别通过insmod命令将device和driver注册到总线上,然后分析log会发现:只有device和driver的name一样,且都注册成功,probe函数才会被调用。

5. device如何描述硬件信息以及driver如何获取device的硬件信息?

paltform_device结构体中有两个重要的成员,这两个成员就是用来描述硬件资源信息的:

u32  num_resources;                 //用来描述硬件资源的数量
struct resource *resource;          //结构体数组,用来描述具体的硬件资源

我们要操作的硬件资源,无非是寄存器地址,内存地址,或者是引脚号中断号等,用这个resource结构体即可描述:

struct resource {
    resource_size_t start;   
    resource_size_t end;
    const char *name;
    unsigned long flags;  //IORESOURCE_MEM(地址资源)  IORESOURCE_IO(IO ports资源) IORESOURCE_IRQ(中断资源)
    unsigned long desc;
    struct resource *parent, *sibling, *child;
};

实例,描述了两个资源(一个寄存器地址资源和一个中断号资源,资源的类型是通过flags成员来确定的)的hello_res结构体:

struct resource hello_src[] = {
    {
        .start = 0x18000000,
        .end   = 0x18000004,
        .flags = IORESOURCE_MEM
    },
    {
        .start = 0x11,
        .end   = 0x11,
       .flags = IORESOURCE_IRQ
    },
    {},
};

那么driver如何获取这些资源呢?在driver里面调用下面的函数即可:

6. 添加硬件资源后的代码实例

device:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/platform_device.h>

struct resource hello_res[] = {
    {
        .start = 0x18000000,
        .end = 0x18000004,
        .flags = IORESOURCE_MEM,
    },
    {
        .start = 0x18000010,
        .end = 0x18000014,
        .flags = IORESOURCE_MEM,
    },
    {
        .start = 0x9,
        .end = 0x9,
        .flags = IORESOURCE_IRQ,
    },
};

struct platform_device hello_device = {
    .name = "hello device",
    .num_resources = ARRAY_SIZE(hello_res),
    .resource = hello_res,
};

static int hello_init(void)
{
    printk("%s : %d platform_device_registered\n", __func__, __LINE__);
    
    platform_device_register(&hello_device);
    return 0;
}

static void hello_exit(void)
{
    printk("%s : %d platform_device_unregistered\n", __func__, __LINE__);
    platform_device_unregister(&hello_device);
}

MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);

driver:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/platform_device.h>

int hello_probe(struct platform_device * pdev)
{
    struct resource * res;
    printk("%s : %d match ok, probed\n", __func__, __LINE__);
    
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (NULL == res)
    {
        printk("%s : %d get resource err\n", __func__, __LINE__);
        return -1;
    }
    printk("%s : %d res.start:0x%x  res.end:0x%x\n", __func__, __LINE__, (unsigned int)res[1].start, (unsigned int)res->end);       //注意观察log
    
    res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    if (NULL == res)
    {
        printk("%s : %d get resource err\n", __func__, __LINE__);
        return -1;
    }
    printk("%s : %d res.start:0x%x  res.end:0x%x\n", __func__, __LINE__, (unsigned int)res->start, (unsigned int)res->end);
    
    return 0;
}

int hello_remove(struct platform_device * pdev)
{
    printk("%s : %d platform_driver has been removed\n", __func__, __LINE__);
    return 0;
}

struct platform_driver hello_driver = {
    .driver = {
        .name = "hello device",
    },
    
    .probe = hello_probe,
    .remove = hello_remove,
};

static int hello_init(void)
{
    printk("%s : %d platform_driver_has been registered\n", __func__, __LINE__);
    
    platform_driver_register(&hello_driver);
    return 0;
}

static void hello_exit(void)
{
    printk("%s : %d platform_driver_has been unregistered\n", __func__, __LINE__);
    platform_driver_unregister(&hello_driver);
}

MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);

那么对于4.x以后的Linux内核,不再使用platform_device来描述设备信息了,而改用的设备树来进行描述(这里暂时对设备树不做详细解释),更为简洁清晰:
设备树一般存放在kernel的arch/arm/boot/dts这个目录下,高通的代码通常放在arch/arm64/boot/dts/qcom目录下,设备树是一个描述设备信息的文件(dts),由一系列的节点构成的,而节点里面使用键值对(key-val)的形式来描述硬件信息的,通过节点中compatible和驱动进行匹配要想使用设备树来对一个硬件设备进行描述,无非就是在相应的dts文件或者dtsi文件中加入一个节点,例如:

 xxx @0x12345678{
    compatible = "qcom, test";
    a = "hello world";
    b = <2>;
    c = <0x40000000 4>;
    ...
 };

注意,当我们加入新的节点时,一定要包含在根节点的某个大的节点里面。其中xxx为你加入的新的节点的名字,@0x12345678是一个可有可无的东西,当有多个重名节点时,@后面加数字可以区分不同的节点,compatible属性是节点中必须存在的,用来和driver进行匹配,一旦匹配成功,就会执行driver中的probe函数。其中a、b、c为三个自定义属性的名字,分别表示字符串,单个int数据,数组。开发时可以根据需要在对应的节点中加入需要的属性。

最后,我们的driver如何描述,才能匹配这个节点呢?那么就必须要初始化platform_driver中的of_match_table成员了,这个在前面分析bus总线中的match匹配函数时说过:

 struct of_device_id hello_table_id[] = {
     {.compatible = "qcom, test"},                  
     {},
 };
 
 struct platform_driver hello_driver = {
     .driver = {
         .name = "hello device",
         .of_match_table = hello_table_id,
     },
    .probe = hello_probe,
    .remove = hello_remove,
};

前面分析bus的match函数时说过,match的时候有一定的顺序,先进行设备树的匹配,如果探测到of_match_table被设置,那么就去遍历dts寻找是否有节点的compatible属性的值和of_match_table中设置的compatible值一样,如何一样就代表匹配成功,并执行probe函数,如果有多个节点的compatible属性值都一样,那么probe就会被执行多次,直至将整个dts中的节点遍历完毕,同时,driver中的name也不会去寻找device结构体去匹配了。这个就是优先级的问题(看match函数即可知)。

然后就是有童鞋有疑问,我们的platform_driver不管是匹配bus的dev链表中的platform_device结构体,还是匹配设备树,最终都会执行同一个probe函数,那么设备树节点的硬件参数是如何传进probe函数的?看我们的probe函数

int hello_probe(struct platform_device * pdev)

首先要看probe的参数platform_device结构体,它里面有一个成员:struct device dev; 前面说过,可以用继承的思想来理解,platform_device继承了device结构体,而device结构体中有一个成员:struct device_node *of_node; 这个of_node成员就对应匹配到的设备树的节点,然后我们可以在probe函数中根据dts的of系列函数来获取资源:

int of_get_named_gpio(struct device_node *np, const char *propname, int index)
int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value)
int of_property_read_string(const struct device_node *np, const char *propname, const char **out_string);
...

linux设备驱动的模型详解 一、什么是设备驱动模型 (1)类class、总线bus、设备device、驱动driver 四个结构体 (2)kobject和对象生命周期 (3)sysfs cat 查看属性信息 、 echo 往里面写东西 (4)udev 同步信息2、设备模型解决了一些什么问题? (1)设备驱动模型负责统一实现和维护一些特性,诸如:电源管理、热插拔、对象生命周期、用 阅读详情

相关推荐

从零搭建AGV避障系统:我用激光雷达+树莓派视觉模块踩过的那些坑

本文分享了基于树莓派与国产激光雷达从零搭建低成本AGV避障系统的实战经验。针对复杂仓库环境,详细剖析了激光雷达数据噪声、视觉模块算力瓶颈、IMU漂移等核心挑战,并提供了多传感器融合、软件架构设计与避障决策的具体解决方案,为中小型自动化改造项目提供了宝贵参考。

git9versioner的博客 983

linux驱动-设备驱动模型(driver驱动)

bus_add_driver 会创建下面节点/ sys / bus / xxx / drivers / drv -> name / sys / bus / xxx / drivers / drv -> name / uevent /* 支持 suppress_bind_attrs */ / sys / bus / xxx / drivers / drv -> name / unbind / sys / bus / xxx / drivers / drv -> name / bind。

sty01z的博客 1306

海康威视国内版监控设备改英文界面难题:原因解析与解决方案

跨境安防设备部署中,国内采购的海康威视监控设备常因仅支持中文界面导致海外用户无法操作。本文剖析了该问题的核心原因:海康威视对国内版和海外版设备实行区域锁定策略,国内版固件仅内置中文且无法通过常规方式切换语言。针对此问题,文章提供了三种解决方案:1)官方合规的海外版固件更换;2)低成本的操作界面翻译与远程协助;3)长期更换海外版设备的彻底解决方案。同时给出了跨境采购的注意事项,强调应提前确认设备版本、拒绝非官方改造并预留适配时间。

海康威视技术支持 3943

探究Linux的总线、设备、驱动模型

理解Linux的总线、设备、驱动模型是理解Linux驱动框架的关键,也是破解Linux为什么极易移植到不同的平台,以及被如此多广泛领域使用根源的关键。我的优快云直播将以浅显易懂地语言,深入地把这一模型剖析清楚,道出这样的设计的好处。

Win10安全模式下修改C盘权限的完整指南(附解决开始菜单失灵方案)

本文提供了一份在Win10安全模式下修复因C盘权限误改导致开始菜单失灵的完整指南。文章深入剖析了权限体系,特别是TrustedInstaller角色的重要性,并详细讲解了通过安全模式进入系统、使用ICACLS命令或图形界面精准重置C盘关键目录权限的步骤,最终恢复系统核心功能。

weixin_29250403的博客 233

STM32移植u8g2库(HAL库)(硬件SPI)(sh1106_128x64)

STM32移植u8g2库(HAL库)(硬件SPI)(sh1106_128x64) MCU型号为STM32F103RCT6,OLED屏为中景园电子1.3寸屏,驱动芯片为sh1106,分辨率为128x64,MDK版本为V5.34。

Master_0_的博客 6270

Linux驱动开发实战(一)——设备驱动模型

在早期的Linux内核中并没有为设备驱动提供统一的设备模型。随着内核的不断扩大及系统更加复杂,编写一个驱动程序越来越困难,所以在Linux2.6内核中添加了一个统一的设备模型。这样,写设备驱动程序就稍微容易一些了。本章将对设备模型进行详细的介绍。设备驱动模型比较复杂,Linux系统将设备和驱动归一到设备驱动模型中来管理。设备驱动模型的提出,解决了以前编写驱动程序没有统一方法的局面。设备驱动模型给各种驱动程序提供了很多辅助性的函数,这些函数经过严格测试,可以很大程度上地提高驱动开发人员的工作效率。

m0_56145255的博客 3357

​非线性分析-增加位移量可能出现下面错误。虽然求解无法在所有时间点完成,但在某些点上仍能够求解部分结果。请参阅“帮助系统”中的故障排除,以了解更多信息详情。由于受约束,规划求解引擎无法收敛

基于收敛状态拆分载荷步‌:在已收敛的载荷步基础上,将未收敛的关键区域拆分为更细的子步,比如在载荷突变点前设置5~10个子步,逐步加载。替换冲突约束为弱约束‌:若存在约束冲突,将刚性约束替换为弱弹簧约束(刚度设为1e-6~1e-4),既限制刚体位移,又不影响结构的变形自由度,命令流:SPRING, NODE, K, 1e-6。部分区域约束完整,但存在未被约束的刚体自由度,或约束类型与大变形/接触逻辑冲突,比如某部件的位移约束在初始阶段有效,但大变形后约束位置脱离实际受力点,导致求解器在该阶段无法收敛。

qq_15963745的博客 143

linux驱动 平台设备驱动模型

文章目录一、设备驱动模型的三大组件1. 总线1. 总线、设备、驱动关系2. 总线数据结构 bus_type3.bus_type声明实例4.总线私有数据bus_type_private5.总线注册bus_register()2. 总线属性和总线方法1. 总线的属性bus_attribute2. 创建和删除总线属性3. 总线上的方法3. 设备1. device结构体2. 设备注册和注销3. 设备属性4. 驱动1. 设备驱动device_driver2. 驱动举例3. 驱动程序注册和注销4. 驱动的属性二、平台设

weixin_42109053的博客 7016

基于Verilog的8位CPU设计及UART扩展实现方案,包含完整的架构设计、核心代码实现和仿真验证方法

基于Verilog的8位CPU设计及UART扩展实现方案,包含完整的架构设计、核心代码实现和仿真验证方法

a_zxswer的博客 186

从 Junior 到 Lead:ABAP 开发者进阶路线图与真实项目练级法

本文拆解了ABAP工程师从初级到高级的成长路径,强调能力提升依赖于可复用经验的积累。对于初级开发者,建议夯实ABAP Dictionary、内表处理和数据库思维三大基础,培养数据流与规则层的结构化思维,并逐步掌握面向对象编程。中级阶段应注重代码可维护性,通过单元测试和Clean ABAP规范提升工程质量。文章指出,ABAP开发者需要学会筛选学习重点,建立知识地图,并重视团队协作中的代码可读性。关键在于将碎片知识整合为可迁移的模型,而非盲目追求新技术。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 171

Linux设备驱动模型

是这是一个比较抽象的概念,并无明确的定义,它是linux内核为了管理硬件上的设备和对应的驱动制定的一套软件体系。以上(1)、(2)、(3)、(4)等都属于设备驱动模型的范畴。

生活需要深度 1265

YOLOv11 模型轻量化全流程:从剪枝到量化,打造移动端“极速检测利器”

将浮点模型量化为INT8模型,减少内存占用并加速推理。# 加载剪枝后的模型# 转换为TorchScript# 静态量化# 保存量化模型量化后模型推理速度可再提升20%,而mAP损失小于1%。

m0_64661770的博客 464

LINUX设备驱动模型分析之一 总体概念说明

这段时间阅读了LINUX SYSFS模块的代码,并完成了相应的学习笔记,阅读这些代码,为我们分析LINUX设备驱动模型提供了基础。下面这一段时间我将分析LINUX设备驱动模型。 本次分析的LINUX设备驱动模型,主要涉及如下几个部分: 一、LINUX设备驱动模型总体概述 二、LINUX总线(BUS)接口分析 三、LINUX设备(DEVICE)接口...

lickylin的专栏 2584

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

LINUX设备驱动模型之class

1、LINUX设备驱动模型中的bus、device、driver,。其中bus:实际的总线,device:实际的设备和接口,而driver:对应存在的驱动。 2、但本节要介绍的class,是设备类,完全是抽象出来的概念,没有对应的实体。所谓设备类,是指提供的用户接口相似的一类设备的集合,常见的设备类的有block、tty、input、usb等等。 3、class对应的代码在drivers/ba

当我荒废时间的时候,会有多少人在拼命 3288

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

linux驱动开发—— 6、linux 设备驱动模型

设备驱动模型一、linux设备驱动模型简介 一、linux设备驱动模型简介 1、什么是设备驱动模型 设备驱动模型其实是Linux内核为了管理硬件上的设备和对应的驱动制定的一套软件体系。那么其实设备驱动模型是一个比较抽象、比较广的一个概念,一两句话是很难说清楚的,类(class)、总线(bus)、设备(device)、驱动(driver)、mdev(自动创建设备节点和设备类)sysfs等都属于设备驱动模型的范畴。 (1)类class、总线bus、设备device、驱动driver 1、都是 Linux 里面

vincent3678的博客 3853

Linux 设备驱动模型

本质:描述硬件特性的数据结构职责声明硬件资源(内存地址、中断号、寄存器映射等)描述设备唯一标识(如 PCI 厂商/设备 ID)提供设备树(Device Tree)兼容性标识本质:操作硬件的软件接口职责实现设备操作方法(probe()remove()注册字符/块/网络设备接口处理中断和数据传输管理电源状态组件角色生命周期依赖关系设备硬件描述符内核启动/热插拔时创建不依赖特定驱动驱动硬件操作器模块加载时注册依赖设备存在总线匹配中介内核初始化时建立。

X 1052

Linux设备驱动模型实验

尝试在Linux内核中建立自己的总线,在总线下创建设备和设备驱动,并导出属性文件到用户空间。

weixin_43908963的博客 1253

linux设备驱动模型

linux设备驱动模型分析

风雨无阻 2338

linux驱动 设备驱动模型

前言 在早期的Liux内核中并没有为设备驱动提供统一的设备模型。随着内核的不断扩大及系统更加复杂,编写一个驱动程序越来越困难,所以在Liux2.6内核中添加了一个统一的设备模型。这样,写设备驱动程序就稍微容易一些了。本章将对设备模型进行详细的介绍。 一、设备驱动模型概述 设备驱动模型比较复杂,Lux系统将设备和驱动归一到设备驱动模型中来管理。设备驱动模型的提出,解决了以前编写驱动程序没有统一方法的局面。设备驱动模型给各种驱动程序提供了很多辅助性的函数,这些函数经过严格测试,可以很大程度地提高驱动开发人员的

weixin_42109053的博客 2804

LINUX设备驱动模型简介

××××××××××××××LINUX设备驱动模型简介×××××××××××××××××第一部分————————————————————————————————————- 1.linux设备驱动模型简介 2.设备驱动模型的底层架构:类,总线,设备,驱动,platform3.实践:使用设备驱动模型来加载上一个led驱动1.linux设备驱动模型简介 《1》什么是设备驱动模型将一个概念时怎样讲明白

love23_linuxer的博客 665

Linux设备驱动模型1——设备驱动模型的简介与底层架构

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

主要记录嵌入式学习与开发过程。 2315
上一篇: (四)Linux设备驱动之多个同类设备共用一套驱动
下一篇: (六)Linux驱动子系统-I2C子系统驱动
hanp_linux
博客等级 码龄10年 139粉丝 22原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值