ZYNQ 7020 之 FPGA知识点重塑笔记一——串口通信

目录

一:串口通信简介

二:三种常见的数据通信方式—RS232串口通信

2.1 实验任务

2.2 串口接收模块的设计

2.2.1 代码设计

2.3 串口发送模块的设计

2.3.1 代码设计

2.4 顶层模块编写

2.4.1 代码设计

2.4.2 仿真验证代码

2.4.3 仿真结果

2.4.4 板上验证

一:串口通信简介

       通信方式一般分为串行通信并行通信并行通信是指多比特数据同时通过并行线进行传送。这种传输方式通信线多、成本高,故不宜进行远距离通信,通常传输距离小于 30 米。串行通信是指数据在一条数据线上,一比特接一比特地按顺序传送的方式。这种运输方式通常节省传输线,大大降低使用成本,但数据传送速度慢。综上可知,串行通信主要应用于长距离、低速率的通信场合。本次实验我们主要讲解下串行通信。

       串行通信一般有 2 种通信方式: 同步串行通信 异步串行通信 同步串行通信需要通信双方在同一时钟的控制下同步传输数据; 异步串行通信是指具有不规则数据段传送特性的串行数据传输。在常见的通信总线协议中,I2C,SPI 属于同步通信而 UART 属于异步通信。同步通信的通信双方必须先建立同步,即双方的时钟要调整到同一个频率,收发双方不停地发送和接收连续的同步比特流。异步通信在发送字符时,发送端可以在任意时刻开始发送字符,所以,在 UART 通信中,数据起始位和停止位是必不可少的。
       UART 串口通信需要两根信号线来实现,一根用于串口发送,另外一根负责串口接收,如下图所示。对于 PC 来说它的 TX 要和对于 FPGA 来说的 RX 连接,同样 PC RX 要和 FPGA TX 连接,如果是两个TX 或者两个 RX 连接那数据就不能正常被发送出去或者接收到。
          
UART 在发送或接收过程中的一帧数据由 4 部分组成,起始位、数据位、奇偶校验位和停止位,如下图所示。
           
起始位:当不传输数据时,UART 数据传输线通常保持高电平。若要开始数据传输,发送 UART 会将传输线从高电平拉到低电平并保持 1 个波特率周期。当接收 UART 检测到高到低电压跃迁时,便开始以波特率对应的频率读取数据帧中的位。
数据帧: 数据帧包含所传输的实际数据。如果使用奇偶校验位,数据帧长度可以是 5 位到 8 位。如果不使用奇偶校验位,数据帧长度可以是 9 位。在很多情况下,数据以最低有效位优先发送。
奇偶校验:奇偶性描述数字是偶数还是奇数。通过奇偶校验位,接收 UART 判断传输期间是否有数据发生改变。
停止位 为了表示数据包结束,发送 UART 将数据传输线从低电压驱动到高电压并保持 1 2 位时间。
波特率:即每秒传输的位数 (bit) 。一般选波特率都会有 9600 19200 115200等选项。其实意思就是每秒传输这么多个比特位数(bit)

二:三种常见的数据通信方式—RS232串口通信

rs232通信: RS-232 是单端输入输出,
RS-232 标准的串口最常见的接口类型为 DB9 ,样式如图 27.1.3 所示,工业控制领域中用到的工控机 一般都配备多个串口,很多老式台式机也都配有串口。但是笔记本电脑以及较新一点的台式机都没有串 口,它们一般通过 USB 转串口线(下图所示 )来实现与外部设备的串口通信。
         
DB9 接口定义以及各引脚功能说明如下图所示,我们一般只用到其中的 2 RXD )、 3 TXD )、 5 (GND)引脚,其他引脚在普通串口模式下一般不使用,如果大家想了解,可以自行百度下。
       

2.1 实验任务

      本节实验任务是上位机通过串口调试助手发送数据给zynq开发板,zynq开发板 PL 端通过 USB     
_UART 串口接收数据并将接收到的数据发送给上位机,完成串口数据环回实验。主要模块如下表所示:

2.2 串口接收模块的设计

      首先完成串口接收模块的设计,串口接收模块我们的输入信号主要有系统时钟信号、系统复位信号与串口接收端口。当我们将一帧的数据接收完成后,那么要告诉下级模块已经将一帧数据接收完了,所以输出为接收完成标志和串口接收数据信号。 模块接口框图如下所示:
                   
串口接收模块端口与功能描述如下表所示:
绘制波形图:
在绘制波形图之前,我们首先要确定串口通信的数据格式及波特率。在这里我们选择串口比较常用的 一种模式,数据位为 8 位,停止位为 1 位,无校验位,波特率为 115200bps 。则传输一帧数据的时序图如下图所示:

2.2.1 代码设计

//串转并
module zdyz_rs232_rx(
    input sys_clk , //系统时钟
    input sys_rst_n , //系统复位,低有效
    
    input uart_rxd , //UART 接收端口
    output reg uart_rx_done, //UART 接收完成信号
    output reg [7:0] uart_rx_data //UART 接收到的数据
);

parameter CLK_FREQ = 5000_0000; //系统时钟频率
parameter UART_BPS = 115200 ; //串口波特率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数 BPS_CNT 次

reg uart_rxd_d0;
reg uart_rxd_d1;//定义两个D触发器进行异步打拍处理
reg rx_flag ; //接收过程标志信号
reg [3:0] rx_cnt ; //接收数据位计数器    
reg [15:0] baud_cnt ; //波特率计数器(位宽为16,防止溢出)
reg [7:0 ] rx_data_t ; //接收数据寄存器

wire start_flag;//开始接收的标志,下降沿到来。
    
//打两拍:波特率时钟和系统时钟不同步,为异步信号,所以要进行打拍处理,防止产生亚稳态  
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) begin
        uart_rxd_d0 <= 1'b0;
        uart_rxd_d1 <= 1'b0;
    end
    else begin
        uart_rxd_d0 <= uart_rxd;
        uart_rxd_d1 <= uart_rxd_d0;
    end
end  
    
assign start_flag = (uart_rxd_d0 == 0)&&(uart_rxd_d1 == 1);//下降沿到来的表示方法
// rx_flag接收信号的拉高与拉低   
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        rx_flag <= 1'b0;
    else if(start_flag) //检测到起始位
        rx_flag <= 1'b1; //接收过程中,标志信号 rx_flag 拉高
    //在停止位一半的时候,即接收过程结束,标志信号 rx_flag 拉低
    else if((rx_cnt == 4'd9) && (baud_cnt == BAUD_CNT_MAX/2 - 1))//rx_flag 要提前拉低,防止其影响下一帧数据的接收
        rx_flag <= 1'b0;
    else
        rx_flag <= rx_flag;
    end 
//波特率的计数器计数逻辑 
always @(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n) 
        baud_cnt <= 0;      
    else if(rx_flag)begin
        if(baud_cnt == BAUD_CNT_MAX - 1)
            baud_cnt <= 0;
        else
            baud_cnt <= baud_cnt + 1;       
    end
    else
        baud_cnt <= 0;
end 
//位计数实现逻辑
always @(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n)
        rx_cnt <= 0;   
    else if(rx_flag)begin
        if(baud_cnt == BAUD_CNT_MAX - 1)
            rx_cnt <= rx_cnt + 1;        
        else
            rx_cnt <= rx_cnt;
    end
    else
        rx_cnt <= 0;//其他情况下都为0,所以不用担心计数超过9,且其计数也不会超过9,当rx_flag为0时就不计数了
end
//根据 rx_cnt 来寄存 rxd 端口的数据
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        rx_data_t <= 0;    
    else if(rx_flag)begin   //系统处于接收过程时
        if(baud_cnt == BAUD_CNT_MAX/2 - 1)begin//判断 baud_cnt 是否计数到数据位的中间 
            case(rx_cnt)
                1:rx_data_t[0] <= uart_rxd_d1; //寄存数据的最低位
                2:rx_data_t[1] <= uart_rxd_d1;
                3:rx_data_t[2] <= uart_rxd_d1;
                4:rx_data_t[3] <= uart_rxd_d1;
                5:rx_data_t[4] <= uart_rxd_d1;
                6:rx_data_t[5] <= uart_rxd_d1;
                7:rx_data_t[6] <= uart_rxd_d1;
                8:rx_data_t[7] <= uart_rxd_d1;//寄存数据的高低位
                default:rx_data_t <= rx_data_t; 
            endcase
        end
        else 
            rx_data_t <= rx_data_t;
    end
    else
        rx_data_t <= 0; 
end
//给接收完成信号和接收到的数据赋值    
always @(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n)begin    
        uart_rx_done <= 0;   
        uart_rx_data <= 0;
    end
    //当接收数据计数器计数到停止位,且 baud_cnt 计数到停止位的中间时
    else if((rx_cnt == 4'd9) && (baud_cnt == BAUD_CNT_MAX/2 - 1))begin
        uart_rx_done <= 1; //拉高接收完成信号
        uart_rx_data <= rx_data_t;//并对 UART 接收到的数据进行赋值
    end    
    else begin
        uart_rx_done <= 0; 
        uart_rx_data <= uart_rx_data;     
    end
end    
endmodule

2.3 串口发送模块的设计

串口发送模块我们的输入信号主要有系统时钟信号、系统复位信号以及发送使能信号和待发送数据, 输出信号主要有发送忙状态标志和串口发送端口。模块接口框图如下所示:
串口发送模块端口与功能描述如下表所示:

2.3.1 代码设计

module zdyz_rs232_tx(
   input sys_clk , //系统时钟
   input sys_rst_n , //系统复位,低有效
   input uart_tx_en , //UART 的发送使能(发送是有标志起始时间的,接收是根据下降沿到来就开始进入起始位)
   input [7:0] uart_tx_data, //UART 要发送的数据
   output reg uart_txd , //UART 发送端口 
   output reg uart_tx_busy //发送忙状态信号 
);
   
   //parameter define
   parameter CLK_FREQ = 50000000; //系统时钟频率
   parameter UART_BPS = 115200 ; //串口波特率
   localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数 BPS_CNT 次    
    
   reg [7:0] tx_data_t; //发送数据寄存器 
   reg [3:0] tx_cnt ; //发送数据位计数器 
   reg [15:0] baud_cnt ; //波特率计数器 
   
 //当 uart_tx_en 为高时,寄存输入的并行数据(防止发生变化影响发送),并拉高 BUSY 信号  
always @(posedge sys_clk or negedge sys_rst_n) begin   
    if(!sys_rst_n)begin  
        tx_data_t <= 0;   
        uart_tx_busy <= 0;            
    end
    else if(uart_tx_en)begin
        tx_data_t <= uart_tx_data;   
        uart_tx_busy <= 1;
    end
    /*为了确保环回实验的成功,在程序的 36 行我们将 uart_tx_busy 提前 1/16 个停止位拉低。尽管串口发送数据只是接收数据的反过程,
    理论上在传输的时间上是一致的,但是考虑到我们模块里计算波特率会有较小的偏差,并且串口对端的通信设备(如电脑等)收发数据的波特率
    同样可能会出现较小的偏差,因此为了确保环回实验的成功,这里将发送模块的停止位略微提前结束。需要说明的是,较小偏差的波特率在
    串口通信时是允许的,同样可以保证数据可靠稳定的传输*/
else if((tx_cnt == 4'd9) && (baud_cnt == BAUD_CNT_MAX - BAUD_CNT_MAX/16))begin
        uart_tx_busy <= 0; 
        tx_data_t <= 0;
    end
else begin
        uart_tx_busy <= uart_tx_busy; 
        tx_data_t <= tx_data_t;    
    end         
end 

//波特率的计数器计数逻辑
always @(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n) 
        baud_cnt <= 0;      
    else if(uart_tx_busy)begin //当处于发送过程时,波特率计数器(baud_cnt)进行循环计数
        if(baud_cnt == BAUD_CNT_MAX - 1)
            baud_cnt <= 0; //计数达到一个波特率周期后清零
        else
            baud_cnt <= baud_cnt + 1;       
    end
    else
        baud_cnt <= 0;//发送过程结束时计数器清零
end
//位计数实现逻辑
always @(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n)
        tx_cnt <= 0;   
    else if(uart_tx_busy)begin//处于发送过程时 tx_cnt 才进行计数
        if(baud_cnt == BAUD_CNT_MAX - 1)//当波特率计数器计数到一个波特率周期时
            tx_cnt <= tx_cnt + 1;   //发送数据计数器加 1     
        else
            tx_cnt <= tx_cnt;
    end
    else
        tx_cnt <= 0;//其他情况下都为0,所以不用担心计数超过9,且其计数也不会超过9,当rx_flag为0时就不计数了
end

//根据 tx_cnt 来给 uart 发送端口赋值
always @(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n)
        uart_txd <= 1 ;//空闲态为1
    else if(uart_tx_busy)begin
        case(tx_cnt)
            4'd0 : uart_txd <= 1'b0 ; //起始位
            4'd1 : uart_txd <= tx_data_t[0]; //数据位最低位
            4'd2 : uart_txd <= tx_data_t[1];
            4'd3 : uart_txd <= tx_data_t[2];
            4'd4 : uart_txd <= tx_data_t[3];
            4'd5 : uart_txd <= tx_data_t[4];
            4'd6 : uart_txd <= tx_data_t[5];
            4'd7 : uart_txd <= tx_data_t[6];
            4'd8 : uart_txd <= tx_data_t[7]; //数据位最高位
            4'd9 : uart_txd <= 1'b1 ; //停止位            
            default:uart_txd <= 1'b1 ;
        endcase
    end
    else
        uart_txd <= 1 ; //空闲时发送端口为高电平
end 
endmodule 

2.4 顶层模块编写

       在顶层模块中完成了对其余各个子模块的例化。本次实验我们需要设置 2 个参数变量,分别是系统时钟频率 CLK_FREQ 与串口波特率 UART_BPS ,大家使用时可以根据不同的系统时钟频率以及所需要的串口波特率设置这两个变量。zynq7020开发板上的系统时钟为 50MHz ,所以这里将 CLK_FREQ 参数设为50000000。在前文我们说过本次实验的波特率设为 115200 ,所以这里的参数 UART_BPS 就设为 115200 。我们可以尝试将串口波特率 UART_BPS 设置为其他值(如 9600 ),在模块例化时会将这个变量传递到串口接收与发送模块中,从而实现不同速率的串口通信。

2.4.1 代码设计


module top_uart(
    input sys_clk , //外部 50MHz 时钟
    input sys_rst_n, //系外部复位信号,低有效
    
    //UART 端口 
    input uart_rxd , //UART 接收端口(串行数据)
    output uart_txd //UART 发送端口
    );
    
    parameter CLK_FREQ = 50000000; //定义系统时钟频率
    parameter UART_BPS = 115200 ; //定义串口波特率
   
    //wire define
    wire uart_rx_done; //UART 接收完成信号
    wire [7:0] uart_rx_data; //UART 接收数据(并行数据)
    wire uart_tx_busy;
 //*****************************************************
 //**                      main code
 //***************************************************** 
 //串口接收
   zdyz_rs232_rx #(
       .CLK_FREQ (CLK_FREQ),
       .UART_BPS (UART_BPS)
   )zdyz_rs232_rx(
    .sys_clk(sys_clk) , //系统时钟
    .sys_rst_n(sys_rst_n) , //系统复位,低有效
    
    .uart_rxd(uart_rxd) , //UART 接收端口
    .uart_rx_done(uart_rx_done), //UART 接收完成信号
    .uart_rx_data(uart_rx_data)//UART 接收到的数据
); 
    
   zdyz_rs232_tx #(
       .CLK_FREQ (CLK_FREQ),
       .UART_BPS (UART_BPS)
   )zdyz_rs232_tx(
   .sys_clk(sys_clk) , //系统时钟
   .sys_rst_n(sys_rst_n) , //系统复位,低有效
   .uart_tx_en(uart_rx_done) , //UART 的发送使能
   .uart_tx_data(uart_rx_data), //UART 要发送的数据
   .uart_txd(uart_txd) , //UART 发送端口 
   .uart_tx_busy(uart_tx_busy) //发送忙状态信号 
); 
    
endmodule

2.4.2 仿真验证代码

 `timescale 1ns/1ns //仿真的单位/仿真的精度
 
 module tb_uart_loopback();
 
//parameter define
parameter CLK_PERIOD = 20;//时钟周期为 20ns

//reg define
 reg sys_clk ; //时钟信号
 reg sys_rst_n; //复位信号
 reg uart_rxd ; //UART 接收端口

 //wire define
 wire uart_txd ; //UART 发送端口

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

 //发送 8'h55 8'b0101_0101
 initial begin
 sys_clk <= 1'b0;
 sys_rst_n <= 1'b0;
 uart_rxd <= 1'b1;
 #200
 sys_rst_n <= 1'b1; 
 #1000
 uart_rxd <= 1'b0; //起始位
 #8680

 uart_rxd <= 1'b1; //D0
 #8680
 uart_rxd <= 1'b0; //D1
 #8680
 uart_rxd <= 1'b1; //D2
 #8680
 uart_rxd <= 1'b0; //D3
 #8680
 uart_rxd <= 1'b1; //D4
 #8680
 uart_rxd <= 1'b0; //D5
 #8680
 uart_rxd <= 1'b1; //D6
 #8680
 uart_rxd <= 1'b0; //D7 
 #8680
 uart_rxd <= 1'b1; //停止位
 #8680
 uart_rxd <= 1'b1; //空闲状态 
 end

 //50Mhz 的时钟,周期则为 1/50Mhz=20ns,所以每 10ns,电平取反一次
 always #(CLK_PERIOD/2) sys_clk = ~sys_clk;

 //例化顶层模块
 top_uart top_uart(
     .sys_clk (sys_clk ),
     .sys_rst_n (sys_rst_n),
     .uart_rxd (uart_rxd ),
     .uart_txd (uart_txd )
 );

 endmodule

2.4.3 仿真结果

2.4.4 板上验证

        上述程序已经经过板上验证了,代码正确,注意若发送和接受都选择了16进制的话,那么就输入0~F,如果不选择16进制的话,就可以任意输入阿拉伯数字和26个字母。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

门控循环单元(GRU)-多输入回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、全部代码数据分享&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译…

HR-net学习与实现

这里会用到预训练模型所以先了解一下预训练是什么以及它的作用是什么&#xff0c;详细内容可以参考教程 1.预训练是什么 深入理解&#xff1a;什么是预训练&#xff1f;预训练有什么作用&#xff1f;预训练和训练的本质区别&#xff1f;&#xff1f;&#xff1f;-CSDN博客 预…

机器学习、人工智能、深度学习的关系

人工智能(Artificial Intelligence&#xff0c;AI) 人工智能范围很广&#xff0c;它是一门新的科学与工程&#xff0c;是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的技术科学&#xff0c;研究内容涵盖语音识别、图像识别、自然语言处理、智能搜索和…

【node-express】在commonjs的项目中使用esm和ts开发的sdk

在commonjs的项目中使用esm和ts开发的sdk 效果实现步骤 效果 在一些demo中, 大部分代码是commonjs规范开发的&#xff0c;但是要用到的sdk是ts开发的并且仅支持esm&#xff0c; 又不想配置很复杂的工程项目&#xff0c;可以这么做。如果你有更好的建议&#xff0c;希望能得到你…

系统账号注册

登录/注册地址&#xff1a;https://id.sf.163.com/login?hshufanqz&tshufanqz&localezh_CN&referrerhttps%3A%2F%2Fcommunity.codewave.163.com%2Frest%2Fcommunity%2Flogin注册成功并登录后&#xff0c;即可进入设计器中。低代码开发者可在设计器中按需要搭建一个…

List集合格式转换

最近遇到一个任务&#xff1a; 需要把A集合数据转成 B集合的形式&#xff1a; A集合&#xff1a; B集合&#xff1a; 代码&#xff1a; package com.example.juc.test;import com.example.juc.entity.Ld; import com.example.juc.entity.Student;import java.lang.reflect.F…

Vue-Vben-Admin:打造高效中大型项目后台解决方案

Vue-Vben-Admin&#xff1a;打造高效中大型项目后台解决方案 摘要&#xff1a; Vue-Vben-Admin是一个基于Vue3.0、Vite、Ant-Design-Vue和TypeScript的开源项目&#xff0c;旨在为开发中大型项目提供一站式的解决方案。它涵盖了组件封装、实用工具、钩子函数、动态菜单、权限验…

conda环境下face_alignment.LandmarksType._2D AttributeError: _2D解决方法

1 问题描述 运行retalking模型时&#xff0c;代码抛出异常&#xff0c;信息如下所示&#xff1a; Traceback (most recent call last):File "D:/ml/video-retalking/inference.py", line 345, in <module>main()File "D:/ml/video-retalking/inference.…

【Vue2+3入门到实战】(18)VUE之Vuex状态管理器概述、VueX的安装、核心概念 State状态代码实现 详细讲解

目录 一、[Vuex](https://vuex.vuejs.org/zh/) 概述1.是什么2.使用场景3.优势4.注意&#xff1a; 二、需求: 多组件共享数据1.创建项目2.创建三个组件, 目录如下3.源代码如下 三、vuex 的使用 - 创建仓库1.安装 vuex2.新建 store/index.js 专门存放 vuex3.创建仓库 store/index…

nginx原理和配置项详解

一、nginx原理 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个IMAP/POP3/SMTP代理服务器。其工作原理和配置项如下&#xff1a; 工作原理&#xff1a; 反向代理&#xff1a;Nginx可以作为反向代理服务器&#xff0c;接收客户端的请求&#xff0c;然后将请求转…

46、激活函数 - Relu 激活

本节介绍一个在神经网络中非常常见的激活函数 - Relu 激活函数。 什么是ReLU激活函数 ReLU 英文名为 Rectified Linear Unit,又称修正线性单元,是一种简单但很有效的激活函数,它的定义如下: 即当输入 x 大于零时,输出等于他自己;当输入小于等于零时,输出为零,下面是re…

ArkTS - 组件生命周期

一、先说下自定义组件 在arkTs中&#xff0c;自定义组件分为两种&#xff08;我的总结&#xff09;&#xff1a; 一种是&#xff1a;根组件&#xff0c;就是被装饰器Entry装饰的入口组件&#xff0c;这也是自定义组件(父组件)。 另一种是&#xff1a;没有被Entry装饰的自定义…

基于Docker的软件环境部署脚本,持续更新~

使用时CtrlF搜索你想要的环境&#xff0c;如果没有你想要的环境&#xff0c;可以评论留言&#xff0c;会尽力补充。 本文提供的部署脚本默认参数仅适合开发测试&#xff0c;请根据实际情况调节参数。 数据库 MySQL version: 3.9 services:mysql:image: mysql:8.0.35container…

25、商城系统(七):商城项目基础功能pom.xml(重要),mybatis分页插件

截止这一章,我们就不把重心放在前端,后台的基础代码,因为后面都是业务层面的crud。 前端直接替换这两个文件夹即可,后台代码也直接复制: 一、重新更新一下所有的pom.xml 这个地方我踩了好多坑,最后得到一个完整的pom.xml,建议大家直接用我的pom.xml替换即可。 1.comm…

磁盘和文件系统管理

一&#xff1a;磁盘结构&#xff1a; 1.磁盘基础&#xff1a; 扇区固定大小&#xff0c;每个扇区4k。磁盘会进行磨损&#xff0c;损失生命周期。 设备文件&#xff1a; 一切皆文件 设备文件&#xff1a;关联至一个设备驱动程序&#xff0c;进而能够跟与之对应硬件设备进行通…

【深度解析C++之运算符重载】

系列文章目录 &#x1f308;座右铭&#x1f308;&#xff1a;人的一生这么长、你凭什么用短短的几年去衡量自己的一生&#xff01; &#x1f495;个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️&#xff1a;【深度解析C之this…

Linux网络编程学习心得.4

1.epoll工作模式 水平触发 LT 边沿触发 ET 因为设置为水平触发,只要缓存区有数据epoll_wait就会被触发,epoll_wait是一个系统调用,尽量少调用 所以尽量使用边沿触发,边沿出触发数据来一次只触发一次,这个时候要求一次性将数据读完,所以while循环读,读到最后read默认带阻塞…

HarmonyOS应用程序包快速修复

快速修复概述 快速修复是HarmonyOS系统提供给开发者的一种技术手段&#xff0c;支持开发者以远快于应用升级的方式对应用程序包进行缺陷修复。和全量应用升级软件版本相比&#xff0c;快速修复的主要优势在小、快和用户体验好。在较短的时间内不中断正在运行的应用的情况下&am…

【数据结构】第2章线性表(头歌习题)【合集】

文章目录 第1关&#xff1a;实现顺序表各种基本运算的算法任务描述编程要求完整代码 第2关&#xff1a;实现单链表各种基本运算的算法任务描述编程要求完整代码 第3关&#xff1a;移除顺序表中所有值等于x的元素任务描述编程要求完整代码 第4关&#xff1a;逆置顺序表任务描述编…

windows go环境安装 swag

windows 下载依赖包 go get github.com/swaggo/swag/cmd/swag编译swag cd $GOPATH\pkg\mod\github.com\swaggo\swagv1.16.2\cmd\swagps: go env 获取 GOPATH位置 go installps: 此时 $GOPATH\bin下出现了 swag.exe 项目根目录下执行swag 初始化 swag init生成结果