整理uvc驱动相关函数的调用流程

目录

  • 1、uvc_video.c
    • 初始化函数的调用关系
  • 2、uvc_queue.c
  • 3、uvc_v4l2.c
  • 4、v4l2-core
  • 5、数据传输
    • 1、分配一个gadget请求
    • 2、请求一个queue

1、uvc_video.c

// uvc_video.c
uvc_video_encode_header
uvc_video_encode_data
uvc_video_encode_bulk
uvc_video_encode_isoc
uvcg_video_ep_queue
uvc_video_complete
uvc_video_free_requests  //释放video请求
uvc_video_alloc_requests  //分配video请求
uvcg_video_pump  //Pump video data into the USB requests
uvcg_video_enable  //Enable or disable the video stream
uvcg_video_init  //Initialize UVC video stream

初始化函数的调用关系

uvc_function_bind //f_uvc.cuvcg_video_init(&uvc->video, uvc) //f_uvc.c   Initialise videouvcg_queue_init  //uvc_video.c Initialize the video buffers queuevb2_queue_init // videobuf2-v4l2.cvb2_core_queue_init //videobuf2-core.c

2、uvc_queue.c

uvc_queue_setup
uvc_buffer_prepare
uvc_buffer_queue
uvcg_queue_init
uvcg_free_buffers
uvcg_alloc_buffers
uvcg_query_buffer
uvcg_dequeue_buffer
uvcg_queue_poll
uvcg_queue_mmap
uvcg_queue_get_unmapped_area
uvcg_queue_cancel
uvcg_queue_enable
uvcg_queue_next_buffer
uvcg_queue_head

3、uvc_v4l2.c

uvc_send_response
uvc_v4l2_querycap
uvc_v4l2_get_format
uvc_v4l2_set_format
uvc_v4l2_reqbufs
uvc_v4l2_querybuf
uvc_v4l2_qbuf
uvc_v4l2_dqbuf
uvc_v4l2_streamon
uvc_v4l2_streamoff
uvc_v4l2_subscribe_event
uvc_v4l2_unsubscribe_event
uvc_v4l2_extend_configuration
uvc_v4l2_ioctl_default
uvc_v4l2_open
uvc_v4l2_release
uvc_v4l2_mmap
uvc_v4l2_poll
uvcg_v4l2_get_unmapped_area
#define call_qop(q, op, args...)					\
({									\int err;							\\log_qop(q, op);							\err = (q)->ops->op ? (q)->ops->op(args) : 0;			\if (!err)							\(q)->cnt_ ## op++;					\err;								\
})
uvc_function_bind //f_uvc.cuvc_register_video //f_uvc.c 结构体uvc_v4l2_ioctl_ops  //uvc_v4l2.cuvc_v4l2_streamon  //uvc_v4l2.cuvcg_video_enable  //uvc_video.cuvcg_queue_enable  //uvc_queue.cvb2_streamon //videobuf2-v4l2.cvb2_core_streamon //videobuf2-core.cvb2_start_streaming //videobuf2-core.ccall_qop(q, start_streaming, q,atomic_read(&q->owned_by_drv_count)) videobuf2-core.c

4、v4l2-core

参考文章:https://blog.csdn.net/u013836909/article/details/125360024

在这里插入图片描述

//drivers\media\v4l2-core\v4l2-dev.c
static const struct file_operations v4l2_fops = {.owner = THIS_MODULE,.read = v4l2_read,.write = v4l2_write,.open = v4l2_open,.get_unmapped_area = v4l2_get_unmapped_area,.mmap = v4l2_mmap,.unlocked_ioctl = v4l2_ioctl,
#ifdef CONFIG_COMPAT.compat_ioctl = v4l2_compat_ioctl32,
#endif.release = v4l2_release,.poll = v4l2_poll,.llseek = no_llseek,
};
video_register_device //include/media/v4l2-dev.h__video_register_device //drivers/media/v4l2-core/v4l2-dev.c//自动创建设备节点device_register //drivers/media/v4l2-core/v4l2-dev.c	
// include\media\v4l2-dev.h
/*** struct v4l2_file_operations - fs operations used by a V4L2 device** @owner: pointer to struct module* @read: operations needed to implement the read() syscall* @write: operations needed to implement the write() syscall* @poll: operations needed to implement the poll() syscall* @unlocked_ioctl: operations needed to implement the ioctl() syscall* @compat_ioctl32: operations needed to implement the ioctl() syscall for*	the special case where the Kernel uses 64 bits instructions, but*	the userspace uses 32 bits.* @get_unmapped_area: called by the mmap() syscall, used when %!CONFIG_MMU* @mmap: operations needed to implement the mmap() syscall* @open: operations needed to implement the open() syscall* @release: operations needed to implement the release() syscall** .. note::**	Those operations are used to implemente the fs struct file_operations*	at the V4L2 drivers. The V4L2 core overrides the fs ops with some*	extra logic needed by the subsystem.*/
struct v4l2_file_operations {struct module *owner;ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);__poll_t (*poll) (struct file *, struct poll_table_struct *);long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPATlong (*compat_ioctl32) (struct file *, unsigned int, unsigned long);
#endifunsigned long (*get_unmapped_area) (struct file *, unsigned long,unsigned long, unsigned long, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct file *);int (*release) (struct file *);
};
static const struct file_operations v4l2_fops = {.owner = THIS_MODULE,.read = v4l2_read,.write = v4l2_write,.open = v4l2_open,.get_unmapped_area = v4l2_get_unmapped_area,.mmap = v4l2_mmap,.unlocked_ioctl = v4l2_ioctl,
#ifdef CONFIG_COMPAT.compat_ioctl = v4l2_compat_ioctl32,
#endif.release = v4l2_release,.poll = v4l2_poll,.llseek = no_llseek,
};

通过V4L2子系统提供的v4l2_fops集合,可直接调用底层驱动实现的Video主设备struct v4l2_file_operations方法

__video_register_devicevdev->cdev->ops = &v4l2_fopsv4l2_openvdev->fops->open(filp) //调用uvc_v4l2.c中的uvc_v4l2_open		v4l2_ioctlvdev->fops->unlocked_ioctl(filp, cmd, arg) //调用uvc_v4l2.c中的video_ioctl2video_usercopy(file, cmd, arg, __video_do_ioctl)回调__video_do_ioctl		ops->vidioc_default //调用uvc_v4l2.c中的vidioc_default
//drivers\media\v4l2-core\v4l2-ioctl.c
long video_ioctl2(struct file *file,unsigned int cmd, unsigned long arg)
{return video_usercopy(file, cmd, arg, __video_do_ioctl);
}
EXPORT_SYMBOL(video_ioctl2);

5、数据传输

参考文章:https://blog.csdn.net/qq_32938605/article/details/119787380

1、分配一个gadget请求

// \udc\ambarella_udc.c
static const struct usb_ep_ops ambarella_ep_ops = {.enable		= ambarella_udc_ep_enable,.disable	= ambarella_udc_ep_disable,.alloc_request	= ambarella_udc_alloc_request,.free_request	= ambarella_udc_free_request,.queue		= ambarella_udc_queue,.dequeue	= ambarella_udc_dequeue,.set_halt	= ambarella_udc_set_halt,/* fifo ops not implemented */
};

usb_ep_alloc_request 分配一个gadget请求

// \udc\core.c
/*** usb_ep_alloc_request - allocate a request object to use with this endpoint* @ep:the endpoint to be used with with the request* @gfp_flags:GFP_* flags to use** Request objects must be allocated with this call, since they normally* need controller-specific setup and may even need endpoint-specific* resources such as allocation of DMA descriptors.* Requests may be submitted with usb_ep_queue(), and receive a single* completion callback.  Free requests with usb_ep_free_request(), when* they are no longer needed.** Returns the request, or null if one could not be allocated.*/
struct usb_request *usb_ep_alloc_request(struct usb_ep *ep,gfp_t gfp_flags)
{struct usb_request *req = NULL;req = ep->ops->alloc_request(ep, gfp_flags);trace_usb_ep_alloc_request(ep, req, req ? 0 : -ENOMEM);return req;
}
EXPORT_SYMBOL_GPL(usb_ep_alloc_request);
//f_uvc.c的bind()函数
/* Preallocate control endpoint request. */uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);uvc->control_buf = kmalloc(UVC_MAX_REQUEST_SIZE, GFP_KERNEL);if (uvc->control_req == NULL || uvc->control_buf == NULL) {ret = -ENOMEM;goto error;}uvc->control_req->buf = uvc->control_buf;uvc->control_req->complete = uvc_function_ep0_complete;uvc->control_req->context = uvc;
 //ambarella_udc.c
ambarella_udc_probeambarella_init_gadgetep->ep.ops = &ambarella_ep_ops

2、请求一个queue

usb_ep_queue 请求一个queue

/*** usb_ep_queue - queues (submits) an I/O request to an endpoint.* @ep:the endpoint associated with the request* @req:the request being submitted* @gfp_flags: GFP_* flags to use in case the lower level driver couldn't*	pre-allocate all necessary memory with the request.** This tells the device controller to perform the specified request through* that endpoint (reading or writing a buffer).  When the request completes,* including being canceled by usb_ep_dequeue(), the request's completion* routine is called to return the request to the driver.  Any endpoint* (except control endpoints like ep0) may have more than one transfer* request queued; they complete in FIFO order.  Once a gadget driver* submits a request, that request may not be examined or modified until it* is given back to that driver through the completion callback.** Each request is turned into one or more packets.  The controller driver* never merges adjacent requests into the same packet.  OUT transfers* will sometimes use data that's already buffered in the hardware.* Drivers can rely on the fact that the first byte of the request's buffer* always corresponds to the first byte of some USB packet, for both* IN and OUT transfers.** Bulk endpoints can queue any amount of data; the transfer is packetized* automatically.  The last packet will be short if the request doesn't fill it* out completely.  Zero length packets (ZLPs) should be avoided in portable* protocols since not all usb hardware can successfully handle zero length* packets.  (ZLPs may be explicitly written, and may be implicitly written if* the request 'zero' flag is set.)  Bulk endpoints may also be used* for interrupt transfers; but the reverse is not true, and some endpoints* won't support every interrupt transfer.  (Such as 768 byte packets.)** Interrupt-only endpoints are less functional than bulk endpoints, for* example by not supporting queueing or not handling buffers that are* larger than the endpoint's maxpacket size.  They may also treat data* toggle differently.** Control endpoints ... after getting a setup() callback, the driver queues* one response (even if it would be zero length).  That enables the* status ack, after transferring data as specified in the response.  Setup* functions may return negative error codes to generate protocol stalls.* (Note that some USB device controllers disallow protocol stall responses* in some cases.)  When control responses are deferred (the response is* written after the setup callback returns), then usb_ep_set_halt() may be* used on ep0 to trigger protocol stalls.  Depending on the controller,* it may not be possible to trigger a status-stage protocol stall when the* data stage is over, that is, from within the response's completion* routine.** For periodic endpoints, like interrupt or isochronous ones, the usb host* arranges to poll once per interval, and the gadget driver usually will* have queued some data to transfer at that time.** Note that @req's ->complete() callback must never be called from* within usb_ep_queue() as that can create deadlock situations.** This routine may be called in interrupt context.** Returns zero, or a negative error code.  Endpoints that are not enabled* report errors; errors will also be* reported when the usb peripheral is disconnected.** If and only if @req is successfully queued (the return value is zero),* @req->complete() will be called exactly once, when the Gadget core and* UDC are finished with the request.  When the completion function is called,* control of the request is returned to the device driver which submitted it.* The completion handler may then immediately free or reuse @req.*/
int usb_ep_queue(struct usb_ep *ep,struct usb_request *req, gfp_t gfp_flags)
{int ret = 0;if (WARN_ON_ONCE(!ep->enabled && ep->address)) {ret = -ESHUTDOWN;goto out;}ret = ep->ops->queue(ep, req, gfp_flags);out:trace_usb_ep_queue(ep, req, ret);return ret;
}
EXPORT_SYMBOL_GPL(usb_ep_queue);

usb_ep_queue的调用流程

// uvc_v4l2.c
ioctl(dev->fd, UVCIOC_SEND_RESPONSE, &resp)//应用层
uvc_v4l2_ioctl_defaultuvc_send_response(uvc, arg)usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL)

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

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

相关文章

【算法|前缀和系列No.4】leetcode238. 除自身以外数组的乘积

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【leetcode】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望…

如何使用 MiniGPT-v2

MiniGPT-v2 是一个基于视觉语言模型(LLM)的多任务学习系统。它可以用于各种视觉语言任务,包括图像描述、图像识别、图像-文本对话等。 本文将介绍如何使用 MiniGPT-v2。 MiniGPT-v2 提供了一个简单的在线演示,可以用于测试模型。…

2023.10.18

头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();private slot…

npm 执行命令时报错npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve

npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: vue-office/docx1.3.0 npm ERR! Found: vue-demi0.14.6 npm ERR! node_modules/vue-demi npm ERR! vue-demi“^0.14.6” from the root project npm ERR! vue-demi“*” from …

神经网络硬件加速器-DPU分析

一 DPU概述 DPU是专为卷积神经网络优化的可编程引擎&#xff0c;其使用专用指令集&#xff0c;支持诸多卷积神经网络的有效实现。 1、关键模块 卷积引擎&#xff1a;常规CONV等ALU&#xff1a;DepthwiseConvScheduler&#xff1a;指令调度分发Buffer Group&#xff1a;片上数据…

基于JAVA+SpringBoot+UniApp+Vue的前后端分离的手机移动端图书借阅平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着社会信息化的快速…

Pandas与数据库交互详解

Pandas 是一个强大的数据分析库&#xff0c;可以与各种数据库进行交互&#xff0c;从而可以方便地从数据库中读取数据、分析数据&#xff0c;并将结果写回数据库中。以下是使用 Pandas 与数据库交互的一般步骤&#xff1a; 一 、数据库交互 安装必要的库&#xff1a;首先&…

标签页的使用

目录 1、引用TabSheet.h和TabSheet.cpp文件&#xff1a; 2、主窗口添加标签页&#xff1a; &#xff08;1&#xff09;、标签页的创建和属性更改 &#xff08;2&#xff09;、添加俩个标签页的类 &#xff08;3&#xff09;、主窗口添加成员变量 &#xff08;4&#xff09…

AI爆文变现-写作项目-脚本配置教程-解放双手

之前给大家分享过AI爆文的写作教程&#xff0c;没看过的可以看下对应的教程&#xff1a; AI爆文撸流量主保姆级教程2.0 因为是怼量&#xff0c;为了高效完成文章&#xff0c;我用python脚本实现了自动写文章的功能&#xff0c;发布文章目前还是要手动进行。 AI爆文教程参考&…

【论文阅读】点云地图动态障碍物去除基准 A Dynamic Points Removal Benchmark in Point Cloud Maps

【论文阅读】点云地图动态障碍物去除基准 A Dynamic Points Removal Benchmark in Point Cloud Maps 终于一次轮到了讲自己的paper了 hahaha&#xff0c;写个中文的解读放在博客方便大家讨论 Title Picture Reference and prenotes paper: https://arxiv.org/abs/2307.07260 …

高校教务系统登录页面JS分析——华东交通大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习&#xff0c;勿用于非法用途。 一、密码加…

【LeetCode刷题(数据结构与算法)】:合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的 **思路&#xff1a;定义一个头尾指针置为NULL while循环依次比较两个链表的值的大小 遍历链表 比较完数值大小过后连接到tail的尾部 然后各自的链表的节点的next指针指向下一…

电脑开不了机用U盘重装系统Win10教程

如果我们遇到了电脑开不起机的问题&#xff0c;这给我们的正常使用带来了很大的影响。这时候我们可以借助U盘重装系统的方法&#xff0c;轻松应对这一问题。下面小编给大家详细介绍关于用U盘给开不机的电脑重装Win10系统的教程步骤&#xff0c;操作后用户就能正常使用电脑了。 …

龙芯3A3000源码编译安装deepin-ide

安装环境 系统为统信专业版1050 CPU为龙芯3A3000 安装步骤 1.安装所有依赖库 sudo apt-get install git debhelper cmake qt5-qmake qtbase5-dev qttools5-dev qttools5-dev-tools lxqt-build-tools libssl-dev llvm llvm-dev libclang-dev libutf8proc-dev libmicrohttpd-d…

MySQL学习(六)——视图和触发器

文章目录 1. 视图1.1 视图语法1.2 检查选项1.3 视图的更新1.4 视图的作用 2. 触发器2.1 介绍2.2 语法介绍2.3 触发器示例2.3.1 插入数据触发器2.3.2 修改数据触发器2.3.3 删除数据触发器 1. 视图 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据…

react antd实现upload上传文件前form校验,同时请求带data

最近的需求&#xff0c;两个下拉框是必填项&#xff0c;点击上传按钮&#xff0c;如果有下拉框没选要有提示&#xff0c;如图 如果直接使用antd的Upload组件&#xff0c;一点击文件选择的窗口就打开了&#xff0c;哪怕在Button里再加点击事件&#xff0c;也只是&#xff08;几乎…

震惊!idea专业版如何配置maven国内源手把手教学

目录 1、创建一个maven项目 2、配置maven国内源&#xff08;阿里&#xff09; 3、在等待过程中&#xff0c;设置新项目的maven配置 4、若下载失败&#xff0c;删除repository文件夹内所有文件&#xff0c;多下几次即可 5、为何配置国内源 1、创建一个maven项目 选择以下三…

微信好友消息自动回复,让你轻松应对好友咨询

有许多用微信做业务、做微商的小伙伴&#xff0c;微信有时候消息太多看不过来&#xff0c;漏看消息&#xff0c;或者不知道怎么引导用户&#xff0c;让他们看到你想让他们看到的消息。微信上用户多微信上的信息容易漏掉&#xff0c;怎么能有时效的回复客户呢&#xff1f;此时你…

vue3.0 + element plus upload图片 上传

直接上图吧&#xff1a; 记录一下&#xff0c;方便后续遇到啥问题

【C++杂货铺】一文总结C++中的异常

文章目录 一、C语言传统的处理错误的方式二、C异常三、异常的使用3.1 异常的抛出和捕获3.1.1 异常的抛出和匹配原则3.1.2 在函数调用链中异常栈展开匹配原则 3.2 异常的重新抛出3.3 异常安全3.4 异常规范 四、自定义异常体系五、C标准库的异常体系六、异常的优缺点6.1 优点6.2 …