整理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.rhkb.cn/news/164431.html

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

相关文章

关闭mysql,关闭redis服务

1. 关闭redis服务: 查询redis安装目录: whereis redis which redis find / -name redis 关闭redis服务: redis-cli -h 127.0.0.1 -p 6379 auth 输入密码 shutdown 关闭redis服务 2. 关闭mysql服务: 查询mysql安装目录&…

Docker逃逸---SYS_PTRACE浅析

一、产生原因 用户授予了容器SYS_PTRACE权限,并且与宿主机共享一个进程命名空间(--pidhost),使得容器内可以查看到宿主机的进程,攻击者可以利用进程注入,反弹shell,从而实现逃逸 二、利用条件 1、容器有SYS_PTRACE权…

(H5轮播)vue一个轮播里显示多个内容/一屏展示两个半内容

效果图 : html: <div class"content"><van-swipeclass"my-swipe com-long-swipe-indicator":autoplay"2500"indicator-color"#00C4FF"><van-swipe-itemclass"flex-row-wrap"v-for"(items, index) in M…

React +AntD + From组件重复提交数据(已解决)

开发场景&#xff1a; react Hooks andt 提交form表单内容给数据库(使用antd的form组件) 问题描述 提交是异步的&#xff0c;请提交方式是POST 方式 提交表单内容给后端&#xff0c;却产生了两次提交记录&#xff08;当然&#xff0c;数据新增了两条数据&#xff09;。可以…

VR虚拟展厅的亮点是什么?有哪些应用?

传统展厅主要是以静态陈列的形式来传达内容&#xff0c;而展示形式则有图片、视频等&#xff0c;虽然视频包含内容多&#xff0c;但是总体具有一定的局限性&#xff0c;客户体验感也较差&#xff0c;往往不能深入了解细节。随着VR技术越来越成熟&#xff0c;VR技术的广泛应用&a…

Qemu镜像安全加密测试

文章目录 简介1.已经过时的qemu自带的加密方式介绍1.1.创建secret uuid的xml1.2.产生uuid1.3.给secret赋值1.4.创建一个存储池1.5.在存储池中创建一个镜像1.6.在虚拟机中使用该镜像 2.弃用以上加密方式2.1.原作者Daniel Berrange的观点2.2.Markus Armbruster更深入的操作 3. LU…

在前端html页面中向服务器发送post登录请求

目录 前言 搭建服务器 搭建前端登录页面 获取表单值 使用axios发送post登录请求 前言 一般在html页面中向服务器发送post请求的模块为登录请求&#xff0c;本文将介绍如何向服务器发送post请求 搭建服务器 如何搭建服务器请看JWT认证这篇文章&#xff0c;有详细的解说。…

性能测试jmeter命令行运行+html测试报告解读

windows下打开jmeter的运行窗口&#xff0c;可以看到提示不要用GUI模式进行负载测试&#xff0c;如果要用负载测试&#xff0c;用cli模式&#xff0c;因为GUI模式运行jmeter比较消耗性能。 命令行模式 windows下找到jemeter所在文件夹&#xff0c;打开cmd输入命令。 jmeter -n…

Leetcode 第 365 场周赛题解

Leetcode 第 365 场周赛题解 Leetcode 第 365 场周赛题解题目1&#xff1a;2873. 有序三元组中的最大值 I思路代码复杂度分析 题目2&#xff1a;2874. 有序三元组中的最大值 II思路代码复杂度分析思路2 题目3&#xff1a;2875. 无限数组的最短子数组思路代码复杂度分析 题目4&a…

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

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

IPETRONIK数采与第三方软件集成

一 第三方软件 IPETRONIK公司提供IPEmotion用于车辆测试&#xff0c;但在某些特殊领域也有一些专业的软件&#xff0c;例如标定&#xff0c;则需要IPETRONIK数采来进行压力、温度、转速等信号的采集。 IPETRONIK提供了INCA和CANape插件&#xff0c;且这两款软件均可直接识别到…

微信小程序修改van-popup的背景颜色

效果图&#xff1a; van-popup背景颜色渐变 使用深度修改样式不生效&#xff0c;直接在 custom-style里面修改即可&#xff1b; <van-popup position"bottom"custom-style"height:25%;background:linear-gradient(95deg, #F8FCFF -0.03%, #EDF5FF 64.44…

【Qt之布局】QVBoxLayout、QHBoxLayout、QGridLayout、QFormLayout介绍及使用

在Qt中&#xff0c;布局管理器&#xff08;Layout&#xff09;用于管理窗口中的控件的位置和大小&#xff0c;以适应不同大小的窗口。 常用的布局管理器包括QVBoxLayout、QHBoxLayout、QGridLayout和QFormLayout。 先放张布局UI&#xff1a; 1. QVBoxLayout&#xff08;垂直布…

Linux性能优化--性能工具:磁盘I/O

6.0 概述 本章介绍的性能工具能帮助你评估磁盘I/O子系统的使用情况。这些工具可以展示哪些磁盘或分区已被使用&#xff0c;每个磁盘处理了多少I/O,发给这些磁盘的I/O请求要等多久才被处理。 阅读本章后&#xff0c;你将能够&#xff1a; 确定系统内磁盘I/O的总量和类型(读/写…

使用 ClickHouse 深入了解 Apache Parquet (一)

​ 【squids.cn】 全网zui低价RDS&#xff0c;免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 自2013年作为Hadoop的列存储发布以来&#xff0c;Parquet几乎已经成为一种无处不在的文件交换格式&#xff0c;它提供了高效的存储和检索。这种采纳使其成为更近期的…

为网站配置SSL

HTTPS &#xff08;全称&#xff1a;Hyper Text Transfer Protocol over SecureSocket Layer&#xff09;&#xff0c;是以安全为目标的 HTTP 通道&#xff0c;在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入SSL 层&#xff0c;HTTPS…

AWS S3加密

Hello大家好&#xff61; 在本课时我们将讨论S3加密相关的内容。 S3加密相关是认证考试的一个重要的主题考点&#xff0c;您需要了解亚马逊S3的几种不同类型的加密方式。| 首先是静态数据的加密&#xff0c;静态数据加密是指数据存储在亚马逊S3 数据中心的磁盘上时&#xff0…

Maven的详细介绍(maven的全据配置以及idea中maven的配置)

maven的理解 Maven 是一个强大的项目管理和构建自动化工具&#xff0c;它通过抽象的项目对象模型(POM&#xff1a;Project Object Model)和构建生命周期模型(Project Lifecycle)来对项目及其构建过程进行管理(Dependency Management System)&#xff0c;Maven 最大化的消除了构…

爬虫/scrapy基础

如果文章对你有帮助&#xff0c;欢迎关注、点赞、收藏一键三连支持以下哦&#xff01; 想要一起交流学习的小伙伴可以加zkaq222&#xff08;备注CSDN&#xff0c;不备注通不过哦&#xff09;进入学习&#xff0c;共同学习进步 目录 0x01 安装和简介 0x02 文件作用 0x04 保存…

阿里巴巴店铺所有商品数据接口及店铺商品数据分析

获取阿里巴巴店铺所有商品数据的接口是阿里巴巴开放平台提供的接口&#xff0c;通过该接口可以获取店铺所有商品数据。 通过阿里巴巴开放平台接口获取店铺所有商品数据的方法如下&#xff1a; 在开放平台注册成为开发者并创建一个应用&#xff0c;获取到所需的 App Key 和 Ap…