当前位置: 首页 > article >正文

【PCI】PCI入门介绍(包含部分PCIe讲解)

先解释一下寻址空间:
机器是32bit的话,意味着4G(2的32次方)寻址空间,内存条作为它的实际物理存储设备。大部分在跑内存程序运行,少部分用来存放其他东西。这是一个常见的4G寻址空间分布(不一定是从 0xC0000000后开始是其他,这只是一个典型分布案例)。而之后会提到的PCI的Memory-Mapping IO配置空间就是分布在0xF0000000之后(地址值大于等于0xF0000000)。

地址范围用途
0x00000000–0xBFFFFFFF可用内存(最多 3GB)
0xC0000000–0xFFFFFFFFMemory-Mapping IO、显存、BIOS 映射等

仅作为bios里需要了解到的PCI知识介绍,不怎么涉及硬件知识,分为4个部分讲:
1.PCI介绍
2.PCI IRQ routing table(Legacy的东西,可不看)
3.PCI config space配置空间
4.如何识别PCIe设备

文章目录

  • 1. PCI介绍
    • 1.1 PCI总线(PCI bus)历史
    • 1.2 PCI总线优点
    • 1.3 PCI结构图
    • 1.4 PCI Bus/Device/Function
    • 1.5 PCI拓扑
    • 1.6 PCI总线信号
    • 1.7 PCI Bridge/PCI device配置空间
  • 2. PCI IRQ routing table(Legacy的东西,可不看)
  • 3. 如何访问PCI config space配置空间
    • 3.1 IO Port(仅用于x86平台,且读写的是Offeset FFh以内的信息)
    • 3.2 MMIO(推荐)
  • 4. 如何识别PCI-e设备

1. PCI介绍

1.1 PCI总线(PCI bus)历史

PCI全称Peripheral Component Interconnect外围部件互连
PCI总线是由ISA(Industy Standard Architecture)总线发展而来的,ISA总线由于CPU资源占用太高,数据传输带宽太小,作为插槽接口已经被淘汰。1992年Intel提出PCI总线,用来连接CPU和外围设备的局部总线,解决了CPU和外围设备尤其是显卡的数据瓶颈(在此之前MCA设备也挺慢,就比ISA好一点)。

PCI规范已经到7.0了,详情可以去官网上看。

1.2 PCI总线优点

高性能,32位同步复用总线,工作频率为33MHz;
线路简化,最少只需47个引脚;
可扩展,通过PCI bridge;
动态配置,init的时候有枚举过程;
中断可共享;
使用方便。

1.3 PCI结构图

在这里插入图片描述
Processer和Cache可以整体看做CPU。
Bridge/memory controller这里看做北桥南桥芯片集合,北桥接内存DRAM,南桥接PCI。
(注意,南桥/主芯片组会对不同类型的设备进行桥接和抽象,使得操作系统可以用统一的方式访问不同总线的设备。即使是PCI发展出的PCIe设备直接连接到CPU,硬件和芯片组也会提供一致的配置空间访问手段。一块板上的PCIe设备不一定只能连接到南桥或只连接到CPU,而是取决于主板设计、芯片组支持和设备类型。不再细讲。)
Bus上连各种PCI设备(图里的是举例,并不是真的都连在Bus0上,Bus0是初始的PCI总线,它上面有PCI设备也有PCI桥,PCI桥一对一连到另外的PCI bus,PCI bus上再接设备或PCI桥,终点是PCI bus。PCI bus号是深度优先来算的,并不是Bus0通过直连bridge后的bus就是bus1,bus2…,后面讲):
比如Audio音频设备,Motion Video视频设备,LAN(实际上是PCI网卡),SCSI(SCSI PCI转换卡,用来接SCSI标准的硬盘/光驱等存储设备),Graphics显卡。

1.4 PCI Bus/Device/Function

这三个是PCI信息读取的重要参数。
Bus:总线号,表示一个PCI设备/PCI桥挂在哪个Bus底下(PCI桥连接上游[数字小的那个,也就是靠Bus0较近的那个]一个bus、下游一个bus,它的bus号是她的上游总线号)。
Host桥(可以看做一个抽象概念,就是连到CPU的东西)引出Bus0,Bus0可以接多个PCI桥(PCI桥只能上游一个bus下游一个bus),PCI桥引出下一级Bus总线。最多可以有256个总线=2的8次方。

非总线0上的设备的bus号由引出该总线的PCI桥的配置空间的offset 19H那一字节代表的
secondary bus number给出。
(之后可以看PCI桥配置空间表格)

Device号:PCI的设备号。一个Bus最多可以接32个Device=2的8次方。
由PCI设备IDSEL引脚所连接的地址线决定。
Function:PCI的功能号,有PCI设备自身决定。PCI桥和设备都可以有多个功能。一个Device最多可以有8个Function=2的3次方。

1.5 PCI拓扑

自己画的,比网上某些清楚多了(。)
可以看到Host Bridge引出Bus 0,Bus 0引出PCI桥进行拓扑,PCI设备挂在PCI Bus上。
在这里插入图片描述

1.6 PCI总线信号

物理电器上的Pin脚(对应实际设备上的金手指)
在这里插入图片描述

左边是必要的pin脚,右边是可选的(64bit的PCI设备卡长度更长,插槽也更长,因为金手指变多)。
图是这样画的,实际上一个Pin脚就是设备某一侧的金手指,设备两侧加起来一共有最少47个金手指。当然设备也可以设计更多金手指,实际使用数量<=提供的数量。
如果是master device的话,就需要REQ和GNT那两个引脚,需要49Pin。所以说32bit PCI最少只需要47Pin。
注意interrupts,中断INT,之后会讲。

(#代表低电平有效,也可以写成字母上面有一道横线)
AD[31:0], 地址线和数据线是复用的。
C/BE[3:0]#,命令和字节使能。
PME#, 电源管理事件。
CLK, 时钟信号,给所有PCI设备提供时钟。
RST#, 复位信号,低电平时有效,会将PCI设备重置为初始状态。
INTA#-INTD#, 中断请求信号。
IDSEL, SEL是select的意思,初始化信号设备选择信号。访问一个设备配置寄存器时作为一个片选信号,决定该设备的设备号。
在这里插入图片描述
每个Bus的PCI device之所以最多32个,是因为AD从0到31。
每个PCI插槽上PCI设备的IDSEL引脚被主板硬件连接到某一根AD线(比如AD18)。
当主机发起配置访问时,它会在地址总线上输出一个地址,其中某一位(比如 AD18)被置为高电平。由于 AD18 和 PCI 插槽 2 的 IDSEL 引脚是连在一起的,所以:AD18 = 高电平 → 插槽 2 的 IDSEL = 高电平
IDSEL 接到哪根 AD 线是由主板硬件布线决定的,所以某一个PCI插槽的device号是固定的,而它的Bus号由BIOS/固件动态分配特别是部署PCI桥的时候,Function号就更不用说了、设备自身定义。

1.7 PCI Bridge/PCI device配置空间

配置空间对于芯片来说其实放的是配置空间寄存器configuration space register各自的值。
PCI device/PCI bridge的配置空间寄存器在其内部。也就是PCI device的配置空间寄存器在PCI设备比如显卡声卡内部(某些PCI device就在主板上,不是外插的);PCI桥的配置空间寄存器在主板的桥芯片组里,逻辑上分出很多bridge但是物理上就是一组bridge配置空间寄存器。
bridge和device的空间配置寄存器配置不一样,配置空间当然也不一样。

配置空间相当于每个register对应某bus device function在写值,多个寄存器总结出来就是下方这种表(没显示全,实际会到FF h)。
比如vendor ID Device ID这一行的值在某个SATA PCI型号设备里是一个叫Identifiers的寄存器对应写的4字节(各个厂商spec规范里都会写,都是符合PCI规范要求的)。
确定了bus device function号,才能获取唯一数据的配置空间,换了任一bus/device/function号,都不是完全一样的数据了。

PCI Bridge配置空间
在这里插入图片描述
PCI桥的00h到0Fh和PCI设备的这部分都是一样的结构(后面会放PCI设备的空间配置图)。先介绍一下pci bridge独有的部分:
Primary Bus Number(Offset 18h):PCl桥的上游总线号(桥不是两头接总线吗,它的上游总线号是数字小的/靠近host bridge的)
Secondary Bus Number(Offset 19h):PCI的下游总线号(数字大的/远离host bridge的)
Subordinate Bus Number(Offset 1Ah):PCI桥下游最大的总线号(拓扑图里桥连接的最末端里bus号最大的)
这3个寄存器是在PCI Bus Scan的时候由BIOS填入的。

PCI device配置空间
在这里插入图片描述

讲一下主要的几个地方的值含义:

Vendor ID (Offset 00~01h)
示例 :ASMedia PCIe-to-PCI Bridge(用于扩展传统PCI插槽) 0x1B21 (代表ASMedia Technology Inc)

Device ID (Offset 02~03h)
示例 :同上的设备 0x1080(代表ASMedia ASM1083/1085 PCIe to PCI Bridge)
所以读这个设备的配置空间的时候第一行是1080 1B21,如果用RU工具查看:21 1B 80 10(从低到高)

Class Code(Offset 09h~0Bh)
这三个字节实际上是Programming Interface(09h)+Sub-Class(0Ah)+Base Class(0Bh)
代表PCI的类别,例如网络类、显示类。
Base Class这字节如果显示02,就表示Network Controller网络类(PCI spec里有写对应类型)。
spec里都有写对应的,照着看就能明白具体类型了。
在这里插入图片描述
Command (Offset 04~07h)
每一bit代表的含义spec都有写,其他的也一样,照着PCI spec看就行了。
在这里插入图片描述

Header Type(Offset 0Eh)
Bit 7 : multiple function。是否是多功能,也就是相同的Bus和Device号,有其他Function号。0表示单功能,1表示多功能。
Bit 6 - 0 : 如果值为0=PCI device,1=PCI to PCI bridge,2=Card Bus bridge。
(举例:如果0E偏移这里的1字节读出来是01h,则表明这是一个单功能PCI bridge;如果是读出来是80h,则是多功能PCI device)

Interrupt Line(Offset 3Ch) :该设备所使用的IRQ Number(值范围是0-0Fh)
什么是IRQ?它是物理上连接到CPU的硬件线(pin脚),用来传递中断信号。当设备需要中断CPU时,会通过具体的IRQ线发送中断请求。而我们需要用PCI的Interrupt Pin去连IRQ。
硬件中断线编号从0到15(0Fh),对应于主要的硬件中断线(如硬盘、声卡、键盘等),这15条中断线(IRQ0-IRQ15)对应不同的pin脚,通常如下:
IRQ0:系统计时器
IRQ1:键盘控制器
IRQ2:级联中断链路
IRQ3:串行端口
IRQ4:串行端口
IRQ5:声卡、其他设备
IRQ6:硬盘控制器
IRQ7:并口
IRQ8-IRQ15:不同的外围设备

Interrupt Pin(Offset 3Dh):该设备所使用的中断引脚
值为0:该设备没用使用中断引脚,1:用中断引脚INTA#,2:INTB#,3:INTC#,4:INTD#,FFh:reserved
参考之前的PCI pin脚图里:
在这里插入图片描述

Capabilities Pointer(Offset 34h) :存储1字节的指针,可以理解为单链表的头指针(例如图上的这一个字节数据A4h代表指到A4h去索引本PCI的第一个Capability)

PCI的Capability(能力结构)是存放在设备配置空间中的一段特殊数据结构。它允许设备定义一些扩展功能,比如电源管理、MSI(消息中断)、热插拔支持等。
每个Capability 结构都有唯一的ID号,每一个Capability 寄存器都有一个指针,这个指针指向下一个Capability 结构,从而组成一个单向链表结构,这个链表的最后一个Capability 结构的指针为0

所以我们只用考虑初始 capability pointer值每个Capability结构里包的指针值
如图:34h里的值是A4h,所以去看A4h偏移,A4h这一字节的内容是这个Capability X的ID,随后的A5一字节是下一个Capability Y的偏移地址,再往后的区域就是这个Capability X的具体内容(具体占多少字节对照PCI规范)。就像图里这样不断寻址链表,直到Capability 结构的指针为0(例如图里的Capability Z)。被寻址到的Capability即为有对应功能的,没有实现某个能力的情况下,链表中就不会有“这个Capability的ID和内容”
在这里插入图片描述

2. PCI IRQ routing table(Legacy的东西,可不看)

IRQ是可以共享,每个IRQ可以供多个PCI device的INT引脚连接。

Windows 98需要知道主板上每个PCI设备的中断引脚(INTX Pin)和PCI Router中断引脚的对应关系。这个对应关系OS无法自动侦测。
Bios在build的时候提供PCI IRQ Routing Table。Post的时候Bios把这个table从Bios Rom里读出到内存的低段(F000段,可以看做20位地址F)。
Bios或OS根据PCI IRQ Routing Table分配IRQ给PCI设备。

如图所示低段存储着IRQ Table。
在这里插入图片描述

这是debug工具查找出来的:
(-s F000:FFFF "$PIR"表示从F0000开始查询FFFF个字节到FFFFF,搜索$PIR)
$PIR是IRQ routing table的标头,在FC5C0找到了(不熟悉这个查询的可以网上找一下资料,F000代表段,C5C0代表偏移,段左移4bit+偏移就是地址),之后就可以按照上面的IRQ Table来对照数据了。

在这里插入图片描述
从32offset开始每16字节就是一份Slot信息,里面包含了Bus号、Device号、对4个INT的Link Value和IRQ Bitmap(这部分是最重要的router信息)等等。
在这里插入图片描述

3. 如何访问PCI config space配置空间

前面介绍了PCI的bridge和device两种类型的配置空间,接下来说一下如何访问PCI配置空间里的值。

3.1 IO Port(仅用于x86平台,且读写的是Offeset FFh以内的信息)

x86体系中,IO端口是通过专门的指令(如IN/OUT)访问的,这是硬件设计的一部分,对于ARM就不适用了。而且它只能访问PCI设备的0-FFh,访问其他板子上PCIe设备扩展的100-FFFh就不行了。
(当然这里只是说一下配置空间访问,实际上PCIe直连CPU的,PCIe规格的设备当然不能插仅支持PCI的板子上用,之后有机会再介绍区别)
在这里插入图片描述
我们要先换算一串32bit数据到CF8(CONFIG_ADDRESS)中表明信息,然后CFC(CONFIG_DATA)进行寄存器读/写(如果不清楚x86的io口读写的自己搜搜资料看看)。
注意:PCI寄存器和配置空间任一改值都会同步,IO读写实际上是在通过IO口改PCI里的寄存器,后面的MMIO改的是内存里的一部分(被PCI寄存器映射出来的配置空间),只针对x86上PCI的话他俩最终效果一样,因为PCI寄存器和内存里的配置空间会同步更新。
上图就是换算数据的每一bit,包含了之前说的非常重要的bus device function属性。bit31置1,bit30:24全置0这是规范,而这个Register对应PCI配置空间图上的偏移,实际上数据是bit 7:0这一整个字节,但是由于规范,我们要对齐来读4字节数据,所以只能让最后2bit置00(详细解释看我另一篇csdn:关于PCI的IO Port读取为什么写入0CF8的32位里最后2bit规定是0)。


举例1,我们要 bus2 device1 function1 register2Ch 的数据,下图是填入数据,最终得到8002092C去填CF8。
在这里插入图片描述

汇编代码:

mov dx,0CF8h
mov eax,8002092Ch
out dx,eax
mov dx,0CFCh
in eax,dx

eax就会向我们展示获取到的4字节PCI寄存器数据。


举例2, bus2 device1 function1 register2Ch 的数据为80868086h:

汇编代码:

mov dx,0CF8h
mov eax,8002092Ch
out dx,eax
mov dx,0CFCh
mov eax,80868086h
out dx,eax

3.2 MMIO(推荐)

MMIO全称memory-mapping io,PCI寄存器映射到内存末端的区域,我们对其进行访问读写。
为什么推荐:1.arm也可以用;2.PCIe设备寄存器多达FFFh=前0-FFh PCI寄存器+后100-FFFh扩展寄存器,而io读写方式寄存器只有8bit,对于扩展部分肯定访问不到。

具体实现C语言mmio相关read/write函数,这里不细说了,只说它要输入的数值,也就是访问的内存空间(PCI映射的配置空间)。

举例:访问Bus2 Dev1 Func1 Reg100h(PCIe设备的扩展寄存器,不然的话PCI寄存器在0~FFh区间)
在这里插入图片描述
同样是需要4字节数据,前4位要求是1111,接8位bus号,5位device号,3位function号,再接12位register(也就是要去访问配置空间的偏移)。同理io口访问,也是最后2bit必须写00来保持对齐4字节访问。得到数据F0209100。

4. 如何识别PCI-e设备

答:用capability list

在这里插入图片描述
1.确认是否支持capability list(status的寄存器也就是偏移06h的bit4),是1意味着设备支持能力链
2.找到capability链表初始指针(从34h开始)
3.追capability链表(链表结束标识是Next是00h)
4.判断是否其中一个capability ID是10h,有的话则是PCIe设备

提一下,PCIe的0~FFh的PCI配置空间capability链表跟PCI一样是以找到next是00h就结束,而扩展部分(100-FFFh)第一个capability就在是100h这里开始。
在这里插入图片描述

参考文档:PCI规范

相关文章:

【PCI】PCI入门介绍(包含部分PCIe讲解)

先解释一下寻址空间&#xff1a; 机器是32bit的话&#xff0c;意味着4G&#xff08;2的32次方&#xff09;寻址空间&#xff0c;内存条作为它的实际物理存储设备。大部分在跑内存程序运行&#xff0c;少部分用来存放其他东西。这是一个常见的4G寻址空间分布&#xff08;不一定是…...

Cloudera Manager 学习笔记

目录 1 基础概念与原理1.1 Cloudera Manager的主要作用是什么&#xff1f;1.2 与Ambari有何区别&#xff1f;1.3 Cloudera Manager 的核心功能和架构是什么&#xff1f;1.4 解释一下 Cloudera Manager 中的服务模型和角色?1.5 Cloudera Manager 是如何实现对 CDH 集群的集中管…...

Deepin 23.10安装Docker

个人博客地址&#xff1a;Deepin 23.10安装Docker | 一张假钞的真实世界 Deepin 是基于 Debian 的国产 Linux 发行版&#xff0c;安装 Docker Desktop 可能会遇到兼容性问题&#xff0c;因为 Docker Desktop 官方主要支持 Ubuntu/Debian/Red Hat/Fedora/Arch 等主流发行版&…...

使用PowerBI个人网关定时刷新数据

使用PowerBI个人网关定时刷新数据 PowerBI desktop连接mysql&#xff0c;可以设置定时刷新数据或在PowerBI服务中手动刷新数据,步骤如下&#xff1a; 第一步&#xff1a; 下载网关。以个人网关为例&#xff0c;如图 第二步&#xff1a; 双击网关&#xff0c;点击下一步&…...

数字人引领政务新风尚:智能设备助力政务服务

在信息技术飞速发展的今天&#xff0c;政府机构不断探索提升服务效率和改善服务质量的新途径。实时交互数字人在政务服务中的应用正成为一大亮点&#xff0c;通过将“数字公务员”植入各种横屏智能设备中&#xff0c;为民众办理业务提供全程辅助。这种创新不仅优化了政务大厅的…...

深入剖析Java类加载机制:双亲委派模型的突破与实战应用

引言&#xff1a;一个诡异的NoClassDefFoundError 某金融系统在迁移到微服务架构后&#xff0c;突然出现了一个诡异问题&#xff1a;在调用核心交易模块时&#xff0c;频繁抛出NoClassDefFoundError&#xff0c;但类明明存在于classpath中。经过排查&#xff0c;发现是由于不同…...

Kotlin JVM 注解详解

前言 Kotlin 作为一门现代 JVM 语言&#xff0c;提供了出色的 Java 互操作性。为了更好地支持与 Java 代码的交互&#xff0c;Kotlin 提供了一系列 JVM 相关注解。这些注解不仅能帮助我们控制 Kotlin 代码编译成 Java 字节码的行为&#xff0c;还能让我们的 Kotlin 代码更好地…...

将 node.js 项目作为后台进程持续运行

将 node.js 项目作为后台进程持续运行 方法 1&#xff1a;使用 pm2&#xff08;生产环境推荐&#xff09; 安装 pm2&#xff08;Node.js 进程管理器&#xff09;&#xff1a;npm install pm2 -g启动应用&#xff1a;pm2 start hd/src/app.js --name "my-app"常用命…...

【PhysUnits】15.5 引入P1后的标准化表示(standardization.rs)

一、源码 这段代码实现了一个类型级别的二进制数标准化系统&#xff0c;主要用于处理二进制数的前导零和特殊值的简化。 use super::basic::{Z0, P1, N1, B0, B1, NonNegOne, NonZero};/// 处理 B0<H> 类型的标准化 /// Standardization for B0<H> types /// ///…...

MySQL-5.7 修改密码和连接访问权限

一、MySQL-5.7 修改密码和连接权限设置 修改密码语法 注意&#xff1a;rootlocalhost 和 root192.168.56.% 是两个不同的用户。在修改密码时&#xff0c;两个用户的密码是各自分别保存&#xff0c;如果两个用户密码设置不一样则登陆时注意登陆密码 GRANT ALL PRIVILEGES ON …...

tauri2项目打开某个文件夹,类似于mac系统中的 open ./

在 Tauri 2 项目中打开文件夹 在 Tauri 2 项目中&#xff0c;你可以使用以下几种方法来打开文件夹&#xff0c;类似于 macOS 中的 open ./ 命令功能&#xff1a; 方法一&#xff1a;使用 shell 命令 use tauri::Manager;#[tauri::command] async fn open_folder(path: Strin…...

企业文件乱、传输慢?用群晖 NAS 构建安全高效的共享系统

在信息化办公不断加速的今天&#xff0c;企业对文件存储、共享与安全管理的需求愈发严苛。传统文件共享方式效率低下、权限混乱、远程访问困难&#xff0c;极大影响了协同办公效率。此时&#xff0c;一套可靠、高效、安全的文件共享解决方案便成为众多企业的“刚需”。 这正是…...

防爆手机VS普通手机,区别在哪里?

在加油站掏出手机接打电话、在化工厂车间随手拍照记录……这些看似寻常的行为&#xff0c;实则暗藏致命风险。普通手机在易燃易爆环境中可能成为“隐形炸弹”&#xff0c;而防爆手机却能安全护航。这两者看似相似&#xff0c;实则从底层基因到应用场景都存在着本质差异&#xf…...

C语言结构体的别名与创建结构体变量

这段代码是用C语言定义了一个链表节点的结构体&#xff0c;并通过typedef为相关类型创建了别名。下面分别解释Lnode和pNode&#xff1a; 1. Lnode Lnode是通过typedef为struct node定义的一个别名。struct node是一个结构体类型&#xff0c;表示一个链表节点。它的定义如下&a…...

在RTX5060Ti上进行Qwen3-4B的GRPO强化微调

导语 最近赶上618活动&#xff0c;将家里的RTX 4060显卡升级为了RTX 5060Ti 16GB版本&#xff0c;显存翻了一番&#xff0c;可以进行一些LLM微调实验了&#xff0c;本篇博客记录使用unsloth框架在RTX 5060Ti 16GB显卡上进行Qwen3-4B-Base模型的GRPO强化微调实验。 简介 GPU性…...

SQL进阶之旅 Day 7:视图与存储过程入门

【SQL进阶之旅 Day 7】视图与存储过程入门 在SQL开发中&#xff0c;视图&#xff08;View&#xff09;和存储过程&#xff08;Stored Procedure&#xff09;是两个非常重要的数据库对象。它们不仅可以简化复杂查询逻辑&#xff0c;还能提高代码复用性和安全性。本文将深入探讨…...

武汉火影数字VR大空间制作

VR大空间是一种利用空旷的物理空间&#xff0c;结合先进的虚拟现实技术&#xff0c;让用户能够在其中自由移动并深度体验虚拟世界的创新项目方式。 在科技飞速发展的当下&#xff0c;VR大空间正以其独特的魅力&#xff0c;成为科技与娱乐领域的耀眼新星&#xff0c;掀起了一股沉…...

Docker部署项目无法访问,登录超时完整排查攻略

项目背景&#xff1a;迁移前后端应用&#xff0c;prod环境要求保留443端口&#xff0c;开发环境37800端口&#xff0c;后端容器端口为8000&#xff0c;前端为80&#xff0c;fastAPI对外端口为41000 生产环境部署在VM01,开发环境部署在VM03&#xff0c;在VM01配置nginx转发 [r…...

(增强)基于sqlite、mysql、redis的消息存储

原文链接&#xff1a;&#xff08;增强&#xff09;基于sqlite、mysql、redis的消息存储 教程说明 说明&#xff1a;本教程将采用2025年5月20日正式的GA版&#xff0c;给出如下内容 核心功能模块的快速上手教程核心功能模块的源码级解读Spring ai alibaba增强的快速上手教程…...

Windows上用FFmpeg推流及拉流的流程概览

1. 视频采集与推流&#xff08;Windows FFmpeg&#xff09; 采集设备&#xff1a;Windows上的摄像头&#xff0c;比如“Integrated Camera”。 采集方式&#xff1a;FFmpeg通过 dshow 设备接口读取摄像头。 推流协议&#xff1a;你可以选择推到 RTMP 或 RTSP 服务器。 推流…...

MFC坦克大战游戏制作

MFC坦克大战游戏制作 前言 现在的游戏制作一般是easyx&#xff0c;有没有直接只用mfc框架的&#xff0c;笔者研究了一番&#xff0c;做出了一个雏形&#xff0c;下面把遇到的问题总结出来 一、MFC框架制作游戏 初步设想&#xff0c;MFC可以选用 对话框 或者 单文档 结构&…...

Kafka ACK机制详解:数据可靠性与性能的权衡之道

在分布式消息系统中&#xff0c;消息确认机制是保障数据可靠性的关键。Apache Kafka 通过 ACK&#xff08;Acknowledgment&#xff09;机制 实现了灵活的数据确认策略&#xff0c;允许用户在 数据可靠性 和 系统性能 之间进行权衡。本文将深入解析 Kafka ACK 机制的工作原理、配…...

VulnStack|红日靶场——红队评估四

信息收集及漏洞利用 扫描跟kali处在同一网段的设备&#xff0c;找出目标IP arp-scan -l 扫描目标端口 nmap -p- -n -O -A -Pn -v -sV 192.168.126.154 3个端口上有web服务&#xff0c;分别对应三个漏洞环境 &#xff1a;2001——Struts2、2002——Tomcat、2003——phpMyAd…...

数据库 | 时序数据库选型

选型目标 高性能与低延迟&#xff1a;满足高频率数据写入与即时查询的需求。资源效率&#xff1a;优化存储空间使用&#xff0c;减少计算资源消耗。可扩展架构&#xff1a;支持数据量增长带来的扩展需求&#xff0c;易于维护。社区活跃度&#xff1a;有活跃的开发者社区&#…...

网络拓扑如何跨网段访问

最近领导让研究下跟甲方合同里的&#xff0c;跨网段访问怎么实现&#xff0c;之前不都是运维网工干的活么&#xff0c;看来裁员裁到动脉上了碰到用人的时候找不到人了&#xff0c; 只能赶鸭子上架让我来搞 IP 网络中&#xff0c;不同网段之间的通信需要通过路由器&#xff0c;…...

CppCon 2014 学习第1天:An SQL library worthy of modern C++

sqlpp11 — 现代 C 应用值得拥有的 SQL 库 template<typename T> struct _member_t {T feature; };你提到的是一个 C 中的“成员模板&#xff08;Member Template&#xff09;”&#xff0c;我们来一步步理解&#xff1a; 基本代码分析&#xff1a; template<typena…...

【LLM相关知识点】 LLM关键技术简单拆解,以及常用应用框架整理(二)

【LLM相关知识点】 LLM关键技术简单拆解&#xff0c;以及常用应用框架整理&#xff08;二&#xff09; 文章目录 【LLM相关知识点】 LLM关键技术简单拆解&#xff0c;以及常用应用框架整理&#xff08;二&#xff09;一、市场调研&#xff1a;业界智能问答助手的标杆案例1、技术…...

数据分析与应用-----使用scikit-learn构建模型

目录 一、使用sklearn转换器处理数据 &#xff08;一&#xff09;、加载datasets模块中的数据集 &#xff08;二&#xff09;、将数据集划分为训练集和测试集 ​编辑 train_test_spli &#xff08;三&#xff09;、使用sklearn转换器进行数据预处理与降维 PCA 二、 构…...

003 flutter初始文件讲解(2)

1.书接上回 首先&#xff0c;我们先来看看昨天最后的代码及展示效果&#xff1a; import "package:flutter/material.dart";void main(){runApp(MaterialApp(home:Scaffold(appBar:AppBar(title:Text("The World")), body:Center(child:Text("Hello…...

Windows系统下 NVM 安装 Node.js 及版本切换实战指南

以下是 Windows 11 系统下使用 NVM 安装 Node.js 并实现版本自由切换的详细步骤&#xff1a; 一、安装 NVM&#xff08;Node Version Manager&#xff09; 1. 卸载已有 Node.js 如果已安装 Node.js&#xff0c;请先卸载&#xff1a; 控制面板 ➔ 程序与功能 ➔ 找到 Node.js…...