v4l2子系统学习(三)编写虚拟摄像头驱动
文章目录
- 1、声明
- 2、前言
- 3、虚拟摄像头驱动编写
- 3.1、编写硬件相关代码
- 3.2、程序示例
1、声明
本文是在学习韦东山《驱动大全》V4L2子系统时,为梳理知识点和自己回看而记录,全部内容高度复制粘贴。
韦老师的《驱动大全》:商品详情
其对应的讲义资料:https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
2、前言
前面两章,我们基于v4l2在应用层实现了获取摄像头数据,了解了应用层中获取摄像头数据应该有的流程。接着,借着应用层的每一步操作来了解其驱动是如何实现的,从而了解整个v4l2的驱动框架。
从宏观的角度来看,前期的所有准备,无非就是想知道在编写设备驱动程序时要去分配设置哪个结构体,实现哪些关键函数。对于其它子系统的学习也是如此,再者,如今编写驱动的机会只会越来越少,学习驱动的首要目的还是为了养兵千日,用兵一时。
3、虚拟摄像头驱动编写
3.1、编写硬件相关代码
ioctl相关:
1、分配设置注册video_device结构体。
2、实现相关的ioctl函数(如获取设备能力、枚举格式、枚举分辨率、设置分辨率等)。
buffer相关:
3、分配设置vb2_queue结构体。
4、实现相关的vb2_ops函数(如queue_setup()、buf_queue()、start_streaming()、stop_streaming()等函数)。
数据传输:
5、实现start_streaming()、stop_streaming()
3.2、程序示例
#include <linux/version.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>extern unsigned char red[8230];
extern unsigned char blue[8267];
extern unsigned char green[8265];static int g_copy_cnt = 0;static struct list_head g_queued_bufs;
static struct timer_list g_virtual_timer;
static struct mutex g_vb_queue_lock; /* Protects vb_queue and capt_file */
static struct mutex g_v4l2_lock; /* Protects everything else *//* intermediate buffers with raw data from the USB device */
struct virtual_frame_buf {/* common v4l buffer stuff -- must be first */struct vb2_v4l2_buffer vb;struct list_head list;
};/* Private functions */
static struct virtual_frame_buf *virtual_get_next_buf(void)
{//unsigned long flags;struct virtual_frame_buf *buf = NULL;//spin_lock_irqsave(&s->queued_bufs_lock, flags);if (list_empty(&g_queued_bufs))goto leave;buf = list_entry(g_queued_bufs.next, struct virtual_frame_buf, list);list_del(&buf->list);
leave://spin_unlock_irqrestore(&s->queued_bufs_lock, flags);return buf;
}#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
static void virtual_timer_expire(unsigned long data)
#else
static void virtual_timer_expire(struct timer_list *t)
#endif
{/* 从硬件上读到数据(使用red/green/blue数组来模拟) *//* 获得第1个空闲buffer */struct virtual_frame_buf *buf = virtual_get_next_buf();void *ptr;if (buf){/* 写入buffer */ptr = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);if (g_copy_cnt <= 60){memcpy(ptr, red, sizeof(red));vb2_set_plane_payload(&buf->vb.vb2_buf, 0, sizeof(red));}else if(g_copy_cnt <= 120){memcpy(ptr, green, sizeof(green));vb2_set_plane_payload(&buf->vb.vb2_buf, 0, sizeof(green));}else {memcpy(ptr, blue, sizeof(blue));vb2_set_plane_payload(&buf->vb.vb2_buf, 0, sizeof(blue));}/* vb2_buffer_done */vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);}g_copy_cnt++;if (g_copy_cnt > 180)g_copy_cnt = 0;/* 再次设置timer的超时时间 */mod_timer(&g_virtual_timer, jiffies + HZ/30);
}static int virtual_querycap(struct file *file, void *fh,struct v4l2_capability *cap)
{strlcpy(cap->driver, "100ask_virtual_video", sizeof(cap->driver));strlcpy(cap->card, "no-card", sizeof(cap->card));cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE ;cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;return 0;
}static int virtual_enum_fmt_cap(struct file *file, void *priv,struct v4l2_fmtdesc *f)
{if (f->index > 0)return -EINVAL;strlcpy(f->description, "100ask motion jpeg", sizeof(f->description));f->pixelformat = V4L2_PIX_FMT_MJPEG;return 0;
}static int virtual_s_fmt_cap(struct file *file, void *priv,struct v4l2_format *f)
{/* 分辨用户传入的参数是否可用* 如果不可用, 给APP提供最接近的、硬件支持的参数*/if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)return -EINVAL;if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)return -EINVAL;f->fmt.pix.width = 800;f->fmt.pix.height = 600;return 0;
}static int virtual_enum_framesizes(struct file *file, void *fh,struct v4l2_frmsizeenum *fsize)
{if (fsize->index > 0)return -EINVAL;fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;fsize->discrete.width = 800;fsize->discrete.height = 600;return 0;
}static int virtual_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{struct v4l2_pix_format *pix = &f->fmt.pix;pix->width = 800;pix->height = 600;pix->field = V4L2_FIELD_NONE;pix->pixelformat = V4L2_PIX_FMT_MJPEG;pix->bytesperline = 0;return 0;
}static const struct v4l2_file_operations virtual_fops = {.owner = THIS_MODULE,.open = v4l2_fh_open,.release = vb2_fop_release,.read = vb2_fop_read,.poll = vb2_fop_poll,.mmap = vb2_fop_mmap,.unlocked_ioctl = video_ioctl2,
};static const struct v4l2_ioctl_ops virtual_ioctl_ops = {.vidioc_querycap = virtual_querycap,.vidioc_enum_fmt_vid_cap = virtual_enum_fmt_cap,.vidioc_s_fmt_vid_cap = virtual_s_fmt_cap,.vidioc_enum_framesizes = virtual_enum_framesizes,.vidioc_g_fmt_vid_cap = virtual_g_fmt,.vidioc_reqbufs = vb2_ioctl_reqbufs,.vidioc_create_bufs = vb2_ioctl_create_bufs,.vidioc_prepare_buf = vb2_ioctl_prepare_buf,.vidioc_querybuf = vb2_ioctl_querybuf,.vidioc_qbuf = vb2_ioctl_qbuf,.vidioc_dqbuf = vb2_ioctl_dqbuf,.vidioc_streamon = vb2_ioctl_streamon,.vidioc_streamoff = vb2_ioctl_streamoff,
};static struct video_device g_vdev = {.name = "100ask_virtual_video",.release = video_device_release_empty,.fops = &virtual_fops, // v4l2接口层相关的ioctl操作函数.ioctl_ops = &virtual_ioctl_ops, // 与硬件相关的ioctl操作函数
};static struct v4l2_device g_v4l2_dev;static struct vb2_queue g_vb_queue;static int virtual_queue_setup(struct vb2_queue *vq,unsigned int *nbuffers,unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[])
{/* 假装:至少需要8个buffer, 每个buffer只有1个plane *//* Need at least 8 buffers */if (vq->num_buffers + *nbuffers < 8)*nbuffers = 8 - vq->num_buffers;*nplanes = 1;sizes[0] = PAGE_ALIGN(800*600*2);return 0;
}static void virtual_buf_queue(struct vb2_buffer *vb)
{/* 把这个buffer告诉硬件相关的驱动程序 */struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);struct virtual_frame_buf *buf =container_of(vbuf, struct virtual_frame_buf, vb);//unsigned long flags;//spin_lock_irqsave(&s->queued_bufs_lock, flags);list_add_tail(&buf->list, &g_queued_bufs); // 把buffer放到驱动程序里的链表//spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
}static int virtual_start_streaming(struct vb2_queue *vq, unsigned int count)
{/* 启动硬件传输 *//* 使用timer来模拟硬件中断* 创建timer* 启动timer*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)setup_timer(&g_virtual_timer, virtual_timer_expire, 0);
#elsetimer_setup(&g_virtual_timer, virtual_timer_expire, 0);
#endifg_virtual_timer.expires = jiffies + HZ/30;add_timer(&g_virtual_timer);return 0;
}static void virtual_stop_streaming(struct vb2_queue *vq)
{/* 停止硬件传输 */del_timer(&g_virtual_timer);while (!list_empty(&g_queued_bufs)) {struct virtual_frame_buf *buf;buf = list_entry(g_queued_bufs.next,struct virtual_frame_buf, list);list_del(&buf->list);vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);}
}/* buffer管理要用到的vb2_ops */
static const struct vb2_ops virtul_vb2_ops = {.queue_setup = virtual_queue_setup, // APP调用ioctl VIDIOC_REQBUFS或VIDIOC_CREATE_BUFS时,驱动程序在分配内存之前,会调用此函数。.buf_queue = virtual_buf_queue, // 把buffer传送给驱动.start_streaming = virtual_start_streaming, // 启动硬件传输(操作硬件).stop_streaming = virtual_stop_streaming, // 关闭硬件传输(操作硬件).wait_prepare = vb2_ops_wait_prepare,.wait_finish = vb2_ops_wait_finish,
};static void virtual_video_release(struct v4l2_device *v)
{
}static int virtual_video_drv_init(void)
{int ret;/* 分配/设置/注册video_device */printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);/* 1、设置vb2_queue结构体 */g_vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;g_vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;g_vb_queue.drv_priv = NULL;g_vb_queue.buf_struct_size = sizeof(struct virtual_frame_buf); /* 分配vb时, 分配的空间大小为buf_struct_size */g_vb_queue.ops = &virtul_vb2_ops; // 设置buffer管理要用到的vb2_opsg_vb_queue.mem_ops = &vb2_vmalloc_memops; // 设置buffer管理要用到的vb2_mem_opsg_vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;ret = vb2_queue_init(&g_vb_queue);if (ret) {printk("Could not initialize vb2 queue\n");return -1;;}printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);mutex_init(&g_vb_queue_lock);/* 2、设置video_device结构体 */g_vdev.queue = &g_vb_queue; g_vdev.queue->lock = &g_vb_queue_lock;/* Register the v4l2_device structure(辅助作用) */g_v4l2_dev.release = virtual_video_release;strcpy(g_v4l2_dev.name, "virtual_v4l2");ret = v4l2_device_register(NULL, &g_v4l2_dev);if (ret) {printk("Failed to register v4l2-device (%d)\n", ret);return -1;}printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);g_vdev.v4l2_dev = &g_v4l2_dev;g_vdev.lock = &g_v4l2_lock;mutex_init(&g_v4l2_lock);/* 3、注册video_device结构体 */ ret = video_register_device(&g_vdev, VFL_TYPE_GRABBER, -1);if (ret) {printk("Failed to register as video device (%d)\n", ret);return -1;}printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);INIT_LIST_HEAD(&g_queued_bufs);return 0;
}static void virtual_video_drv_exit(void)
{/* 反注册/释放video_device */v4l2_device_unregister(&g_v4l2_dev);video_unregister_device(&g_vdev);
}module_init(virtual_video_drv_init);
module_exit(virtual_video_drv_exit);MODULE_LICENSE("GPL");
相关文章:
v4l2子系统学习(三)编写虚拟摄像头驱动
文章目录 1、声明2、前言3、虚拟摄像头驱动编写3.1、编写硬件相关代码3.2、程序示例 1、声明 本文是在学习韦东山《驱动大全》V4L2子系统时,为梳理知识点和自己回看而记录,全部内容高度复制粘贴。 韦老师的《驱动大全》:商品详情 其对应的…...
堆排序(详解)c++
堆排序 (可以⽤ ppt 演⽰流程) 堆排序(Heap Sort)是指利⽤堆这种数据结构所设计的⼀种排序算法。本质上是优化了选择排序算法,选择排序的思想是在堆排序元素中拿出最大值或最小值,然后把这个位置的值放在它该放的位置上就可以了&a…...
API测试工具:Swagger vs Postman 2025最新全面对比
随着微服务架构的普及和云原生应用的激增,高效的 API 开发、测试和文档管理工具变得越来越重要。在众多 API 工具中,Swagger 和 Postman 各自以不同的方式解决着 API 开发生命周期中的关键问题,本文将从多个维度深入对比这两款工具࿰…...
算法-图-数据结构(邻接矩阵)-BFS广度优先遍历
邻接矩阵广度优先遍历(BFS)是一种用于遍历或搜索图的算法,以下是具体介绍: 1. 基本概念 图是一种非线性的数据结构,由顶点和边组成,可分为无向图、有向图、加权图、无权图等。邻接矩阵是表示图的一种数…...
List的模拟实现(2)
前言 上一节我们讲解了list的基本功能,那么本节我们就结合底层代码来分析list是怎么实现的,那么废话不多说,我们正式进入今天的学习:) List的底层结构 我们先来看一下list的底层基本结构: 这里比较奇怪的…...
【C++设计模式】观察者模式(1/2):从基础到优化实现
1. 引言 在 C 软件与设计系列课程中,观察者模式是一个重要的设计模式。本系列课程旨在深入探讨该模式的实现与优化。在之前的课程里,我们已对观察者模式有了初步认识,本次将在前两次课程的基础上,进一步深入研究,着重…...
可狱可囚的爬虫系列课程 13:Requests使用代理IP
一、什么是代理 IP 代理 IP(Proxy IP)是一个充当“中间人”的服务器IP地址,用于代替用户设备(如电脑、手机等)直接与目标网站或服务通信。用户通过代理IP访问互联网时,目标网站看到的是代理服务器的IP地址&…...
冒险岛079 V8 整合版源码搭建教程+IDEA启动
今天教大家来部署下一款超级怀旧游戏冒险岛,冒险岛源码是开源的,但是开源的代码会有各种,本人进行了加工整合,并且用idea进行了启动测试,经过修改后没有任何问题。 启动截图 后端控制台 前端游戏界面 声明 冒险岛源码…...
Web刷题之PolarDN(中等)
1.到底给不给flag呢 代码审计 一道典型的php变量覆盖漏洞 相关知识 什么是变量覆盖漏洞 自定义的参数值替换原有变量值的情况称为变量覆盖漏洞 经常导致变量覆盖漏洞场景有:$$使用不当,extract()函数使用不当,parse_str()函数使用不当&…...
[250224] Yaak 2.0:Git集成、WebSocket支持、OAuth认证等 | Zstandard v1.5.7 发布
目录 Yaak 2.0 发布:Git 集成、WebSocket 支持、OAuth 认证等众多功能!Zstandard v1.5.7 发布:性能提升,稳定性增强 Yaak 2.0 发布:Git 集成、WebSocket 支持、OAuth 认证等众多功能! Yaak,一款…...
插入排序:一种简单而直观的排序算法
大家好!今天我们来聊聊一个简单却非常经典的排序算法——插入排序(Insertion Sort)。在所有的排序算法中,插入排序是最直观的一个。 一、插入排序的基本思想 插入排序的核心思想是:将一个待排序的元素,插…...
vue2响应式数据原理
1. 核心原理 Vue 2 的响应式系统基于 Object.defineProperty,通过 依赖收集 和 派发更新 来实现数据的响应式 依赖收集:在读取数据时,记录哪些函数(或组件)依赖了该数据。派发更新:在修改数据时ÿ…...
对免认证服务提供apikey验证
一些服务不带认证,凡是可以访问到服务端口,都可以正常使用该服务,方便是方便,但是不够安全。 比如ollama默认安装后就是这样。现在据说网上扫一下端口11434,免apikey的ollama服务一大堆。。。 那我们怎样将本机安装的o…...
算法——Trie 树
Trie 树(前缀树或字典树)是一种高效处理字符串集合的树形数据结构,核心思想是通过共享公共前缀来优化存储和查询。以下是 Trie 树的详细介绍: 1. Trie 树的基本概念 结构特点: 每个节点表示一个字符。从根节点到某一节…...
python中的JSON数据格式
文章目录 什么是json主要功能Python数据和Json数据的相互转化 什么是json JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据。JSON本质上是一个带有特定格式的字符串。 主要功能 json就是一种在各个编程语言中流通的数据格式,负责不同编…...
服务器能否拒绝非浏览器发起的HTTP请求?
互联网各领域资料分享专区(不定期更新): Sheet 前言 服务器可以采取多种方法来拒绝非浏览器发起的HTTP请求,但需要明确的是:HTTP协议本身并不限制客户端类型,任何符合协议规范的请求都会被处理。因此,拒绝非浏览器请求需依赖额外策略。 正文 一、基于请求头过滤 1、Us…...
深度学习之图像分类(二)
前言 文章主要是通过实战项目——食品分类来理解分类项目的整体流程。除此之外,还需要对半监督学习,迁移学习,数据增广,Adam和AdamW进行了解。 数据增广 图片增广(Image Data Augmentation)是深度学习中一种…...
数据库高安全—openGauss安全整体架构安全认证
openGauss作为新一代自治安全数据库,提供了丰富的数据库基础安全能力,并逐步完善各类高阶安全能力。这些安全能力涵盖了访问登录认证、用户权限管理、审计与追溯及数据安全隐私保护等。本章节将围绕openGauss安全机制进行源码解读,以帮助数据…...
利用开源小智AI制作桌宠机器狗
本文主要介绍如何利用开源小智AI制作桌宠机器狗 1 源码下载 首先下载小智源码,下载地址, 下载源码后,使用vsCode打开,需要在vscode上安装esp-idf,安装方式请自己解决 2 源码修改 2.1添加机器狗控制代码 在目录main/iot/things下添加dog.cc文件,内容如下; #include…...
uniapp在app下使用mqtt协议!!!支持vue3
什么?打包空白?分享一下我的解决方法! 第一步 找大师算过了,装4.1版本运气好! 所以根目录执行命令… npm install mqtt4.1.0第二步 自己封装一个mqtt文件方便后期开坛做法! // utils/mqtt.js import mqt…...
Orange 开源项目 - 集成阿里云大模型
1 阿里云的大模型服务平台百炼 阿里云的大模型服务平台百炼是一站式的大模型开发及应用构建平台。不论是开发者还是业务人员,都能深入参与大模型应用的设计和构建。您可以通过简单的界面操作,在5分钟内开发出一款大模型应用,或在几小时内训练…...
DSP芯片C6678的SRIO及其中断跳转的配置
C6678SRIO读写测试门铃中断跳转测试 SRIO简述代码前言SRIO配置原始代码1.使能电源2.初始化SRIO回环修改 3.SRIO测试 Doorbell门铃中断1.初始化中断函数2.中断向量表建立3.中断向量表的链接 本博客基于创龙“678ZH产品线”的SRIO代码,部分参考于网友们的博客…...
MongoDB#常用脚本
批量插入数据脚本 const oneDayAgo new Date(Date.now() - 1 * 24 * 60 * 60 * 1000);const documents []; for (let i 1; i < 100; i) {documents.push({id: i, // 递增的 idcreateTime: oneDayAgo, // 1天前的日期data: Sample data ${i} // 其他字段(可选…...
MySQL 主从集群同步延迟问题分析与解决方案
MySQL 主从复制(Replication)是构建高可用架构的核心技术,但在实际应用中,主从同步延迟(Replication Lag)是常见且棘手的问题。延迟会导致从库数据不一致、读请求返回旧数据,甚至引发业务逻辑错…...
论文笔记(七十二)Reward Centering(五)
Reward Centering(五) 文章概括摘要附录B 理论细节C 实验细节D 相关方法的联系 文章概括 引用: article{naik2024reward,title{Reward Centering},author{Naik, Abhishek and Wan, Yi and Tomar, Manan and Sutton, Richard S},journal{arX…...
FFmpeg 是什么?为什么?怎么用?
摘要:本文介绍了 FFmpeg,一个功能强大的开源多媒体处理工具,广泛应用于视频和音频文件的处理。FFmpeg 支持多种多媒体格式,能够实现视频编码/解码、格式转换、裁剪、合并、音频提取、流媒体处理等功能。本文详细阐述了 FFmpeg 的主…...
雷池WAF动态防护技术实测
作者; Hacker / 0xh4ck3r 介绍 长亭雷池(SafeLine)是由北京长亭科技有限公司耗时近10年研发并推出的Web应用防火墙(WAF),其核心检测能力由智能语义分析算法驱动。雷池旨在为用户提供高质量的Web攻击防护、…...
BUU40 [CSCCTF 2019 Qual]FlaskLight1【SSTI】
模板: {{.__class__.__base__.__subclasses__()[80].__init__.__globals__[__builtins__].eval("__import__(os).popen(type flag.txt).read()")}} 是个空字符串,.__class__代表这个空字符串的类是什么(这里是单引号双引号都行&a…...
【每日八股】Redis篇(二):数据结构
Redis 数据类型? 主要有 STRING、LIST、ZSET、SET 和 HASH。 STRING String 类型底层的数据结构实现主要是 SDS(简单动态字符串),其主要应用场景包括: 缓存对象:可以用 STRING 缓存整个对象的 JSON&…...
VScode+stfp插件,实现文件远程同步保存【2025实操有效】
目录 1 痛点2 准备工作3 操作步骤3.1 第一步,下载STFP插件3.2 第二步,修改配置文件3.3 第三步,测试是否成功 4 后记 1 痛点 我一直用vscode远程连接服务器,传代码文件等到服务器上面,突然有一次服务器那边尽心维修&am…...
115 道 MySQL 面试题,从简单到深入!
1. 什么是数据库事务? 数据库事务是一个作为单个逻辑工作单元执行的一系列操作。事务具有ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性…...
不同安装路径重复R包清理
df <- as.data.frame(installed.packages()) table(duplicated(df$Package)) ids <- df$Package[duplicated(df$Package)] df2 <- subset(df, df$Package %in% ids)...
Grouped-Query Attention(GQA)详解: Pytorch实现
Grouped-Query Attention(GQA)详解 Grouped-Query Attention(GQA) 是 Multi-Query Attention(MQA) 的改进版,它通过在 多个查询头(Query Heads)之间共享 Key 和 Value&am…...
选择排序:简单高效的选择
大家好,今天我们来聊聊选择排序(Selection Sort)算法。这是一个非常简单的排序算法,适合用来学习排序的基本思路和操作。选择排序在许多排序算法中以其直观和易于实现的特点著称,虽然它的效率不如其他高效算法…...
(教程)PDF 字体技术入门
PDF字体技术 许多人觉得PDF字体令人困惑的主要原因在于PDF文件可以使用多种不同的字体技术。PDF文件规范已经存在16年,在此期间,出现了多种不同的字体技术(既有技术方面的原因,也有商业方面的原因)。因此,…...
LabVIEW中CFURL.llb 工具库说明
CFURL.llb 是 LabVIEW 2019 安装目录下 C:\Program Files (x86)\National Instruments\LabVIEW 2019\vi.lib\Platform\ 路径下的工具库,主要用于处理 LabVIEW 与 URL 相关的操作,涵盖 URL 解析、HTTP 请求发送、数据传输等功能模块,帮助开发者…...
BGP配置华为——路径优选验证
实验拓扑 实验要求 实现通过修改AS-Path属性来影响路径选择实现通过修改Local_Preference属性来影响路径选择实现通过修改MED属性来影响路径选择实现通过修改preferred-value属性来影响路径选择 实验配置与效果 1.改名与IP配置 2.as300配置OSPF R3已经学到R2和R4的路由 3.…...
Linux8-互斥锁、信号量
一、前情回顾 void perror(const char *s);功能:参数: 二、资源竞争 1.多线程访问临界资源时存在资源竞争(存在资源竞争、造成数据错乱) 临界资源:多个线程可以同时操作的资源空间(全局变量、共享内存&a…...
【Springboot3】Springboot3 搭建RocketMQ 最简单案例
说来也奇怪,RocketMQ 不能很好的兼容Springboot3,刚开始上手Springboot3集成RocketMQ会发现总是不能实例化RocketMQTemplate,老是启动时报错。本项目采用Springboot3,JDK21 ,Maven 3.9,提供一个非常简单的示…...
使用docker安装mysql 挂起之后 再次运行无法连接问题
# 首先 vim /usr/lib/sysctl.d/00-system.conf # 在最后面添加 net.ipv4.ip_forward 1 # 然后保存退出,接着重启网络服务 systemctl restart network # 重启以后,输入以下命令,查看IPv4转发状态 sysctl net.ipv4.ip_forward # 显示net.ipv4…...
hot100-二叉树
二叉树 二叉树递归 相当于这个的顺序来回调换 class Solution {private List<Integer> res new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {if(root null)return res;inorderTraversal(root.left);res.add(root.val);inorde…...
从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(二)
1.安装mogondb数据库 参考MongoDB安装配置教程(详细版)_mongodb安装详细步骤-CSDN博客 安装mondbcompass数据库连接工具 参考https://www.mongodb.com/zh-cn/docs/compass/current/connect/ 2.后端服务 1.创建src文件夹 并在src文件夹下创建 index…...
基于Spring Boot的党员学习交流平台设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
Plantsimulation中机器人怎么通过阻塞角度设置旋转135°
创建一个这样的简单模型。 检查PickAndPlace的角度表。源位于180的角位置,而物料终结位于90的角位置。“返回默认位置”选项未被勾选。源每分钟生成一个零件。启动模拟时,Plant Simulation会选择两个位置之间的最短路径。示例中的机器人无法绕135的角位…...
2025.2.23机器学习笔记:PINN文献阅读
2025.2.23周报 一、文献阅读题目信息摘要Abstract创新点网络架构架构A架构B架构C 实验结论后续展望 一、文献阅读 题目信息 题目: Physics-Informed Neural Networks for Modeling Water Flows in a River Channel期刊: IEEE TRANSACTIONS ON ARTIFICI…...
关于Postman自动获取token
在使用postman测试联调接口时,可能每个接口都需要使用此接口生成的令牌做Authorization的Bearer Token验证,最直接的办法可能会是一步一步的点击,如下图: 在Authorization中去选择Bearer Token,然后将获取到的token粘贴…...
Android KMP初探
Android KMP初探 前言: 最近线上听了Kotlin官网举行的KMP会议,感觉听神奇的,于是就把官方demo下载下来尝试了一下,下载插件和所需要的依赖都用了很久,但是发现里面的代码很少,于是尝试自己手写了一下&…...
ncDLRES:一种基于动态LSTM和ResNet的非编码RNA家族预测新方法
现有的计算方法主要分为两类:第一类是通过学习序列或二级结构的特征来预测ncRNAs家族,另一类是通过同源序列之间的比对来预测ncRNAs家族。在第一类中,一些方法通过学习预测的二级结构特征来预测ncRNAs家族。二级结构预测的不准确性可能会导致…...
前端项目打包过滤指定icon文件
1.需求背景 项目中有部分功能需要vip权限才可以使用,所有部分筛选、按钮 等有vip的icon提示 如下图 此项目衍生出一个特殊版本,此版本无需登录且拥有最高权限,所以产品要求去除项目中的所有vip相关的提示。 2.解决思路 (1&am…...
蓝桥杯 Java B 组之最短路径算法(Dijkstra、Floyd-Warshall)
Day 2:最短路径算法(Dijkstra、Floyd-Warshall) 📖 一、最短路径算法简介 最短路径问题是图论中的经典问题,主要用于求解 单源最短路径 或 多源最短路径。在实际应用中,最短路径广泛应用于 导航系统、网络…...