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

Tang Prime 20K板OV2640例程

  准备用Tang Prime 20K开发板进行OV2640摄像头采集验证。
在这里插入图片描述

  Tang Primer 20K是由开源硬件厂商SiPEED矽速科技推出,是一款以 GW2A-LV18PG256C8/I7 为主芯片的核心板,准备了 2 个扩展板,Dock 和 Lite。板卡包含有HDMI输出,DVP接口(外接OV2640/OV5640摄像头),5个按键,6个LED灯。另外JTAG下载器已集成在板上,只需一根USB Type-C的线就可以实现下载调试,板卡供电也是依靠这条Type-C的线。板卡相关资料可参考官方网址:https://wiki.sipeed.com/hardware/en/tang/tang-primer-20k/primer-20k.html

1. 运行camera_hdmi例程

(1)程序主要结构框图
在这里插入图片描述

(2)github上的例程是OV5640摄像头,这里修改成OV2640摄像头。主要是I2c寄存器设置发生改变,OV2640的寄存器地址是8bit,按RGB565方式采集。

module sccb_Registers #
(parameter HACT 		= 12'd640 ,parameter VACT 		= 12'd480 ,parameter HTOL  	= 13'd1632,parameter VTOL  	= 13'd1232
)
(input 			clk, input 			rst, input 			advance, output [23:0] 	command, output 			finished
);// Internal signals
reg [23:0] sreg;
reg finished_temp;
reg [9:0] address = 10'd0;// Assign values to outputs
assign command = sreg; 
assign finished = finished_temp;// When register and value is FFFF
// a flag is asserted indicating the configuration is finished
always @ (sreg) beginif(sreg == 24'hFFFFFF) beginfinished_temp <= 1'b1;endelse beginfinished_temp <= 1'b0;end
end// Get value out of the LUT
always @ (posedge clk) beginif(rst == 1'b1) begin           // reset the configurationaddress <= 10'd0;endelse if(advance == 1'b1) begin     // Get the next valueaddress <= address+1'b1;endcase (address) 000     : sreg <= 24'h00FF_01; //选择 sensor相关寄存器组001     : sreg <= 24'h0012_80;002     : sreg <= 24'h00FF_00; //选择 DSP相关寄存器组003     : sreg <= 24'h002C_FF; // 0x2c 保留004     : sreg <= 24'h002E_DF; // VSYNC脉冲宽MSB 8位 默认每个VSYNC 的脉冲为 4 x T_line ,MSB 每增加 一个计数 VSYNC 活动周期增加 256  x T_line005     : sreg <= 24'h00FF_01; //选择 sensor相关寄存器组006     : sreg <= 24'h003C_32; // 0x3c 保留007     : sreg <= 24'h0011_80;/* Set PCLK divider */008     : sreg <= 24'h0009_02;/* Output drive x2 */009     : sreg <= 24'h0004_28;010     : sreg <= 24'h0013_E5; // 曝光的相干设置 条状过滤器选择,手动/自动 增益控制 , 曝光控制011     : sreg <= 24'h0014_48; // 设置 AGC 增益上限012     : sreg <= 24'h0015_00;//Invert VSYNC013     : sreg <= 24'h002c_0c;014     : sreg <= 24'h0033_78;015     : sreg <= 24'h003a_33;016     : sreg <= 24'h003b_fb;017     : sreg <= 24'h003e_00;018     : sreg <= 24'h0043_11;019     : sreg <= 24'h0016_10;020     : sreg <= 24'h0039_02;021     : sreg <= 24'h0035_88;022     : sreg <= 24'h0022_0a;023     : sreg <= 24'h0037_40;024     : sreg <= 24'h0023_00;025     : sreg <= 24'h0034_a0;026     : sreg <= 24'h0006_02;027     : sreg <= 24'h0006_88;028     : sreg <= 24'h0007_c0;029     : sreg <= 24'h000d_b7;030     : sreg <= 24'h000e_01;031     : sreg <= 24'h004c_00;032     : sreg <= 24'h004a_81;033     : sreg <= 24'h0021_99;034     : sreg <= 24'h0024_40;035     : sreg <= 24'h0025_38;036     : sreg <= 24'h0026_82;/* AGC/AEC fast mode operating region */	037     : sreg <= 24'h0048_00;/* Zoom control 2 MSBs */038     : sreg <= 24'h0049_00;/* Zoom control 8 MSBs */039     : sreg <= 24'h005c_00;040     : sreg <= 24'h0063_00;041     : sreg <= 24'h0046_00;042     : sreg <= 24'h0047_00;043     : sreg <= 24'h000C_3A;/* Set banding filter */044     : sreg <= 24'h005D_55;045     : sreg <= 24'h005E_7d;046     : sreg <= 24'h005F_7d;047     : sreg <= 24'h0060_55;048     : sreg <= 24'h0061_70;049     : sreg <= 24'h0062_80;050     : sreg <= 24'h007c_05;051     : sreg <= 24'h0020_80;052     : sreg <= 24'h0028_30;053     : sreg <= 24'h006c_00;054     : sreg <= 24'h006d_80;055     : sreg <= 24'h006e_00;056     : sreg <= 24'h0070_02;057     : sreg <= 24'h0071_94;058     : sreg <= 24'h0073_c1;059     : sreg <= 24'h003d_34;060     : sreg <= 24'h005a_57;061     : sreg <= 24'h004F_bb;062     : sreg <= 24'h0050_9c;063     : sreg <= 24'h00FF_00;064     : sreg <= 24'h00e5_7f;065     : sreg <= 24'h00F9_C0;066     : sreg <= 24'h0041_24;067     : sreg <= 24'h00E0_14;068     : sreg <= 24'h0076_ff;069     : sreg <= 24'h0033_a0;070     : sreg <= 24'h0042_20;071     : sreg <= 24'h0043_18;072     : sreg <= 24'h004c_00;073     : sreg <= 24'h0087_D0;074     : sreg <= 24'h0088_3f;075     : sreg <= 24'h00d7_03;076     : sreg <= 24'h00d9_10;077     : sreg <= 24'h00D3_82;078     : sreg <= 24'h00c8_08;079     : sreg <= 24'h00c9_80;080     : sreg <= 24'h007C_00;081     : sreg <= 24'h007D_00;082     : sreg <= 24'h007C_03;083     : sreg <= 24'h007D_48;084     : sreg <= 24'h007D_48;085     : sreg <= 24'h007C_08;086     : sreg <= 24'h007D_20;087     : sreg <= 24'h007D_10;088     : sreg <= 24'h007D_0e;089     : sreg <= 24'h0090_00;090     : sreg <= 24'h0091_0e;091     : sreg <= 24'h0091_1a;092     : sreg <= 24'h0091_31;093     : sreg <= 24'h0091_5a;094     : sreg <= 24'h0091_69;095     : sreg <= 24'h0091_75;096     : sreg <= 24'h0091_7e;097     : sreg <= 24'h0091_88;098     : sreg <= 24'h0091_8f;099     : sreg <= 24'h0091_96;100     : sreg <= 24'h0091_a3;101     : sreg <= 24'h0091_af;102     : sreg <= 24'h0091_c4;103     : sreg <= 24'h0091_d7;104     : sreg <= 24'h0091_e8;105     : sreg <= 24'h0091_20;106     : sreg <= 24'h0092_00;107     : sreg <= 24'h0093_06;108     : sreg <= 24'h0093_e3;109     : sreg <= 24'h0093_03;110     : sreg <= 24'h0093_03;111     : sreg <= 24'h0093_00;112     : sreg <= 24'h0093_02;113     : sreg <= 24'h0093_00;114     : sreg <= 24'h0093_00;115     : sreg <= 24'h0093_00;116     : sreg <= 24'h0093_00;117     : sreg <= 24'h0093_00;118     : sreg <= 24'h0093_00;119     : sreg <= 24'h0093_00;120     : sreg <= 24'h0096_00;121     : sreg <= 24'h0097_08;122     : sreg <= 24'h0097_19;123     : sreg <= 24'h0097_02;124     : sreg <= 24'h0097_0c;125     : sreg <= 24'h0097_24;126     : sreg <= 24'h0097_30;127     : sreg <= 24'h0097_28;128     : sreg <= 24'h0097_26;129     : sreg <= 24'h0097_02;130     : sreg <= 24'h0097_98;131     : sreg <= 24'h0097_80;132     : sreg <= 24'h0097_00;133     : sreg <= 24'h0097_00;134     : sreg <= 24'h00a4_00;135     : sreg <= 24'h00a8_00;136     : sreg <= 24'h00c5_11;137     : sreg <= 24'h00c6_51;138     : sreg <= 24'h00bf_80;139     : sreg <= 24'h00c7_10;140     : sreg <= 24'h00b6_66;141     : sreg <= 24'h00b8_A5;142     : sreg <= 24'h00b7_64;143     : sreg <= 24'h00b9_7C;144     : sreg <= 24'h00b3_af;145     : sreg <= 24'h00b4_97;146     : sreg <= 24'h00b5_FF;147     : sreg <= 24'h00b0_C5;148     : sreg <= 24'h00b1_94;149     : sreg <= 24'h00b2_0f;150     : sreg <= 24'h00c4_5c;151     : sreg <= 24'h00a6_00;152     : sreg <= 24'h00a7_20;153     : sreg <= 24'h00a7_d8;154     : sreg <= 24'h00a7_1b;155     : sreg <= 24'h00a7_31;156     : sreg <= 24'h00a7_00;157     : sreg <= 24'h00a7_18;158     : sreg <= 24'h00a7_20;159     : sreg <= 24'h00a7_d8;160     : sreg <= 24'h00a7_19;161     : sreg <= 24'h00a7_31;162     : sreg <= 24'h00a7_00;163     : sreg <= 24'h00a7_18;164     : sreg <= 24'h00a7_20;165     : sreg <= 24'h00a7_d8;166     : sreg <= 24'h00a7_19;167     : sreg <= 24'h00a7_31;168     : sreg <= 24'h00a7_00;169     : sreg <= 24'h00a7_18;170     : sreg <= 24'h007f_00;171     : sreg <= 24'h00e5_1f;172     : sreg <= 24'h00e1_77;173     : sreg <= 24'h00dd_7f;174     : sreg <= 24'h00C2_0E;175     : sreg <= 24'h00FF_01; //选择 sensor相关寄存器组176     : sreg <= 24'h00FF_00; //选择 DSP相关寄存器组177     : sreg <= 24'h00E0_04;178     : sreg <= 24'h00DA_08;//08:RGB565  04:RAW10179     : sreg <= 24'h00D7_03;180     : sreg <= 24'h00E1_77;181     : sreg <= 24'h00E0_00;182     : sreg <= 24'h00FF_00; //选择 DSP相关寄存器组183     : sreg <= 24'h0005_01;184     : sreg <= {16'h005A,HACT[9:2]};//(w>>2)&0xFF	//28:w=160 //A0:w=640 //C8:w=800185     : sreg <= {16'h005B,VACT[9:2]};//(h>>2)&0xFF	//1E:h=120 //78:h=480 //96:h=600186     : sreg <= 24'h005C_00;//((h>>8)&0x04)|((w>>10)&0x03)		187     : sreg <= 24'h00FF_01; //选择 sensor相关寄存器组188     : sreg <= 24'h0011_80;//clkrc=0x83 for resolution <= SVGA		189     : sreg <= 24'h00FF_01;190     : sreg <= 24'h0012_40;/* DSP input image resoultion and window size control */191     : sreg <= 24'h0003_0A;/* UXGA=0x0F, SVGA=0x0A, CIF=0x06 */192     : sreg <= 24'h0032_09;/* UXGA=0x36, SVGA/CIF=0x09 */193     : sreg <= 24'h0017_11;/* UXGA=0x11, SVGA/CIF=0x11 */194     : sreg <= 24'h0018_43;/* UXGA=0x75, SVGA/CIF=0x43 */195     : sreg <= 24'h0019_00;/* UXGA=0x01, SVGA/CIF=0x00 */196     : sreg <= 24'h001A_4b;/* UXGA=0x97, SVGA/CIF=0x4b */197     : sreg <= 24'h003d_38;/* UXGA=0x34, SVGA/CIF=0x38 */198     : sreg <= 24'h0035_da;199     : sreg <= 24'h0022_1a;200     : sreg <= 24'h0037_c3;201     : sreg <= 24'h0034_c0;202     : sreg <= 24'h0006_88;203     : sreg <= 24'h000d_87;204     : sreg <= 24'h000e_41;205     : sreg <= 24'h0042_03;206     : sreg <= 24'h00FF_00; //选择 DSP相关寄存器组/* Set DSP input image size and offset. The sensor output image can be scaled with OUTW/OUTH */207     : sreg <= 24'h0005_01;208     : sreg <= 24'h00E0_04;209     : sreg <= 24'h00C0_64;/* Image Horizontal Size 0x51[10:3] */  //11_0010_0000 = 800210     : sreg <= 24'h00C1_4B;/* Image Vertiacl Size 0x52[10:3] */    //10_0101_1000 = 600   211     : sreg <= 24'h008C_00;/* {0x51[11], 0x51[2:0], 0x52[2:0]} */212     : sreg <= 24'h0053_00;/* OFFSET_X[7:0] */213     : sreg <= 24'h0054_00;/* OFFSET_Y[7:0] */214     : sreg <= 16'h0051_C8;/* H_SIZE[7:0]= 0x51/4 */ //200215     : sreg <= 16'h0052_96;/* V_SIZE[7:0]= 0x52/4 */ //150       216     : sreg <= 24'h0055_00;/* V_SIZE[8]/OFFSET_Y[10:8]/H_SIZE[8]/OFFSET_X[10:8] */217     : sreg <= 24'h0057_00;/* H_SIZE[9] */218     : sreg <= 24'h0086_3D;219     : sreg <= 24'h0050_80;/* H_DIVIDER/V_DIVIDER */        220     : sreg <= 24'h00D3_80;/* DVP prescalar */221     : sreg <= 24'h0005_00;222     : sreg <= 24'h00E0_00;223     : sreg <= 24'h00FF_00;224     : sreg <= 24'h0005_00;225     : sreg <= 24'h00FF_00;226     : sreg <= 24'h00E0_04;227     : sreg <= 24'h00E1_77;228     : sreg <= 24'h00E0_00;            default : sreg <= 24'hFFFF_FF;    // End configurationendcase              
end 
endmodule  

(3)实际显示效果如下,整体分辨率为1280x720,摄像头画面大小为640x480,图像是RGB565彩色图。
在这里插入图片描述

2.转灰度图

  通过以下RGB转YC模块,获取亮度信息Y,用Y代替R,G,B分量,就可以得到灰度图。

module rgb_yc444
(input             pix_clk     ,input             rst_n       ,input      [7:0]  r_in        ,input      [7:0]  g_in        ,input      [7:0]  b_in        ,input             hs_i        ,input             vs_i        ,input             din_valid   ,output            dout_valid  ,output            hs_o        ,output            vs_o        ,output reg [23:0] ycbcr444_out  //{Y,Cb,Cr}
);//---------------------------------------------------------
//  =>Ycustom = 0.213R′ + 0.715G′ + 0.072B′
//  =>Cb      = –0.114R′ – 0.384G′ + 0.498B′ + 128
//  =>Cr      = 0.498R′ – 0.452G′ – 0.046B′ + 128
//---------------------------------------------------------wire [15:0] y_r_tmp ;wire [15:0] y_g_tmp ;wire [15:0] y_b_tmp ;wire [15:0] cb_b_tmp;wire [15:0] cb_g_tmp;wire [15:0] cb_r_tmp;wire [15:0] cr_r_tmp;wire [15:0] cr_g_tmp;wire [15:0] cr_b_tmp;reg [15:0]  y_r_reg  = 16'd0;reg [15:0]  y_g_reg  = 16'd0;reg [15:0]  y_b_reg  = 16'd0;reg [15:0]  cb_b_reg = 16'd0;reg [15:0]  cb_g_reg = 16'd0;reg [15:0]  cb_r_reg = 16'd0;reg [15:0]  cr_r_reg = 16'd0;reg [15:0]  cr_g_reg = 16'd0;reg [15:0]  cr_b_reg = 16'd0;wire [8:0]  Y_tmp ;wire [8:0]  Cb_tmp;wire [8:0]  Cr_tmp;reg dout_valid1 = 1'b0;reg dout_valid2 = 1'b0;reg dout_valid3 = 1'b0;reg hs_o_1 = 1'b0;reg hs_o_2 = 1'b0;reg hs_o_3 = 1'b0;reg vs_o_1 = 1'b0;reg vs_o_2 = 1'b0;reg vs_o_3 = 1'b0;  reg  [7:0]Y_node;reg  [7:0]Cb_node;reg  [7:0]Cr_node;//=======================================================assign  y_r_tmp = (r_in<<6) - (r_in<<3) - (r_in<<1);assign  y_g_tmp = (g_in<<8) - (g_in<<6) - (g_in<<3) - g_in;assign  y_b_tmp = (b_in<<4) + (b_in<<1);assign cb_r_tmp = (r_in<<5) - (r_in<<1) - r_in;assign cb_g_tmp = (g_in<<6) + (g_in<<5) + (g_in<<1) ;assign cb_b_tmp = (b_in<<7) - b_in;assign cr_r_tmp = (r_in<<7) - r_in;assign cr_g_tmp = (g_in<<7) -(g_in<<3) -(g_in<<2) -g_in;assign cr_b_tmp = (b_in<<3) +(b_in<<2);always@(posedge pix_clk)beginy_r_reg  <= y_r_tmp ;y_g_reg  <= y_g_tmp ;y_b_reg  <= y_b_tmp ;cb_b_reg <= cb_b_tmp;cb_g_reg <= cb_g_tmp;cb_r_reg <= cb_r_tmp;cr_r_reg <= cr_r_tmp;cr_g_reg <= cr_g_tmp;cr_b_reg <= cr_b_tmp;end//  --------+128为四舍五入操作-----------------------------assign Y_tmp = (y_r_reg +y_g_reg +y_b_reg+8'd128 )>>8;assign Cb_tmp= (cb_b_reg-cb_g_reg-cb_r_reg+8'd128+ 32768)>>8;assign Cr_tmp= (cr_r_reg-cr_g_reg-cr_b_reg+8'd128+ 32768)>>8;//=====================================================
//overflow controlalways@(posedge pix_clk or negedge rst_n)begin if(!rst_n)Y_node<=8'b0;else if(Y_tmp[8]==1'b1)Y_node<=8'hff;elseY_node<=Y_tmp[7:0];endalways@(posedge pix_clk or negedge rst_n)begin if(!rst_n)Cb_node<=8'b0;else if(Cb_tmp[8]==1'b1)Cb_node<=8'hff;elseCb_node<=Cb_tmp[7:0];endalways@(posedge pix_clk or negedge rst_n)beginif(!rst_n)     Cr_node<=8'b0;else if(Cr_tmp[8]==1'b1)Cr_node<=8'hff;elseCr_node<=Cr_tmp[7:0];endalways@(posedge pix_clk or negedge rst_n)beginif(!rst_n) ycbcr444_out<=24'b0;else ycbcr444_out<={Y_node,Cb_node,Cr_node}; end//-----------------------------------------------------  always@(posedge pix_clk)begindout_valid1<=din_valid;dout_valid2<=dout_valid1;dout_valid3<=dout_valid2;endalways@(posedge pix_clk)begin hs_o_1<=hs_i;hs_o_2<=hs_o_1;hs_o_3<=hs_o_2;end always@(posedge pix_clk)begin vs_o_1<=vs_i;vs_o_2<=vs_o_1;vs_o_3<=vs_o_2;endassign dout_valid = dout_valid3;assign hs_o       = hs_o_3;assign vs_o       = vs_o_3;endmodule

在这里插入图片描述

3.转二值图

  利用以下简单sobel算子计算,还可以得到边缘信息的二值图。

module sobel(input wire clk,input wire rst_n,input wire Y_de,input wire Y_hsync,		input wire Y_vsync,input wire [ 7:0] Y_data,output wire sobel_de,output wire sobel_hsync,output wire sobel_vsync,output wire [ 7:0] sobel_data		
);wire de_o;		//matrix_3x3 ----------------------------------------wire  [ 7:0]   matrix_11  ;wire  [ 7:0]   matrix_12  ;wire  [ 7:0]   matrix_13  ;wire  [ 7:0]   matrix_21  ;wire  [ 7:0]   matrix_22  ;wire  [ 7:0]   matrix_23  ;wire  [ 7:0]   matrix_31  ;wire  [ 7:0]   matrix_32  ;wire  [ 7:0]   matrix_33  ;//sobel ------------------作为行列的寄存,最终取值
reg     [ 9:0]              Gx1,Gx3,Gy1,Gy3,Gx,Gy   ;
reg     [10:0]              G                       ;		//阈值
wire    [ 7:0]      value ;  //信号同步 ----------------------------------------------
reg     [ 3:0]              Y_de_r                  ;
reg     [ 3:0]              Y_hsync_r               ;
reg     [ 3:0]              Y_vsync_r               ;shift_matrix3_3 #
(.BITS  (8  ),         .WIDTH (640)     //
)
shift_matrix3_3_inst
(.clk    (clk),  .rst_n  (rst_n  ),.vs_i   (Y_vsync  ), .de_i   (Y_de  ), .din    (Y_data ),    //.vs_o   (       ),  .de_o   (de_o       ), 	.mat_p11(matrix_11), //line1  .mat_p12(matrix_12),  .mat_p13(matrix_13), .mat_p21(matrix_21), //line2  .mat_p22(matrix_22),  .mat_p23(matrix_23), .mat_p31(matrix_31), //line3 .mat_p32(matrix_32),  .mat_p33(matrix_33)		
);//sobel处理
/*-1 0 +1	 							gx =	-2 0 +2 									-1 0 +1	+1 +2 +1gy = 	0  0  0	-1 -2 -1		
*/ 
//延时1个clk		
always @ (negedge rst_n or posedge clk)
begin// Reset whenever the reset signal goes low, regardless of the clockif (!rst_n)beginGx1 <= 10'd0;Gx3 <= 10'd0;Gy1 <= 10'd0;Gy3 <= 10'd0; end// If not resetting, update the register output on the clock's rising edgeelsebeginGx1 <= matrix_11 + (matrix_21 << 1) + matrix_31;    //矩阵相乘,第一列为x1+2x2+x1,Gx3 <= matrix_13 + (matrix_23 << 1) + matrix_33;Gy1 <= matrix_11 + (matrix_12 << 1) + matrix_13;Gy3 <= matrix_31 + (matrix_32 << 1) + matrix_33;end
end//      G = |Gx| + |Gy|
//延时1个clk//取  Gx 、Gy的绝对值
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginGx <= 10'd0;Gy <= 10'd0;endelse begin  //也可判断bit[7]来确定Gx <= (Gx1 > Gx3) ? (Gx1 - Gx3) : (Gx3 - Gx1);Gy <= (Gy1 > Gy3) ? (Gy1 - Gy3) : (Gy3 - Gy1);end 
end //得G
//延时1个clk
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginG <= 10'd0;endelse beginG <= Gx + Gy;end
end//设置判决阈值
assign value = 8'd100;assign sobel_data = (G > value) ? 8'h00 : 8'hFF;// white backgroud, black frontgroud
// assign sobel_data = (G > value) ? 8'hFF : 8'h00;// black backgroud, white frontgroud//==    信号同步
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginY_de_r    <= 4'b0;Y_hsync_r <= 4'b0;Y_vsync_r <= 4'b0;endelse begin  Y_de_r    <= {Y_de_r[2:0],    de_o};//Y_de};Y_hsync_r <= {Y_hsync_r[2:0], Y_hsync};Y_vsync_r <= {Y_vsync_r[2:0], Y_vsync};end
end
assign sobel_de    = Y_de_r[3];
assign sobel_hsync = Y_hsync_r[3];
assign sobel_vsync = Y_vsync_r[3];endmodule

在这里插入图片描述

相关文章:

  • 30套精品论文答辩开题报告PPT模版
  • (八)聚类
  • node js入门,包含express,npm管理
  • 【3.3】Pod详解——容器探针部署第一个pod
  • Python 可迭代的对象、迭代器 和生成器(另一个示例:等差数列生成器)
  • 设计模式 | 组合模式
  • Excel之证件照换底色3
  • Ubuntu无法显示IP地址
  • 【算法设计与分析】(二)什么是递归,以及分治法的基本思想
  • Mac homebrew 安装教程
  • 左神算法之Zigzag方式打印矩阵
  • Redis分布式锁核心原理源码
  • SpringCloud系列(40)--SpringCloud Gateway的Filter的简介及使用
  • 和ai对话:讨论一个简单的理财方案
  • Halcon 常用算子总结
  • 基于 SpringBoot 实现一个 JAVA 代理 HTTP / WS
  • MyBatis实战指南(八)MyBatis日志
  • 热传导方程能量分析与边界条件研究
  • HarmonyOS实战:自定义表情键盘
  • < OS 有关 4 台 Ubuntu VPSs 正在被攻击:nginx 之三> 记录、分析、防护的过程 配置 ufw Fail2Ban 保护网络上的主机