OFDM802.11a的FPGA实现(七)一级交织:分组交织器(含verilog和matlab代码)

news2024/10/7 17:30:21

1.前言

  在前面的文章中讲解了卷积编码和删余,实现了1/2、2/3、3/4编码速率的输出。数据域在编码之后,下一个部分就是交织。今天对交织进行具体实现。

  交织是为了在时域或频域或者同时在时域、频域上分布传输的信息比特,使信道的突发错误在时间上得以扩散,从而使得译码器可以将它们当作随机错误处理。交织器在几个分组长度或几个约束长度的范围内对码元进行混洗,这个范围是由突发持续时间决定的。通信系统的交织模式取决于信道特性。如果系统在一个纯粹的AWGN环境下运行,即准平稳信道,那么在一个数据包的持续时间上基本没有什么变化,就不需要交织。因为这时,通过重新分配的方法是无法改变误码分布的。

  交织必然在系统中引人延时,这是因为接收到的比特顺序与信息源发送时的顺序是不相同的。通信系统通常规定了系统所能容忍的最大延时,因此也限制了所能使用的交织器的交织深度。

2.原理

2.1分组交织器

  分组交织器是针对一组bit进行的,该分组当中bit的数量称为交织深度,交织深度越大,离散度越大,抗突发差错的能力也就越大,相应的引起的交织编码处理时间也越长。
我们可以用一个矩阵来描述分组交织器,将数据按照行进行写入数据,按照列的方式进行读出,或者按照相反的方式也是可以的。

4x5分组交织器的写和读的结构

  4x5的分组交织器,由此可见交织深度为20,以行的方式进行写入,以列的方式进行读出。

01234
56789
1011121314
1516171819

  反交织的作用与交织的作用正好相反,将上图当中的矩阵进行转秩,然后同样按照以行的方式进行写入,以列的方式进行读出,即可将原始的数据恢复。

051015
161116
271217
381318
491419

2.2 802.11a当中的交织

  802.11a规定了包括调制方案、编码效率以及数据速率之间的关系,如下面三个表所示:
表1

表2

表3
  802.11a当中交织的深度为一个OFDM符号,因此这是一个分组交织器,交织深度与所采用的调制方式有关:BPSK,QPSK,16QAM,64QAM的交织深度分别为48,96,192,288个bit。每种调制当时的交织深度是通过数据子载波的数量与每个符号当中bit的个数相乘得到的。确定了调制方案、编码效率以及数据速率之后,就可以计算出每个OFDM符号在调制前的码长,公式如下:
N C B P S = 48 × M ÷ R N_{CBPS} = 48 \times M \div R NCBPS=48×M÷R

  其中,$ N_{CBPS} 表示每个 O F D M 符号在调制前的码长, 表示每个OFDM符号在调制前的码长, 表示每个OFDM符号在调制前的码长,M 表示调制阶数( 1 − B P S K , 2 − Q P S K , 3 − 8 Q A M , 4 − 16 Q A M , 5 − 32 Q A M , 6 − 64 Q A M ) , 表示调制阶数(1-BPSK,2-QPSK,3-8QAM,4-16QAM,5-32QAM,6-64QAM), 表示调制阶数(1BPSK2QPSK,38QAM,416QAM532QAM,664QAM,R$表示编码效率。

  802.11a规定数据域的交织分为两个步骤,今天主要讲第一次交织,其目的是保证相邻的比特在经过ofdm调制之后数据会落在不相邻的子载波上。
以QAM64调制,速率为54Mb/s为例,能够确定 s = 3 , N C B P S = 288 s=3,N_{CBPS = 288} s=3NCBPS=288有了这些参数之后,我们就可以将这个交织的变换关系给计算出来,我们只需要根据这个关系进行将数据写入到一个RAM对应的地址当中,再依次将数据从RAM中读取出来即可以完成交织的工作。802.11a中最大的交织深度即为288,搞定了这个之后其他的也是一样的操作,其关系网如下所示:

以QAM64调制,速率为54Mb/s为例的交织关系

3.verilog代码

  在设计上,为保证流水线设计结构,能够对数据进行连续处理,需要将RAM的存储空间设置为最大交织深度288的一倍。相邻的OFDM符元就能实现乒乓缓存。0-287地址空间为乒乓缓存A区数据空间,288-575为乒乓缓存B区数据空间,实现A区写入数据,B区读取数据。 当输入数据有效时,对输入数据按一级交织方式进行错位写入RAM,并驱动写入计数器以交织深度为长度进行计数,计满一个交织深度后,拉高当前缓存区标志信号,并驱动读取计数器以当前缓存区长度计数。模块接口如下所示:

**《基于XILINX FPGA的OFDM通信系统基带设计》**书中对于这个模块是这样设计的:

  他又用到了跨时钟域,其实很没有必要,还是采用之前的valid-ready握手机制就可以解决这个问题。还有这里虽说是用到了RAM,但是个人认为并没有必要去调用FPGA的Block RAM资源,因为一块Block RAM一般都是18k或者36k,用在这里很浪费。具体可以去查看芯片资料。这里两个缓存区加起来不过也才576位,直接用两个288位的寄存器即可。

  接下来需要解决写地址的问题:定义第一次交织前的编码比特序列角标顺序号用 k 表示,交织之后的数据序列角标顺序号用 i 表示,第二次交织后数据序列角标顺序号用 j 来表示,我们可以得到如下公式:

  由于FPGA中直接用除法和取余非常浪费资源,此处处被除数是固定的,我们只需要采用移位的方式就可以实现除法和取余。代码如下:

//---------valid-ready握手---------//
assign	wr_en	 = intv1_dout_rdy & intv1_din_vld ;//与上游握手成功,开始接收数据
assign	rd_en	 = intv1_din_rdy & intv1_dout_vld ;//与下游握手成功,开始输出
assign	intv1_dout_rdy = (~bufferA_full | ~bufferB_full) ? 1'b1 : 1'b0;
assign	intv1_dout_vld = ( bufferA_full |  bufferB_full) ? 1'b1 : 1'b0;
//------------buffer读写控制----------------//	
always@(posedge clk or negedge rst_n ) begin
	if(!rst_n)
		buffer_flag <= 1'b0;//0为A区,1为B区
	else if(w_cnt_last & wr_en)
		buffer_flag <= ~buffer_flag;//0为A区,1为B区
end
//-----------buffer写满和读空控制------------//	
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		bufferA_full <= 1'b0;
	else if(w_cnt_last & wr_en & ~buffer_flag)
		bufferA_full <= 1'b1;
	else if(r_cnt_last & rd_en & bufferA_full)
		bufferA_full <= 1'b0;
end

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		bufferB_full <= 1'b0;
	else if(w_cnt_last & wr_en & buffer_flag)
		bufferB_full <= 1'b1;
	else if(r_cnt_last & rd_en & bufferB_full)
		bufferB_full <= 1'b0;
end
//-----------根据符号长度选择写计数值------------//	
always@( * ) begin  
    case ( intv1_Con )
		N_48 	:  	cnt_Max = 48 -1	; 
		N_96 	:  	cnt_Max = 96 -1	;  
		N_192	:  	cnt_Max = 192 -1;  
		N_288	:  	cnt_Max = 288 -1;  
		default	:	cnt_Max = 48 -1	;
    endcase 
end
//------buffer写入操作,以行写入,但是地址换算为列输出时的地址--//
counter_in #(.CNT_NUM('d288),
		.ADD(1'b1))
u_counter_w(
.clk		(clk				),	
.rst_n		(rst_n				),
.En_cnt		(wr_en				), 
.cnt_din	(cnt_Max			),     
.cnt		(w_cnt				),	
.cnt_last	(w_cnt_last			)
);

always@(*) begin
	if(!rst_n) 
		w_addr = 0; 
	else begin
		case(intv1_Con)
			N_48	: w_addr = w_cnt[3:0] + (w_cnt[3:0]<<1) + w_cnt[8:4] ; //N = 48//w_cnt *3	  
			N_96	: w_addr = (w_cnt[3:0]<<1)  + (w_cnt[3:0]<<2) + w_cnt[8:4] ;//N = 96 //w_cnt *6
			N_192	: w_addr = (w_cnt[3:0]<<3)  + (w_cnt[3:0]<<2) + w_cnt[8:4]; //N = 192//w_cnt *12
			N_288	: w_addr = (w_cnt[3:0]<<4)  + (w_cnt[3:0]<<1) + w_cnt[8:4]; //N = 288//w_cnt *18
			default	: w_addr = w_cnt[3:0] + (w_cnt[3:0]<<1) + w_cnt[8:4] ; //N = 48//w_cnt *3
		endcase
	end	
end

always@(posedge clk or negedge rst_n ) begin
	if(!rst_n)begin
		bufferA <= 1'b0;
		bufferB <= 1'b0;	
	end
	else if(wr_en)begin
		if(buffer_flag)
			bufferB[w_addr] <= intv1_din;
		else
			bufferA[w_addr] <= intv1_din;
	end	
end

//------buffer读出操作,按照顺序地址读出---------//
counter_in #(.CNT_NUM('d288),
		.ADD(1'b1))
u_counter_r(
.clk		(clk				),	
.rst_n		(rst_n				),
.En_cnt		(rd_en				), 
.cnt_din	(cnt_Max			),     
.cnt		(r_cnt				),	
.cnt_last	(r_cnt_last			)
);

assign	intv1_dout = (rd_en & buffer_flag) ? bufferA[r_cnt] : bufferB[r_cnt];

//输出Map_Type,作为后面调制映射的输入,确定调制方式
always@(posedge clk or negedge rst_n ) begin
    if(!rst_n) begin 
        Map_Type <= 0;        
    end    
    else if(intv1_dout_vld) begin 
        Map_Type <= intv1_Con ; 
    end   
end 

4.Matlab仿真

  Matlab代码如下:

%% 一级交织
%一级交织器产生:16*list 列写行读
conv_out_Len = length(conv_out);    %编码后的长度
symbol_Len = conv_out_Len / k;      %单个符号码长度
list = conv_out_Len / k / 16;       %一级交织的列数
row = length(conv_out)/list;        %将数据转为list列的矩阵 
ram = zeros(row,list);              %将输入数据存储在list列,row行的矩阵中
for n = 1:k                         %将ram矩阵拆为n个16*list的矩阵,每次写入list列
    for m = 1:symbol_Len            %以列写入
        row_index = mod(m-1,16)+1;      %写入到矩阵中行的位置
        list_index = ceil(m/16);           %写入到矩阵中列的位置
        ram((n-1)*16+row_index,list_index) = conv_out((n-1)*symbol_Len+m); %将数据写入ram矩阵
    end
end
int_lea_1_out = zeros(1,conv_out_Len);
for n = 1:k
    for row_index = 1:16
        for list_index = 1:list    %按行读出ram中的数据,每次读list列
            int_lea_1_out((n-1)*symbol_Len+(row_index-1)*list+list_index) = ...
            ram(((n-1)*16+row_index),list_index);
        end
    end
end

5.ModelSim仿真

  按照如下连接仿真:

  仿真截图如下,可以看到读写可以同时进行,实现了乒乓操作。


为了验证模块的正确性,仿真使用4个OFDM符号输入,调制方式位BPSK(其他调制方式数据太多,不方便展示),3/4编码效率。计算得知,每个符号码长为48,即16行3列,列写入的数据如下:

110
100
100
100
110
001
100
110
010
100
000
011
001
101
101
000
001
101
011
011
010
000
010
010
010
001
100
111
010
110
011
011
001
001
011
011
100
011
100
001
100
100
011
010
111
000
100
101
110
001
000
111
111
100
101
101
110
001
100
101
100
010
011
110

  将matlab仿真的数据和ModelSim中的数据进行对比。

clc;
%% 串并转换
test_data = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/test_data.txt')';
display(test_data);
FPGA_S2P2S = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/u2_data_out.txt')';
display(FPGA_S2P2S);
check_S2P = test_data == FPGA_S2P2S; 
display(check_S2P);
%% 扰码
FPGA_scram_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/scram_data_out.txt')';
display(scram_out0);
display(FPGA_scram_dout);
check_scram = FPGA_scram_dout == scram_out0;
display(check_scram);
%% 卷积编码
FPGA_conv_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/conv_data_out.txt')';
display(conv_out0);
display(FPGA_conv_dout);
check_conv = FPGA_conv_dout == conv_out0;
display(check_conv);
%% 删余
FPGA_punt_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/punt_data_out.txt')';
display(conv_out);
display(FPGA_punt_dout);
check_punt = FPGA_punt_dout == conv_out;
display(check_punt);
%% 交织
FPGA_intv1_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/intv1_data_out.txt')';
display(int_lea_1_out);
display(FPGA_intv1_dout);
check_intv1 = FPGA_intv1_dout == int_lea_1_out;
display(check_intv1);

  matlab交织输出如下:

int_lea_1_out =

列 1 至 25

 1     1     0     1     0     0     1     0     0     1     0     0     1     1     0     0     0     1     1     0     0     1     1     0     0

列 26 至 50

 1     0     1     0     0     0     0     0     0     1     1     0     0     1     1     0     1     1     0     1     0     0     0     0     0

列 51 至 75

 1     1     0     1     0     1     1     0     1     1     0     1     0     0     0     0     0     1     0     0     1     0     0     1     0

列 76 至 100

 0     0     1     1     0     0     1     1     1     0     1     0     1     1     0     0     1     1     0     1     1     0     0     1     0

列 101 至 125

 0     1     0     1     1     0     1     1     1     0     0     0     1     1     1     0     0     0     0     1     1     0     0     1     0

列 126 至 150

 0     0     1     1     0     1     0     1     1     1     0     0     0     1     0     0     1     0     1     1     1     0     0     0     1

列 151 至 175

 0     0     0     1     1     1     1     1     1     1     0     0     1     0     1     1     0     1     1     1     0     0     0     1     1

列 176 至 192

 0     0     1     0     1     1     0     0     0     1     0     0     1     1     1     1     0

  FPGA交织输出如下:
FPGA_intv1_dout =

列 1 至 25

 1     1     0     1     0     0     1     0     0     1     0     0     1     1     0     0     0     1     1     0     0     1     1     0     0

列 26 至 50

 1     0     1     0     0     0     0     0     0     1     1     0     0     1     1     0     1     1     0     1     0     0     0     0     0

列 51 至 75

 1     1     0     1     0     1     1     0     1     1     0     1     0     0     0     0     0     1     0     0     1     0     0     1     0

列 76 至 100

 0     0     1     1     0     0     1     1     1     0     1     0     1     1     0     0     1     1     0     1     1     0     0     1     0

列 101 至 125

 0     1     0     1     1     0     1     1     1     0     0     0     1     1     1     0     0     0     0     1     1     0     0     1     0

列 126 至 150

 0     0     1     1     0     1     0     1     1     1     0     0     0     1     0     0     1     0     1     1     1     0     0     0     1

列 151 至 175

 0     0     0     1     1     1     1     1     1     1     0     0     1     0     1     1     0     1     1     1     0     0     0     1     1

列 176 至 192

 0     0     1     0     1     1     0     0     0     1     0     0     1     1     1     1     0

  对比结果如下:

check_intv1 =

1×192 logical 数组

列 1 至 38

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

列 39 至 76

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

列 77 至 114

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

列 115 至 152

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

列 153 至 190

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

列 191 至 192

1 1

  结果全为1,说明完全正确。作者也对其他调制方式和编码方案进行了测试,都是正确的,这里就不再赘述。

4总结

  需要回顾前面知识请点击链接:OFDM 802.11a的xilinx FPGA实现

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

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

相关文章

LSTM-KDE的长短期记忆神经网络结合核密度估计多变量回归区间预测(Matlab)

LSTM-KDE的长短期记忆神经网络结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09; 目录 LSTM-KDE的长短期记忆神经网络结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.LSTM-KDE的长短期…

CVE-2022-2602:unix_gc 错误释放 io_uring 注册的文件从而导致的 file UAF

前言 复现该漏洞只是为了学习相关知识&#xff0c;在这里仅仅做简单记录下 exp&#xff0c;关于漏洞的详细内容请参考其他文章&#xff0c;最后在 v5.18.19 内核版本上复现成功&#xff0c;v6.0.2 复现失败 漏洞利用 diff --git a/include/linux/skbuff.h b/include/linux/s…

网络安全之密码学技术

文章目录 网络信息安全的概念数据加密|解密概念密码学概论密码学分类古典密码学现代密码学 现代密码学的相关概念对称加密算法对称加密算法—DES对称加密算法—3DES对称加密算法—AES对称加密算法—IDEA 非对称加密算法非对称加密算法—RSA非对称加密算法—ElGamal非对称加密算…

高扬程水泵,提升水源新选择!— 恒峰智慧科技

在炎炎夏日&#xff0c;阳光炙烤着大地&#xff0c;森林火灾的发生频率也随之上升。火势猛烈&#xff0c;烟雾弥漫&#xff0c;给森林带来了极大的破坏。为了保护森林资源&#xff0c;我们必须采取有效的措施来扑灭火灾。而在这其中&#xff0c;高扬程水泵成为了提升水源新选择…

buuctf——web题目练习

1.极客大挑战2019 easysql 密码或者用户输入万能密码即可 关于万能密码的理解和原理&#xff0c;可以参考这篇BUUCTF[极客大挑战 2019] EasySQL 1_[极客大挑战 2019]easysql 1-CSDN博客 2.极客大挑战2019 have fun 题目源码 需要构造payload 网页传参可参考&#xff1a;…

Vue Cli脚手架—安装Nodejs和Vue Cli

一&#xff0c;Vue Cli 文档地址: https://cli.vuejs.org/zh/ 二&#xff0c;.环境配置&#xff0c;搭建项目 1.安装node.js 2.下载 node.js10.16.3 地址: https://nodejs.org/en/blog/release/v10.16.3/ 3.安装 node.js10.16.3 , 直接下一步即可, 安装到 d:\program\nodejs…

ubuntu sudo apt-get install neo4j 配置安装与设置远程访问

文章目录 下载Adding the Debian repositoryInstalling Neo4j安装流程设置远程访问 下载 neo4j 官方的下载地址&#xff0c;进入页面之后&#xff0c;往下滑&#xff1a; https://neo4j.com/deployment-center/#community 点击 Visit https://debian.neo4j.com/ Adding the …

Windows Server Backup设置定时备份保留N天

Windows Server - 运维篇 第四章 Windows Server Backup设置定时备份保留N天 Windows Server - 运维篇系列文章回顾Windows Server Backup设置定时备份保留N天使用VSS卷影复制服务工具删除指定天数的VSS备份文件CMD&#xff1a;wbadmin.exeCMD&#xff1a;wbadmin.mscPowerShel…

【RSGIS数据资源】2018-2020年中国农业大学石羊河实验站主要农作物的无人机观测数据

文章目录 摘要数据介绍2018年蒸腾(T)数据集2020年蒸散发&#xff08;ET)数据集2020年LAI数据集2019年NDVI数据集作物2020年NDVI数据集作物三温模型的输入参数气象数据净辐射通量数据 参考文献引用 摘要 本数据集涵盖了甘肃武威绿洲农业高效用水国家野外科学观测研究站&#xf…

AI系列:大语言模型的RAG(检索增强生成)技术(上)

前言 大型语言模型&#xff08;LLM&#xff09;虽然在生成文本方面表现出色&#xff0c;但仍然存在一些局限性&#xff1a;数据是静态的&#xff0c;而且缺乏垂直细分领域的知识。为了克服这些限制&#xff0c;有时候会进行进一步的模型训练和微调。在实际应用中&#xff0c;我…

教育机构必备利器:全面解析教培管理系统的关键功能

一个优秀的教培管理系统是培训机构实现高效运营和学员满意度的关键所在。那么&#xff0c;这样的系统应该具备哪些功能呢&#xff1f;今天&#xff0c;我们就来了解一下乔拓云平台开发的教育系统&#xff0c;看看它如何满足这些需求。 乔拓云教育系统的后端功能丰富多样&#x…

百度文库公测智能漫画和智能话本,有兴趣的可以申请一下

百度文库上线智能文库和智能话本功能&#xff0c;目前处于公测中&#xff0c;我刚申请&#xff0c;还在审核中。 智能漫画&#xff0c;参照官网的示例截图&#xff0c;生成的图片看起来不错&#xff0c;没试用过所以不太清楚他的操作模式是什么 智能话本&#xff0c;生成的话…

网站建设企业网站优化

近年来&#xff0c;随着互联网的迅速发展&#xff0c;企业网站已经成为了企业展示自我形象与实力的重要载体之一。然而&#xff0c;单单拥有一个美观、简洁的企业网站并不能让企业在竞争激烈的市场中脱颖而出。因此&#xff0c;在建设企业网站的过程中&#xff0c;我们需要将企…

上位机图像处理和嵌入式模块部署(树莓派4b开机界面程序自启动)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们学习了如何在树莓派4b上面开发qt&#xff0c;也学习了如何用/etc/rc.local启动控制台程序&#xff0c;那今天我们继续学习一下如何利用树莓…

渗透测试流程(一)

文章目录 1、信息收集渗透测试的流程信息收集的内容信息收集的分类Google hacking 信息收集目录扫描信息收集旁站和C段信息收集旁站和C段在线查询地址&#xff1a; 存活资产探测nmap扫描nmap扫描扫描指定的IP开放端口&#xff1a;穿透防火墙扫描&#xff1a;常用命令--2漏洞扫描…

如何用OceanBase的 Load Data 导入CSV文件

0 前言 CSV文件&#xff08;Comma-Separated Values&#xff0c;字符分隔值&#xff09;是一种普遍采用的数据存储格式&#xff0c;有不少企业和机构都用它来进行数据的管理和存储。身为开发者&#xff0c;您可能经常遇到这样的需求&#xff1a;需要将CSV的数据导入OceanBase数…

python基础知识(17)面向对象 1

一、面向对象的概念 1、面向对象的两个基本概念 编程语言中&#xff0c;一般有两种编程思维&#xff0c;面向过程和面向对象。 面向过程&#xff0c;看重的是解决问题的过程。 这好比我们解决日常生活问题差不多&#xff0c;分析解决问题的步骤&#xff0c;然后一步一步的解决…

知乎热议:未来几年,AI技术在科研领域将有哪些新的发展趋势或突破?

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 一年多以来&#xff0c;各种国内外的AI模型和应用应接不暇&#xff0c;从刚开始ChatGPT一家独大&#xff0c;到现在的百花齐放&#xff0c;各种AI模型各有千秋&#xff0c;一时…

CVE-2023-48795修复方法

CVE-2023-48795修复方法 1、修复原理2、检测漏洞3、修复漏洞4、成功修复 近期nessus扫描经常出现一个中危漏洞CVE-2023-48795&#xff0c;但网上的修复方法清一色的将openSSH升级到9.6p1版本 而我在升级当中处处碰壁&#xff0c;甚至于差点给服务器都干崩溃&#xff0c;特意研究…

Coursera: An Introduction to American Law 学习笔记 Week 01: Tort Law

An Introduction to American Law 本文是 https://www.coursera.org/programs/career-training-for-nevadans-k7yhc/learn/american-law 这门课的学习笔记。 文章目录 An Introduction to American LawInstructors SyllabusWeek 01: Tort LawKey Tort Law TermsTort Law: Part …