基于FPGA的SD NAND图片显示实现

news2024/11/20 6:33:49

文章目录

0、前言

1、目标

2、图片的预处理

3、SD NAND的预处理

4、FPGA实现

4.1、详细设计

4.2、仿真

4.3、实验结果


0、前言

        在上一篇文章《基于FPGA的SD卡的数据读写实现(SD NAND FLASH)》中,我们了解到了SD NAND Flash的相关知识,并在FPGA平台上实现了对SD NAND的读写测试。SD NAND的读写测试可能会有点简单和枯燥,所以本文我们来搞点有乐趣性的----将存储在SD NAND内的两张图片通过FPGA读取,并通过VGA的方式在显示器上轮回显示。


1、目标

        使用 SD NAND数据读写控制器读取事先存储在 SD NAND的图片数据,将读取的图片数据通过SDRAM 数据读写控制器暂存在 SDRAM 芯片中,通过 VGA 显示器将暂存在 SDRAM 的图片显示出来。 SD 卡内存储两张图片,其交替显示在 VGA 显示器上,分辨率为 640*480。

        SD NAND在SD2.0版本协议下,SPI模式的理论最大传输速率为50Mbps,加上命令号以及等待返回响应信号的时间,实际上的传输速率还会下降。对于采用分辨率为640*480@60Hz 的显示器来说,一幅图像的数据量达到640*480*16bit = 4915200bit = 4800Kbit(1Kbit=1024bit), 每秒钟刷新60次,那么每秒钟需要传输的数据量达到4800Kbit*60 = 288000Kbit =281.25Mbit (1Mbit=1024Kbit)。由此可以看出,SD卡的读写速度完全跟不上VGA的数据发送速度,因此必须先缓存一幅图像到内部或外部存储器,再通过VGA接口显示。FPGA的片内存储资源较少,对于缓存如此大量的数据,只能使用SDRAM或DDR3缓存数据。


2、图片的预处理

        首先选取要显示的图片两张,使用 Window 系统自带的画图工具对图片进行处理,将图片处理为分辨率 640*480。

        VGA的显示格式为16位RGB565格式,为了使SD NAND读出的数据可以直接在VGA上显示,需要将图片通过 “ IMG2LCD ” 上位机软件转成16位的RGB565格式的bin文件,再将bin文件导入SD NAND中。

        使用 “ IMG2LCD ” 上位机软件打开两张图片,按如下设置相关参数,然后点击保存,就生成了两个图片的二进制文件(像素值)。


3、SD NAND的预处理

        SD NAND在经过多次存放数据与删除数据之后,存入的文件有可能不是按照连续的扇区地址存储的,为了避免图片显示错误,我们将bin文件导入SD NAND之前,需要对SD NAND进行一个格式化处理。

        首先得找个读卡器,再把所用到的SD NAND开发板插到读卡器上边,通过USB接口与PC建立链接。

        

        本次实验我依然选用的是深圳雷龙公司的一款SD NAND产品----CSNP32GCR01-AOW。 可以看到这款SD NAND开发板设计得很巧妙,把对外接口设计成了通用的micro接口,兼容性非常强,不管是插读卡器还是直接插FPGA开发板,都是即插即用,十分方便。

      

        接着说回来对SD NAND的初始化处理。插上读卡器后,选择对应的磁盘,点击“格式化”,并点击“开始”

        格式化完成后,将前面生成的两张图片对应的bin文件存入对应的SD NAND磁盘中:

        SD NAND内部的存储资源是以扇区的形式进行划分的,为了将图片的bin数据从SD NAND中读取出来,我们需要找到图片存储对应的扇区地址。扇区地址可以用“WinHex 软件”来查看。

        以管理员身份运行软件 WinHex 软件,点击“工具 ”,然后点击“打开磁盘”:

        双击打开对应的SD NAND,记录下两个 bin文件的第一扇区地址:

       

        此时查询到的扇区地址就是bin文件存放的起始扇区地址,我们只需要按照这个起始扇区地址,按顺序读出SD NAND中的数据即可,直到读完一张图片中的所有数据。SD NAND中一个扇区存放512个字节,也就是256个16位数据,对于分辨率为640*480的图片来说,共需要读出1200(640*480/256)个扇区数据。


4、FPGA实现

        先说下总体思路:

  • SD NAND中存有两幅图片,一副为雷龙公司的官网截图,另一幅则是本博客的头像
  • FPGA从SD NAND中读取这两幅图片的像素信息,并缓存到SDRAM中
  • 将SDRAM中的数据(两幅图片的像素信息)通过VGA接口显示在显示器上 

        根据这个思路,可以对应的画对应的系统框图:

        

        FPGA顶层模块例化了以下五个模块:PLL时钟模块、SD NAND读取图片控制模块、SD NAND控制器模块、SDRAM控制器模块和VGA驱动模块。 


4.1、详细设计

(1) 顶层模块

        顶层模块:顶层模块主要完成对其余各模块的例化,实现各模块之间的数据交互。需要注意的是,系统初始化完成是在SD NAND以及SDRAM都初始化完成后才开始拉高的,该信号控制着SD NAND读取图片控制模块的复位信号,因此SD NAND读取图片控制模块是在系统初始化完成后才工作的,防止因SD NAND或者SDRAM初始化未完成导致数据错误。

        此部分代码如下:

module top_sd_photo_vga(
    input                 sys_clk     ,  //系统时钟
    input                 sys_rst_n   ,  //系统复位,低电平有效
                          
    //SD NAND接口               
    input                 sd_miso     ,  //SD NANDSPI串行输入数据信号
    output                sd_clk      ,  //SD NANDSPI时钟信号
    output                sd_cs       ,  //SD NANDSPI片选信号
    output                sd_mosi     ,  //SD NANDSPI串行输出数据信号
    //SDRAM接口
    output                sdram_clk   ,  //SDRAM 时钟
    output                sdram_cke   ,  //SDRAM 时钟有效
    output                sdram_cs_n  ,  //SDRAM 片选
    output                sdram_ras_n ,  //SDRAM 行有效
    output                sdram_cas_n ,  //SDRAM 列有效
    output                sdram_we_n  ,  //SDRAM 写有效
    output       [1:0]    sdram_ba    ,  //SDRAM Bank地址
    output       [1:0]    sdram_dqm   ,  //SDRAM 数据掩码
    output       [12:0]   sdram_addr  ,  //SDRAM 地址
    inout        [15:0]   sdram_data  ,  //SDRAM 数据    
    //VGA接口                          
    output                vga_hs      ,  //行同步信号
    output                vga_vs      ,  //场同步信号
    output        [15:0]  vga_rgb        //红绿蓝三原色输出     
    );

//parameter define
parameter  PHOTO_H_PIXEL = 24'd640     ;  //设置SDRAM缓存大小
parameter  PHOTO_V_PIXEL = 24'd480     ;  //设置SDRAM缓存大小

//wire define
wire                  clk_100m        ;  //100mhz时钟,SDRAM操作时钟
wire                  clk_100m_shift  ;  //100mhz时钟,SDRAM相位偏移时钟
wire                  clk_50m         ;
wire                  clk_50m_180deg  ;
wire                  clk_25m         ;
wire                  rst_n           ;
wire                  locked          ;
wire                  sys_init_done   ;  //系统初始化完成
                                      
wire                  sd_rd_start_en  ;  //开始写SD NAND数据信号
wire          [31:0]  sd_rd_sec_addr  ;  //读数据扇区地址    
wire                  sd_rd_busy      ;  //读忙信号
wire                  sd_rd_val_en    ;  //数据读取有效使能信号
wire          [15:0]  sd_rd_val_data  ;  //读数据
wire                  sd_init_done    ;  //SD NAND初始化完成信号

wire                  wr_en           ;  //sdram_ctrl模块写使能
wire   [15:0]         wr_data         ;  //sdram_ctrl模块写数据
wire                  rd_en           ;  //sdram_ctrl模块读使能
wire   [15:0]         rd_data         ;  //sdram_ctrl模块读数据
wire                  sdram_init_done ;  //SDRAM初始化完成

//*****************************************************
//**                    main code
//*****************************************************

assign  rst_n = sys_rst_n & locked;
assign  sys_init_done = sd_init_done & sdram_init_done;  //SD NAND和SDRAM都初始化完成
assign  wr_en = sd_rd_val_en;
assign  wr_data = sd_rd_val_data;

//锁相环
pll_clk u_pll_clk(
    .areset       (1'b0           ),
    .inclk0       (sys_clk        ),
    .c0           (clk_100m       ),
    .c1           (clk_100m_shift ),
    .c2           (clk_50m        ),
    .c3           (clk_50m_180deg ),
    .c4           (clk_25m        ),
    .locked       (locked         )
    );

//读取SD NAND图片
sd_read_photo u_sd_read_photo(
    .clk             	(clk_50m),
    //系统初始化完成之后,再开始从SD NAND中读取图片
    .rst_n           	(rst_n & sys_init_done), 
    .rd_busy         	(sd_rd_busy),
    .rd_start_en     	(sd_rd_start_en),
    .rd_sec_addr     	(sd_rd_sec_addr)
    );     

//SD NAND顶层控制模块
sd_ctrl_top u_sd_ctrl_top(
    .clk_ref           (clk_50m),
    .clk_ref_180deg    (clk_50m_180deg),
    .rst_n             (rst_n),
    //SD NAND接口
    .sd_miso           (sd_miso),
    .sd_clk            (sd_clk),
    .sd_cs             (sd_cs),
    .sd_mosi           (sd_mosi),
    //用户写SD NAND接口
    .wr_start_en       (1'b0),               //不需要写入数据,写入接口赋值为0
    .wr_sec_addr       (32'b0),
    .wr_data           (16'b0),
    .wr_busy           (),
    .wr_req            (),
    //用户读SD NAND接口
    .rd_start_en       (sd_rd_start_en),
    .rd_sec_addr       (sd_rd_sec_addr),
    .rd_busy           (sd_rd_busy),
    .rd_val_en         (sd_rd_val_en),
    .rd_val_data       (sd_rd_val_data),    
    
    .sd_init_done      (sd_init_done)
    );  

//SDRAM 控制器顶层模块,封装成FIFO接口
//SDRAM 控制器地址组成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]}
sdram_top u_sdram_top(
 .ref_clk      (clk_100m),                   //sdram 控制器参考时钟
 .out_clk      (clk_100m_shift),             //用于输出的相位偏移时钟
 .rst_n        (rst_n),                      //系统复位
                                             
  //用户写端口                                   
 .wr_clk       (clk_50m),                    //写端口FIFO: 写时钟
 .wr_en        (wr_en),                      //写端口FIFO: 写使能
 .wr_data      (wr_data),                    //写端口FIFO: 写数据
 .wr_min_addr  (24'd0),                      //写SDRAM的起始地址
 .wr_max_addr  (PHOTO_H_PIXEL*PHOTO_V_PIXEL),//写SDRAM的结束地址
 .wr_len       (10'd512),                    //写SDRAM时的数据突发长度
 .wr_load      (~rst_n),                     //写端口复位: 复位写地址,清空写FIFO
                                             
  //用户读端口                                  
 .rd_clk       (clk_25m),                    //读端口FIFO: 读时钟
 .rd_en        (rd_en),                      //读端口FIFO: 读使能
 .rd_data      (rd_data),                    //读端口FIFO: 读数据
 .rd_min_addr  (24'd0),                      //读SDRAM的起始地址
 .rd_max_addr  (PHOTO_H_PIXEL*PHOTO_V_PIXEL),//读SDRAM的结束地址
 .rd_len       (10'd512),                    //从SDRAM中读数据时的突发长度
 .rd_load      (~rst_n),                     //读端口复位: 复位读地址,清空读FIFO
                                             
 //用户控制端口                                
 .sdram_read_valid  (1'b1),                  //SDRAM 读使能
 .sdram_pingpang_en (1'b0),                  //SDRAM 乒乓操作使能
 .sdram_init_done (sdram_init_done),         //SDRAM 初始化完成标志
                                             
 //SDRAM 芯片接口                                
 .sdram_clk    (sdram_clk),                  //SDRAM 芯片时钟
 .sdram_cke    (sdram_cke),                  //SDRAM 时钟有效
 .sdram_cs_n   (sdram_cs_n),                 //SDRAM 片选
 .sdram_ras_n  (sdram_ras_n),                //SDRAM 行有效
 .sdram_cas_n  (sdram_cas_n),                //SDRAM 列有效
 .sdram_we_n   (sdram_we_n),                 //SDRAM 写有效
 .sdram_ba     (sdram_ba),                   //SDRAM Bank地址
 .sdram_addr   (sdram_addr),                 //SDRAM 行/列地址
 .sdram_data   (sdram_data),                 //SDRAM 数据
 .sdram_dqm    (sdram_dqm)                   //SDRAM 数据掩码
    );

//VGA驱动模块
vga_driver u_vga_driver(
    .vga_clk        (clk_25m),    
    .sys_rst_n      (rst_n),    

    .vga_hs         (vga_hs),       
    .vga_vs         (vga_vs),       
    .vga_rgb        (vga_rgb),      
    
    .pixel_data     (rd_data), 
    .data_req       (rd_en),                 //请求像素点颜色数据输入
    .pixel_xpos     (), 
    .pixel_ypos     ()
    ); 

endmodule

(2) PLL时钟模块

        PLL时钟模块:PLL时钟模块通过调用锁相环(PLL)IP核实现,总共输出五个时钟,频率分别为100Mhz、100Mhz(相位偏移-180度)、50Mhz、50Mhz(相位偏移180度)和25Mhz。 两个100Mhz的时钟用于为SDRAM控制器模块提供驱动时钟;两个50Mhz的时钟用于为SD NAND控制器模块提供驱动时钟;25Mhz用于为VGA驱动模块提供驱动时钟。

(3) SD NAND读取图片控制模块

        SD NAND读取图片控制模块:SD NAND读取图片控制模块通过控制SD NAND控制器的读接口,从SD NAND中读取图像数据,并在读完一张图片后延时一段时间,再去读取另一张图片数据,实现两张图片的循环切换读取。

        此部分代码:


module sd_read_photo(
    input                clk           ,  	//时钟信号
    input                rst_n         ,  	//复位信号,低电平有效
		
    input                rd_busy       ,  	//SD NAND读忙信号
    output  reg          rd_start_en   ,  	//开始写SD NAND数据信号
    output  reg  [31:0]  rd_sec_addr      	//读数据扇区地址
    );

//parameter define                          
parameter PHOTO_SECCTION_ADDR0 = 32'd16640;  //第一张图片扇区起始地址 
parameter PHOTO_SECTION_ADDR1  = 32'd17856; //第二张图片扇区起始地址 
//640*480/256 = 1200
parameter RD_SECTION_NUM  = 11'd1200    ;   //单张图片总共读出的次数  

//reg define
reg    [1:0]          rd_flow_cnt      ;    //读数据流程控制计数器
reg    [10:0]         rd_sec_cnt       ;    //读扇区次数计数器
reg                   rd_addr_sw       ;    //读两张图片切换
reg    [25:0]         delay_cnt        ;    //延时切换图片计数器

reg                   rd_busy_d0       ;    //读忙信号打拍,用来采下降沿
reg                   rd_busy_d1       ;  

//wire define
wire                  neg_rd_busy      ;    //SD NAND读忙信号下降沿

//*****************************************************
//**                    main code
//*****************************************************

assign  neg_rd_busy = rd_busy_d1 & (~rd_busy_d0);

//对rd_busy信号进行延时打拍,用于采rd_busy信号的下降沿
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        rd_busy_d0 <= 1'b0;
        rd_busy_d1 <= 1'b0;
    end
    else begin
        rd_busy_d0 <= rd_busy;
        rd_busy_d1 <= rd_busy_d0;
    end
end

//循环读取SD NAND中的两张图片(读完之后延时1s再读下一个)
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rd_flow_cnt <= 2'd0;
        rd_addr_sw <= 1'b0;
        rd_sec_cnt <= 11'd0;
        rd_start_en <= 1'b0;
        rd_sec_addr <= 32'd0;
    end
    else begin
        rd_start_en <= 1'b0;
        case(rd_flow_cnt)
            2'd0 : begin
                //开始读取SD NAND数据
                rd_flow_cnt <= rd_flow_cnt + 2'd1;
                rd_start_en <= 1'b1;
                rd_addr_sw <= ~rd_addr_sw;                     //读数据地址切换
                if(rd_addr_sw == 1'b0)
                    rd_sec_addr <= PHOTO_SECCTION_ADDR0;
                else
                    rd_sec_addr <= PHOTO_SECTION_ADDR1;    
            end
            2'd1 : begin
                //读忙信号的下降沿代表读完一个扇区,开始读取下一扇区地址数据
                if(neg_rd_busy) begin                          
                    rd_sec_cnt <= rd_sec_cnt + 11'd1;
                    rd_sec_addr <= rd_sec_addr + 32'd1;
                    //单张图片读完
                    if(rd_sec_cnt == RD_SECTION_NUM - 11'b1) begin 
                        rd_sec_cnt <= 11'd0;
                        rd_flow_cnt <= rd_flow_cnt + 2'd1;
                    end    
                    else
                        rd_start_en <= 1'b1;                   
                end                    
            end
            2'd2 : begin
                delay_cnt <= delay_cnt + 26'd1;                //读取完成后延时1秒
                if(delay_cnt == 26'd50_000_000 - 26'd1) begin  //50_000_000*20ns = 1s
                    delay_cnt <= 26'd0;
                    rd_flow_cnt <= 2'd0;
                end 
            end    
            default : ;
        endcase    
    end
end

endmodule

(4)SD NAND控制器模块

        SD NAND控制器模块:SD NAND控制器模块负责驱动SD NAND,该模块将SD NAND的读写操作封装成方便用户使用的接口。关于SD NAND读写控制器模块在上一篇文章中已经详细说明了,可参考: 基于FPGA的SD卡的数据读写实现(SD NAND FLASH)

(5)SDRAM读写控制模块

        SDRAM读写控制模块:SDRAM读写控制器模块负责驱动SDRAM存储器,缓存图像数据。该模块将SDRAM复杂的读写操作封装成类似FIFO的用户接口, 非常方便用户的使用。关于此部分,有详尽的系列文章供参考:相信我,SDRAM真的不难----汇总篇

(6)VGA驱动模块

        VGA驱动模块根据VGA时序参数输出行、场同步信号;同时它还要输出数据请求信号用于读取SDRAM中的图片数据,并将图片通过VGA接口在显示器上显示。关于此部分,有详尽的文章供参考:如何用VGA接口乳法?


4.2、仿真

        一般的测试中,我们都需要先进行仿真来观察时序等测试行为。此次实验由于找不到好的SD NAND的Verilog模型,所以仿真测试略。


4.3、实验结果

        编译工程,把程序下载到FPGA开发板,通过VGA接口连接VGA线到显示器,如下:

       

        接着观察显示器是否会交替显示我们事先保存的两幅图片。实验现象果然与预期一致:

        第1幅图片: 深圳市雷龙发展有限公司

        第2幅图片:本博客图像(星爷yyds) 

        好啦,本次实验就做完啦。

        如果屏幕前的你也有存储产品方面的需求的话,你都可以试试雷龙公司的SD NAND产品哦。

        这是一家专业做存储产品的公司,NAND Flash是其主要产品。 该公司专注NAND Flash设计研发13年,在这一块可以说是相当专业。如果你对NAND Flash仍有疑惑的问题,或者你想在你的设计中使用NAND Flash产品,都可以直接联系:深圳市雷龙发展有限公司

        术业有专攻,闻道有先后,专业的事就交给专业的人处理。顺便说一句,他们的样品都免费哦。如果你有这方面的设计需求都可以直接找他们要样品哦。我就是随便咨询了一下,就直接给我寄了这么多样品让我做前期调研,真的赞。

       

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

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

相关文章

大(json)文件压缩(minify)

文章目录Preface解决方案Preface 现在在做一个 GIS 地图的项目, 做过地图的应该就知道各省/市/县的json文件有多大(大部分都是经纬度数据), 就直接放前台public目录下了. 文件过大, 上传到服务器就占用很多空间, 这时候就有人提出需求, 让把这个问题处理一下. (虽然这个事情没…

mysql日志管理 、备份与恢复

目录 一、数据备份的重要性与分类 1、数据备份的重要性 2、从物理与逻辑的角度&#xff0c;备份分为 3、从数据库的备份策略角度&#xff0c;备份可分为 3.1 完全备份&#xff08;只适合第一次&#xff09; 3.2 差异备份&#xff08;用的较少&#xff0c;有丢失数据的现象…

应用 Serverless 化,让业务开发心无旁骛

我们希望让用户做得更少而收获更多&#xff0c;通过Serverless化&#xff0c;用云就像用电一样简单。”张建锋表示&#xff0c;Serverless 让云计算从一种资源真正变成一种能力&#xff0c;未来云将全面 Serverless 化&#xff0c;更加接近“电网”模式&#xff0c;按计算的调用…

使用Visual Studio Code 进行Python编程

1、下载Visual Studio Code 到微软的Visual Studio Code官方主页下载Visual Studio Code: Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器Visual Studio 开发工具和服务让任何开发人员在任何平台和语言的应用开发都更加轻松。 随时随地免费使用代码编辑器或 I…

web期末网站设计大作业:基于HTML+CSS+JavaScript制作新能源汽车企业网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

负载均衡四层和七层的区别

一. 什么是负载均衡 1&#xff09;负载均衡&#xff08;Load Balance&#xff09;建立在现有网络结构之上&#xff0c;它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。负载均衡有两方面的含义&#…

基于Boost库的在线搜索引擎

文章目录Boost库搜索引擎1. 项目背景2. 宏观原理3. 搜索引擎技术栈和项目环境4.正排索引vs倒排索引&#xff08;index.hpp&#xff09;1. 正排索引:数组vector<>2. 目标文档进行分词(方便倒排索引和查找)3. 倒排索引&#xff1a;unordered_map<>模拟一次查找的过程…

反向传播不香了?解读 Hinton 大佬的 Forward-Forward 算法

今天解读一篇Hinton大佬最近分享的论文。 在最近的NeurIPS2022会议上&#xff0c;图灵奖得主Hinton作为演讲嘉宾&#xff0c;分享了一个题为《The Forward-Forward Algoritm: Some Preliminary Investigations》的论文。 该论文提出了一种取代反向传播的前向-前向传播的训练方…

华为机试 - 比较两个版本号的大小

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 输入两个版本号 version1 和 version2&#xff0c;每个版本号由多个子版本号组成。 子版本号之间由 “.” 隔开&#xff0c;由大小写字母、数字组成&#xff0c;并且至少有一个字符。 按从左到右的顺…

spirng boot 打包,胖fat包和瘦thin包

一、打胖包fat 打胖包采用的是spring的标准来执行&#xff0c;所以使用的是spring boot提供的打包插件 参考来源&#xff1a;打包Spring Boot应用 - 廖雪峰的官方网站 步骤 pom配置 <project ...>...<build><plugins><plugin><groupId>org.s…

Python 奇淫技巧,助你更好的摸鱼

作为一个数据分析者&#xff0c;日常工作几乎离不 python。一路走来&#xff0c;积累了不少有用的技巧和 tips&#xff0c;现在就将这些技巧分享给大家。这些技巧将根据其首字母按 A-Z 的顺序进行展示。 ALL OR ANY Python 之所以成为这么一门受欢迎的语言一个原因是它的可读…

(一)整合管理范围管理

爬虫组件分析目录概述需求&#xff1a;设计思路实现思路分析1.指定项目章程2.项目管理计划3.指导4。管理项目知识4.5.监控项目工作4.6 实施整体变更控制4.7 项目收尾合同5。范围管理收集需求定义范围创建WBS确认范围&#xff1b;控制范围Survive by day and develop by night. …

Redis内存耗尽后会发生什么?

Redis内存耗尽后会发生什么?前言设置有效期过期策略8 种淘汰策略LRU 算法Redis 如何管理热度数据LFU 算法访问频次递增访问频次递减前言 作为一台服务器来说&#xff0c;内存并不是无限的&#xff0c;所以总会存在内存耗尽的情况&#xff0c;那么当 Redis 服务器的内存耗尽后…

什么是Spring的AOP功能?

如果说 IOC 是 Spring 的核心&#xff0c;那么面向切面编程AOP就是 Spring 另外一个最为重要的核心。 AOP的定义 AOP &#xff08;Aspect Orient Programming&#xff09;,直译过来就是 面向切面编程,AOP 是一种编程思想&#xff0c;是面向对象编程&#xff08;OOP&#xff0…

学会这3个小技巧,轻松去图片水印

有些小伙伴在浏览个别平台时&#xff0c;会看到一些心水的图片&#xff0c;就想保存下来&#xff0c;拿来当头像壁纸&#xff0c;或是发朋友圈时用来配图。但是有些图片下载后会发现自带着平台水印&#xff0c;虽然理解它们是为了保护自身权益&#xff0c;但我们并不是进行商用…

【Java实战】大厂都是怎样进行单元测试的

目录 一、前言 二、单元测试 1.【强制】好的单元测试必须遵守 AIR 原则。 2.【强制】单元测试应该是全自动执行的&#xff0c;并且非交互式的。测试用例通常是被定期执行的&#xff0c;执行过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试。不…

微服务的灰度发布就该这样设计

实际生产中如有需求变更&#xff0c;并不会直接更新线上服务&#xff0c;最通常的做法便是&#xff1a;切出线上的小部分流量进行体验测试&#xff0c;经过测试后无问题则全面的上线。 这样做的好处也是非常明显&#xff0c;一旦出现了BUG&#xff0c;能够保证大部分的客户端正…

Hygieia (Devops)开源-搭建步骤(一)

什么是Hygieia Hygieia出现在两个独立的仪表板中-一个用于工程师&#xff0c;另一个用于高管-直观地描绘了CICD管道。本质上&#xff0c;Hygieia本身是一个聚合器&#xff0c;可从团队在其CICD管道中使用的各种DevOps工具中提取数据&#xff0c;从而使其易于在仪表板视图中进行…

Docker搭建私有镜像仓库及推送、拉取私服镜像

1.搭建私有镜像仓库 搭建镜像仓库可以基于Docker官方提供的DockerRegistry来实现。 1.1 简化版镜像仓库 Docker官方的Docker Registry是一个基础版本的Docker镜像仓库&#xff0c;具备仓库管理的完整功能&#xff0c;但是没有图形化界面。 搭建方式比较简单&#xff0c;命令…

【配准:泛锐化】

SIPSA-Net: Shift-Invariant Pan Sharpening with Moving Object Alignment for Satellite Imagery &#xff08;SIPSA-Net&#xff1a;卫星影像平移不变平移锐化与运动目标对齐&#xff09; 全色锐化是合并高分辨率&#xff08;HR&#xff09;全色&#xff08;PAN&#xff0…