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

SPI简介及FPGA通用MOSI模块实现

简介

SPI(Serial Peripheral Interface,串行外围设备接口)通讯协议,是Motorola公司提出的一种同步串行接口技术。是一种高速、全双工、同步通信总线。在芯片中只占用四根管脚用来控制及数据传输。

优缺点:

SPI通讯协议的优点是支持全双工通信,通讯方式较为简单,且相对数据传输速率较快;

缺点是没有指定的流控制,没有应答机制确认数据是否接收,与IIC总线通讯协议相比,在数据可靠性上有一定缺陷。

物理层

对于SPI协议的物理层,需要讲解的就是SPI通讯设备的连接方式和设备引脚的功能描述。

SPI通讯设备的通讯模式是主从通讯模式,通讯双方有主从之分,根据从机设备的个数,SPI通讯设备之间的连接方式可分为一主一从和一主多从,具体见下图1、2。

SPIFla002

图 1 一主一从SPI通讯设备连接图

SPIFla003

图 2 一主多从SPI通讯设备连接图

SPI通讯协议包含1条时钟信号线、2条数据总线和1条片选信号线, 时钟信号线为SCK,2条数据总线分别为MOSI(主输出从输入)、MISO(主输入从输出),片选信号线为,它们的作用介绍如下:

  1. SCK (Serial Clock):时钟信号线,用于同步通讯数据。由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不同,两个设备之间通讯时,通讯速率受限于低速设备。

  2. MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,数据方向由主机到从机。

  3. MISO (Master Input,Slave Output):主设备输入/从设备输出引脚。主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,数据方向由从机到主机。

  4. (Chip Select):片选信号线,也称为CS_N,以下用CS_N表示。当有多个SPI从设备与SPI主机相连时,设备的其它信号线SCK、MOSI及MISO同时并联到相同的SPI总线上,即无论有多少个从设备,都共同使用这3条总线;而每个从设备都有独立的这一条CS_N信号线,本信号线独占主机的一个引脚,即有多少个从设备,就有多少条片选信号线。

I2C协议中通过设备地址来寻址、选中总线上的某个设备并与其进行通讯;而SPI协议中没有设备地址,它使用CS_N信号线来寻址,当主机要选择从设备时,把该从设备的CS_N信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行 SPI通讯。所以SPI通讯以CS_N线置低电平为开始信号,以CS_N线被拉高作为结束信号。

四种通讯模式

SPI通讯协议一共有四种通讯模式,模式0、模式1、模式2以及模式3,这4种模式分别由时钟极性(CPOL,Clock Polarity)和时钟相位(CPHA,Clock Phase)来定义。

CPOL参数规定了空闲状态(CS_N为高电平,设备未被选中)时SCK时钟信号的电平状态;

CPHA规定了数据采样是在SCK时钟的奇数边沿还是偶数边沿。

极性和相位

SPI的极性Polarity和相位Phase,最常见的写法是CPOL和CPHA,不过也有一些其他写法,简单总结如下:
(1) CKPOL (Clock Polarity) = CPOL = POL = Polarity = (时钟)极性
(2) CKPHA (Clock Phase) = CPHA = PHA = Phase = (时钟)相位
(3) SCK=SCLK=SPI的时钟
(4) Edge=边沿,即时钟电平变化的时刻,即上升沿(rising edge)或者下降沿(falling edge)

模式判别

CPOL,表示当SCLK空闲idle的时候,其电平的值是低电平0还是高电平1:
CPOL=0,时钟空闲idle时候的电平是低电平,所以当SCLK有效的时候,就是高电平,就是所谓的active-high;
CPOL=1,时钟空闲idle时候的电平是高电平,所以当SCLK有效的时候,就是低电平,就是所谓的active-low;

CPHA=0,表示第一个边沿
对于CPOL=0,idle时候的是低电平,第一个边沿就是从低变到高,所以是上升沿;
对于CPOL=1,idle时候的是高电平,第一个边沿就是从高变到低,所以是下降沿;

CPHA=1,表示第二个边沿
对于CPOL=0,idle时候的是低电平,第二个边沿就是从高变到低,所以是下降沿;
对于CPOL=1,idle时候的是高电平,第一个边沿就是从低变到高,所以是上升沿;

SPI通讯协议的4种模式如下,通讯模式时序图,具体见下图 :

模式0:CPOL= 0,CPHA=0。空闲状态时SCK串行时钟为低电平;数据采样在SCK时钟的上升沿;数据更新在SCK时钟的下降沿。

模式1:CPOL= 0,CPHA=1。空闲状态时SCK串行时钟为低电平;数据采样在SCK时钟的下降沿;数据更新在SCK时钟的上升沿。

模式2:CPOL= 1,CPHA=0。空闲状态时SCK串行时钟为高电平;数据采样在SCK时钟的下降沿;数据更新在SCK时钟的上升沿。

模式3:CPOL= 1,CPHA=1。空闲状态时SCK串行时钟为高电平;数据采样在SCK时钟的上升沿;数据更新在SCK时钟的下降沿。

在这里插入图片描述

模式的判断:

如果起始的SCLK的电平是0,那么CPOL=0,如果是1,那么CPOL=1,

然后看数据采样时刻,对应到上面SCLK时钟的位置,对应着是第一个边沿或是第二个边沿,即CPHA是0或1

时序需求

tSLCH:cs_n拉低到sck高的时间

tCHSH:sck高到cs_n拉高的时间

SCK上升沿MOSI的建立时间保持时间需求

在这里插入图片描述

SPI通用模块

实现功能

用于将任意宽度向量型数据转换为SPI串行输出,模式0:CPOL= 0,CPHA=0;
默认串行数据mosi数据的建立时间和保持时间均为2个clk(0.5*DIV_FREQUENCY)周期,即sck上升沿的前后2个(0.5*DIV_FREQUENCY)clk数据稳定,串行时钟sck周期为4*clk(DIV_FREQUENCY)的周期;
默认tSLCH(cs_n拉低到sck高的时间为6*clk(1.5*DIV_FREQUENCY)周期),tCHSH(sck高到cs_n拉高的时间为2*clk(0.5*DIV_FREQUENCY)周期);
若时序满足此模块可以不做修改。若需要修改在外部例化时修改DIV_FREQUENCY(只能偶分频)和PERIOD_WIDTH_MAX即可。

使用方法

输入data的位宽和计数器位宽在外部进行例化时修改参数的值即可,不必修改SPI模块
DATA_WIDTH_MAX修改为输入数据的位宽,如[31:0]的数据则DATA_WIDTH_MAX=32
CNT_DATA_WIDTH_MAX修改为输入数据的位宽计数器需要的位宽上限,即DATA_WIDTH_MAX=32对应的二进制位宽32=6’b10_0000,所以CNT_DATA_WIDTH_MAX=6

输入输出端口说明:

//input
input 		wire 						clk 			, //系统时钟,spi串行时钟的分频基准 			
input 		wire						clr_n 			, //spi信号标志信号,允许发送时一直拉高,重新发送时拉低复位再拉高
input 	  	wire  [DATA_WIDTH_MAX-1:0] 	data 			, //需要data与clr_n一同进入			//output	                                            
output		reg							cs_n 			, //片选信号
output 	  	reg			 				sck 			, //串行时钟
output		reg							mosi 			, //主输出从输入数据
output		reg							flag 			  //spi发送完成标志位,完成则一直拉高;clr_n置0时拉低

例化模板:

spi #(
.DATA_WIDTH_MAX 	(8	 	),
.CNT_DATA_WIDTH_MAX	(4		) 
)
u_spi(.clk 	(clk			),.clr_n  (clr_n			),.data   (data_in		),.cs_n   (cs_n			),.sck    (sck 			),.mosi   (mosi			),.flag   (flag			)
); 

SPI模块

//========================================================================
// 	module_name.v	:spi.v
// 	Author			:YprgDay
// 	Description		:用于将任意宽度向量型数据转换为SPI串行输出,模式0:CPOL= 0,CPHA=0。
//========================================================================
module spi#(//=========================< Parameter >==============================parameter 				DATA_WIDTH_MAX		=	32				,//例化时修改为输入数据的位宽,如[31:0]的数据则DATA_WIDTH_MAX	=32parameter 				CNT_DATA_WIDTH_MAX	=	6				,//例化时修改为输入数据的位宽计数器需要的位宽上限,即DATA_WIDTH_MAX=32对应的二进制位宽32=6'b10_0000,所以CNT_DATA_WIDTH_MAX=6parameter 				DIV_FREQUENCY		=	4				,//分频数(只允许偶分频),串行时钟sck周期为DIV_FREQUENCY*clk的周期parameter 				PERIOD_WIDTH_MAX	=	2				,//(DIV_FREQUENCY-1)对应的二进制位宽即为PERIOD_WIDTH_MAXparameter 				CNT_PERIOD_MAX		=	DIV_FREQUENCY-1	,parameter 				CNT_HALF_PERIOD_MAX	=	CNT_PERIOD_MAX >> 1	//计数分频中值
) 
(//=========================< Port Name >==============================//inputinput 		wire 						clk 			, //系统时钟,spi串行时钟的分频基准 			input 		wire						clr_n 			, //spi信号标志信号,允许发送时一直拉高,重新发送时拉低复位再拉高		input 	  	wire  [DATA_WIDTH_MAX-1:0] 	data 			, //需要data与clr_n一同进入			//output	                                            output		reg							cs_n 			, //片选信号output 	  	reg			 				sck 			, //串行时钟output		reg							mosi 			, //主输出从输入数据output		reg							flag 			  //spi发送完成标志位,完成则一直拉高;clr_n置0时拉低);//=========================< Always block >===========================reg [CNT_DATA_WIDTH_MAX-1:0] 	cnt_data_width			;reg [PERIOD_WIDTH_MAX-1:0] 		cnt_spi_period			;reg [DATA_WIDTH_MAX-1:0] 		data_reg	  			;//输出的cs_n片选信号always @(posedge clk or negedge clr_n)beginif(clr_n == 1'b0)begincs_n <= 1'b1;endelse if(cnt_data_width == DATA_WIDTH_MAX && cnt_spi_period == CNT_PERIOD_MAX)begincs_n <= 1'b1;endelse begincs_n <= 1'b0;endend	//输出的sck串行时钟信号,always @(posedge clk or negedge clr_n)beginif(clr_n == 1'b0)beginsck <= 0;endelse if(cnt_data_width > 0 && cnt_spi_period == CNT_PERIOD_MAX)beginsck <= 0;endelse if(cnt_data_width > 0 && cnt_spi_period == CNT_HALF_PERIOD_MAX)beginsck <= 1;endelse beginsck <= sck;endend//mosi的串行输出always @(posedge clk or negedge clr_n)beginif(clr_n == 1'b0)beginmosi <= 0;endelse if(cnt_data_width == DATA_WIDTH_MAX && cnt_spi_period == CNT_PERIOD_MAX)beginmosi <= 0;endelse if(cnt_spi_period == CNT_PERIOD_MAX)beginmosi <= data_reg[DATA_WIDTH_MAX-1-cnt_data_width];endelse beginmosi <= mosi;endend //输出的串行数据发送完成标志信号,发送完成即拉高always @(posedge clk or negedge clr_n)beginif(clr_n == 1'b0)beginflag <= 0;endelse if(cnt_data_width == DATA_WIDTH_MAX && cnt_spi_period == CNT_PERIOD_MAX)beginflag <= 1;endelse beginflag <= 0;endend//输入数据寄存,保证data在一串SPI数据发完之间不发生变化always @(posedge clk or negedge clr_n)beginif(clr_n == 1'b0)begindata_reg <= 0;endelse if(cnt_data_width == 0 && cnt_spi_period == 1)begindata_reg <= data;endelse begindata_reg <= data_reg;endend//时钟四分频计数always @(posedge clk or negedge clr_n)beginif(clr_n == 1'b0)begincnt_spi_period <= 0;endelse if(cnt_data_width == DATA_WIDTH_MAX && cnt_spi_period == CNT_PERIOD_MAX)begincnt_spi_period <= cnt_spi_period;endelse if(cnt_spi_period == CNT_PERIOD_MAX)begincnt_spi_period <= 0;endelse if(cs_n == 0)begincnt_spi_period <= cnt_spi_period + 1'b1;endelse;end	//计数表示此时输出到[DATA_WIDTH_MAX:0] data的第几位位置always @(posedge clk or negedge clr_n)beginif(clr_n == 1'b0)begincnt_data_width <= 0;endelse if(cnt_data_width == DATA_WIDTH_MAX && cnt_spi_period == CNT_PERIOD_MAX)begincnt_data_width <= cnt_data_width;endelse if(cnt_spi_period == CNT_PERIOD_MAX)begincnt_data_width <= cnt_data_width + 1'b1;endelse;endendmodule

仿真模块

`timescale 1ns / 1ps
//
// Module Name: tb_spi
// Dependencies: spi模块仿真
//
module tb_spi();//=========================< Parameter >==============================parameter 				SPI_CLK_PERIOD		=	2			    ;//设置spi时钟信号周期parameter 				HALF_SPI_CLK_PERIOD	=	SPI_CLK_PERIOD/2;//生成spi时钟信号半周期//=========================< Port Name >==============================//inputreg						clk								;reg    					clr_n							;reg 		[7:0]		data_in							;//outputwire					mosi							;wire					cs_n							;wire					sck								;wire					flag							;//==========================< Clock block >============================always 	  	#HALF_SPI_CLK_PERIOD		clk = ~clk	;//==========================< Reset block >============================initial beginclk 		= 	1'b1	;clr_n  		<= 	1'b0	;data_in     <=	0		;#HALF_SPI_CLK_PERIODclr_n  		<= 	1'b1	;data_in     <=	8'h83	;#30data_in     <=	8'h54	;#300clr_n  		<= 	1'b0	;data_in     <=	8'hc7	;#10clr_n  		<= 	1'b1	;end//==========================< Module Instance >============================spi #(.DATA_WIDTH_MAX 	(8	 	),.CNT_DATA_WIDTH_MAX	(4		)				)u_spi(.clk 	(clk			),.clr_n  (clr_n			),.data   (data_in		),.cs_n   (cs_n			),.sck    (sck 			),.mosi   (mosi			),.flag   (flag			)); endmodule

仿真时序图

以8位输入数据[7:0]data的SPI时序图为例

img

相关文章:

SPI简介及FPGA通用MOSI模块实现

简介 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外围设备接口&#xff09;通讯协议&#xff0c;是Motorola公司提出的一种同步串行接口技术。是一种高速、全双工、同步通信总线。在芯片中只占用四根管脚用来控制及数据传输。 优缺点&#xff1a; SPI通讯协…...

K8S篇之K8S详解

一、K8S简介 k8s全称kubernetes&#xff0c;是为容器服务而生的一个可移植容器的编排管理工具。k8s目前已经主导了云业务流程&#xff0c;推动了微服务架构等热门技术的普及和落地。 k8s是自动化容器操作的开源平台。这些容器操作包括&#xff1a;部署、调度和节点集群间扩展。…...

进博会再现上亿大单 EZZ携手HIC海橙嗨选签署2024年度合作备忘录

正在举行的第六届中国国际进口博览会上&#xff0c;再现上亿大单。11月6日&#xff0c;在澳大利亚新南威尔士州政府代表的见证下&#xff0c;澳交所基因组龙头上市公司EZZ生命科学和中国跨境社交电商龙头HIC海橙嗨选签署2024合作备忘录&#xff0c;在未来的一年&#xff0c;EZZ…...

深度学习基于python+TensorFlow+Django的花朵识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 花朵识别系统&#xff0c;基于Python实现&#xff0c;深度学习卷积神经网络&#xff0c;通过TensorFlow搭建卷积神经…...

Azure 机器学习 - 机器学习中的企业安全和治理

目录 限制对资源和操作的访问网络安全性和隔离数据加密数据渗透防护漏洞扫描审核和管理合规性 在本文中&#xff0c;你将了解可用于 Azure 机器学习的安全和治理功能。 如果管理员、DevOps 和 MLOps 想要创建符合公司策略的安全配置&#xff0c;那么这些功能对其十分有用。 通过…...

Unity - 各向异性 - 丝绸材质

文章目录 目的环境主观美术效果的[假]丝绸基于物理的方式ProjectPBR filament web captureReferences 目的 拾遗&#xff0c;备份 环境 Unity : 2020.3.37f1 Pipeline : Builtin Rendering Pipeline 主观美术效果的[假]丝绸 非常简单 : half specualr pow(1 - NdotV, _Edg…...

MySQL中UUID主键的优化

UUID&#xff08;Universally Unique IDentifier 通用唯一标识符&#xff09;&#xff0c;是一种常用的唯一标识符&#xff0c;在MySQL中&#xff0c;可以利用函数uuid()来生产UUID。因为UUID可以唯一标识记录&#xff0c;因此有些场景可能会用来作为表的主键&#xff0c;但直接…...

Python实现WOA智能鲸鱼优化算法优化BP神经网络分类模型(BP神经网络分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…...

Rust语言代码示例

安装Rust语言&#xff0c;然后创建一个新的Rust项目。接下来&#xff0c;你需要安装一个名为"requests"的Rust包&#xff0c;这个包可以帮助你发送请求。然后&#xff0c;你需要安装一个名为"rust-crawler"的Rust包&#xff0c;这个包可以帮助你编写爬虫程…...

【SpringBoot3+Vue3】一【基础篇】

目录 一、Spring Boot概述 1、Spring Boot 特性 1.1 起步依赖 1.2 自动配置 1.3 其他特性 1.3.1 内嵌的Tomcat、Jetty (无需部署WAR文件) 1.3.2 外部化配置 1.3.3 不需要XML配置(properties/yml) 二、Spring Boot入门 1、一个入门程序需求 2、步骤 2.1 创建Maven工…...

麒麟信安登录央视,深度展现为中国信息安全铸“魂”之路

麒麟信安登录央视&#xff0c;深度展现为中国信息安全铸“魂”之路 近日&#xff0c;麒麟信安登录央视频道&#xff0c;《麒麟信安——为中国信息安全铸“魂”》在CCTV-4中文国际频道、CCTV-7国防军事频道、CCTV-10 科教频道、CCTV-12社会与法频道、CCTV-17农业农村频道&#x…...

Flutter的专属Skia引擎解析+用法原理

Skia是一款跨平台的2D图形库&#xff0c;是Google公司开发的&#xff0c;可以用于开发各种应用程序&#xff0c;如浏览器、游戏、移动应用程序等。Skia引擎的主要特点是速度快、可移植性强、占用的内存少、稳定性佳&#xff0c;适用于多种硬件平台。 Skia的目标是提供快速、高…...

python poetry的教程

Poetry Python世界中&#xff0c;Poetry是一个近年来备受瞩目的工具&#xff0c;它为开发者提供了一个灵活且强大的依赖管理解决方案。Poetry可以帮助开发者管理项目的依赖关系&#xff0c;同时提供了一系列的工具和功能&#xff0c;使开发者能够更轻松地创建和管理复杂的项目。…...

jq里的ajax超详细参数讲解

目录 1、url&#xff1a;要发送请求的URL地址。 2、type&#xff1a;请求的类型&#xff0c;可选参数&#xff0c;包括GET、POST、PUT、DELETE等&#xff0c;默认为GET。 3、data&#xff1a;要发送到服务器的数据&#xff0c;可以是一个字符串、数组或对象。默认为null。 4…...

郑州大学2020级信息安全专业——保研小结

最终上岸 夏令营&#xff1a; 夏令营开始的时间一般比较早&#xff0c;在期末考试之前就已经开始了&#xff0c;需要提前联系导师&#xff0c;有的学校是弱com&#xff0c;导师愿意要你入营的概率和优营的概率就会比较大&#xff0c;因此要提前联系导师&#xff0c;复习好项目…...

【系统架构设计】架构核心知识: 3.6 负载均衡和Session

目录 一 负载均衡 1 应用层负载均衡 2 传输层负载均衡 二 Session 1 Session共享机制...

python pip安装特定包,网络慢的问题

文件requirements.txt httpx0.24.0 Pillow9.5.0 playwright1.33.0 tenacity8.2.2 tornado6.3.2 PyExecJS1.5.1 opencv-python4.7.0.72 tortoise-orm[asyncmy]0.19.3 aerich0.7.2 numpy~1.24.4 redis~4.6.0 Pydantic1.7将文件放入任意一个目录下 cd 到该目录下执行 while read…...

CMT2300A超低功耗127-1020MHz Sub-1GHz全频段SUB-1G 射频收发芯片

CMT2300A超低功耗127-1020MHz Sub-1GHz全频段SUB-1G 射频收发芯片 Sub-1GHz&#xff0c;是指小于1GHz频率的统称。Sub-1GHz无线电频段应用的主要特点&#xff1a;&#xff08;1&#xff09;频率较低波长较长&#xff0c;传输距离远&#xff0c;穿透性强&#xff1b;&#xff0…...

设计模式之工厂模式 ( Factory Pattern )(1)

其他设计模式也会后续更新… 设计模式其实需要有一定开发经验才好理解&#xff0c;对代码有一定的设计要求&#xff0c;工作中融入才是最好的 工厂模式 ( Factory Pattern ) 工厂模式&#xff08;Factory Pattern&#xff09;提供了一种创建对象的最佳方式 工厂模式在创建对…...

OpenCV入门11:轮廓提取和形状识别

轮廓分析主要用于轮廓提取和形状识别等任务。在OpenCV中&#xff0c;轮廓提取和形状识别是图像处理和计算机视觉中常见的任务。下面是关于这两个知识点的一些基本内容&#xff1a; 轮廓提取&#xff1a; 轮廓提取是指从图像中提取出物体轮廓的过程。在OpenCV中&#xff0c;可…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

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

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

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...