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

FPGA跨时钟域处理

文章目录

  • 一、为什么要做跨时钟域处理
  • 二、单bit信号从慢时钟到快时钟处理
    • 2.1 使用同步寄存器链(打两拍)
    • 2.2 仿真代码编写
    • 2.3 仿真结果观察
  • 三、单bit信号从快时钟域到慢时钟域处理
    • 3.1 使用脉冲展宽
    • 3.2 仿真代码编写
    • 3.3 仿真结果观察
  • 四、在任意时钟域跨单bit信号
    • 4.1 使用握手协议传输单bit脉冲信号
    • 4.2 从快到慢仿真代码编写
    • 4.3 从快到慢仿真结果观察
    • 4.4 从慢到快仿真结果观察
  • 五、多bit数据跨时钟域


一、为什么要做跨时钟域处理

  在之前的文章《FPGA静态时序分析与约束(一)、理解亚稳态》中,我知道了什么是亚稳态以及亚稳态对系统的危害。通常我们的系统工程中不止有一个处理时钟,当不同时钟域下的信号进行交互的时候就涉及到跨时钟域的问题了。由于不同时钟的频率、相位都可能不同,所以就存在目标时钟在采集源时钟域信号时发生亚稳态情况,如下图所示:

在这里插入图片描述
  此时源时钟域下的信号变化刚好在目标时钟域的上升沿建立或保持时间范围内,因此发生了建立或保持时间违规从而造成亚稳态的输出。因此我们必须对这种情况进行处理,处理方式分为三种情况:

  1. 单bit信号从慢时钟到快时钟
  2. 单bit信号从快时钟到慢时钟
  3. 多bit信号跨时钟域

二、单bit信号从慢时钟到快时钟处理

2.1 使用同步寄存器链(打两拍)

  在快时钟域频率高于慢时钟域时,理论上一个慢时钟域周期的信号可以百分百被快时钟采集到,为了防止亚稳态的产生可以通过打两拍的方式处理,如下图所示:

在这里插入图片描述
  就算第一级寄存器产生了亚稳态,但是经过自身寄存器输出后能够使信号快速回落至稳定状态,稳定输出的概率为70%~80%左右,第二级寄存器可以稳定输出的概率为99%左右,再后面改善就不明显了,所以一般情况下进行两级寄存就能消除大多数情况下的亚稳态。代码如下:

`timescale 1ns / 1ps
module single_bit_slow2fast(input                                               i_signal_a      ,   //慢时钟域的信号input                                               i_clk_b         ,   //快时钟input                                               i_rst_b         ,   //快时钟域复位信号,高电平有效       output                                              o_signal_b      ,   //快时钟域同步后的信号output                                              o_signal_b_pos  ,   //同步后的信号上升沿output                                              o_signal_b_neg      //同步后的信号下降沿
);reg                                                 r_signal_a_d1   ;
reg                                                 r_signal_a_d2   ;
reg                                                 r_signal_a_d3   ;       //再打一拍是用最稳定的两拍检测边沿信号assign      o_signal_b      = r_signal_a_d2;
assign      o_signal_b_pos  = r_signal_a_d2 & (~r_signal_a_d3);
assign      o_signal_b_neg  = (~r_signal_a_d2) & r_signal_a_d3;always @(posedge i_clk_b or posedge i_rst_b) beginif(i_rst_b == 1'b1)beginr_signal_a_d1 <= 1'b0;r_signal_a_d2 <= 1'b0;r_signal_a_d3 <= 1'b0;endelse beginr_signal_a_d1 <= i_signal_a;r_signal_a_d2 <= r_signal_a_d1;r_signal_a_d3 <= r_signal_a_d2;end
endendmodule

2.2 仿真代码编写

  仿真代码产生两个不同快慢时钟,以及慢时钟域的信号,代码如下:

`timescale 1ns / 1ns
module tb_single_bit_slow2fast();reg                                                 i_clk_b ;reg                                                 clk_a   ;reg                                                 i_rst_b ;reg                                                 i_signal_a  ;initial begini_clk_b = 0;clk_a = 0;i_rst_b = 1;i_signal_a = 0;#300 @(posedge i_clk_b) i_rst_b = 0;
endalways #2  i_clk_b = ~ i_clk_b; 
always #15 clk_a = ~clk_a;always @(posedge clk_a) beginrepeat(20)begini_signal_a <= {$random}%2;#30i_signal_a <= 0;#200;end
endsingle_bit_slow2fast u_single_bit_slow2fast(.i_signal_a      ( i_signal_a      ),.i_clk_b         ( i_clk_b         ),.i_rst_b         ( i_rst_b         ),.o_signal_b      ( o_signal_b      ),.o_signal_b_pos  ( o_signal_b_pos  ),.o_signal_b_neg  ( o_signal_b_neg  )
);endmodule

2.3 仿真结果观察

在这里插入图片描述
  从仿真来看,慢时钟信号无论什么时候发送,快时钟依然能采集到。

三、单bit信号从快时钟域到慢时钟域处理

3.1 使用脉冲展宽

   对于快时钟域的信号让慢时钟来采集,不能使用打两拍来处理,因为快时钟信号宽度太小很可能慢时钟采集不到,如下图这种情况:

在这里插入图片描述
   在这种情况下,我们可以将快时钟下的信号进行展宽至慢时钟能采集到为止,然后再用慢时钟打两拍进行同步处理,如下所示:

在这里插入图片描述
  具体展宽多长,需要看两个时钟频率之间的比值,例如快时钟频率是175.5M,慢时钟是27M,快慢时钟之比=6.5,所以要将快时钟的脉冲展宽至7个时钟周期宽度才能确保被慢时钟采到。代码如下:

`timescale 1ns / 1ps
module single_bit_fast2slow#
(parameter CLKA_FPQ = 100_000_000,parameter CLKB_FPQ = 33_000_000
)
(input                                               i_clk_a     ,   //快时钟input                                               i_rst_a     ,   //快时钟域复位信号,高电平有效input                                               i_signal_a  ,   //快时钟脉冲信号input                                               i_clk_b     ,   //慢时钟input                                               i_rst_b     ,   //慢时钟复位信号,高电平有效output                                              o_signal_b      //慢时钟同步后的信号
);localparam                                          CLK_NUM = CLKA_FPQ / CLKB_FPQ;/***********a时钟域*******************/ reg             [7:0]                               clk_cnt         ;   //快时钟域下的计数器
reg                                                 r_i_signal_a    ;   //需要展宽的信号always @(posedge i_clk_a) beginif(i_rst_a)r_i_signal_a <= 1'b0;else if(clk_cnt == CLK_NUM)r_i_signal_a <= 1'b0;else if(i_signal_a == 1'b1)r_i_signal_a <= 1'b1;elser_i_signal_a <= r_i_signal_a;
endalways @(posedge i_clk_a) beginif(i_rst_a)clk_cnt <= 'd0;else if(clk_cnt == CLK_NUM)clk_cnt <= 'd0;else if(r_i_signal_a == 1'b1)clk_cnt <= clk_cnt + 1'b1;elseclk_cnt <= 'd0;
end/******************b时钟域**************/
reg                                                 r_signal_b1  ;
reg                                                 r_signal_b2  ;assign o_signal_b = r_signal_b2;always @(posedge i_clk_b) beginif(i_rst_b)beginr_signal_b1 <= 1'b1;r_signal_b2 <= 1'b1;endelse beginr_signal_b1 <= r_i_signal_a;r_signal_b2 <= r_signal_b1;endendendmodule

3.2 仿真代码编写

`timescale 1ns / 1nsmodule tb_single_bit_fast2slow();reg i_clk_a;
reg i_rst_a;
reg i_signal_a;
reg i_clk_b;
reg i_rst_b;initial begini_clk_a = 0;i_rst_a = 1;i_clk_b = 0;i_rst_b = 1;#150i_rst_a = 0;#100i_rst_b = 0;   
endalways#5   i_clk_a = ~i_clk_a;
always#15  i_clk_b = ~i_clk_b;always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)i_signal_a <= 1'b0;else begini_signal_a <= {$random}%2;#10;i_signal_a <= 1'b0;#100;endendsingle_bit_fast2slow#(.CLKA_FPQ    ( 100_000_000 ),.CLKB_FPQ    ( 30_000_000 )
)u_single_bit_fast2slow(.i_clk_a     ( i_clk_a     ),.i_rst_a     ( i_rst_a     ),.i_signal_a  ( i_signal_a  ),.i_clk_b     ( i_clk_b     ),.i_rst_b     ( i_rst_b     ),.o_signal_b  ( o_signal_b  )
);endmodule

3.3 仿真结果观察

在这里插入图片描述
  仿真设置快时钟频率为100M,慢时钟频率为30M,因此需要将脉冲宽度展宽四个快时钟周期,然后慢时钟再打两拍同步一下,由仿真结果观察结果正确,我们下面将快时钟设置为500M,结果如下:

在这里插入图片描述
  由上面可以看出,快时钟为500M,慢时钟为30M依然也能正确的采集到快时钟的脉冲信号。

四、在任意时钟域跨单bit信号

  前面两种情况,我们实现了单bit时钟从快到慢,或者从慢到快时钟之间的传输。除了使用以上两种方式外,我们还可以通过握手信号来实现任意时钟域之间的单bit信号传输。

4.1 使用握手协议传输单bit脉冲信号

  从A时钟域向B时钟域传输脉冲信号,可以在A时钟检测脉冲信号,然后随即拉高一个valid信号,直到B时钟检测到valid信号后拉高一个周期的同步信号,同时给出ack信号,然后A时钟检测到ack信号后,拉低valid信号表示一次传输完成。

在这里插入图片描述
  代码如下:

`timescale 1ns / 1ps
module single_bit_handshake#
(parameter CLKA_FPQ = 100_000_000,parameter CLKB_FPQ = 20_000_000
)
(input                                               i_clk_a     ,   //A时钟input                                               i_rst_a     ,   //A时钟域复位信号,高电平有效input                                               i_signal_a  ,   //A时钟脉冲信号input                                               i_clk_b     ,   //B时钟input                                               i_rst_b     ,   //B时钟复位信号,高电平有效output                                              o_signal_b      //B时钟同步后的信号
);localparam                                          CLK_NUM = (CLKA_FPQ >= CLKB_FPQ) ? 1 : (CLKB_FPQ / CLKA_FPQ);/****************A时钟域*********************/
reg                                                 r_signal_a_valid    ;
reg                                                 r_ack_a1            ;
reg                                                 r_ack_a2            ;
/****************B时钟域*********************/
reg                                                 r_signal_b1         ;
reg                                                 r_signal_b2         ;
reg                                                 r_signal_b3         ;
reg                                                 r_signal_b_ack      ;
reg             [7:0]                               r_clk_cnt_b         ;assign o_signal_b   = r_signal_b3;/****************A时钟域*********************/
always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)r_signal_a_valid <= 1'b0;else if(r_ack_a2 == 1'b1)r_signal_a_valid <= 1'b0;else if(i_signal_a == 1'b1)r_signal_a_valid <= 1'b1;elser_signal_a_valid <= r_signal_a_valid;
endalways @(posedge i_clk_a) beginif(i_rst_a == 1'b1)beginr_ack_a1 <= 1'b0;r_ack_a2 <= 1'b0;endelse beginr_ack_a1 <= r_signal_b_ack;r_ack_a2 <= r_ack_a1;endend/****************B时钟域*********************/
always @(posedge i_clk_b) beginif(i_rst_b == 1'b1)beginr_signal_b1 <= 1'b0;r_signal_b2 <= 1'b0; endelse if(r_signal_a_valid == 1'b1)beginr_signal_b1 <= 1'b1;r_signal_b2 <= r_signal_b1;endelse beginr_signal_b1 <= 1'b0;r_signal_b2 <= 1'b0;end
endalways @(posedge i_clk_b) beginif(i_rst_b == 1'b1)r_signal_b3 <= 1'b0;else if((r_signal_b1 ==1'b1)&&(r_signal_b2 == 1'b0))r_signal_b3 <= 1'b1;elser_signal_b3 <= 1'b0;
endalways @(posedge i_clk_b) beginif(i_rst_b == 1'b1)r_signal_b_ack <= 1'b0;else if(r_clk_cnt_b == CLK_NUM)r_signal_b_ack <= 1'b0;else if((r_signal_b1 ==1'b1)&&(r_signal_b2 == 1'b0))r_signal_b_ack <= 1'b1;elser_signal_b_ack <= r_signal_b_ack;
endalways @(posedge i_clk_b) beginif(i_rst_b == 1'b1)r_clk_cnt_b <= 'd0;else if(r_clk_cnt_b == CLK_NUM)r_clk_cnt_b <= 'd0;else if(r_signal_b_ack == 1'b1)r_clk_cnt_b <= r_clk_cnt_b + 1'b1;elser_clk_cnt_b <= 'd0;
endendmodule

4.2 从快到慢仿真代码编写

  先设置从快时钟到慢时钟

`timescale 1ns / 1ps
module tb_single_bit_handshake();reg i_clk_a;
reg i_rst_a;
reg i_signal_a;
reg i_clk_b;
reg i_rst_b;initial begini_clk_a = 0;i_rst_a = 1;i_clk_b = 0;i_rst_b = 1;#150i_rst_a = 0;#100i_rst_b = 0;   
endalways#1   i_clk_a = ~i_clk_a;
always#15  i_clk_b = ~i_clk_b;always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)i_signal_a <= 1'b0;else begini_signal_a <= {$random}%2;#2;i_signal_a <= 1'b0;#100;endendsingle_bit_handshake#(.CLKA_FPQ    ( 500_000_000 ),.CLKB_FPQ    ( 30_000_000 )
)u_single_bit_handshake(.i_clk_a     ( i_clk_a     ),.i_rst_a     ( i_rst_a     ),.i_signal_a  ( i_signal_a  ),.i_clk_b     ( i_clk_b     ),.i_rst_b     ( i_rst_b     ),.o_signal_b  ( o_signal_b  )
);endmodule

4.3 从快到慢仿真结果观察

在这里插入图片描述
  由图可看出,从500M的快时钟到30M的慢时钟能成功传输。

4.4 从慢到快仿真结果观察

  将仿真代码的AB时钟互换一下,变成从30M慢时钟传输到500M快时钟,仿真代码如下:

`timescale 1ns / 1ps
module tb_single_bit_handshake();reg i_clk_a;
reg i_rst_a;
reg i_signal_a;
reg i_clk_b;
reg i_rst_b;initial begini_clk_a = 0;i_rst_a = 1;i_clk_b = 0;i_rst_b = 1;#150i_rst_a = 0;#100i_rst_b = 0;   
endalways#15   i_clk_a = ~i_clk_a;
always#1  i_clk_b = ~i_clk_b;always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)i_signal_a <= 1'b0;else begini_signal_a <= {$random}%2;#30;i_signal_a <= 1'b0;#100;endendsingle_bit_handshake#(.CLKA_FPQ    ( 30_000_000 ),.CLKB_FPQ    ( 500_000_000 )
)u_single_bit_handshake(.i_clk_a     ( i_clk_a     ),.i_rst_a     ( i_rst_a     ),.i_signal_a  ( i_signal_a  ),.i_clk_b     ( i_clk_b     ),.i_rst_b     ( i_rst_b     ),.o_signal_b  ( o_signal_b  )
);endmodule

仿真结果如下:

在这里插入图片描述
  由图可以看出,从慢时钟到快时钟依然能够同步成功。值得注意的是,前面这几种单bit跨时钟处理方法不适合连续的触发信号,如果需要同步连续的脉冲信号,则需要考虑使用异步fifo或者ram。

五、多bit数据跨时钟域

  对于多bit情况,设计者必须习惯于采用例如双时钟 FIFO 这样的电路(DCFIFO)来存取数据和进行握手。FIFO 逻辑仅使用同步器传输转换两个时钟域之间的控制信号,而数据的读和写则使用双端口的存储器,具体FIFO的使用参考《详解Xilinx Native FIFO的使用以及RST复位的注意事项》。

相关文章:

FPGA跨时钟域处理

文章目录 一、为什么要做跨时钟域处理二、单bit信号从慢时钟到快时钟处理2.1 使用同步寄存器链(打两拍)2.2 仿真代码编写2.3 仿真结果观察 三、单bit信号从快时钟域到慢时钟域处理3.1 使用脉冲展宽3.2 仿真代码编写3.3 仿真结果观察 四、在任意时钟域跨单bit信号4.1 使用握手协…...

【Docker深入浅出】Docker镜像

文章目录 一. Docker镜像简介二. Docker镜像详解1. 镜像和容器的关系2. 镜像通常比较小3. 拉取镜像4. 镜像命名4.1. 镜像仓库服务4.2. 官方和非官方镜像仓库4.3. 镜像的命名和标签 5. 为镜像打多个标签6. 过滤镜像内容6.1. 虚空镜像6.2. 删除虚空镜像6.3. 过滤器与格式化输出 7…...

“LOCAL_LISTENER”参数导致业务无法连接数据库,文末附Oracle连接故障检查监听的排查流程

1. 背景及问题 今天在Oracle BCV技术[1]做数据同步&#xff0c;建立生产库的测试库&#xff0c;需要DBA配合同步前后的停库和起库。在同步完起库后&#xff0c;有部门反应同步好的测试库连接不上去。 2. 问题排查 以我当前的知识储备&#xff0c;能想到的可能就是以下几点进…...

Vmware虚拟机接入物理机路由器网络

网络适配器增加至两个&#xff0c;一个选NAT, 另一个选host-only,再加一个桥接&#xff0c;不勾选使用物理网卡&#xff0c;然后重启即可&#xff01;...

yolov8旋转框+关键点检测

一、Yolov8obb_kpt -----------------------------------现已在v8官方库上更新旋转框分割算法和旋转框关键点检测算法-------------------------- ------------------------------------------- https://github.com/yzqxy/ultralytics-obb_segment---------------------------…...

Qt-QWidget的windowTitle属性(13)

目录 描述 相关API 使用观察 描述 这个我们之前用过很多次了&#xff0c;就不再赘述了&#xff0c;简单说就是可以给那个边框设置标题&#xff0c;但是这里有一个小细节需要我们注意&#xff0c;就是谁的窗口谁设置 相关API 使用观察 我们这样写的话会发现一个问题&#x…...

RCE编码绕过--php://filter妙用

目录 代码 如何绕过 payload构造 代码 <?php $content <?php exit; ?>; $content . $_POST[txt]; file_put_contents($_POST[filename],$content); 当你想要输入代码的时候前面会有<?php exit;?>;&#xff0c;代码没有办法执行下去&#xff0c;所以…...

FactoryBean 与 BeanFactory

首先从字面理解: FactoryBean -->工厂Bean&#xff1b; BeanFactory -->Bean工厂。 即&#xff1a; FacttoryBean 是一个bean&#xff0c; BeanFactory 是bean的工厂。 使用&#xff1a; 1、BeanFactory&#xff1a; 提供获取bean的API。 2、FactoryBean&#xff1a; p…...

【迅为RK3568开发板】OpenHarmony学习开发系列教程(第2期 南向基础篇一)

P1P1_搭建Ubuntu开发环境-8:23 P2P2_获取OpenHarmony源码-10:21 P3P3_初次编译OpenHarmony源码-7:11 P4P4_OpenHarmony镜像简介以及烧写工具配置-9:18 P5P5_优化开发流程-搭建windows开发环境-5:34 P6P6_优化开发流程-搭建ubuntu开发环境-2:09 P7P7_优化开发流程-配置远程访问环…...

编程修炼之Hibernate--- springboot启动初始化ddl过程与如何自定义修改 table 字段长度

文章目录 springboot启动初始化ddl过程如何自定义修改 table springboot启动初始化ddl过程 跟踪Springboot整合hibernate的启动代码&#xff1a; SessionFactoryImpl 的初始化里做了非常多的事情&#xff0c;初始化各种资源&#xff0c;并调用 SchemaManagementToolCoordinat…...

TOMCAT入门到精通

目录 一 WEB技术 1.1 HTTP协议和B/S 结构 1.2 前端三大核心技术 1.2.1 HTML 1.2.2 CSS&#xff08;Cascading Style Sheets&#xff09;层叠样式表 1.2.3 JavaScript 二 WEB框架 2.2后台应用架构 2.2.1单体架构 2.2.2微服务 2.2.3单体架构和微服务比较 三 tomcat的…...

Android笔试面试题AI答之Kotlin(18)

文章目录 86. 阐述Kotlin中性能优化之局部函数 &#xff1f;局部函数的优点间接的性能优化注意事项 87. 简述Kotlin中性能优化之数组使用 &#xff1f;1. 选择合适的数组类型2. 避免不必要的数组创建3. 优化数组访问4. 合理使用数组遍历方式5. 利用Kotlin的集合操作API6. 注意数…...

Linux基础知识学习(五)

1. 用户组管理 每个用户都有一个用户组&#xff0c;系统可以对一个用户组中的所有用户进行集中管理&#xff08;开发、测试、运维、root&#xff09;。不同Linux 系统对用户组的规定有所不同&#xff0c;如Linux下的用户属于与它同名的用户组&#xff0c;这个用户组在创建用户…...

股票买卖的思路与代码

题目 1302&#xff1a;股票买卖 时间限制: 1000 ms 内存限制: 65536 KB 提交数:8660 通过数: 4290 【题目描述】 最近越来越多的人都投身股市&#xff0c;阿福也有点心动了。谨记着“股市有风险&#xff0c;入市需谨慎”&#xff0c;阿福决定先来研究一下简化版的股…...

Eureka Server与Eureka Client详解:服务注册与发现的交互机制

Eureka Server与Eureka Client详解&#xff1a;服务注册与发现的交互机制 Eureka 是 Netflix 开源的一个服务发现框架&#xff0c;它是 Spring Cloud 微服务架构中的核心组件之一。Eureka 主要由两个关键组件构成&#xff1a;Eureka Server 和 Eureka Client。它们之间通过一定…...

php-fpm 如何查看哪个正在执行死循环 并终止

php-fpm 如何查看哪个正在执行死循环 并终止 1. 检查 PHP-FPM 进程的 CPU 使用情况 首先&#xff0c;使用 top 或 htop 命令检查哪个 PHP-FPM 进程占用了大量的 CPU 资源。这个进程很可能是在死循环中。 top -c在 top 命令输出中&#xff0c;按 P 键可以按 CPU 使用率排序。…...

电脑硬盘坏了怎么恢复数据?

在数字化时代&#xff0c;电脑硬盘作为存储核心&#xff0c;承载着我们的工作文档、学习资料、家庭照片以及无数珍贵的回忆。然而&#xff0c;硬盘作为机械设备&#xff0c;也有其寿命和脆弱性&#xff0c;一旦出现故障&#xff0c;数据恢复便成为了一个紧迫而棘手的问题。本文…...

cdga|某大型企业数据治理的成功转型:构建数据驱动的竞争力新引擎

在当今这个数据爆炸的时代&#xff0c;数据已成为企业最宝贵的资产之一&#xff0c;其有效管理和利用直接关系到企业的核心竞争力。某大型企业&#xff0c;作为行业内的领军企业&#xff0c;面对海量数据带来的机遇与挑战&#xff0c;果断启动了一项全面而深入的数据治理项目&a…...

C#使用 ModeBusTCP读取汇川Easy521PLC

Modbus TCP是一种基于以太网TCP/IP的Modbus协议变种&#xff0c;它允许Modbus协议在以太网网络上运行&#xff0c;使得设备之间可以通过IP网络交换数据。Modbus由MODICON公司于1979年开发&#xff0c;是一种工业现场总线协议标准&#xff0c;广泛应用于工业自动化领域。 #regio…...

PostgreSQL的postgres主进程

PostgreSQL的postgres主进程 在PostgreSQL数据库系统中&#xff0c;主要的后台进程各司其职&#xff0c;保证数据库的高效运行。其中&#xff0c;主进程postgres&#xff08;也称为Postmaster&#xff09;是整个数据库的核心&#xff0c;它负责管理和协调所有其他后台进程&…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...