MSI_MSI-X中断之源码分析
MSI_MSI-X中断之源码分析
文章目录
- MSI_MSI-X中断之源码分析
- 一、 怎么发出MSI/MSI-X中断
- 1.1 在RK3399上体验
- 1.1.1 安装工具
- 1.1.2 查看设备MSI-X信息
- 1.1.3 验证MSI-X信息
- 二、 怎么使用MSI/MSI-X
- 三、 MSI/MSI-X中断源码分析
- 3.1 IRQ Domain创建流程
- 3.1.1 GIC
- 3.1.2 ITS
- 3.1.3 PCI MSI
- 3.1.4 PCIe控制器
- 3.2 分配中断
- 致谢
开发板资料:
- 开发板Firefly-rk3399资料
参考内核文件:
Documentation\PCI\MSI-HOWTO.txtdrivers\pci\host\pcie-rockchip.cdrivers\nvme\host\pci.cdrivers\irqchip\irq-gic-v3.cdrivers\irqchip\irq-gic-v3-its.cdrivers\irqchip\irq-gic-v3-its-pci-msi.c
一、 怎么发出MSI/MSI-X中断
PCIe设备向发出中断,它发出TLP包,往某个地址写入某个数据即可:
- 往哪个地址?GICv3 ITS的GITS_TRANSLATER寄存器,TLP包里使用的是PCI地址
- 写什么数据?0、1、2、……,要发出第1个中断时写0,要发出第2个中断时写1,……
在设备树文件rk3399.dtsi中,可以看到ITS的基地址是0xfee20000:
its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};
在IHI0069G_gic_architecture_specification.pdf中有ITS寄存器的偏移地址:

GITS_TRANSLATER寄存器的CPU地址是:0xfee20000 + 0x010000 + 0x0040 = 0xfee30040。
对应的PCI地址也是0xfee30040(驱动程序里为例方便,故意使得CPU地址跟PCI地址相同,这2个地址属于不同地址空间),
所以下图中PCI地址都是0xfee30040。

1.1 在RK3399上体验
在RK3399开发板,插上了NVMe SSD固态硬盘。

1.1.1 安装工具
请给RK3399刷入Ubuntu映像文件,然后在开发板上执行:
udhcpc # 获取IP
apt update # 更新源
apt install pciutils # 安装lspci工具
apt install devmem2 # 安装devmem2工具
1.1.2 查看设备MSI-X信息
执行lspci -vvv,得到如下信息:
01:00.0 Non-Volatile memory controller: Silicon Motion, Inc. Device 2263 (rev 03) (prog-if 02 [NVM Express])Subsystem: Silicon Motion, Inc. Device 2263Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-Latency: 0Interrupt: pin A routed to IRQ 231Region 0: Memory at fa000000 (64-bit, non-prefetchable) [size=16K]Capabilities: [40] Power Management version 3Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-Capabilities: [50] MSI: Enable- Count=1/8 Maskable+ 64bit+Address: 0000000000000000 Data: 0000Masking: 00000000 Pending: 00000000Capabilities: [70] Express (v2) Endpoint, MSI 00DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimitedExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0.000WDevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop- FLReset-MaxPayload 128 bytes, MaxReadReq 512 bytesDevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-LnkCap: Port #0, Speed 8GT/s, Width x4, ASPM L1, Exit Latency L0s <1us, L1 <8usClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR+, OBFF Not SupportedDevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF DisabledLnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-Compliance De-emphasis: -6dBLnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-, EqualizationPhase1-EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-Capabilities: [b0] MSI-X: Enable+ Count=16 Masked-Vector table: BAR=0 offset=00002000PBA: BAR=0 offset=00002100Capabilities: [100 v2] Advanced Error ReportingUESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-Capabilities: [158 v1] #19Capabilities: [178 v1] Latency Tolerance ReportingMax snoop latency: 0nsMax no snoop latency: 0nsCapabilities: [180 v1] L1 PM SubstatesL1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+PortCommonModeRestoreTime=10us PortTPowerOnTime=10usL1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-T_CommonMode=0us LTR1.2_Threshold=0nsL1SubCtl2: T_PwrOn=10usKernel driver in use: nvme
从上述信息可以看到:
Region 0: Memory at fa000000 (64-bit, non-prefetchable) [size=16K]Capabilities: [b0] MSI-X: Enable+ Count=16 Masked-Vector table: BAR=0 offset=00002000PBA: BAR=0 offset=00002100
这表示:
- MSI-X: Enable+:使用MSI-X功能
- Vector table: BAR=0 offset=00002000:MSI的向量在BAR 0偏移地址0x00002000处
- Region 0: Memory at fa000000:
- BAR 0的PCI地址是0xfa000000,
- 驱动程序里为了方便令CPU地址等于PCI地址,所以BAR的CPU地址也是0xfa000000。
我们可以去读取 0xfa000000 + 0x00002000开始的向量表,验证里:
- msg addr为0xfee30040
- msg data为0、1、……

1.1.3 验证MSI-X信息

二、 怎么使用MSI/MSI-X
参考内核文档:Documentation\PCI\MSI-HOWTO.txt、drivers\nvme\host\pci.c
主要函数是这2个:
int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,int minvec, int maxvec);
int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec);
示例代码如下:
// 分配 msix_entry 数组,每一数组项用来保存一个中断的信息dev->entry = kzalloc_node(num_possible_cpus() * sizeof(*dev->entry),GFP_KERNEL, node);// 先尝试使用MSI-Xvecs = pci_enable_msix_range(pdev, dev->entry, 1, nr_io_queues);if (vecs < 0) {// 再尝试使用MSIvecs = pci_enable_msi_range(pdev, 1, min(nr_io_queues, 32));if (vecs < 0) {vecs = 1;} else {for (i = 0; i < vecs; i++)dev->entry[i].vector = i + pdev->irq;}}// request_irq: 中断号都保存在dev->entry[i].vector里for (i = 0; i < vecs; i++)request_irq(dev->entry[i].vector, ...);
注意,在pci_enable_msix_range或者pci_enable_msi_range函数中:
- minvec从1开始
- 对于pci_enable_msix_range,中断号保存在entries[i].vector里
- 对于pci_enable_msi_range,第1个中断号保存在pdev->irq里
三、 MSI/MSI-X中断源码分析
3.1 IRQ Domain创建流程
从PCI设备触发,涉及三个IRQ Domain:
drivers\irqchip\irq-gic-v3-its-pci-msi.cdrivers\irqchip\irq-gic-v3-its.cdrivers\irqchip\irq-gic-v3.c
3.1.1 GIC
设备树:
gic: interrupt-controller@fee00000 {compatible = "arm,gic-v3";#interrupt-cells = <4>;#address-cells = <2>;#size-cells = <2>;ranges;interrupt-controller;reg = <0x0 0xfee00000 0 0x10000>, /* GICD */<0x0 0xfef00000 0 0xc0000>, /* GICR */<0x0 0xfff00000 0 0x10000>, /* GICC */<0x0 0xfff10000 0 0x10000>, /* GICH */<0x0 0xfff20000 0 0x10000>; /* GICV */interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};
驱动代码:`drivers\irqchip\irq-gic-v3.c

3.1.2 ITS
设备树:
its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};
驱动代码:`drivers\irqchip\irq-gic-v3-its.c

3.1.3 PCI MSI
对应的设备节点跟ITS驱动使用的一样的:
its: interrupt-controller@fee20000 {compatible = "arm,gic-v3-its";msi-controller;reg = <0x0 0xfee20000 0x0 0x20000>;};
驱动代码:drivers\irqchip\irq-gic-v3-its-pci-msi.c,它只是在ITS下面再增加了一个处理层:

3.1.4 PCIe控制器
设备树:
pcie0: pcie@f8000000 {compatible = "rockchip,rk3399-pcie";#address-cells = <3>;#size-cells = <2>;aspm-no-l0s;clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,<&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;clock-names = "aclk", "aclk-perf","hclk", "pm";bus-range = <0x0 0x1f>;max-link-speed = <1>;linux,pci-domain = <0>;msi-map = <0x0 &its 0x0 0x1000>;
里面的msi-map = <0x0 &its 0x0 0x1000>;是用来把PCIe设备映射到MSI控制器,它的格式为:
msi-map = <rid-base &msi-controller msi-base length>;
- rid-base:第1个Request ID,就是使用<bus, dev, function>组成的一个数字
- msi-controller:这个PCIe设备映射到哪个MSI控制器?
- msi-base:第1个PCIe设备映射到MSI控制器哪个中断?
- length:能映射多少个设备
3.2 分配中断
代码:drivers\nvme\host\pci.c
nvme_probe > nvme_probe_work > nvme_setup_io_queues pci_enable_msix_rangepci_enable_msix(dev, entries, nvec);msix_capability_init(dev, entries, nvec);pci_enable_msi_rangemsi_capability_init(dev, nvec);msix_capability_init/msi_capability_initpci_msi_setup_msi_irqspci_msi_domain_alloc_irqsmsi_domain_alloc_irqsret = ops->msi_prepare(domain, dev, nvec, &arg); // its_pci_msi_prepareits_pci_msi_prepare // irq-gic-v3-its-pci-msi.c// rid = (bus << 8) | (dev << 4) | functioninfo->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev); return msi_info->ops->msi_prepare(...) // 上一层irq-gic-v3-its.cits_msi_preparedev_id = info->scratchpad[0].ul; // ridits_dev = its_create_device(its, dev_id, nvec);// 从ITS全局的位图里找到空闲位 chunk// 一个chunk表示32个中断// its的hwirq = (chunk << 5) + 8192// 这也是GIC的hwirqlpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);// 等于(chunk << 5) + 8192 dev->event_map.lpi_base = lpi_base;__irq_domain_alloc_irqsirq_domain_alloc_irqs_recursiveret = domain->ops->alloc(domain, irq_base, nr_irqs, arg);its_irq_domain_allocerr = its_alloc_device_irq(its_dev, &hwirq);*hwirq = dev->event_map.lpi_base + idx;irq_domain_set_hwirq_and_chipirq_data->hwirq = hwirq;irq_data->chip = chip ? chip : &no_irq_chip;irq_domain_activate_irq(irq_data);domain->ops->activate(domain, irq_data);msi_domain_activateirq_chip_compose_msi_msg(irq_data, &msg) // 构造msg,里面含有MSI或msi-x的addr/valits_irq_compose_msi_msgaddr = its->phys_base + GITS_TRANSLATER;msg->address_lo = addr & ((1UL << 32) - 1);msg->address_hi = addr >> 32;// its_get_event_id:// d->hwirq - its_dev->event_map.lpi_base;msg->data = its_get_event_id(d); // 设置msi-x的entry地址 irq_chip_write_msi_msg(irq_data, &msg);data->chip->irq_write_msi_msg(data, msg);pci_msi_domain_write_msg__pci_write_msi_msg(desc, msg);__pci_write_msi_msg(desc, msg);// 对于MSI-Xwritel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR);writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);writel(msg->data, base + PCI_MSIX_ENTRY_DATA);// 对于MSIpci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl);pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,msg->address_lo);// 为PCI设备确定hwirq
its_domain_ops.alloc
its_irq_domain_allocits_alloc_device_irq*hwirq = dev->event_map.lpi_base + idx;
致谢
以上笔记源自
韦东山老师的视频课程,感谢韦老师,韦老师是嵌入式培训界一股清流,为嵌入式linux开发点起的星星之火,也愿韦老师桃李满园。聚是一团火,散是满天星!
在这样一个速食的时代,坚持做自己,慢下来,潜心琢磨,心怀敬畏,领悟知识,才能向下扎到根,向上捅破天,背着世界往前行!
仅此向嵌入行业里的每一个认真做技术的从业者致敬!
相关文章:
MSI_MSI-X中断之源码分析
MSI_MSI-X中断之源码分析 文章目录MSI_MSI-X中断之源码分析一、 怎么发出MSI/MSI-X中断1.1 在RK3399上体验1.1.1 安装工具1.1.2 查看设备MSI-X信息1.1.3 验证MSI-X信息二、 怎么使用MSI/MSI-X三、 MSI/MSI-X中断源码分析3.1 IRQ Domain创建流程3.1.1 GIC3.1.2 ITS3.1.3 PCI MSI…...
Docker--consul
目录 前言 一、Consul 简介 1.1、 consul 概述 1.2 、consul 的两种模式 1.3、consul 提供的一些关键特性 二、Consul 容器服务更新与发现 三、consul 部署 3.2、查看集群信息 四、registrator服务器 consul-template 五、consul 多节点 前言 服务注册与发现是微服…...
ESP-01S使用AT指令连接阿里云
ESP-01S使用AT指令连接阿里云 烧录MQTT AT固件 出厂的ESP-01S是基本的AT指令固件,没有MQTT的,所以无法通过MQTT指令与云平台通信,需要烧录固件(如果测试到有MQTT相关的指令,则不用重新烧录固件) 固件烧录…...
【Kafka】【三】安装Kafka服务器
Kafka基本知识 Kafka介绍 Kafka是最初由Linkedin公司开发,是⼀个分布式、⽀持分区的(partition)、多副本的 (replica),基于zookeeper协调的分布式消息系统,它的最⼤的特性就是可以实时的处理 …...
关于适配器模式,我遗漏了什么
近期有些tasks需要 重构or适配 老的代码。 与其向上面堆💩,不如优雅的去解决。 首先我的问题在于,错误的把 堆屎的操作 ,当作了适配器模式的操作。 比如原函数入参,需要更改某个属性,把这种操作外包一层…...
SQL Serve 日志体系结构
SQL Server 事务日志记录着 undo 及 redo 日志,为了保证数据库在崩溃后恢复,或者在正常数据库操作期间进行回滚,保证数据库事务完整性和持久化。如果没有事务日志记录,数据库在事务上将不一致,并且在数据库崩溃后可能导…...
【C++1】函数重载,类和对象,引用,string类,vector容器,类继承和多态,/socket,进程信号,public,ooci
文章目录1.函数重载:writetofile(),Ctrue和false,C0和非02.类和对象:vprintf2.1 构造函数:对成员变量初始化2.2 析构函数:一个类只有一个,不允许被重载3.引用:C中&取地址&#x…...
asio网络编程 tcp、udp、rpc
轻量级的tcp/udp/rpc库,简化socket程序编写。 同时,RPC部分也提供了方便易用的功能。 仓库地址 https://github.com/shuai132/asio_net asio_net a Tiny Async TCP/UDP/RPC library based on ASIO and RpcCore Features 简化TCP、UDP相关程序的编写…...
双目测距------双目相机V1.0,将双目相机采集到任意一点的深度数据进行串口传输(带源码)
Depth2Uart 双目测距------双目相机V1.0,将双目相机采集到任意一点的深度数据进行串口传输 一、项目说明/Overview 所实现的功能:基于Intel Realsense官方提供的SDK,双目深度相机能获取到相机任何一个像素点距离前方障碍物的距离࿰…...
jetson nano(ubuntu)安装Cmake
文章目录安装环境一.命令行安装二.Cmake源码编译安装安装环境 jetson nano 系统:4.6.1 一.命令行安装 sudo apt install cmake这种直接安装cmake的方式,其实安装的版本都太老了,这种方式不推荐 二.Cmake源码编译安装 更新一下系统软件 su…...
图的基本介绍和表示方式
图的基本介绍 为什么要有图这个基本数据结构? 我们还学习过线性表(数组、队列、链表和栈)和树,但是我们可以发现,线性表局限于一个直接前驱(就是只能有唯一一个前面的结点)和一个直接后继的(…...
本周大新闻|传微软解散工业元宇宙团队,MIT研发垂直堆叠全彩Micro LED
本周大新闻,AR方面,消息称微软解散工业元宇宙团队;德国AR公司Gixel GmbH亮相;Brilliant推出单片式附加形态AR眼镜;MIT研发垂直堆叠全彩Micro LED;谷歌XR串流正式上线。VR方面,索尼发布了PS VR2的…...
SpringMVC:拦截器(12)
拦截器1. 拦截器概念2. 拦截器入门案例2.1 环境准备2.2 拦截器开发步骤1: 创建拦截器类步骤2: 配置拦截器类步骤3: SpringMVC添加SpringMvcSupport包扫描和interceptor包扫描步骤4: 简化SpringMvcSupport的编写5 测试3. 拦截器参数解析(了解)3.1 前置处理…...
计算机网络3:HTTP1.0和HTTP1.1的区别
目录1. HTTP是什么2.HTTP1.0和HTTP1.1的区别3.名词解释(1)If-Modified-Since(IMS)、Expires(2)If-None-Match,Etag(3)If-Unmodified-Since1. HTTP是什么 超文本传输协议…...
Urho3D 编辑器说明
Urho3D编辑器是一个脚本应用程序,可以与Urho3D播放器应用程序一起运行。要开始,请执行以下任意命令:(在bin目录中)Editor.bat、Editor.sh或Urho3DPlayer Scripts/Editor.as Urho3D播放器应用程序支持的所有命令行选项…...
C++类基础(十一)
运算符重载(二) ● 对称运算符通常定义为非成员函数以支持首个操作数的类型转换 struct Str {int val 0;Str(int input): val(input){}auto operator(Str x){std::cout << "auto operator(Str x)\n";return Str(val x.val);} }; int …...
Windows安装系列:SVN Server服务
一、下载与安装 1、下载VisualSVN-Server-5.1.1-x64.msi 地址:Download | VisualSVN Server 2、找到最新版本SVN 5.1.1,直接双击它,弹出如下安装界面 3、点击Next 4、勾选我接受, 点击"Next" 5、默认选项,…...
快速傅里叶算法(FFT)快在哪里?
目录 前言 1、DFT算法 2、FFT算法 2.1 分类 2.2 以基2 DIT(时间抽取) FFT 算法为例 2.2.1 一次分解 2.2.2 多次分解 参考 前言 对信号分析的过程中,为了能换一个角度观察问题,很多时候需要把时域信号波形变换到频域进行分…...
利用Markdown写学术论文资料汇总贴
1是最详细的,重点看! Markdown 写作,Pandoc 转换:我的纯文本学术写作流程 2补充一些细节,也可以看看。 用Markdown写作学术论文 3写得和上面差不多,如果上面两篇有什么问题还没解决,可以看看…...
MySQL 高级查询
目录1.左关联2.右关联3.子查询4.联合查询5.分组查询1.左关联 MySQL中的左关联(Left Join)是一种基于共同列的连接操作, 它将左侧表中的所有行与右侧表中匹配的行结合在一起, 如果右侧表中没有匹配的行,则结果集中右侧…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
