usb摄像头驱动-core层driver.c

news2024/9/30 11:33:19

usb摄像头驱动-core层driver.c


文章目录

  • usb摄像头驱动-core层driver.c
  • usb_bus_type
    • usb_device_match
    • usb_uevent
  • usb_register_driver


在这里插入图片描述

在这里插入图片描述

在ubuntu中接入罗技c920摄像头打印的信息如下:
在这里插入图片描述

在内核中,/driver/usb/core/driver.c 文件扮演了 USB 核心驱动程序管理的重要角色。该文件包含了 USB 核心驱动程序的实现,负责管理和调度 USB 设备的注册、匹配、连接和断开等操作。
具体而言,driver.c 文件的功能和作用包括:
USB 驱动程序的注册和注销:该文件实现了 usb_register_driver 和 usb_deregister_driver 函数,用于注册和注销 USB 驱动程序。

USB 设备的匹配和连接:通过实现 usb_match_id 函数和 usb_probe_interface 函数,该文件负责在 USB 子系统中进行设备的匹配和连接。当 USB 设备插入时,USB 核心会调用 usb_probe_interface 函数,以便驱动程序对设备进行初始化和配置。

USB 设备的断开和注销:通过实现 usb_disconnect 函数和 usb_remove_interface 函数,该文件负责在 USB 设备断开时执行相应的操作。当 USB 设备断开连接时,USB 核心会调用 usb_disconnect 函数,以便驱动程序对设备进行清理和注销。

驱动程序与 USB 接口的关联:通过实现 usb_register_interface 和 usb_deregister_interface 函数,该文件负责将驱动程序与 USB 接口进行关联。这样,在 USB 设备连接时,USB 核心可以根据驱动程序与接口的关联关系,选择正确的驱动程序来处理设备。

USB 驱动程序的挂起和恢复:通过实现 usb_suspend_interface 和 usb_resume_interface 函数,该文件处理 USB 设备的挂起和恢复操作。当 USB 设备进入挂起状态或从挂起状态恢复时,USB 核心会调用相应的函数通知驱动程序执行相应的操作。

总结起来,/driver/usb/core/driver.c 文件在内核中扮演了 USB 核心驱动程序管理的关键角色。它实现了 USB 驱动程序的注册、匹配、连接和断开等功能,负责与 USB 子系统协作,管理 USB 设备的初始化、配置和操作等操作。该文件的功能对于整个 USB 子系统的正常运行至关重要。

usb_bus_type

在/driver/usb/core/driver.c文件中,下面的内容定义了一个名为usb_bus_type的struct bus_type结构体,并对其成员进行了初始化。该结构体用于表示USB总线类型,并定义了与USB总线相关的操作。
具体来说,下面的内容的作用如下:
.name = “usb”:设置总线类型的名称为"usb",用于标识USB总线。
.match = usb_device_match:指定匹配函数为
usb_device_match。匹配函数用于在插入USB设备时判断该设备是否与该总线类型的驱动程序匹配。
.uevent = usb_uevent:指定uevent函数为
usb_uevent。uevent函数用于生成和发送与USB设备插入和拔出相关的uevent事件。
这些成员的初始化可以使USB核心了解USB总线类型,并在需要的时候调用相应的函数,从而实现与USB总线相关的操作和事件处理。
在实际使用中,USB总线类型结构体usb_bus_type会与具体的USB驱动程序进行关联,以便在USB设备插入和拔出时触发相应的操作。这样,当有新的USB设备插入时,USB核心会调用匹配函数进行驱动程序的匹配,并根据匹配结果调用相应的probe函数来初始化和配置驱动程序与设备的连接。同时,uevent函数可以生成和发送uevent事件,通知用户空间有关USB设备的信息变化。

/* USB总线类型结构体 */
struct bus_type usb_bus_type = {
    /* 名称 */
    .name =     "usb",
    /* 匹配函数 */
    .match =    usb_device_match,
    /* uevent函数 */
    .uevent =   usb_uevent,
};

usb_device_match

static int usb_device_match(struct device *dev, struct device_driver *drv)
{
    /* devices and interfaces are handled separately */
    if (is_usb_device(dev)) { // 如果是 USB 设备

        /* interface drivers never match devices */
        if (!is_usb_device_driver(drv)) // 如果不是 USB 设备驱动
            return 0;

        /* TODO: Add real matching code */ // TODO: 添加真正的匹配代码
        return 1;

    } else if (is_usb_interface(dev)) { // 如果是 USB 接口
        struct usb_interface *intf;
        struct usb_driver *usb_drv;
        const struct usb_device_id *id;

        /* device drivers never match interfaces */
        if (is_usb_device_driver(drv)) // 如果是 USB 设备驱动
            return 0;

        intf = to_usb_interface(dev); // 获取 USB 接口
        usb_drv = to_usb_driver(drv); // 获取 USB 驱动

        id = usb_match_id(intf, usb_drv->id_table); // 匹配 USB 设备 ID
        if (id)
            return 1;

        id = usb_match_dynamic_id(intf, usb_drv); // 匹配动态 USB 设备 ID
        if (id)
            return 1;
    }

    return 0;
}

该函数的作用是判断USB设备和设备驱动是否匹配,用于设备与驱动之间的匹配过程。
函数的主要步骤如下:
首先判断设备类型,如果是USB设备,则执行设备匹配逻辑;如果是USB接口,则执行接口匹配逻辑。
如果是USB设备,首先判断驱动类型是否为USB设备驱动。如果是USB设备驱动,返回0,表示设备和驱动不匹配。如果不是USB设备驱动,执行后续的实际匹配代码(TODO:此处需要添加真正的匹配代码),并返回1表示设备和驱动匹配。
如果是USB接口,首先获取USB接口和USB驱动的相关信息。然后调用
usb_match_id函数,通过USB设备ID表来匹配USB设备ID。如果匹配成功,返回1表示设备和驱动匹配。如果未匹配成功,调用
usb_match_dynamic_id函数,通过动态USB设备ID匹配来匹配设备和驱动。如果匹配成功,返回1表示设备和驱动匹配。
如果以上都不匹配,则返回0表示设备和驱动不匹配。
该函数在USB核心中用于设备和驱动的匹配过程。当有USB设备或接口与设备驱动进行匹配时,USB核心会调用该函数来判断设备和驱动是否匹配,从而确定是否加载对应的驱动程序。

usb_uevent

static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
{
    struct usb_device *usb_dev;

    if (is_usb_device(dev)) { // 如果是 USB 设备
        usb_dev = to_usb_device(dev); // 获取 USB 设备
    } else if (is_usb_interface(dev)) { // 如果是 USB 接口
        struct usb_interface *intf = to_usb_interface(dev); // 获取 USB 接口
        usb_dev = interface_to_usbdev(intf); // 获取 USB 设备
    } else {
        return 0; // 如果不是 USB 设备或 USB 接口,返回 0
    }

    if (usb_dev->devnum < 0) { // 如果设备号小于 0
        /* driver is often null here; dev_dbg() would oops */
        pr_debug("usb %s: already deleted?\n", dev_name(dev)); // 打印调试信息
        return -ENODEV; // 返回错误码
    }
    if (!usb_dev->bus) { // 如果设备总线不存在
        pr_debug("usb %s: bus removed?\n", dev_name(dev)); // 打印调试信息
        return -ENODEV; // 返回错误码
    }

    /* per-device configurations are common */ // 常见的每个设备的配置
    if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
               le16_to_cpu(usb_dev->descriptor.idVendor),
               le16_to_cpu(usb_dev->descriptor.idProduct),
               le16_to_cpu(usb_dev->descriptor.bcdDevice))) // 添加设备信息
        return -ENOMEM; // 返回错误码

    /* class-based driver binding models */ // 基于类的驱动程序绑定模型
    if (add_uevent_var(env, "TYPE=%d/%d/%d",
               usb_dev->descriptor.bDeviceClass,
               usb_dev->descriptor.bDeviceSubClass,
               usb_dev->descriptor.bDeviceProtocol)) // 添加设备类型信息
        return -ENOMEM; // 返回错误码

    return 0; // 返回成功
}

该函数的作用是处理USB设备的uevent事件,即生成与USB设备插入和拔出相关的环境变量,并将其添加到uevent环境中。
函数的主要步骤如下:
判断设备类型,如果是USB设备,则获取USB设备;如果是USB接口,则获取对应的USB设备。
检查设备号和设备总线的有效性。如果设备号小于0或设备总线不存在,打印调试信息并返回错误码。
通过
add_uevent_var函数将设备的产品信息(vendor ID、product ID和device version)添加到uevent环境中。
通过
add_uevent_var函数将设备的类型信息(device class、device subclass和device protocol)添加到uevent环境中。
返回成功。
该函数在USB核心中起到了生成与USB设备插入和拔出相关的uevent事件的作用。当有USB设备插入或拔出时,USB核心会调用该函数来获取设备的相关信息,并生成相应的uevent事件,通知用户空间进行设备的动态管理和配置

usb_register_driver

/driver/usb/core/driver.c
函数 usb_register_driver 用于注册一个 USB 驱动程序,并将其与 USB 子系统进行关联。它的作用是告诉 USB 子系统,有一个新的驱动程序可用于管理特定类型的 USB 设备。
该函数的参数包括:
new_driver:指向 usb_driver 结构的指针,表示要注册的驱动程序。
owner:指向驱动程序所属内核模块的指针,通常是使用 THIS_MODULE 宏。
mod_name:表示驱动程序所属模块的名称,用于标识该驱动程序。
usb_register_driver 函数在驱动程序初始化阶段调用,通常在驱动程序的入口点函数中使用。当驱动程序调用 usb_register_driver 注册成功后,USB 子系统会将该驱动程序添加到其驱动程序列表中,并在有匹配的 USB 设备插入时调用该驱动程序的相应回调函数。
驱动程序注册后,USB 子系统会与该驱动程序进行协作,以匹配和管理符合驱动程序定义的设备。当插入符合驱动程序定义的 USB 设备时,USB 子系统会调用驱动程序中的回调函数来执行设备的初始化、配置、数据传输和管理等操作。
总结起来,usb_register_driver 函数的作用是将一个 USB 驱动程序注册到 USB 子系统中,以便USB子系统能够调用驱动程序的相应回调函数来管理特定类型的USB设备。通常在驱动程序初始化阶段调用该函数。

int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
            const char *mod_name)
{
    int retval = 0;

    if (usb_disabled())
        return -ENODEV;

    // 设置驱动的相关信息
    new_driver->drvwrap.for_devices = 0; // 0表示注册的是接口驱动
    new_driver->drvwrap.driver.name = new_driver->name; // 驱动名
    new_driver->drvwrap.driver.bus = &usb_bus_type; // 驱动所属总线
    new_driver->drvwrap.driver.probe = usb_probe_interface; // 探测函数
    new_driver->drvwrap.driver.remove = usb_unbind_interface; // 卸载函数
    new_driver->drvwrap.driver.owner = owner; // 模块所有者
    new_driver->drvwrap.driver.mod_name = mod_name; // 模块名
    spin_lock_init(&new_driver->dynids.lock); // 初始化动态ID锁
    INIT_LIST_HEAD(&new_driver->dynids.list); // 初始化动态ID链表

    // 注册驱动
    retval = driver_register(&new_driver->drvwrap.driver);
    if (retval)
        goto out;

    // 创建新ID文件
    retval = usb_create_newid_files(new_driver);
    if (retval)
        goto out_newid;

    pr_info("%s: registered new interface driver %s\n",
            usbcore_name, new_driver->name);

out:
    return retval;

out_newid:
    driver_unregister(&new_driver->drvwrap.driver);

    printk(KERN_ERR "%s: error %d registering interface "
            "   driver %s\n",
            usbcore_name, retval, new_driver->name);
    goto out;
}
EXPORT_SYMBOL_GPL(usb_register_driver);

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

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

相关文章

自动化遍历测试技术之android maxim遍历测试工具

这里写目录标题 一、问题1、例如app中存在问题2、解决方法3、改进策略4、自动遍历测试5、常见遍历工具与技术 二、android maxim 遍历测试工具策略使用环境预备命令行模式策略 三、android fastbot 遍历测试工具使用 一、问题 业务线众多 业务流程复杂 依赖传统券商一些资源 …

2023年最新软件测试面试题,自动化测试面试题,接口自动化测试面试题详解,对标大厂。

【软件测试面试题】 1、你的测试职业发展是什么&#xff1f;   测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程…

软件测试之性能测试

性能测试是与时间相关的。 主要内容 性能测试基础概念和术语介绍性能测试模型性能测试分类介绍性能测试实施与管理 性能测试基础 为什么要进行性能测试&#xff08;WHY&#xff09;&#xff08;最重要&#xff09; 应用程序是否能够很快的响应用户的要求&#xff1f;应用程…

【C程序设计】——程序=算法+数据结构

目录 &#x1f34a;&#x1f34a;一、什么是算法&#xff1f; &#x1f34a;&#x1f34a;二、简单的算法举例 &#x1f34a;&#x1f34a;三、算法的特性 &#x1f34a;&#x1f34a;四、怎样表示一个算法 一个程序主要包括以下两方面的信息&#xff1a; &#xff08;1&am…

软件测试项目实战经验附视频以及源码【商城项目,app项目,电商项目,银行项目,医药项目,金融项目】

前言&#xff1a; ​​大家好&#xff0c;我是凡叔。 很多初学的测试小白都在烦恼找不到合适的项目去练习&#xff0c;这也是难倒大部分测试小白的一个很常见的问题&#xff0c;项目经验确实是每一个测试非常宝贵的经验&#xff01;这里凡叔给大家找了一些常用的项目合集&…

数据结构与算法十二 图进阶

一 有向图 在实际生活中&#xff0c;很多应用相关的图都是有方向性的&#xff0c;最直观的就是网络&#xff0c;可以从A页面通过链接跳转到B页面&#xff0c;那么a和b连接的方向是a->b,但不能说是b->a,此时我们就需要使用有向图来解决这一类问题&#xff0c;它和我们之前…

行业集体迈进全屋智能,华为的“空间智能跃升”独领风骚?

智能家居近年来发展飞速&#xff0c;市场正在从最初的单品智能向全屋联动智能切换。 据IDC数据&#xff0c;2022年中国全屋智能市场销售额突破100亿元&#xff0c;同比增长54.9%。一个住宅往往由卧室、客厅、厨房、卫生间、餐厅等多个基本功能区组成&#xff0c;全屋智能便是在…

企业进行产品管理内训至少有这5大好处

企业需要重视产品管理&#xff0c;建立完善的产品管理流程和标准&#xff0c;提高员工的产品管理能力&#xff0c;以应对各种挑战和机遇&#xff0c;在企业进行内训是最好的方式。 企业进行产品管理内训的目的是为了提高员工的产品管理能力&#xff0c;从而实现以下几个方面的好…

ChatGPT创始人采访 | GPT-4报告中文版

关于采访OpenAl Co创始人 Greg Brockman的要点记录分析&#xff0c;先介绍Gpt-4的基本内容&#xff0c;然后说下采访的重点部分&#xff0c;最后读一下154页Gpt-4的技术报告&#xff0c;这个大家可以在官网下载文档后&#xff0c;百度翻译支持每人限量一次的PDF翻译。面对文心一…

图(课堂笔记)

图的引入与术语 两种图 1. 有向图&#xff08;Digraph&#xff09;&#xff1a;Each edge of arc has an associated direction. 2. 无向图&#xff08;non-directed graph&#xff09;&#xff1a;Every edge or arc is two-way. 简单图是一种特殊的无向图。无向图没有自环…

即时设计是一款什么软件,有什么优势

即时设计是什么软件 即时设计是一款「专业UI设计工具」&#xff0c;不受平台限制&#xff0c;打开浏览器即可开始创作。它不仅具备精细化设计能力&#xff0c;还自带丰富的共享设计资源&#xff0c;同时支持多人实时协作、设计成果一键分享交付&#xff0c;让设计师在工作中每…

C++:使用位图处理海量数据

目录 一. 什么是位图 1.1 海量数据处理问题 1.2 位图的概念 二. 位图的实现 2.1 成员变量及成员函数 2.2 成员函数的实现 2.3 位图模拟实现完整代码 三. 关于位图处理海量数据的几个面试题 一. 什么是位图 1.1 海量数据处理问题 问题&#xff1a;假设有30亿个不重复的…

QT 学习笔记1 创建一个简单的cmd窗口界面

QT creator最大的特点是把界面和逻辑分开了 视频&#xff1a; 3、开发工具-QtCreator 目录 0、新建一个应用项目的步骤 一、设计相关&#xff1a; 1、控件 布局 Layouts 垫子 Spacers ​编辑 按钮 Buttons 单元视图 Item Views(Model-Based) 单元控件 Item Widgets(…

2023年美、英仍是最受欢迎的留学目标国家,硕士占比76%

2023年申请出国留学的时间已经不远了&#xff0c;要想顺利实现留学梦想&#xff0c;希望你能够把握好以下几个要点&#xff1a; 首先&#xff0c;要清楚自己的留学目标&#xff0c;要考虑到自己的学习能力、英语水平、专业设置、学费等因素&#xff0c;以便挑选一个最合适的国…

startActivityForResult被标记为废弃?Activity Result API闪亮登场!

本文已同步发表于我的微信公众号&#xff0c;搜索 代码说 即可关注&#xff0c;欢迎与我沟通交流。 文章目录 startActivityForResult()被标记为过时registerForActivityResult替代方案使用示例ActivityResultContract 场景自定义ActivityResultContract 源码浅析registerForAc…

(4.2)STM32中断系统

目录 1.中断基本概念 2.中断的意义 3.中断处理过程 4. 中断体系结构 5.NVIC 6.EXTI 1.中断基本概念 在处理器中&#xff0c;中断相当于对于突发事件的处理过程。 当遇到内部/外部的紧急事件需要处理时&#xff0c;暂时中止当前程序&#xff0c;转而去处理紧急事件&#xff0c; …

使用 ESP32 UWB DW3000进行测距和定位

什么是超宽带及其工作原理? UWB 是一种类似于蓝牙或 Wi-Fi 的短距离无线通信协议。它还使用无线电波进行通信并以非常高的频率运行。顾名思义,它还使用几 GHz 的宽频谱。可以将其想象成一种雷达,可以连续扫描整个房间并像激光束一样精确锁定物体以发现其位置并传输数据。 超…

08-用户权限控制

1、用户权限控制 权限控制是什么:控制用户对系统资源(URI)的操作。 前端的权限控制:对页面或页面元素的权限控制。 > 页面访问权限:哪些页面可以访问、哪些页面元素可见等等。 > 操作权限:如页面按钮是否可点击、是否可以增删改查等等 后端的权限控制:对接口及…

网络协议之HTTP详细解释

文章目录 前言一.Web发展的阶段二.http协议初识2.1 概念2.2 http的发展史2.3 http协议的作用2.4http协议的格式 三.抓包工具的介绍什么是抓包抓包工具的原理抓包工具的使用和下载- 具体下载过程:- 使用过程 四.HTTP请求请求行请求报头 五.HTTP响应状态行响应报头响应正文 前言 …

Java+Redis实现撤销重做功能

文章目录 1.背景2.需求分析3.实现逻辑分析4.统一过期时间设置5.初始图表栈6.记录图表变化7.撤销操作8.重做操作9.删除图表处理 1.背景 ​ 在一个编辑页面中&#xff0c;存在多个图表&#xff0c;对图表的配置操作允许撤销和重做&#xff1b;撤销和重做只是针对页面中图…