FPGA - 以太网UDP通信(二)

news2025/1/21 15:32:55

一,引言

前文链接:FPGA - 以太网UDP通信(一)

在上文章中介绍了以太网简介,以太网UDP通信硬件结构,以及PHY芯片RGMII接口-GMII接口转换逻辑,接下来介绍UDP通信结构框图以及数据链路层(MAC层)接受发送逻辑。

二,以太网UDP通信结构框图

在上一篇文章中介绍了以太网UDP通信组包过程图:

可以看到用户数据通过UDP层添加udp头部,然后经过IP层添加ip头部,在经过数据链路层(MAC层)添加mac头部,送到PHY芯片物理层。一步步完成组包发送过程。同样的,从PHT芯片输出的数据经过MAC层IP层UDP层一步步完成解包校验过程。因此根据此思路画出简易结构框图如下:

在上篇文章中实现了rgmii_interface(rgmii_receive和rgmii_send)模块,接下来实现mac_layermac_receivemac_send)模块。

三,数据链路层(MAC层)

MAC不是物理层,MAC层是数据链路层的两个子层之一。

以太网V2的MAC帧格式:

------------------------------------- mac数据包头  22byte  -------------------------------------      

|     前导码(前同步码) 7 byte                                                                           |  
|     8'h55             ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​                                              ​​​​​​​        ​​​​​​​   |

|     SFD(帧开始定结符)  1byte     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​   |
|     8'hd5     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​                                         |

|     目的mac地址 6byte     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​            ​​​​​​​      |

|     源mac地址   6byte     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​                    |

|     类型/长度   2byte     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​            ​​​​​​​        ​​​​​​​   |
|     小于1536表示长度,     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​            ​​​​​​​     |
|     大于1536表示类型 arp:16'h0806 , ip: 16'h0800     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​|

|     数据 46-1500byte     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​                      |

|     FCS(帧校验序列CRC) 4byte     ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​|

---------------------------------------------------------------------------------------------------------- 

四,MAC层代码设计

在上面的结构框图中,可以看到,mac_layer中包括mac_receivemac_send模块。

----------------------------------------------------------  思路 ------------------------------------------------------------

1,在MAC帧格式中,最后4byte 是FCS(帧校验序列CRC), 所以在接受和发送过程中必须把帧校验序列前面的数据存储(fifo)起来,等到CRC校验完成,再进行数据传输。

2,在以太网UDP通信中,用户端数据传输是在用户时钟下进行的,而PHY芯片数据传输是在PHY芯片的时钟下进行的。所以在这里我们要做一个跨时钟域的处理。

3,跨时钟域处理:在多bit信号跨时钟域中常常使用异步fifo来处理,但如何很好的设计这一处理过程呢?在这里我们进行双fifo跨时钟域(其实在之前文章中也用过这样的处理方式)。

首先第一个是数据fifo,缓存有效数据+last数据(用来指示有效数据的最后一个数据)

其次第二个是控制fifo,缓存数据对应的地址,长度,类型.....(在mac_layer中缓存的是帧类型和CRC校验结果)

然后判断fifo非空(rdemoty信号为低), 就把有效数据和控制信息从fifo里面读出来,

控制fifo的读使能rden只需要拉高一拍,数据fifo读使能rden要一直拉高,直到读出来最后一个数据,通过判断读出来的last信号,来拉低rden。

4,CRC校验

5,如何准确有效的进行数据组包,解包校验呢?

设置计数器,接受端设置rx_cnt,发送端设置tx_cnt。用计数器控制组包解包校验过程。

下图是mac_lay层的结构框图:

-----------------------------------------------------------------------------------------------------------------------------

五,MAC层代码编写

CRC32校验:

CRC校验

`timescale 1ns / 1ps

module crc32_d8(
	input				clk,
	input               reset,

	input               crc_din_vld,
	input   [7:0]       crc_din    ,
	input               crc_done   ,
	output  [31:0]      crc_dout   

    );

wire [7:0]  crc_din_r;
reg  [31:0] crc_dout_r;
wire [31:0] crc_data;

assign crc_din_r = {crc_din[0],crc_din[1],crc_din[2],crc_din[3],crc_din[4],crc_din[5],crc_din[6],crc_din[7]};
assign crc_dout  = ~{crc_dout_r[0],crc_dout_r[1],crc_dout_r[2],crc_dout_r[3],crc_dout_r[4],crc_dout_r[5],crc_dout_r[6],crc_dout_r[7],
                    crc_dout_r[8],crc_dout_r[9],crc_dout_r[10],crc_dout_r[11],crc_dout_r[12],crc_dout_r[13],crc_dout_r[14],crc_dout_r[15],
                    crc_dout_r[16],crc_dout_r[17],crc_dout_r[18],crc_dout_r[19],crc_dout_r[20],crc_dout_r[21],crc_dout_r[22],crc_dout_r[23],
                    crc_dout_r[24],crc_dout_r[25],crc_dout_r[26],crc_dout_r[27],crc_dout_r[28],crc_dout_r[29],crc_dout_r[30],crc_dout_r[31]
                    };

assign crc_data[0] = crc_din_r[6] ^ crc_din_r[0] ^ crc_dout_r[24] ^ crc_dout_r[30];
assign crc_data[1] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[1] ^ crc_din_r[0] ^ crc_dout_r[24] ^ crc_dout_r[25] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[2] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[2] ^ crc_din_r[1] ^ crc_din_r[0] ^ crc_dout_r[24] ^ crc_dout_r[25] ^ crc_dout_r[26] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[3] = crc_din_r[7] ^ crc_din_r[3] ^ crc_din_r[2] ^ crc_din_r[1] ^ crc_dout_r[25] ^ crc_dout_r[26] ^ crc_dout_r[27] ^ crc_dout_r[31];
assign crc_data[4] = crc_din_r[6] ^ crc_din_r[4] ^ crc_din_r[3] ^ crc_din_r[2] ^ crc_din_r[0] ^ crc_dout_r[24] ^ crc_dout_r[26] ^ crc_dout_r[27] ^ crc_dout_r[28] ^ crc_dout_r[30];
assign crc_data[5] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[5] ^ crc_din_r[4] ^ crc_din_r[3] ^ crc_din_r[1] ^ crc_din_r[0] ^ crc_dout_r[24] ^ crc_dout_r[25] ^ crc_dout_r[27] ^ crc_dout_r[28] ^ crc_dout_r[29] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[6] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[5] ^ crc_din_r[4] ^ crc_din_r[2] ^ crc_din_r[1] ^ crc_dout_r[25] ^ crc_dout_r[26] ^ crc_dout_r[28] ^ crc_dout_r[29] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[7] = crc_din_r[7] ^ crc_din_r[5] ^ crc_din_r[3] ^ crc_din_r[2] ^ crc_din_r[0] ^ crc_dout_r[24] ^ crc_dout_r[26] ^ crc_dout_r[27] ^ crc_dout_r[29] ^ crc_dout_r[31];
assign crc_data[8] = crc_din_r[4] ^ crc_din_r[3] ^ crc_din_r[1] ^ crc_din_r[0] ^ crc_dout_r[0] ^ crc_dout_r[24] ^ crc_dout_r[25] ^ crc_dout_r[27] ^ crc_dout_r[28];
assign crc_data[9] = crc_din_r[5] ^ crc_din_r[4] ^ crc_din_r[2] ^ crc_din_r[1] ^ crc_dout_r[1] ^ crc_dout_r[25] ^ crc_dout_r[26] ^ crc_dout_r[28] ^ crc_dout_r[29];
assign crc_data[10] = crc_din_r[5] ^ crc_din_r[3] ^ crc_din_r[2] ^ crc_din_r[0] ^ crc_dout_r[2] ^ crc_dout_r[24] ^ crc_dout_r[26] ^ crc_dout_r[27] ^ crc_dout_r[29];
assign crc_data[11] = crc_din_r[4] ^ crc_din_r[3] ^ crc_din_r[1] ^ crc_din_r[0] ^ crc_dout_r[3] ^ crc_dout_r[24] ^ crc_dout_r[25] ^ crc_dout_r[27] ^ crc_dout_r[28];
assign crc_data[12] = crc_din_r[6] ^ crc_din_r[5] ^ crc_din_r[4] ^ crc_din_r[2] ^ crc_din_r[1] ^ crc_din_r[0] ^ crc_dout_r[4] ^ crc_dout_r[24] ^ crc_dout_r[25] ^ crc_dout_r[26] ^ crc_dout_r[28] ^ crc_dout_r[29] ^ crc_dout_r[30];
assign crc_data[13] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[5] ^ crc_din_r[3] ^ crc_din_r[2] ^ crc_din_r[1] ^ crc_dout_r[5] ^ crc_dout_r[25] ^ crc_dout_r[26] ^ crc_dout_r[27] ^ crc_dout_r[29] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[14] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[4] ^ crc_din_r[3] ^ crc_din_r[2] ^ crc_dout_r[6] ^ crc_dout_r[26] ^ crc_dout_r[27] ^ crc_dout_r[28] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[15] = crc_din_r[7] ^ crc_din_r[5] ^ crc_din_r[4] ^ crc_din_r[3] ^ crc_dout_r[7] ^ crc_dout_r[27] ^ crc_dout_r[28] ^ crc_dout_r[29] ^ crc_dout_r[31];
assign crc_data[16] = crc_din_r[5] ^ crc_din_r[4] ^ crc_din_r[0] ^ crc_dout_r[8] ^ crc_dout_r[24] ^ crc_dout_r[28] ^ crc_dout_r[29];
assign crc_data[17] = crc_din_r[6] ^ crc_din_r[5] ^ crc_din_r[1] ^ crc_dout_r[9] ^ crc_dout_r[25] ^ crc_dout_r[29] ^ crc_dout_r[30];
assign crc_data[18] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[2] ^ crc_dout_r[10] ^ crc_dout_r[26] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[19] = crc_din_r[7] ^ crc_din_r[3] ^ crc_dout_r[11] ^ crc_dout_r[27] ^ crc_dout_r[31];
assign crc_data[20] = crc_din_r[4] ^ crc_dout_r[12] ^ crc_dout_r[28];
assign crc_data[21] = crc_din_r[5] ^ crc_dout_r[13] ^ crc_dout_r[29];
assign crc_data[22] = crc_din_r[0] ^ crc_dout_r[14] ^ crc_dout_r[24];
assign crc_data[23] = crc_din_r[6] ^ crc_din_r[1] ^ crc_din_r[0] ^ crc_dout_r[15] ^ crc_dout_r[24] ^ crc_dout_r[25] ^ crc_dout_r[30];
assign crc_data[24] = crc_din_r[7] ^ crc_din_r[2] ^ crc_din_r[1] ^ crc_dout_r[16] ^ crc_dout_r[25] ^ crc_dout_r[26] ^ crc_dout_r[31];
assign crc_data[25] = crc_din_r[3] ^ crc_din_r[2] ^ crc_dout_r[17] ^ crc_dout_r[26] ^ crc_dout_r[27];
assign crc_data[26] = crc_din_r[6] ^ crc_din_r[4] ^ crc_din_r[3] ^ crc_din_r[0] ^ crc_dout_r[18] ^ crc_dout_r[24] ^ crc_dout_r[27] ^ crc_dout_r[28] ^ crc_dout_r[30];
assign crc_data[27] = crc_din_r[7] ^ crc_din_r[5] ^ crc_din_r[4] ^ crc_din_r[1] ^ crc_dout_r[19] ^ crc_dout_r[25] ^ crc_dout_r[28] ^ crc_dout_r[29] ^ crc_dout_r[31];
assign crc_data[28] = crc_din_r[6] ^ crc_din_r[5] ^ crc_din_r[2] ^ crc_dout_r[20] ^ crc_dout_r[26] ^ crc_dout_r[29] ^ crc_dout_r[30];
assign crc_data[29] = crc_din_r[7] ^ crc_din_r[6] ^ crc_din_r[3] ^ crc_dout_r[21] ^ crc_dout_r[27] ^ crc_dout_r[30] ^ crc_dout_r[31];
assign crc_data[30] = crc_din_r[7] ^ crc_din_r[4] ^ crc_dout_r[22] ^ crc_dout_r[28] ^ crc_dout_r[31];
assign crc_data[31] = crc_din_r[5] ^ crc_dout_r[23] ^ crc_dout_r[29];

always @(posedge clk) begin
    if (reset) 
        crc_dout_r <= 32'hffffffff;
    else if (crc_done) 
        crc_dout_r <= 32'hffffffff;
    else if (crc_din_vld)
 		crc_dout_r <= crc_data;
    else 
    	crc_dout_r <= crc_dout_r; 
end

endmodule

mac_receive

mac_receive代码:

//功能 :  ①完成校验,将有效数据和MAC头部分离出来
//        ②跨时钟域
// -----------------------------------------------------------------------------
`timescale 1ns / 1ps

module mac_receive #(
	parameter	LOCAL_MAC_ADDR = 48'hffffff_ffffff,
	parameter   CRC_CHACK_EN   = 1

)(
	input								clk             , //用户接受端时钟
	input                               phy_rx_clk      , //phy芯片提供的时钟

	input                               reset            , //用户端复位信号
	input                               phy_rx_reset     , //phy接受端复位
  
	/*-------rgmii_recive模块交互的信号----------------*/
	input                               gmii_rx_data_vld ,
	input       [7:0]                   gmii_rx_data     ,

	/*-------mac_to_arp_ip模块交互的信号----------------*/	
	output  reg                         mac_rx_data_vld  ,
	output  reg                         mac_rx_data_last ,
	output  reg [7:0]                   mac_rx_data      ,
	output  reg [15:0]                  mac_rx_frame_type,

	/*-------rx_crc32_d8模块交互的信号----------------*/	   
	output  reg 					    rx_crc_din_vld   ,
	output  reg [7:0]                   rx_crc_din       ,
	output  reg                         rx_crc_done      ,
	input       [31:0]                  rx_crc_dout         
    );




















    

endmodule

mac_send

mac_send代码:

//功能    ① 完成crc校验 mac头部 有效数据 crc校验 ...等组包
//        ② 跨时钟域 
// -----------------------------------------------------------------------------
`timescale 1ns / 1ps
module mac_send #(
	parameter	LOCAL_MAC_ADDR  = 48'hffffff_ffffff,
	parameter   TARGET_MAC_ADDR = 48'hffffff_ffffff	

)(
	input								clk             , //用户发送端时钟
	input                               phy_tx_clk      , 

	input                               reset            , 
	input                               phy_tx_reset     , 
  
	/*-------rgmii_send模块交互的信号----------------*/
	output  reg                         gmii_tx_data_vld ,
	output  reg [7:0]                   gmii_tx_data     ,

	/*-------ip_send模块交互的信号--------------------*/	
	input                               mac_tx_data_vld  ,
	input                               mac_tx_data_last ,
	input       [7:0]                   mac_tx_data      ,
	input       [15:0]                  mac_tx_frame_type,
	input       [15:0]                  mac_tx_length    ,

	/*-------tx_crc32_d8模块交互的信号----------------*/	   
	output  reg 					    tx_crc_din_vld   ,
	output      [7:0]                   tx_crc_din       ,
	output  reg                         tx_crc_done      ,
	input       [31:0]                  tx_crc_dout    	

    );



















endmodule 

顶层设计

mac层分别实现了接收和发送两部分,将两部分例化封装顶层mac_layer

`timescale 1ns / 1ps

module mac_layer #(
	parameter	LOCAL_MAC_ADDR  = 48'hffffff_ffffff   ,
	parameter   TARGET_MAC_ADDR = 48'hffffff_ffffff	,	
	parameter   CRC_CHACK_EN    = 1                

)(
	input                               app_tx_clk       ,
	input                               app_rx_clk       ,
	input                               phy_tx_clk       , 
	input                               phy_rx_clk       , 	

	input                               app_tx_reset     ,
	input                               app_rx_reset     ,
	input                               phy_tx_reset     , 
	input                               phy_rx_reset     , 

	input                               gmii_rx_data_vld ,
	input       [7:0]                   gmii_rx_data     ,
	output                              gmii_tx_data_vld ,
	output      [7:0]                   gmii_tx_data     ,	

	output                              mac_rx_data_vld  ,
	output                              mac_rx_data_last ,
	output      [7:0]                   mac_rx_data      ,
	output      [15:0]                  mac_rx_frame_type,		

	input                               mac_tx_data_vld  ,
	input                               mac_tx_data_last ,
	input       [7:0]                   mac_tx_data      ,
	input       [15:0]                  mac_tx_frame_type,
	input       [15:0]                  mac_tx_length    

    );




	wire        tx_crc_din_vld;
	wire  [7:0] tx_crc_din    ;
	wire        tx_crc_done   ;
	wire [31:0] tx_crc_dout   ;

	wire        rx_crc_din_vld;
	wire  [7:0] rx_crc_din    ;
	wire        rx_crc_done   ;
	wire [31:0] rx_crc_dout   ;


	mac_send #(
			.LOCAL_MAC_ADDR(LOCAL_MAC_ADDR),
			.TARGET_MAC_ADDR(TARGET_MAC_ADDR)
		) mac_send (
			.clk               (app_tx_clk),
			.phy_tx_clk        (phy_tx_clk),

			.reset             (app_tx_reset),
			.phy_tx_reset      (phy_tx_reset),

			.gmii_tx_data_vld  (gmii_tx_data_vld),
			.gmii_tx_data      (gmii_tx_data),

			.mac_tx_data_vld   (mac_tx_data_vld),
			.mac_tx_data_last  (mac_tx_data_last),
			.mac_tx_data       (mac_tx_data),
			.mac_tx_frame_type (mac_tx_frame_type),
			.mac_tx_length     (mac_tx_length),

			.tx_crc_din_vld    (tx_crc_din_vld),
			.tx_crc_din        (tx_crc_din),
			.tx_crc_done       (tx_crc_done),
			.tx_crc_dout       (tx_crc_dout)
		);

	mac_receive #(
			.LOCAL_MAC_ADDR(LOCAL_MAC_ADDR),
			.CRC_CHACK_EN  (CRC_CHACK_EN)
		) mac_receive (
			.clk               (app_rx_clk),
			.phy_rx_clk        (phy_rx_clk),

			.reset             (app_rx_reset),
			.phy_rx_reset      (phy_rx_reset),

			.gmii_rx_data_vld  (gmii_rx_data_vld),
			.gmii_rx_data      (gmii_rx_data),

			.mac_rx_data_vld   (mac_rx_data_vld),
			.mac_rx_data_last  (mac_rx_data_last),
			.mac_rx_data       (mac_rx_data),
			.mac_rx_frame_type (mac_rx_frame_type),

			.rx_crc_din_vld    (rx_crc_din_vld),
			.rx_crc_din        (rx_crc_din),
			.rx_crc_done       (rx_crc_done),
			.rx_crc_dout       (rx_crc_dout)
		);

	crc32_d8 tx_crc32_d8
		(
			.clk         (phy_tx_clk),
			.reset       (phy_tx_reset),

			.crc_din_vld (tx_crc_din_vld),
			.crc_din     (tx_crc_din),
			.crc_done    (tx_crc_done),
			.crc_dout    (tx_crc_dout)
		);

	crc32_d8 rx_crc32_d8
		(
			.clk         (phy_rx_clk),
			.reset       (phy_rx_reset),

			.crc_din_vld (rx_crc_din_vld),
			.crc_din     (rx_crc_din),
			.crc_done    (rx_crc_done),
			.crc_dout    (rx_crc_dout)
		);



endmodule

 六,总结

至此,我们完成了以太网发送过程中最底层 ,也是最重要的部分MAC层的发送与接受。 关于本节中的CRC校验部分没有过多介绍,这部分可通过CRC生成网页来生成CRC校验代码。

接下来,在下一篇博客中将会实现ip层的接收与发送。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1587373.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

政安晨:【Keras机器学习实践要点】(二十六)—— 内卷神经网络

目录 简介 设置 卷积 演变 测试逆卷积层 图像分类 获取 CIFAR10 数据集 数据可视化 卷积神经网络 逆向传播神经网络 比较 损失图和准确率图 可视化卷积核 结论 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Ke…

从 SQLite 3.5.9 迁移到 3.6.0(二十一)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;从 SQLite 3.4.2 迁移到 3.5.0&#xff08;二十&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 ​SQLite 版本 3.6.0 &#xff08;2008-07-16&#xff09; 包含许多更改。按照惯例 SQLite项目&#xff…

FPGA在医疗的应用,以4K医疗内窥镜为例

前言 随着技术的发展&#xff0c;医学影像作为科学技术的主要成就之一&#xff0c;在无创诊断和治疗领域已经有了多种应用。其中一个应用是内窥镜&#xff0c;在20世纪90年代&#xff0c;当利用电荷耦合装置将图像传输到显示器上成为可能时&#xff0c;内窥镜变得更加广泛。为…

自动化测试框架 Selenium(3)

目录 1.前言 2.等待方式 2.1死等 2.2智能等待 3.游览器操作 3.1游览器最大化 3.2设置游览器的宽 高 3.3 游览器的前进和后退 3.4游览器滚动条 1.前言 本篇博客,我们将继续Selenium自动化测试的学习.在前面的章节中,俺介绍了Selenium是怎么回事,和键盘鼠标操作.还有url和…

数据应用OneID:ID-Mapping Spark GraphX实现

前言 说明 以用户实体为例&#xff0c;ID 类型包含 user_id 和 device_id。当然还有其他类型id。不同id可以获取到的阶段、生命周期均不相同。 device_id 生命周期通常指的是一个设备从首次被识别到不再活跃的整个时间段。 user_id是用户登录之后系统分配的唯一标识&#xff…

(2022级)成都工业学院数据库原理及应用实验三:数据定义语言DDL

唉&#xff0c;用爱发电连赞都没几个&#xff0c;博主感觉没有动力了 想要完整版的sql文件的同学们&#xff0c;点赞评论截图&#xff0c;发送到2923612607qq,com&#xff0c;我就会把sql文件以及如何导入sql文件到navicat的使用教程发给你的 基本上是无脑教程了&#xff0c;…

Vue ElementUI el-input-number 改变控制按钮 icon 箭头为三角形

el-input-number 属性 controls-position 值为 right 时&#xff1b; <el-input-number v-model"num" controls-position"right" :min"1" :max"10"></el-input-number>原生效果 修改后效果 CSS 修改 .el-input-number…

医院订餐平台:为患者提供贴心服务的创新解决方案

在现代医疗服务中&#xff0c;患者的就餐问题一直是一个备受关注的议题。传统的医院饮食服务往往面临着餐品单一、服务不及时等问题&#xff0c;无法满足患者的个性化需求。为了提高患者的就餐体验&#xff0c;医院订餐平台应运而生&#xff0c;通过数字化、个性化的服务&#…

Mac M2安装 Windows

由于需要在 Windows 上使用一些软件&#xff0c;今天在 Mac M2 上安装了 Windows 11。以前在 X86 Mac 上安装很容易&#xff0c;都是 X86 架构随便找个镜像安装上就可以用了。到了 M1/M2 Arm 架构就会麻烦一些&#xff0c;先在网上找到 Windows 10 Arm 架构的安装镜像&#xff…

LVGL9.1移植STM32F103C8T6花屏问题解决

这一次的话算是花了一下午差不多解决了一个问题&#xff0c;具体我是用 stm32f103c8t6(20k RAM, 128k Flash) 移植的LVGL库(屏幕是240x240的st7789, 因为RAM的buf不太够所以缩小了显示面积) 直接切入主题: 如果出现花屏问题&#xff0c; 这个问题出在你自定义编写的lv_set_flu…

搜维尔科技:【煤矿安全仿真】煤矿事故预防处置VR系统,矿山顶板灾害,冲击地压灾害等预防演练!

产品概述 煤矿事故预防处置VR系统 系统内容&#xff1a; 事故预防处置VR系统的内容包括&#xff1a;火灾的预防措施、火灾预兆、防灭火系统、火灾案例重现、顶板事故预兆、顶板事故原因、顶板事故案例重现、瓦斯概念及性质、瓦斯的涌出形式、瓦斯预兆、瓦斯爆炸条件及预防措…

文献速递:深度学习肝脏肿瘤诊断---动态对比增强 MRI 上的自动肝脏肿瘤分割使用 4D 信息:基于 3D 卷积和卷积 LSTM 的深度学习模型

Title 题目 Automatic Liver Tumor Segmentation on Dynamic Contrast Enhanced MRI Using 4D Information: Deep Learning Model Based on 3D Convolution and Convolutional LSTM 动态对比增强 MRI 上的自动肝脏肿瘤分割使用 4D 信息&#xff1a;基于 3D 卷积和卷积 LSTM …

nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)

一、安装nvm 1. 下载nvm 点击 网盘下载 进行下载 2、双击下载好的 nvm-1.1.12-setup.zip 文件 3.双击 nvm-setup.exe 开始安装 4. 选择我接受&#xff0c;然后点击next 5.选择nvm安装路径&#xff0c;路径名称不要有空格&#xff0c;然后点击next 6.node.js安装路径&#…

案例三 BeautifulSoup之链家二手房

本案例用到列表&#xff0c;函数&#xff0c;字符串等知识点&#xff0c;知识点参考链接如下&#xff1a; python基础知识&#xff08;一&#xff09;&输入输出函数 python基础知识&#xff08;二&#xff09;&基本命令 python基础知识&#xff08;三&#xff09;&…

.[[backup@waifu.club]].svh勒索病毒数据怎么处理|数据解密恢复

尊敬的读者&#xff1a; 近年来&#xff0c;随着信息技术的迅猛发展&#xff0c;网络安全问题日益凸显&#xff0c;其中勒索病毒成为了一大威胁。.[[backupwaifu.club]].svh、.[[MyFilewaifu.club]].svh勒索病毒就是其中之一&#xff0c;它以其独特的传播方式和恶劣的加密手段…

嵌入式驱动学习第七周——pinctrl子系统

前言 pinctrl子系统用来控制每个端口的复用功能和电气属性&#xff0c;这篇博客来介绍一下pinctrl子系统。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xff0c;一起讨…

java数据结构与算法刷题-----LeetCode461. 汉明距离

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 异或统计1的个数2. 位移操作处理3. Brian Kernighan算法 位运…

构建强大的物联网平台系统架构:关键步骤与最佳实践

随着物联网&#xff08;IoT&#xff09;技术的快速发展和广泛应用&#xff0c;越来越多的企业开始意识到搭建一个强大而可靠的物联网平台系统架构的重要性。一个完善的物联网平台可以帮助企业高效地管理和监控各种连接设备&#xff0c;并实现数据的收集、处理和分析。在本文中&…

个人劳保用品穿戴检测系统 安全帽、工服、面罩、防护手套、防护鞋、安全背带穿戴检测等

背景 在工业生产、医疗护理、消防救援等高风险领域&#xff0c;正确穿戴个人防护装备或劳保用品&#xff08;PPE&#xff1a;Personal Protective Equipment&#xff09;是保障人员安全的重要措施&#xff0c;如安全帽、反光衣、安全背带等。然而&#xff0c;现实中往往会出现…

数据结构之排序了如指掌(一)

目录 题外话 正题 排序概念 稳定性 直接插入排序 直接插入排序代码详解 直接插入排序复杂度分析 希尔排序(缩小增量排序) 希尔排序代码详解 小结 题外话 昨晚肚子疼没睡好,今天博客写的确实有点晚(找个借口),我一定会坚持,不辜负热爱我的家人们!! 正题 排序概念 一串…