Nios-II编程入门实验
文章目录
- 一 Verilog实现流水灯
- 二 Nios实现流水灯
- 2.1 创建项目
- 2.2 SOPC添加模块
- 2.3 SOPC输入输出连接
- 2.4 Generate
- 2.5 软件部分
- 2.6 运行结果
- 三 Verilog实现串口
- 3.1 代码
- 3.2 引脚
- 3.3 效果
- 四 Nios2实现串口
- 4.1 sopc硬件设计
- 4.2 top文件
- 4.3 软件代码
- 4.4 实现效果
- 五 参考资料
- 六 总结
一. 实验目标:学习 Quartus 、Platform Designer、Nios-II SBT 的基本操作;初步了解 SOPC 的开发流程,基本掌握 Nios-II 软核的定制方法;掌握 Nios-II 软件的开发流程,软件的基本调试方法。
二. 实验过程:
1、完成以下实验:
- 在DE2-115开发板上分别用 Verilog和 Nios软件编程两种方式完成LED流水灯显示,理解两种方式的差异;
- 分别用Verilog和Nios软件编程, 实现DE2-115开发板串口输出“Hello Nios-II”字符到笔记本电脑串口助手。
3)分别在DE2-115开发板和树莓派上编写串口通信程序, 实现树莓派串口指令对FPGA板子上的流水灯程序的控制,控制方式自定。
一 Verilog实现流水灯
使用quartus创建好工程项目,将verilog文件加入项目中,分析综合一次后,添加引脚,引脚如下:
添加完后直接全编译,最后连接DE2-115下载即可。
代码如下:
module led_flow #(parameter TIME_0_5S = 25_000_000)(input sys_clk ,input sys_rst_n ,output reg [7:0] led
);reg [24:0] cnt ;wire add_cnt ;wire end_cnt ;reg [2:0] cnt1;wire add_cnt1;wire end_cnt1;always @(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n) begincnt <= 25'b0;endelse if(add_cnt) beginif(end_cnt) begincnt <= 25'b0;endelse begincnt <= cnt+1'b1;endendelse begincnt <= cnt;endend// 异步复位always @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)begincnt1 <= 3'b0;endelse if(add_cnt1) beginif(end_cnt1)begincnt1 <= 3'b0;endelse begincnt1 <= cnt1 + 1'b1;endendendalways @(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginled <= 8'b0;endelse begincase (cnt1)3'b000 : led <= 8'b0000_0001;3'b001 : led <= 8'b0000_0010;3'b010 : led <= 8'b0000_0100;3'b011 : led <= 8'b0000_1000;3'b100 : led <= 8'b0001_0000;3'b101 : led <= 8'b0010_0000;3'b110 : led <= 8'b0100_0000;3'b111 : led <= 8'b1000_0000;default: led <= led;endcaseendendassign add_cnt = 1'b1;assign end_cnt = add_cnt && cnt == TIME_0_5S - 1;assign add_cnt1 = (cnt == TIME_0_5S-1);assign end_cnt1 = add_cnt1 && cnt1 == 3'b111;endmodule
运行效果如下:
二 Nios实现流水灯
2.1 创建项目
在文件夹下(你放项目的文件夹)创建一个新的项目,名称任意,最好和项目有关,我的是NiosII,并在里面创建prj目录:
创建好之后打开quartus新建工程:
一直next,到选择型号界面。
选择芯片型号,根据实际情况选择
点击finish
2.2 SOPC添加模块
这里以前是叫qsys,现在变成了platform designer,他俩都是为了设置sopc(system on programmble chip),在这里面可以使用一些已经写好了的模块(IP核)来构建你自己想完成的功能。
首先,最基本的需要一个cpu(NIosII处理器)、ram存储器、jtag、systemid,这几个是最基本的配置。其次我们需要点灯,所以就需要pio。
-
添加基本配置cpu
在platform designer的左侧,有一个IP Catalog,是IP 目录的意思,可以在搜索栏输入关键字查找你想添加的ip核。如下:
添加之后,有弹框,让你配置这个模块,一般保持默认。
然后点击finish。
右键Rename,将名字改为cpu
-
添加基本配置jtag
保持默认配置,finish之后改名字为uart
-
添加基本配置ram
这个需要修改一下,Size变为40960bytes,因为后续的软件代码都是存储到ram中的,还包括一些指令什么的需要较大的空间,你可以在这设定充足,或者在后续eclipse软件中修改,有点类似于cube里面的一些操作。
修改之后finish,改名字为onchip_ram
-
添加基本配置systemid
保持默认选项,finish。 -
添加流水灯的pio
点击finish后将名字改为pio_led,并且要在led下的externel_connection该名称为out_led。这里是为了说明顶层文件中有一个输出是out_led。可以在后面看到生成的模块实例格式中输出就有这个,输入包括时钟和复位信号。
以上就是你需要的所有模块,接下来就是连线。过程类似你要编写顶层top文件,需要把输出输出等地方连接起来。
2.3 SOPC输入输出连接
在打开这个platform designer的时候有一个clk_0模块,是它本身就有的,需要双击一下,看其中时钟频率是多少:
可以看到这里是50MHz,和手里的fpga晶振是同样的频率。所以不用修改,如果不同,就需要做一些额外的操作比如添加一个锁相环,进行倍频操作。
cpu,uart,onchip_ram,pio_led、sys_id都有clk和reset的需求,所以要把他们的时钟和复位连接起来。
接着是cpu作为处理器,uart以及pio、ram等都有数据相关的操作,需要通过数据总线,所以要将这些连接到数据总线上去。连线结果如下:
连接完后,再配置一下处理器,双击cpu:
这些模块都是基于Avalon总线,需要确保他们地址不同。
点击system->assign base address后可以看到每个模块base那一列都分配了不同的地址。
分配完成之后,可以看到最下方Messages中没有报错了,如果还有报错就是前面有地方没有配对。
2.4 Generate
点击generate中的generate HDL
完成之后,再点击show…template,可以看到现在这个模块的实例顶层格式:
复制下来。可以关闭platform designer回到quartus中。
点击File,new创建一个verilog HDL file
开始编写顶层文件:
创建一个顶层模块后,填写庶出庶出,并将刚才复制的粘贴进去,作为实例化的对象。
之后再添加qip文件:Assignments–>Settings–>
Applay之后,就开始分析综合、绑定引脚(可参考数据手册led绑定):
然后全编译。硬件部分就编好了。
2.5 软件部分
先有点led_flow_bsp
保持硬件的最新性。
然后右键led_flow,build project。如果编译没问题就开始下一步。
先把硬件烧录到fpga板子上。
连接板子,
start。
再烧软件:
会出现一个报错,点击右侧的refresh…就可以了。
2.6 运行结果
三 Verilog实现串口
项目创建和以前的一样。
3.1 代码
uart.tx:
//波特率为115200bps,即每秒传送115200bit的数据,传送1bit数据需要434个时钟周期
//tx内部是并行数据,需要串行传出去,一般数据格式是1bit的起始位,8bit的数据位,1bit的停止位
//所以需要一个8bit的计数器,计算传送了多少个bit,起始位是低电平有效,停止位是持续的高电平
//需要接收8bit的数据
//需要1bit的传送出去
module uart_tx(input clk ,input rst_n ,//ininput [7:0] din ,//要发送的数据input din_vld,//数据有效//outoutput reg [3:0] cnt_byte,//现在输出第几个byte了output reg tx //串口数据
);parameter Baud = 434;//波特率计时器
reg [8:0] cnt_baud ;
wire add_cnt_baud ;
wire end_cnt_baud ;
reg flag;always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_baud <= 0;end else if(add_cnt_baud)begin if(end_cnt_baud)begincnt_baud <= 0;endelse begincnt_baud<=cnt_baud+1;endend else begin cnt_baud <= cnt_baud;end
end
assign add_cnt_baud = flag;
assign end_cnt_baud = add_cnt_baud && cnt_baud == Baud - 1;always @(posedge clk or negedge rst_n)beginif(!rst_n)beginflag <= 1'b0;endelse if(din_vld)beginflag <= 1'b1;endelse if(end_cnt_bit)beginflag <= 1'b0;endelse beginflag <= flag;end
end//波特率计数完成,就可以发送下一个bit
//表示需要把第几位发送出去
reg [3:0] cnt_bit;//最多是8
wire add_cnt_bit;
wire end_cnt_bit;
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_bit <= 0;end else if(add_cnt_bit)begin if(end_cnt_bit)begincnt_bit <= 0;endelse begincnt_bit <= cnt_bit + 1;endend else begin cnt_bit <= cnt_bit;end
end
assign add_cnt_bit = end_cnt_baud;
assign end_cnt_bit = add_cnt_bit && cnt_bit == 8;//发送到第几个字符,总共要发15个字符
wire add_cnt_byte ;
wire end_cnt_byte ;always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_byte <= 0;end else if(add_cnt_byte)begin if(end_cnt_byte)begincnt_byte <= 0;endelse begincnt_byte <= cnt_byte + 1;endend else begin cnt_byte <= cnt_byte;end
endassign add_cnt_byte = end_cnt_bit;//发送完8bit后
assign end_cnt_byte = add_cnt_byte && cnt_byte == 14;//发送数据的逻辑,先加上起始位reg [8:0] data ;
always @(posedge clk or negedge rst_n)beginif(!rst_n)begindata <= 9'h1ff;endelse if(din_vld)begindata <= {din,1'b0}; //数据加上起始位endelse begindata <= data;end
end//并行转串行逻辑
always @(posedge clk or negedge rst_n)begin if(!rst_n)begintx <= 0;end else if(cnt_baud == 1)begin //每发送完1bit,就发送一个tx;tx <= data[cnt_bit];//LSP,低位先发end else if(end_cnt_bit)begin//处理停止位tx <= 1'b1;endelse begin tx <= tx;end
endendmodule
test.v
module test(input clk ,input rst_n ,input wire [3:0] cnt_byte,//现在输出第几个byte了output reg dout_vld,//表示200us间隔实现output reg [7:0] led_data//表示输出的数据
);
//总共需要发送15个字符,所以需要15的计数器//200us计数器
parameter TIME_200uS = 1_000_0;
reg [13:0] cnt_200uS;
wire add_cnt_200uS;
wire end_cnt_200uS;
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_200uS <= 0;end else if(add_cnt_200uS)begin if(end_cnt_200uS)begin cnt_200uS <= 0;endelse begin cnt_200uS <= cnt_200uS + 1;end endelse begincnt_200uS <= 0;end
end
assign add_cnt_200uS = 1'b1;
assign end_cnt_200uS = add_cnt_200uS && cnt_200uS == TIME_200uS - 1;//定义输出数据//Hello Nios-II到串口always @(posedge clk or negedge rst_n)beginif(!rst_n)begindout_vld <= 1'b0;endelse if(end_cnt_200uS)begindout_vld <= 1'b1;case(cnt_byte)0 : led_data = 8'b01001000;//H1 : led_data = 8'b01100101;//e2 : led_data = 8'b01101100;//l3 : led_data = 8'b01101100;//l4 : led_data = 8'b01101111;//o5 : led_data = 8'b00100000;//space6 : led_data = 8'b01001110;//N7 : led_data = 8'b01101001;//i8 : led_data = 8'b01101111;//o9 : led_data = 8'b01110011;//s10 : led_data = 8'b00101101;//-11 : led_data = 8'b01001001;//I12 : led_data = 8'b01001001;//I13 : led_data = 8'b00001101;//\r14 : led_data = 8'b00001010;//\ndefault : led_data = 8'b0;endcaseendelse begindout_vld <= 1'b0;endendendmodule
top.v
module top(input clk ,input rst_n ,output tx
);wire [7:0] led_data ;wire [3:0] cnt_byte ;wire din_vld ;uart_tx inst_uart_tx(.clk (clk ),.rst_n (rst_n ),//in.din (led_data),//如果串口占用时,uart_data.din_vld (din_vld),
//out.cnt_byte (cnt_byte),.tx (tx ) );test inst_test(.clk (clk ),.rst_n (rst_n ),//in.cnt_byte (cnt_byte),//out.led_data (led_data ),.dout_vld (din_vld));endmodule
3.2 引脚
指定gpio口为tx和rx,编程实现硬件逻辑
3.3 效果
四 Nios2实现串口
4.1 sopc硬件设计
4.2 top文件
module nios2_uart_top(input clk,input rst_n,input rxd,output txd
);nios2_uart u0 (.clk_clk (clk), // clk.clk.reset_reset_n (rst_n), // reset.reset_n.uart_rxd (rxd), // uart.rxd.uart_txd (txd) // .txd);
endmodule
4.3 软件代码
#include <stdio.h>
#include "unistd.h"
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_uart_regs.h"
#include "sys\alt_irq.h"/** 串口发送字符串函数* */
/*
void Uart_sendString(char *data, unsigned int len)
{alt_u8 i;for(i=0;i<len;i++){IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, data[i]); //数据发送完,将TRDY置为1while((IORD_ALTERA_AVALON_UART_STATUS(UART_BASE) & 0x40)!=0x40); //判断数据(TRDY==1)是否发送完毕}
}
*/int main()
{char *str = "hello Niosii!\r\n";while(1){alt_u8 j;for(j = 0; j < 17; j++){IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, str[j]); //数据发送完,将TRDY置为1while((IORD_ALTERA_AVALON_UART_STATUS(UART_BASE) & 0x40)!=0x40); //判断数据(TRDY==1)是否发送完毕}int i = 0;while(i<500000){i++;}}return 0;
}
4.4 实现效果
五 参考资料
1、正点原子视频
2、NiosII流水灯
3、NiosII串口
六 总结
verilog和nios-II比较下来,verilog编程的时候可以选择性的编程,比如我现在要串口传送,我可以只写一个串口传送就可以传出去,但是在细节方面比如时序很容易搞混,简洁但是要很细心,否则就是bug。Nios-II是添加ip核,使用已有的模块去建立程序逻辑,相当于模拟一个电脑,大致了解一下是能上手的。但是要深究还是有点难度的。相比较下来,nios-ii确实方便了一点点,并且它有点像拼图,把模块拼起来,然后软件编程实现。
相关文章:

Nios-II编程入门实验
文章目录 一 Verilog实现流水灯二 Nios实现流水灯2.1 创建项目2.2 SOPC添加模块2.3 SOPC输入输出连接2.4 Generate2.5 软件部分2.6 运行结果 三 Verilog实现串口3.1 代码3.2 引脚3.3 效果 四 Nios2实现串口4.1 sopc硬件设计4.2 top文件4.3 软件代码4.4 实现效果 五 参考资料六 …...

从0开始学python(七)
目录 前言 1 break、continue和pass函数 1.1 break 1.2 continue 1.3 pass 2、序列的索引及切片操作 2.1字符串的索引和切片 2.1.1 字符串索引 2.1.2 字符串切片 总结 前言 上一篇文章我们介绍了python中的循环结构,包括for和while的使用。本章接着往下讲。…...

【二叉树算法题记录】404. 左叶子之和
题目描述 给定二叉树的根节点 root ,返回所有左叶子之和。 题目分析 其实这题无论是迭代法还是递归法,最重要的是要明确判断左叶子的条件:当前节点有左孩子,且这个左孩子没有它的左孩子和右孩子。 迭代法 感觉只要二叉树相关…...

面试集中营—Spring篇
Spring 框架的好处 1、轻量:spring是轻量的,基本的版本大约2MB; 2、IOC:控制反转,Spring的IOC机制使得对象之间的依赖不再需要我们自己来控制了,而是由容易来控制,一个字:爽…...

Lia 原理
训练阶段 论文流程: 具体实现: 通过latent space传递运动信息,实现分两部分。 1)image space->latent space 将源图像映射到隐空间编码。X_s (source image )映射到编码Z_sr,通过W_rd方向上的变化,得到新的编码Z…...

文本批量操作技巧:内容查找不再繁琐,自动化批量移动至指定文件夹
在文本处理和信息管理的日常工作中,我们经常需要处理大量的文件和数据。面对这些海量的信息,如何快速而准确地查找特定的内容,并将它们批量移动至指定的文件夹,成为了一项关键的技能。本文将介绍办公提效工具一些实用的文本批量操…...

[数据结构]动画详解单链表
💖💖💖欢迎来到我的博客,我是anmory💖💖💖 又和大家见面了 欢迎来到动画详解数据结构系列 用通俗易懂的动画的动画使数据结构可视化 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低…...

图片批量管理迈入智能新时代:一键输入关键词,自动生成并保存惊艳图片,轻松开启创意之旅!
在数字化时代,图片已成为我们表达创意、记录生活、传递信息的重要工具。然而,随着图片数量的不断增加,如何高效、便捷地管理这些图片,却成为了一个令人头疼的问题。 第一步,进入首助编辑高手主页面,在上方…...

【硬件模块】ESP-01SWiFi模块基于AT指令详解(WiFi,TCP/IP,MQTT)
ESP-01S ESP-01S是由安信可科技开发的一款Wi-Fi模块。其核心处理器是ESP8266,该处理器在较小尺寸的封装中集成了业界领先的Tensilica L106超低功耗32位微型MCU,带有16位精简模式,主频支持80MHz和160MHz,并集成了Wi-Fi MAC/BB/RF/P…...

数据结构之单单单——链表
目录 一.链表 1)链表的概念 2)链表的结构 二.单链表的实现 三.链表的分类 1)单向或者双向 2)带头或不带头 3)循环或非循环 一.链表 1)链表的概念 链表(Linked List)是一种…...

【Linux笔记】 基础指令(二)
风住尘香花已尽 日晚倦梳头 重命名、剪切指令 -- mv 简介: mv 命令是 move 的缩写,可以用来移动文件或者将文件改名,是 Linux 系统下常用的命令,经常用来备份文件或者目录 语法: mv [选项] 源文件或目录 目标文件或目录…...

软件全套资料梳理(需求、开发、实施、运维、安全、测试、交付、认证、评审、投标等)
软件全套精华资料包清单部分文件列表: 工作安排任务书,可行性分析报告,立项申请审批表,产品需求规格说明书,需求调研计划,用户需求调查单,用户需求说明书,概要设计说明书,…...

javacv实时解析pcm音频流
javacv实时解析pcm音频流 解析代码 try (ByteArrayInputStream inputStream new ByteArrayInputStream(bytes);){FFmpegFrameGrabber grabber new FFmpegFrameGrabber(inputStream);// PCM S16LE 格式grabber.setFormat("s16le");// 采样率grabber.setSampleRate(1…...

Matlab|考虑极端天气线路脆弱性的配电网分布式电源和储能优化配置模型
1主要内容 程序主要参考《考虑极端天气线路脆弱性的配电网分布式电源配置优化模型-马宇帆》,针对极端天气严重威胁配电网安全稳定运行的问题。基于微气象、微地形对配电网的线路脆弱性进行分析,然后进行分布式电源接入位置与极端天气的关联性分析&#…...

【Python基础】装饰器(3848字)
文章目录 [toc]闭包什么是装饰器装饰器示例不使用装饰器语法使用装饰器语法 装饰器传参带参数的装饰器类装饰器魔术方法\__call__()类装饰器示例带参数类装饰器property装饰器分页操作商品价格操作 个人主页:丷从心 系列专栏:Python基础 学习指南&…...

十、Redis内存回收策略和机制
1、Redis的内存回收 在Redis中可以设置key的过期时间,以期可以让Redis回收内存,循环使用。在Redis中有4个命令可以设置Key的过期时间。分别为 expire、pexpire、expireat、pexpireat。 1.1、expire expire key ttl:将key的过期时间设置为tt…...

Ansible --- playbook 脚本+inventory 主机清单
一 inventory 主机清单 Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或 多个主机组内。 如果是名称类似的主机,可以使用列表的方式标识各个主机。vim /etc/ansible/hosts[webservers]192.168.10.1…...

【hive】transform脚本
文档地址:https://cwiki.apache.org/confluence/display/Hive/LanguageManualTransform 一、介绍二、实现1.脚本上传到本地2.脚本上传到hdfs 三、几个需要注意的点1.脚本名不要写全路径2.using后面语句中,带不带"python"的问题3.py脚本Shebang…...

5款可用于LLMs的爬虫工具/方案
5款可用于LLMs的爬虫工具/方案 Crawl4AI 功能: 提取语义标记的数据块为JSON格式,提供干净的HTML和Markdown文件。 用途: 适用于RAG(检索增强生成)、微调以及AI聊天机器人的开发。 特点: 高效数据提取,支持LLM格式,多U…...

投影、选择转SQL语言
使用以下两个表进行举例,第一个表为R表,第二个表为S表 R.AR.BR.C123456789 S.AS.BS.C101112131415161718 1、投影转SQL语言: 兀 A,B,C (R) 等价于select A,B,C from R 解释: 兀:相当于select (R):相当于from R…...

系统加固-自用
一、windows 1、概述 (1)、权限最高:system(系统账户),权限比administrator权限还高 (2)、常见操作系统安全漏洞类型 缓冲区溢出漏洞TCP/IP协议漏洞web应用安全漏洞开放端口的安全漏洞 2、系统安全加固方法 (1)、系统不显示上次登录的用户名 进入…...

Java面试题:阐述Java中的自动装箱与拆箱机制,以及使用它们时可能遇到的性能问题
在Java中,自动装箱(Autoboxing)和拆箱(Unboxing)是Java 5引入的特性,它们允许基本数据类型和对应的包装类之间的自动转换。 自动装箱 自动装箱是指将基本数据类型(如int、double等)…...

初识sql注入--手工注入
目录 可能使用的sql函数 入侵网站方式 1、文件上传漏洞 2、rce 3、sql注入 SQL注入 什么是sql注入 进行SQL注入 实验环境 开始实验(使用information_shema数据库) 1、进入靶场 2、报列数 下面来解释一下为什么要照上面SQL语句写 url编码 单…...

OceanBase 缺少 dbms_obfuscation_toolkit.md5 包函数的解决方案
因为 dbms_obfuscation_toolkit.md5 是一个 Oracle 不推荐继续使用的函数,所以 OceanBase 没有对其兼容,取而代之的是兼容了 dbms_crypto.hash,其用法详见这篇 KB 但是,并不是所有业务都接受修改源码,因为复杂系统里&…...

Java---类和对象第一节
目录 1.面向对象初步认识 1.1什么是面向对象 1.2面向对象和面向过程的区别 2.类的定义和使用 2.1简单认识类 2.2类的定义格式 2.3类的实例化 2.4类和对象的说明 3.this关键字 3.1访问本类成员变量 3.2调用构造方法初始化成员变量 3.3this引用的特性 4.对象的构造以…...

Zeller公式的应用:给定日期,确定周几
开篇 本篇文章依然是对于日期相关函数的实现。 问题概要 给定一个日期,返回为周几 思路分析 这个问题的思路只是对于Zeller公式的直接引用,不存在其他逻辑。公式详情可参考Zeller公式百科 代码实现 #include <stdio.h>// 根据Zeller公式计算 int …...

程序链接和运行 - 笔记
1 linux下程序a连接b.so后,运行时如何找到调用的函数 在Linux下,当程序A连接了动态链接库B(.so文件)后,在运行时,程序A会使用动态链接器(dynamic linker)来解析并加载动态链接库B中的函数。动态链接器会在系统中搜索动态链接库,并将它们加载到程序的地址空间中。 当…...

pyqt 按钮常用格式Qss设置
pyqt 按钮常用格式Qss设置 QSS介绍按钮常用的QSS设置效果代码 QSS介绍 Qt Style Sheets (QSS) 是 Qt 框架中用于定制应用程序界面样式的一种语言。它类似于网页开发中的 CSS(Cascading Style Sheets),但专门为 Qt 应用程序设计。使用 QSS&am…...

websevere服务器从零搭建到上线(一)|阻塞、非阻塞、同步、异步
文章目录 数据准备(阻塞和非阻塞)、数据读写(同步和异步)小总结(陈硕老师的总结) 知识拓展同步执行实例异步编程实例 八股 数据准备(阻塞和非阻塞)、数据读写(同步和异步) 无论是什么样的IO都包含两个阶段:数据准备和数据读写。 我们的网络IO…...

【C++】引用传递 常量引用
在C中,引用传递和常量引用是两个常用的概念,主要用于函数参数传递。它们提供了对变量或对象更有效率和更安全的访问方式。 引用传递(Pass by Reference) 引用传递意味着当你将变量作为参数传递给函数时,你实际上是传…...