整理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】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望…

Linux UWB Stack实现——MCPS帧处理

MCPS帧处理 用于处理IEEE 802.15.4中的相关帧,Frame Processing,简写为:fproc。 在实现中,维护了关于帧处理的有限状态机(FSM)。本文从帧处理的数据结构和部分典型处理实现上进行简要的介绍。 1. 数据结构定义 关于帧处理状态…

如何使用 MiniGPT-v2

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

如何取消a链接点击时的背景颜色

引言 在网页设计中,链接是非常重要的元素之一。当用户点击链接时,通常会出现一个背景颜色或者下划线来表示链接的状态。然而,有时候我们可能希望取消链接点击时出现的背景颜色,以便更好地控制链接的外观。本文将介绍如何取消a链接…

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…

手机怎么监控电脑?

随着企业对电脑监控需求的增加&#xff0c;越来越多的管理者意识到使用电脑监控电脑的不便性&#xff0c;一旦外出就无法实时查看监控。其实可以用手机实现监控电脑的需求&#xff0c;只需在被监控端安装电脑监控软件后&#xff0c;将电脑设备和员工信息进行绑定&#xff0c;使…

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 …

linux系统编程之一

1&#xff09;fcntl的使用方法 fcntl作用:可以用fcntl函数改变一个已打开的文件属性而不必重新打开文件&#xff1b; 堆排序是完全二叉树&#xff0c;但不是排序二叉树&#xff1b; 排序二叉树要求兄弟节点之间有大小关系&#xff0c;比如说左小右大&#xff1b; 堆排序仅要求…

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

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

加深我对typeScript的印象(、|、Partial、Required、Pick、Omit)

发现有错误、或者理解错误&#xff0c;及时联系我&#xff0c;感谢&#xff01;&#xff01; 文章目录 1、‘&’符号2、‘|’符号3、‘‘Partial’’4、‘Required’5、‘Pick’6、 ‘Omit’ testA、testB、testC是我下面要用到的类 type testA {name: string,age: numbe…

Can Language Models Make Fun? A Case Study in Chinese Comical Crosstalk

本文是LLM系列文章&#xff0c;针对《Can Language Models Make Fun? A Case Study in Chinese Comical Crosstalk》的翻译。 语言模型能制造乐趣吗?中国滑稽相声个案研究 摘要1 引言2 问题定义3 数据集4 使用自动评估生成基准5 人工评估6 讨论7 结论与未来工作 摘要 语言是…

旧版Mac如何装新系统

macOS Ventura 最低系统需要&#xff0c;17年序列电脑。老电脑15年的&#xff0c;无法安装新系统。使用方法直接采用大佬方法 一.在GitHub下载 OpenCore、Hackintool OpenCore 用来修改系统的机型&#xff0c;修改后可直接在软件更新中更新macOS Ventura。 Hackintool 用来生…

基于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 …

中国社科院与美国杜兰大学金融管理硕士---不将就的人生

“万般皆下品&#xff0c;惟有读书高”、“书中自有颜如玉&#xff0c;书中自有黄金屋”&#xff0c;古往今来&#xff0c;读书的好处为人们所重视。从而想拿到学历没有知识的沉淀&#xff0c;没有一定的学识水平&#xff0c;又怎么能拿到含金量颇高的学历呢&#xff1f;退一步…

vue图片懒加载

Vue图片懒加载是一种优化页面性能的技术&#xff0c;它可以延迟加载页面上的图片&#xff0c;直到它们进入可见区域。这可以减少页面的加载时间&#xff0c;提高用户体验。 在Vue中实现图片懒加载可以使用第三方库vue-lazyload。首先需要安装该库&#xff1a; npm install vu…

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

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