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

verilog bug记录——正点原子spi_drive存在的问题

verilog bug记录——正点原子spi_drive存在的问题

  • 问题概述
  • 代码修改—spi_drive.v
  • 遗留问题

问题概述

因为项目需求,需要利用spi对flash进行擦除和写入操作,所使用的开发板是正电原子的达芬奇开发板,我事先往Flash里面存了两个bit,分别对应LED0和LED1的点亮,但是我使用了正点原子的spi_dirve进行全擦除操作之后发现了很奇怪的现象:
1、没擦完,因为明显的看到LED1的灯亮了,说明擦除操作或许有效,但是可能只是破坏了第一个bit,第二个bit没有做修改;
2、时序不对,通过ila抓波形可以发现,全擦除之后的轮询寄存器,竟然只查了一次就自动跳出轮询的状态了,但是全擦除怎么说也不至于这么快吧。
我的flash_contol部分的指令操作顺序如下:

always @(*)begincase(cmd_cnt)0 : spi_cmd = WEL_CMD		;			//写使能1 : spi_cmd = R_STA_REG_CMD	;			//轮询2 : spi_cmd = WEL_CMD		;			//写使能3 : spi_cmd = R_STA_REG_CMD	;			//轮询4 : spi_cmd = BE_CMD		;			//全擦除5 : spi_cmd = R_STA_REG_CMD		;	    //轮询6 : spi_cmd = WEL_CMD	;			//轮询7 : spi_cmd = R_STA_REG_CMD		;			//读数据default:;endcase
end

我只执行了0~5步,另外原代码中指令运行是一上电就会自动运行,但是我改成了只有我按键按下的时候才会执行。
出问题的时序如下:
在这里插入图片描述
从图中黄线部分可以看到,CS信号在spi_clk信号立即拉高,但是我们看数据手册可以发现
在这里插入图片描述
在这里插入图片描述
在spi_clk停止输出的时候,CS信号至少要间隔4ns才拉高,虽然说实际上的时钟信号并不是理想的马上拉高,而是有一段过渡时间,但是这个过渡时间并不好把控,所以稳妥起见还是应该至少打一拍,因为时钟频率是100MHz,那么延迟未0.01us,即10ns,是满足时序要求的;

另外还有问题,看下图:
在这里插入图片描述
在这里插入图片描述
红圈标注的位置,从图中可以看出,我第一次发送写使能命令后进行轮询,会发现状态寄存器的第6位WEL并没有拉高,而是第二次发送写使能命令的时候才拉高。

根据数据手册上的要求,发送完写使能命令后,WEL位是应该拉高为高电平的
在这里插入图片描述
最后一个问题如下图所示:
在这里插入图片描述
该时序图是我我发送完全擦除指令随即发送轮询寄存器指令(读状态寄存器指令),会发现蓝线部分表示WEL位,红线部分表示WIP位,此时WIP位应该是高电平,轮询寄存器应该继续轮询才对,直到WIP为0表示擦除操作已完成,但是原代码中却是直接拉高,这就不合理。

代码修改—spi_drive.v

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2018-2028
//All rights reserved
//----------------------------------------------------------------------------------------
// File name:           spi_drive
// Last modified Date:  2020/12/01 10:39:20
// Last Version:        V1.0
// Descriptions:        FLASH读写实验
//                      
//----------------------------------------------------------------------------------------
// Created by:          正点原子
// Created date:        2020/12/01 10:39:20
// Version:             V1.0
// Descriptions:        The original version
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//
module spi_drive(input             clk_100m      ,input             sys_rst_n     ,//user interfaceinput             spi_start     ,//spi开启使能。input [7:0 ]      spi_cmd       ,//FLAH操作指令input [23:0]      spi_addr      ,//FLASH地址input [7:0 ]      spi_data      ,//FLASH写入的数据input [3:0 ]      cmd_cnt       ,//指令计数器output            idel_flag_p   ,//空闲状态标志的上升沿 output reg        w_data_req    ,//FLASH写数据请求 output reg        error_flag     ,//读出的数据错误标志//spi interfaceoutput reg        spi_cs        ,//SPI从机的片选信号,低电平有效。output reg        spi_clk       ,//主从机之间的数据同步时钟。output reg        spi_mosi      ,//数据引脚,主机输出,从机输入。input             spi_miso       //数据引脚,主机输入,从机输出。);//define parameter
//状态机
parameter IDLE          = 4'd0;		//空闲状态
parameter WR_EN         = 4'd1;		//写使能状态
parameter S_ERA         = 4'd2;		//扇区擦除状态
parameter B_ERA         = 4'd3;		//全局擦除
parameter READ          = 4'd4;		//读状态
parameter WRITE         = 4'd5;		//写状态
parameter R_STA_REG     = 4'd6;		//读状态寄存器状态
//指令集
parameter WEL_CMD       = 8'h06;	//写使能指令
parameter SE_CMD        = 8'hd8;	//扇区擦除指令
parameter BE_CMD        = 8'hc7;	//全擦除指令
parameter READ_CMD      = 8'h03;	//读指令
parameter WRITE_CMD     = 8'h02;	//写指令
parameter R_STA_REG_CMD = 8'h05;	//读状态寄存器指令//wire define
wire      idel_flag;//reg define
reg		      		idel_flag_d0   ;		
reg		      		idel_flag_d1   ;	
reg		      		spi_clk_d0     ;
reg		[3:0] 		current_state  ;		
reg		[3:0] 		next_state     ;		
reg		[7:0 ]		data_reg	   ;		//数据寄存
reg		[7:0 ]		cmd_reg        ;		//指令寄存
reg		[23:0]		addr_reg       ;		//地址寄存器
reg		[31:0]		bit_cnt        ;		//bit计数器
reg		      		clk_cnt        ;		//时钟计数器
reg		      		delay_cnt      ;		//延迟计数器
reg		[15:0]		delay_state_cnt ;		//状态延迟计数器
reg		[7:0 ]		rd_data_reg    ;		//读数据寄存器	
reg		      		stdone         ;		//状态完成标志
reg		[7:0 ]		data_check     ;		//数据校验reg     [2047:0]    r_w_data       ;
reg                 r_w_data_req   ;
reg     [2047:0]    r_r_data       ;//FLASH读出的数据reg                 r_wip_flag          ;
reg     [7 :0  ]    r_rd_status_reg;
reg                 r_wel          ;
//*****************************************************
//**                    main code
//*****************************************************assign idel_flag = (current_state == IDLE) ? 1:0;		//空闲状态标志
assign idel_flag_p = idel_flag_d0 && (~idel_flag_d1);	//空闲状态标志的上升沿//idel_flga打拍取沿
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)beginidel_flag_d0 <= 1'b1;idel_flag_d1 <= 1'b1;endelse beginidel_flag_d0 <= idel_flag;idel_flag_d1 <= idel_flag_d0;end
end//写数据请求信号
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)w_data_req <= 1'b0;else if(current_state == WRITE && (bit_cnt+2)%8 == 0 && bit_cnt >= 30 && clk_cnt == 0)w_data_req <= 1'b1;elsew_data_req <= 1'b0;
endalways @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)r_w_data_req <= 'd0;elser_w_data_req <= w_data_req;
endalways @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)r_w_data <= 'd0;else if(r_w_data_req)r_w_data <= {r_w_data[2039:0],spi_data};
end//读出的数据移位寄存
always @(posedge clk_100m or negedge sys_rst_n )begin	if(!sys_rst_n)rd_data_reg <= 8'd0;else if(current_state == READ && bit_cnt >= 32 && bit_cnt <= 2080 && clk_cnt == 0)									rd_data_reg <= {rd_data_reg[6:0],spi_miso};elserd_data_reg <= rd_data_reg;
end// //检查读出的数据是否正确
// always @(posedge clk_100m or negedge sys_rst_n )begin
// 	if(!sys_rst_n)
// 		data_check <= 8'd0;
// 	else if(current_state == READ && bit_cnt%8 == 0 && bit_cnt >= 40 && clk_cnt == 1)
// 		data_check <= data_check + 1'd1;
// 	else
// 		data_check <= data_check;
// end//读出的数据
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)r_r_data <= 2048'd0;else if(current_state == READ && bit_cnt%8 == 0 && bit_cnt >38 && clk_cnt==1)r_r_data <= {r_r_data[2039:0],rd_data_reg};elser_r_data <= r_r_data;
end//读出的数据错误标志
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)error_flag<=1'd0;else if(current_state == READ && cmd_cnt == 6 && idel_flag_p)beginif(r_r_data!=r_w_data)error_flag <= 1'd1;elseerror_flag <= error_flag;endelseerror_flag <= error_flag;
end//数据寄存器	
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)data_reg <= 8'd0;else if((bit_cnt + 1'd1)%8 == 0 && bit_cnt > 30 && clk_cnt == 1)data_reg <= spi_data;else if(current_state == WRITE && clk_cnt == 1 && bit_cnt >= 32)data_reg <= {data_reg[6:0],data_reg[7]};elsedata_reg <= data_reg;
end//指令寄存器
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)cmd_reg <= 8'd0;else if(spi_cs == 0 && delay_cnt == 0)cmd_reg <= spi_cmd;else if((clk_cnt == 1) && (current_state == WR_EN || current_state == S_ERA|| current_state == B_ERA || current_state == READ || current_state == WRITE || current_state == R_STA_REG) && (bit_cnt < 8))cmd_reg <= {cmd_reg[6:0],1'b1};elsecmd_reg <= cmd_reg;
end//地址寄存器
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)addr_reg <= 8'd0;else if(spi_cs == 0 && delay_cnt == 0)addr_reg <= spi_addr;else if(clk_cnt==1 && (current_state == READ || current_state == WRITE) && bit_cnt >= 8 && bit_cnt < 32)addr_reg <= {addr_reg[22:0],addr_reg[23]};elseaddr_reg <= addr_reg;
end//时钟计数器
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)clk_cnt <= 1'd0;else if(delay_cnt==1)clk_cnt <= clk_cnt+1'd1;else clk_cnt <= 1'd0;
end	//延迟标志
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)delay_cnt <= 1'd0;else if(spi_cs == 0)beginif(delay_cnt < 1)delay_cnt <= delay_cnt + 1'd1;elsedelay_cnt <= delay_cnt;endelsedelay_cnt <= 1'd0;
end//状态延迟计数器
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)delay_state_cnt <= 1'd0;else if(spi_start)delay_state_cnt <= 1'd0;else if(spi_cs)beginif(delay_state_cnt < 20)delay_state_cnt <= delay_state_cnt + 1'd1;elsedelay_state_cnt <= delay_state_cnt;endelsedelay_state_cnt <= 1'd0;
end//bit计数器
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)bit_cnt <= 16'd0;else if(delay_cnt == 1)beginif(clk_cnt == 1'b1)bit_cnt <= bit_cnt+1'd1;elsebit_cnt <= bit_cnt;endelsebit_cnt <= 16'd0;
end// RDSR状态寄存器寄存
always @(posedge clk_100m or negedge sys_rst_n )begin	if(!sys_rst_n)r_rd_status_reg <= 8'd0;else if(current_state == R_STA_REG && bit_cnt >= 8 && clk_cnt == 1)r_rd_status_reg <= {r_rd_status_reg[6:0],spi_miso};elser_rd_status_reg <= r_rd_status_reg;
end//三段式状态机
always @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n)current_state <= IDLE;elsecurrent_state <= next_state;
endalways @(*)begincase(current_state)IDLE: beginif(spi_start && spi_cmd == WEL_CMD)next_state = WR_EN;else if(spi_start && spi_cmd == BE_CMD)next_state = B_ERA;else if(spi_start && spi_cmd == SE_CMD)next_state = S_ERA;else if(spi_start && spi_cmd == READ_CMD)next_state = READ;else if(spi_start && spi_cmd == WRITE_CMD)next_state = WRITE;else if(spi_start && spi_cmd == R_STA_REG_CMD)next_state = R_STA_REG;elsenext_state = IDLE;endWR_EN: beginif(stdone && bit_cnt >= 8)next_state = IDLE;elsenext_state = WR_EN;endS_ERA: beginif(stdone)next_state = IDLE;elsenext_state = S_ERA;endB_ERA: begin		if(stdone)next_state = IDLE;elsenext_state = B_ERA;endREAD: begin 		if(stdone && bit_cnt >= 8)next_state = IDLE;elsenext_state = READ;endWRITE: begin		if(stdone && bit_cnt >= 8)next_state = IDLE;elsenext_state = WRITE;endR_STA_REG: begin		if(stdone)next_state = IDLE;elsenext_state = R_STA_REG;enddefault: next_state = IDLE;			endcase				
endalways @(posedge clk_100m or negedge sys_rst_n )beginif(!sys_rst_n) beginspi_cs <= 1'b1;spi_clk <= 1'b0;spi_clk_d0 <= 1'b0;spi_mosi <= 1'b0;	stdone <= 1'b0;		endelse begincase(current_state)IDLE: beginstdone <= 1'b0;spi_cs <= 1'b1;spi_clk <= 1'b0;spi_mosi <= 1'b0;	r_wip_flag <= 1'b0;	spi_clk_d0 <= 'd0;endWR_EN: beginstdone <= 1'b0;if(delay_state_cnt == 10)  spi_cs <= 1'b0;else if(delay_cnt == 1 && bit_cnt < 8) begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= cmd_reg[7];endelse if(bit_cnt == 8 && clk_cnt == 0)beginstdone <= 1'b1;spi_clk <= 1'b0;						spi_mosi <= 1'b0;						endelse if(bit_cnt == 8 && clk_cnt == 1)beginspi_cs <= 1'b1;						endendB_ERA: beginstdone <= 1'b0;if(delay_state_cnt == 10)                spi_cs <= 1'b0;else if(delay_cnt == 1 && bit_cnt < 8) begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= cmd_reg[7];endelse if(bit_cnt == 8 && clk_cnt == 0)beginstdone <= 1'b1;				    spi_clk <= 1'b0;spi_mosi <= 1'b0;	endelse if(bit_cnt == 8 && clk_cnt == 1)beginspi_cs <= 1'b1;						endendS_ERA: beginstdone <= 1'b0;				 if(delay_state_cnt == 10)                spi_cs <= 1'b0;else if(delay_cnt == 1 && bit_cnt < 8) begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= cmd_reg[7];endelse if(bit_cnt >= 8&& bit_cnt < 32 && spi_cs == 0)beginspi_cs <= 1'b0;spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= addr_reg[23];endelse if(bit_cnt == 32 && clk_cnt == 0) beginspi_cs <= 1'b1;spi_clk <= 1'b0;spi_mosi <= 1'b0;stdone <= 1'b1;endendREAD: beginstdone <= 1'b0;if(delay_state_cnt == 10)                spi_cs <= 1'b0;else if(delay_cnt == 1 && bit_cnt < 8) begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= cmd_reg[7];endelse if(bit_cnt >= 8 && bit_cnt < 32 && spi_cs == 0)begin					    spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= addr_reg[23];endelse if(bit_cnt >= 32 && bit_cnt < 2080)begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= 1'b0;						endelse if(bit_cnt == 2080 && clk_cnt == 0) begin						spi_clk <= 1'b0;spi_mosi <= 1'b0;stdone <= 1'b1;						endelse if(bit_cnt == 2080 && clk_cnt == 1) beginspi_cs<=1'b1;endendWRITE: beginstdone<=1'b0;if(delay_state_cnt == 10)                spi_cs <= 1'b0;else if(delay_cnt == 1 && bit_cnt < 8) begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= cmd_reg[7];endelse if(bit_cnt >= 8 && bit_cnt < 32 && spi_cs == 0)begin					   spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= addr_reg[23];endelse if(bit_cnt >= 32 && bit_cnt < 2080)begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= data_reg[7];endelse if(bit_cnt == 2080 && clk_cnt == 0) beginspi_clk <= 1'b0;spi_mosi <= 1'b0;stdone <= 1'b1;endelse if(bit_cnt == 2080 && clk_cnt == 1) beginspi_cs <= 1'b1;endendR_STA_REG:begin				              stdone <= 1'b0;if(delay_state_cnt == 10)                spi_cs <= 1'b0;else if(delay_cnt == 1 && bit_cnt < 8)begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= cmd_reg[7];endelse if(bit_cnt == 8)begin					   				    spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= 1'b0;						end           else if(~spi_miso && bit_cnt % 8==0 && bit_cnt > 8 && clk_cnt == 0)beginr_wip_flag <= 1'b1;spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;endelse if(r_wip_flag && ~spi_miso && bit_cnt % 8==0 && bit_cnt > 8 && clk_cnt == 1)beginspi_clk <= 1'b0;spi_cs <= 1'b1;stdone <= 1'b1;endelse if(~spi_cs && delay_cnt == 1)beginspi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;end	   			         	 end default: beginstdone <= 1'b0;spi_cs <= 1'b1;spi_clk <= 1'b0;spi_clk_d0 <= 1'b0;spi_mosi <= 1'b0;				        endendcaseend
endila_spi u_ila_spi (.clk(clk_100m), // input wire clk.probe0(spi_start), // input wire [0:0]  probe0  .probe1(spi_cmd  ), // input wire [7:0]  probe1 .probe2(spi_addr ), // input wire [23:0]  probe2 .probe3(spi_data ), // input wire [7:0]  probe3 .probe4(cmd_cnt  ), // input wire [3:0]  probe4 .probe5(idel_flag_p), // input wire [0:0]  probe5 .probe6(w_data_req ), // input wire [0:0]  probe6 .probe7(error_flag ), // input wire [0:0]  probe7 .probe8(spi_cs  ), // input wire [0:0]  probe8 .probe9(spi_clk ), // input wire [0:0]  probe9 .probe10(spi_mosi), // input wire [0:0]  probe10 .probe11(spi_miso), // input wire [0:0]  probe11.probe12(idel_flag), // input wire [0:0]  probe12 .probe13(idel_flag_d0), // input wire [0:0]  probe13 .probe14(idel_flag_d1), // input wire [0:0]  probe14 .probe15(spi_clk_d0  ), // input wire [0:0]  probe15 .probe16(current_state  ), // input wire [3:0]  probe16 .probe17(next_state     ), // input wire [3:0]  probe17 .probe18(data_reg	   ), // input wire [7:0]  probe18 .probe19(cmd_reg        ), // input wire [7:0]  probe19 .probe20(addr_reg       ), // input wire [23:0]  probe20 .probe21(bit_cnt        ), // input wire [31:0]  probe21 .probe22(clk_cnt        ), // input wire [0:0]  probe22 .probe23(delay_cnt      ), // input wire [0:0]  probe23 .probe24(delay_state_cnt), // input wire [15:0]  probe24 .probe25(rd_data_reg    ), // input wire [7:0]  probe25 .probe26(stdone         ), // input wire [0:0]  probe26 .probe27(data_check     ), // input wire [7:0]  probe27 .probe28(r_w_data_req), // input wire [0:0]  probe28.probe29(r_wip_flag)
);endmodule

修改后的代码核心在于判断轮询寄存器那里,以及spi_clk_d0每次在idle状态的时候都要清零,清零这个步骤是在为了确保每次新的指令来时,时钟状态都能从0开始(由SPI的驱动模式决定);

R_STA_REG:begin				              stdone <= 1'b0;if(delay_state_cnt == 10)                spi_cs <= 1'b0;else if(delay_cnt == 1 && bit_cnt < 8)begin						spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= cmd_reg[7];endelse if(bit_cnt == 8)begin					   				    spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;spi_mosi <= 1'b0;						end           else if(~spi_miso && bit_cnt % 8==0 && bit_cnt > 8 && clk_cnt == 0)beginr_wip_flag <= 1'b1;spi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;endelse if(r_wip_flag && ~spi_miso && bit_cnt % 8==0 && bit_cnt > 8 && clk_cnt == 1)beginspi_clk <= 1'b0;spi_cs <= 1'b1;stdone <= 1'b1;endelse if(~spi_cs && delay_cnt == 1)beginspi_clk_d0 <= ~spi_clk_d0;spi_clk <= spi_clk_d0;end	   			         	 end 

主要修改的就是这里,思路是:
我会首先判断WIP位是否为0,如果为0,则把r_wip_flag标志位拉高,等到下一次轮询状态寄存器的时候就可以跳出当前轮询寄存器的状态。
修改后的时序如下:
在这里插入图片描述
可以看到擦除命令执行完之后,还需要等待一段时间后才会完成擦除,擦除后的时序为:
在这里插入图片描述

在这里插入图片描述
即回到初始状态。

遗留问题

其实从上面波形中可以看到,仍然是第二次发送写指令的时候,WEL位才会拉高,目前猜测是flash本身的问题,之后的思路可以改成直到WEL位拉高后才执行之后的擦除或者写命令,否则就会一直发送写使能指令,直到WEL拉高。
目前可以暂时改成发送两次写使能

相关文章:

verilog bug记录——正点原子spi_drive存在的问题

verilog bug记录——正点原子spi_drive存在的问题 问题概述代码修改—spi_drive.v遗留问题 问题概述 因为项目需求&#xff0c;需要利用spi对flash进行擦除和写入操作&#xff0c;所使用的开发板是正电原子的达芬奇开发板&#xff0c;我事先往Flash里面存了两个bit&#xff0c…...

vue+watermark-dom实现页面水印效果

前言 页面水印大家应该都不陌生&#xff0c;它可以用于验证数字媒体的来源和完整性&#xff0c;还可以用于版权保护和信息识别&#xff0c;这些信息可以在不影响媒体质量的情况下嵌入&#xff0c;‌并在需要时进行提取。‌本文将通过 vue 结合 watermark-dom 库&#xff0c;教大…...

为什么要学习网安技术?

学习网络安全&#xff08;网安&#xff09;技术在当今社会变得尤为重要&#xff0c;这主要源于以下几个方面的原因&#xff1a; 保护个人隐私&#xff1a;随着互联网的普及&#xff0c;个人信息如姓名、地址、电话号码、甚至银行账户信息等都在网络上留下了痕迹。学习网安技术可…...

2024春秋杯网络安全联赛夏季赛Crypto(AK)解题思路及用到的软件

2024春秋杯网络安全联赛夏季赛Crypto(AK) 2024春秋杯网络安全联赛夏季赛Crypto解题思路以及用到的软件 所有题用到的软件 1.vm(虚拟机kali)和Ubuntu&#xff0c;正常配置即可B站有很多。 2.Visual Studio Code(里面要配置python&#xff0c;crypto库和Sagemath数学软件系统S…...

vue2 使用代码编辑器插件 vue-codemirror

vue 使用代码编辑器插件 vue-codemirror 之前用过一次&#xff0c;当时用的一知半解的&#xff0c;所以也没有成文&#xff0c;前几天又因为项目有需求&#xff0c;所以说有用了一次&#xff0c;当然&#xff0c;依旧是一知半解&#xff0c;但是还是稍微写一下子吧&#xff01;…...

自动驾驶系列—智能巡航辅助功能中的横向避让功能介绍

自动驾驶系列—智能巡航辅助功能中的车道中央保持功能介绍 自动驾驶系列—智能巡航辅助功能中的车道变换功能介绍 自动驾驶系列—智能巡航辅助功能中的横向避让功能介绍 自动驾驶系列—智能巡航辅助功能中的路口通行功能介绍 文章目录 1. 背景介绍2. 功能定义3. 功能原理4. 传感…...

通过this.$options.data()重置变量时,会影响到引用了props或methods的变量

之前的文章我有提到过通过this.$options.data().具体某个值来将该值进行初始化 但我在项目中遇到了一个问题&#xff1a; 具体情况是&#xff1a;在data中定义一个变量时有用到methods中的一个方法&#xff0c;在后续的方法中我通过this. $options.data.值去重置了另一个数据&…...

[PM]产品运营

生命周期 运营阶段 主要工作 拉新 新用户的定义 冷启动 拉新方式 促活 用户活跃的原因 量化活跃度 运营社区化/内容化 留存 用户流失 培养用户习惯 用户挽回 变现 变现方式 付费模式 广告模式 数据变现 变现指标 传播 营销 认识营销 电商营销中心 拼团活动 1.需求整理 2.…...

流程控制语句

目录 前言 一、SET 语句 二、BEGIN END 语句 三、IF ELSE 语句 四、CASE 语句 五、WHILE 语句 六、GOTO 语句 七、RETURN 语句 前言 T-SQL 提供了用于编写过程性代码的语法结构&#xff0c;可用来进行顺序、分支、循环、存储过程等程序设计&#xff0c;编写结构化的模…...

杰发科技AC7840——SENT数据解析及软件Sent发送的实现

0. 测试环境 AC7840官方Demo板&#xff1b; 图莫斯0503 DSlogic U2Basic 使用引脚 输出脚&#xff1a;PB1 时钟&#xff1a;PB2&#xff0c;其他引脚可以不初始化&#xff0c;不接线 1. 数据解析 以下是SENT数据的格式&#xff08;1tick以3us为例&#xff09;&#…...

Java后端开发(十五)-- Ubuntu 开启activemq开机自启动功能

目录 1. 修改Wrapper.conf文件配置内容 2. 在/etc/systemd/system目录下创建activemq.service文件 3. 重启服务器,验证是否生效 4. 系统启动目标问题 操作环境: 1、Ubuntu 22.04.4 LTS (GNU/Linux 6.5.0-28-generic x86_64) 2、jdk17.0.11 3、apache-activemq-6.0.1 1. 修…...

56 网络层

本节重点 理解网络层的作用&#xff0c;深入理解IP协议的基本原理 对整个TCP/IP协议有系统的理解 对TCP/IP协议体系下的其他重要协议和技术有一定的了解 目录 前置认识ip协议基本概念协议头格式网段划分特殊的ip地址ip地址的数量限制私有ip和公有ip路由路由表生成算法 在复杂…...

MAC地址泛洪——华为ensp

首先搭建好网络拓扑&#xff0c;包含客户端、服务端、一台交换机 以及 云。 客户端client1和服务端server1各自配置好IP地址&#xff0c;服务端充当FTP服务器&#xff0c;启动ftp服务 其中要先配置cloud1相关配置&#xff0c;然后才可以进行连线&#xff0c; 第一步进行端口…...

golang 字符编码 gbk/gb2312 utf8编码相互转换,判断字符是否gbk编码函数, 字符编码转换基础原理解析, golang默认编码utf8

虽然golang里面的默认编码都是统一的unicode utf8编码&#xff0c; 但是我们在调用外部系统提供的api时&#xff0c;就可能会遇到别人的接口提供的编码非 utf8编码&#xff0c;而是gbk/gb2312编码&#xff0c; 这时候我们就必须要将别人的gbk编码转换为go语言里面的默认编码ut…...

CentOS(7.x、8)上安装EMQX

EMQX 是一个高度可扩展的分布式 MQTT 消息服务器&#xff0c;适用于 IoT、M2M 和移动应用程序。以下是在 CentOS 系统上安装 EMQX 的基本步骤&#xff1a; 在 CentOS 上安装 EMQ X 步骤 1: 添加 EMQ X YUM 源 首先&#xff0c;你需要添加 EMQ X 的官方 YUM 源到你的 CentOS 系…...

Mojo模型魔法:动态定制特征转换的艺术

标题&#xff1a;Mojo模型魔法&#xff1a;动态定制特征转换的艺术 在机器学习领域&#xff0c;模型的灵活性和可扩展性是至关重要的。Mojo模型&#xff08;Model-as-a-Service&#xff09;提供了一种将机器学习模型部署为服务的方式&#xff0c;允许开发者和数据科学家轻松地…...

多任务高斯过程数学原理和Pytorch实现示例

高斯过程其在回归任务中的应用我们都很熟悉了&#xff0c;但是我们一般介绍的都是针对单个任务的&#xff0c;也就是单个输出。本文我们将讨论扩展到多任务gp&#xff0c;强调它们的好处和实际实现。 本文将介绍如何通过共区域化的内在模型(ICM)和共区域化的线性模型(LMC)&…...

【PPT把当前页输出为图片】及【PPT导出图片模糊】的解决方法(sci论文图片清晰度)

【PPT把当前页输出为图片】及【PPT导出图片模糊】的解决方法 内容一&#xff1a;ppt把当前页输出为图片&#xff1a;内容二&#xff1a;ppt导出图片模糊的解决方法&#xff1a;方法&#xff1a;步骤1&#xff1a;打开注册表编辑器步骤2&#xff1a;修改注册表&#xff1a; 该文…...

TeraTerm 使用技巧

参考资料 自分がよく使うTeratermマクロによる自動ログインのやり方をまとめてみたよTera Term マクロでログインを自動化してみたTera Term のススメ 目录 简介一. 常用基础设置1.1 语言变更1.2 log设置 二. 小技巧2.1 指定host别名2.2 新开窗口2.3 设置粘贴多行命令时的行间…...

意得润色打折啦

新注册使用可以减15%&#xff0c;ABSJU202&#xff0c;直接使用哦ㅤ 此外&#xff0c;如果老板经费充足&#xff0c;预算高&#xff0c;完全可以试试他家的投稿套餐&#xff0c;科学深度编辑&#xff0c;从期刊选择&#xff0c;到投稿协助&#xff0c;投稿信都帮你写好&#xf…...

微软研发致胜策略 06:学无止境

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1994 年发布。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Debugging the Development Process》&#xff0c;这本书详细阐述了软件开发过程中的常见问题及其解决方案&a…...

学习大数据DAY21 Linux基本指令2

目录 思维导图 搜索查看查找类 find 从指定目录查找文件 head 与 tail 查看行 cat 查看内容 more 查看大内容 grep 过滤查找 history 查看已经执行过的历史命令 wc 统计文件 du 查看空间 管道符号 | 配合命令使用 上机练习 4 解压安装类 zip unzip 压缩解压 tar …...

【18】Android 线程间通信(三) - Handler

概述 接下来我们会从native层来分析一下&#xff0c;Handler做了什么&#xff0c;以及之前提到过的应用层的两个native的调用链。 nativeWake 最早接触这个方法还记得是什么时候吗&#xff1f;MessageQueue#enqueueMessage中&#xff0c;在这个方法的末尾&#xff0c;我们看…...

静态路由技术

一、路由的概念 路由是指指导IP报文发送的路径信息。 二、路由表的结构 1、Destination/Mask:IP报文的接收方的IP地址及其子网掩码; 2、proto:协议(Static:静态路由协议,Direct:表示直连路由) 3、pref:优先级(数值和优先级成反比) 4、cost:路由开销(从源到目的…...

SpringBoot缓存注解使用

背景 除了 RedisTemplate 外&#xff0c; 自Spring3.1开始&#xff0c;Spring自带了对缓存的支持。我们可以直接使用Spring缓存技术将某些数据放入本机的缓存中&#xff1b;Spring缓存技术也可以搭配其他缓存中间件(如Redis等)进行使用&#xff0c;将某些数据写入到缓存中间件…...

@RequestBody接收到的参数中如何限制List的长度?

在Spring MVC中&#xff0c;你可以使用Valid注解和自定义的验证注解来限制List的长度&#xff0c;防止DOS攻击。具体步骤如下&#xff1a; 创建自定义注解&#xff1a;首先&#xff0c;创建一个自定义注解来验证List的长度。 import javax.validation.Constraint; import jav…...

Linux C语言 54-目录操作

Linux C语言 54-目录操作 本节关键字&#xff1a;Linux、C语言、目录操作、遍历目录 相关C库函数&#xff1a;opendir、readdir、closedir 遍历目录 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dirent.h> #include <…...

Java实战中如何使用多线程(线程池)及其为什么使用?

这个话题在入行之前就想过很多次&#xff0c;很多8古文或者你搜索的结果都是告诉你什么提高高并发或者是一些很高大上的话&#xff0c;既没有案例也没有什么公式去证明&#xff0c;但是面试中总是被问到&#xff0c;也没有实战经历&#xff0c;所以面试时一问到多线程的东西就无…...

kafka集群搭建-使用zookeeper

1.环境准备&#xff1a; 使用如下3台主机搭建zookeeper集群&#xff0c;由于默认的9092客户端连接端口不在本次使用的云服务器开放端口范围内&#xff0c;故端口改为了8093。 172.2.1.69:8093 172.2.1.70:8093 172.2.1.71:8093 2.下载地址 去官网下载&#xff0c;或者使用如…...

【python】Numpy运行报错分析:IndexError与形状不匹配问题

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

你有多自律就有多自由

当你失去对时间的控制权&#xff0c;生活也就失去了平衡。 真正对自己有要求的人&#xff0c;都是高度自律的人。 追求自己想要的生活&#xff0c;任何时候开始都不会晚&#xff0c;关键在于你能够坚持下去&#xff0c;以高度自律的精神&#xff0c;日复一日、年复一年的坚持下…...

Codeforces Round 959 (Div. 1 + Div. 2 ABCDEFG 题) 文字讲解+视频讲解

Problem A. Diverse Game Statement 给定 n m n\times m nm 的矩形 a a a&#xff0c; a a a 中的每一个数均在 1 ∼ n m 1\sim nm 1∼nm 之间且互不相同。求出 n m n\times m nm 的矩形 b b b&#xff0c; b b b 中的每一个数均在 1 ∼ n m 1\sim nm 1∼nm 之间且互…...

WSL2 Centos7 Docker服务启动失败怎么办?

wsl 安装的CentOS7镜像,安装了Docker之后,发现用systemctl start docker 无法将docker启动起来。 解决办法 1、编辑文件 vim /usr/lib/systemd/system/docker.service将13行注释掉,然后在下面新增14行的内容。然后保存退出。 2、再次验证 可以发现,我们已经可以正常通过s…...

分布式锁-redisson锁重试和WatchDog机制

抢锁过程中&#xff0c;获得当前线程&#xff0c;通过tryAcquire进行抢锁&#xff0c;该抢锁逻辑和之前逻辑相同。 1、先判断当前这把锁是否存在&#xff0c;如果不存在&#xff0c;插入一把锁&#xff0c;返回null 2、判断当前这把锁是否是属于当前线程&#xff0c;如果是&a…...

ESP8266模块(2)

实例1 查看附近的WiFi 步骤1&#xff1a;进入AT指令模式 使用USB转串口适配器将ESP8266模块连接到电脑。打开串口终端软件&#xff0c;并设置正确的串口和波特率&#xff08;通常为115200&#xff09;。输入以下命令并按回车确认&#xff1a; AT如果模块响应OK&#xff0c;…...

Docker安装笔记

1. Mac安装Docker 1.1 Docker安装包下载 1.1.1 阿里云 对于10.10.3以下的用户 推荐使用 对于10.10.3以上的用户 推荐使用 1.1.2 官网下载 系统和芯片选择适合自己的安装包 1.2 镜像加速 【推荐】阿里镜像 登陆后&#xff0c;左侧菜单选中镜像加速器就可以看到你的专属地…...

《昇思25天学习打卡营第21天|Pix2Pix实现图像转换》

Pix2Pix 是一种图像转换模型&#xff0c;使用条件生成对抗网络&#xff08;Conditional Generative Adversarial Networks&#xff0c;cGANs&#xff09;实现图像到图像的转换。它主要由生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;…...

Python和MATLAB网络尺度结构和幂律度大型图生成式模型算法

&#x1f3af;要点 &#x1f3af;算法随机图模型数学概率 | &#x1f3af;图预期度序列数学定义 | &#x1f3af;生成具有任意指数的大型幂律网络&#xff0c;数学计算幂律指数和平均度 | &#x1f3af;随机图分析中巨型连接分量数学理论和推论 | &#x1f3af;生成式多层网络…...

在jsPsych中使用Vue

jspsych 介绍 jsPsych是一个非常好用的心理学实验插件&#xff0c;可以用来构建心理学实验。具体的就不多介绍了&#xff0c;大家可以去看官网&#xff1a;https://www.jspsych.org/latest/ 但是大家在使用时就会发现&#xff0c;这个插件只能使用js绘制界面&#xff0c;或者…...

机器学习·概率论基础

概率论 概率基础 这部分太简单&#xff0c;直接略过 条件概率 独立性 独立事件A和B的交集如下 非独立事件 非独立事件A和B的交集如下 贝叶斯定理 先验 事件 后验 在概率论和统计学中&#xff0c;先验概率和后验概率是贝叶斯统计的核心概念 简单来说后验概率就是结合了先验概…...

c生万物系列(面向对象:封装)

本系列博客主要介绍c语言的一些屠龙技&#xff0c;里面包含了笔者本人的一些奇思妙想。 该系列博客笔者只是用作记录。如果你偶然找到了这篇博客&#xff0c;但是发现不知所云&#xff0c;请不要过多投入时间&#xff0c;可能笔者本人那时候也看不懂了。 笔者决定用c语言模仿…...

当当网数据采集:Scrapy框架的异步处理能力

在互联网数据采集领域&#xff0c;Scrapy框架以其强大的异步处理能力而著称。Scrapy利用了Python的异步网络请求库&#xff0c;如twisted&#xff0c;来实现高效的并发数据采集。本文将深入探讨Scrapy框架的异步处理能力&#xff0c;并展示如何在当当网数据采集项目中应用这一能…...

React——useEffect和自定义useUpdateEffect

useEffect 是React的一个内置Hook&#xff0c;用于在组件渲染后执行副作用&#xff08;例如数据获取、订阅或手动更改DOM&#xff09;。它将在第一次渲染后和每次更新后都会执行。 useEffect(() > {// 这里的代码将在组件挂载和更新时执行。 }, [dependencies]); // depend…...

Hadoop大数据处理架构中ODB、DIM、DWD、DWS

在Hadoop的大数据处理架构中&#xff0c;ODS、DIM、DWD和DWS分别代表了数据仓库体系中不同的层次和功能。下面解释这几个概念&#xff1a; ODS (Operational Data Store) 想象你有一家超市&#xff0c;每天营业结束后&#xff0c;你会把当天所有的销售记录、顾客信息、商品库…...

【刷题汇总 -- 爱丽丝的人偶、集合、最长回文子序列】

C日常刷题积累 今日刷题汇总 - day0211、爱丽丝的人偶1.1、题目1.2、思路1.3、程序实现 2、集合2.1、题目2.2、思路2.3、程序实现 -- set 3、最长回文子序列3.1、题目3.2、思路3.3、程序实现 -- dp 4、题目链接 今日刷题汇总 - day021 1、爱丽丝的人偶 1.1、题目 1.2、思路 …...

基于vue3 + vite产生的 TypeError: Failed to fetch dynamically imported module

具体参考这篇衔接&#xff1a; Vue3报错&#xff1a;Failed to fetch dynamically imported module-CSDN博客 反正挺扯淡的&#xff0c;错误来源于基于ry-vue-plus来进行二次开发的时候遇到的问题。 错误起因 我创建了一个广告管理页面。然后发现访问一直在加载中。报的是这样…...

批量自动添加好友,高效拓展人脉圈.

随着微信使用数量的不断增加&#xff0c;手动添加好友成为了一项耗时且繁琐的任务。为了帮助大家解决这个问题&#xff0c;下面分享一款高效的微信管理系统&#xff0c;它能够帮助你实现批量自动添加好友&#xff0c;极大提升了人脉拓展的效率。 这款微信管理系统可以同时管理多…...

Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

目录 一、需求描述 二、实现效果 三、完整代码 四、实现过程 1、HTML 页面结构 2、CSS 元素样式 3、JavaScript动态控制 &#xff08;1&#xff09;获取元素 &#xff08;2&#xff09;显示\隐藏遮罩层与模态框 &#xff08;3&#xff09;实现模态框拖动效果 一、需求…...

【深度学习】fooocusapi,docker,inpainting图像

基础镜像制作来源 fooocusapi接口官方写的&#xff1a; docker run -d --gpusall \-e NVIDIA_DRIVER_CAPABILITIEScompute,utility \-e NVIDIA_VISIBLE_DEVICESall \-p 8888:8888 konieshadow/fooocus-api会下载一些模型&#xff0c;下载完后推这个镜像 docker commit 4dfd1…...

算法017:二分查找

二分查找. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/binary-search/ 二分查找&#xff0c;其实是双指针的一种特殊情况&#xff0c;但是时间复杂度极低&#…...