FPGA学习历程(四):SDRAM 控制器(初始化与刷新)

article/2025/10/26 14:59:28

目录

  • 一、数据手册相关信息
    • 1.1 命令真值表
    • 1.2 时间参数
    • 1.3 模式寄存器配置
  • 二、初始化模块
    • 2.1 模块时序图
    • 2.2 模块源码
      • 2.2.1 sdram_init.v
      • 2.2.2 sdram_top.v
      • 2.2.3 tb_sdram_top.v
    • 2.3 Modelsim仿真
  • 三、刷新模块
    • 3.1 模块时序图
    • 3.2 模块源码
      • 3.2.1 sdram_aref.v
      • 3.2.2 sdram_top.v
    • 3.3 Modelsim仿真


以下内容学习自开源骚客教程: SDRAM那些事儿第一季。

一、数据手册相关信息

1.1 命令真值表

  关于这个表,博主特意核对了好几款不同型号的 SDRAM,结果不能说完全相同,只能说高度一致,最多在一些可有可无的小功能上有所区别,貌似在遵循公共的协议一样。
在这里插入图片描述
在这里插入图片描述
  把需要用到的抓出来:

CmdCSRASCASWE
Precharge0010
Auto-Refresh0001
NOP0111
Mode-Set0000

1.2 时间参数

  这个也是从数据手册上找的。不过因为用的是 Micron 的时序图,里面还是有一些参数只能在 Micron 的手册上才能找到定义和具体值,这里就统一一下贴 Micron 的出来吧:
在这里插入图片描述
在这里插入图片描述

1.3 模式寄存器配置

  博主使用的是 13 位地址、16位数据的 SDRAM,但是店家给的手册上没有这个,所以借用了其他 SDRAM 芯片的模式寄存器位分布说明(一般来说是通用的)。这里先将模式寄存器配置为 13‘b0_0000_0011_0010,即 CL = 3,Burst Length = 4。
在这里插入图片描述

二、初始化模块

2.1 模块时序图

  这是数据手册上的初始化时序图,暂时只用到 tRP 和 tRFC(tMRD 在刷新部分才会用到):
在这里插入图片描述
  这是实际设计中 SDRAM 初始化模块的时序图:
在这里插入图片描述

  • cnt_200us 是 SDRAM 上电稳定期的计时。手册上说最少 100us,咱稳妥点给它多留一倍的时间;
  • Flag_200us 是计满 200us 后开始初始化操作的标志;
  • cnt_cmd 是初始化操作期间的时钟周期计数器,使它来起到一个时间轴的作用;
  • cmd_reg 就是命令寄存器了,从命令真值表可以看出这里需要 4 位位宽的寄存器;
  • sdram_addr 很明显是 SDRAM 的地址线;
  • Flag_init_end 是初始化完成的标志。

2.2 模块源码

2.2.1 sdram_init.v

module sdram_init
(// system signalsinput 				    sclk	        ,       // 板载系统时钟 50MHzinput                   s_rst_n         ,       // 复位信号,低电平有效// othersoutput  reg [3:0]       cmd_reg         ,       // 输出的命令(即 CS、RAS、CAS、WE 这四位)output  wire [12:0]     sdram_addr      ,       // SDRAM 地址output  wire            flag_init_end           // 初始化结束标志
);/**************************************************************************/
/***************** Define Parameter and Internal Signals ******************/
/**************************************************************************/
localparam                  DEALY_200US =   10000   ;//SDRAM Command
localparam                  NOP         =   4'b0111 ;
localparam                  PRE         =   4'b0010 ;
localparam                  AREF        =   4'b0001 ;
localparam                  MSET        =   4'b0000 ;                  reg [13:0]                  cnt_200us               ;       // 200 * 1000 / 20 = 10000,转换为2进制表示有 14 位
wire                        flag_200us              ;       // 200us 计时结束标志
reg [3:0]                   cnt_cmd                 ;       // 初始化阶段一共要给4个命令,其中 tRP 占1个 CLK,2个 tRFC 共占8个 CLK,要计9个CLK/**************************************************************************/
/******************************* Main Code ********************************/
/**************************************************************************/
// cnt_200us:200us 计时未结束时持续自加
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)cnt_200us <= 'd0;else if(flag_200us == 1'b0)cnt_200us <= cnt_200us + 1'b1;
end// cnt_cmd:只在初始化期间自加计时
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)cnt_cmd <= 'd0;else if(flag_200us == 1'b1 && flag_init_end == 1'b0)cnt_cmd <= cnt_cmd + 1'b1;
end// cmd_reg
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)cmd_reg <= NOP;else if(flag_200us == 1'b1)case(cnt_cmd)0:          cmd_reg <=  PRE;1:          cmd_reg <=  AREF;5:          cmd_reg <=  AREF;9:          cmd_reg <=  MSET;default:    cmd_reg <=  NOP;endcase
endassign  flag_init_end   =   (cnt_cmd >=  'd10) ? 1'b1 : 1'b0;                                   // 初始化期间命令全部输出完成
assign  flag_200us      =   (cnt_200us >= DEALY_200US) ? 1'b1 : 1'b0;
assign  sdram_addr      =   (cmd_reg == MSET) ? 13'b0_0000_0011_0010 : 13'b0_0100_0000_0000;    // Precharge All Banks 时,A10 需拉高,其余脚无关endmodule 

2.2.2 sdram_top.v

  这次的仿真并不是直接仿真 init 模块,而是将 init 模块例化到 sdram_top 模块中,转而仿真 sdram_top 模块,因此还需要完成 sdram_top 模块的代码。

// sdram_top.v 源码,跟 Kevin 大佬敲下来发现这里没有配置 sdram_bank 信号的连接通路,不过只是仿真初始化模块的话则没有影响
module sdram_top
(// system signalsinput 				    sclk	    ,       // 板载系统时钟 50MHzinput                   s_rst_n     ,       // 复位信号,低电平有效// SDRAM Interfacesoutput  wire            sdram_clk   ,output  wire            sdram_cke   ,output  wire            sdram_cs_n  ,output  wire            sdram_cas_n ,output  wire            sdram_ras_n ,output  wire            sdram_we_n  ,output  wire [1:0]      sdram_bank  ,output  wire [12:0]     sdram_addr  ,output  wire [1:0]      sdram_dqm   ,inout        [15:0]     sdram_dq
);/**************************************************************************/
/***************** Define Parameter and Internal Signals ******************/
/**************************************************************************/
// init module
wire                        flag_init_end   ;
wire    [3:0]               init_cmd        ;
wire    [12:0]              init_addr       ;/**************************************************************************/
/******************************* Main Code ********************************/
/**************************************************************************/
assign  sdram_cke       =   1'b1;
assign  sdram_addr      =   init_addr;
assign  {sdram_cs_n, sdram_ras_n, sdram_cas_n, sdram_we_n} =   init_cmd;
assign  sdram_dqm       =   2'b00;
assign  sdram_clk       =   ~sclk;		// sdram 命令生成时钟与 sdram 命令采集时钟反向,保证命令采集时命令已经稳定生成sdram_init sdram_init_inst
(// system signals.sclk	        (sclk),             // 板载系统时钟 50MHz.s_rst_n        (s_rst_n),          // 复位信号,低电平有效// others.cmd_reg        (init_cmd),         // 输出的命令(即 CS、RAS、CAS、WE 这四位).sdram_addr     (init_addr),        // SDRAM 地址.flag_init_end  (flag_init_end)     // 初始化结束标志
);endmodule 

2.2.3 tb_sdram_top.v

// tb_sdram_top.v 源码
`timescale 1ns/1nsmodule tb_sdram_top;reg             sclk		;
reg             s_rst_n		;wire            sdram_clk   ;
wire            sdram_cke   ;
wire            sdram_cs_n  ;
wire            sdram_cas_n ;
wire            sdram_ras_n ;
wire            sdram_we_n  ;
wire [1:0]      sdram_bank  ;
wire [12:0]     sdram_addr  ;
wire [1:0]      sdram_dqm   ;
wire [15:0]     sdram_dq    ;initial 
beginsclk    =   1;s_rst_n <=  0;#100s_rst_n <=  1;
endalways  #10     sclk    =   ~sclk;sdram_top sdram_top_inst
(// system signals.sclk	        (sclk),             // 板载系统时钟 50MHz.s_rst_n        (s_rst_n),          // 复位信号,低电平有效// SDRAM Interfaces.sdram_clk      (sdram_clk),.sdram_cke      (sdram_cke),.sdram_cs_n     (sdram_cs_n),.sdram_cas_n    (sdram_cas_n),.sdram_ras_n    (sdram_ras_n),.sdram_we_n     (sdram_we_n),.sdram_bank     (sdram_bank),.sdram_addr     (sdram_addr),.sdram_dqm      (sdram_dqm),.sdram_dq       (sdram_dq)
);defparam	sdram_model_plus_inst.addr_bits = 13;					// 13
defparam    sdram_model_plus_inst.data_bits = 16;
defparam	sdram_model_plus_inst.col_bits	= 9;
defparam    sdram_model_plus_inst.mem_sizes = 2*1024*1024;		    // 2Msdram_model_plus sdram_model_plus_inst
(.Dq              (sdram_dq), .Addr            (sdram_addr), .Ba              (sdram_bank), .Clk             (sdram_clk), .Cke             (sdram_cke), .Cs_n            (sdram_cs_n), .Ras_n           (sdram_ras_n), .Cas_n           (sdram_cas_n), .We_n            (sdram_we_n), .Dqm             (sdram_dqm),.Debug           (1'b1)
);endmodule 

2.3 Modelsim仿真

  SDRAM 的仿真需要使用到一个模拟 SDRAM 的仿真插件(即 tb_sdram_top.v 源码中例化的 sdram_model_plus 例化模块),可以在 Kevin 大佬的交流群里获取。顺带一提,拿到手上的插件是适用于 11 位地址的 SDRAM,要用在 13 位地址的 SDRAM 上还得自行重定义一些参数(已经在 tb 文件中改完了)。另外,在 sdram_model_plus 中还有关于时间参数的配置,可以根据手册与实际配置酌情调整:
在这里插入图片描述
  之后创建 Modelsim 工程,将 tb_sdram_top.v 、sdram_model_plus.v、 sdram_top.v 和 sdram_init.v 加入工程进行编译,编译通过后检查仿真波形:
在这里插入图片描述
  仿真中的复位信号是延时 100ns 之后释放的,加上模块里的 200us 延时,正好 200100 ns 开始动作,仿真的波形变化正常,符合预期,且因为 SDRAM 仿真插件的缘故,可以在 Modelsim 的调试信息栏中看到仿真插件也识别出了 SDRAM 初始化模块的指令以及模式寄存器配置:
在这里插入图片描述

PS:根据初始化时序图要求,在给出模式寄存器的配置命令后还需要经过 tMRD 时间,也就是 2 个时钟周期以后才能进行 ACTIVE 操作,而初始化模块的完成标志实际上在进行模式寄存器配置的瞬间就拉高了。考虑到当前时间周期拉高,下一个周期信号能被其他模块正常接收,所以如果想要再稳妥一些,可以让初始化完成标志再晚 1 个时钟周期后拉高。

三、刷新模块

3.1 模块时序图

  Precharge 命令后实际上只需要给一次 Auto Refresh 命令就可以了,不用给两次:
在这里插入图片描述

3.2 模块源码

3.2.1 sdram_aref.v

module sdram_aref
(// system signalsinput 				    sclk	        ,       // 板载系统时钟 50MHzinput                   s_rst_n         ,       // 复位信号,低电平有效// communicate with ARBITinput                   ref_en          ,output  wire            ref_req         ,output  wire            flag_ref_end    ,       // 刷新结束标志// othersoutput  reg     [3:0]   aref_cmd        ,       // 刷新命令output  wire    [12:0]  sdram_addr      ,input                   flag_init_end
);/**************************************************************************/
/***************** Define Parameter and Internal Signals ******************/
/**************************************************************************/
localparam      DELAY_7_8US     =       389     ;       // 64ms 刷新 8192 行,刷新周期为 64 * 1000 / 8192 = 7.8us,转换为 20ns 的时钟周期数约为 390 个localparam      CMD_AREF        =       4'b0001 ;
localparam      CMD_NOP         =       4'b0111 ;
localparam      CMD_PRE         =       4'b0010 ;reg [3:0]                   cmd_cnt             ;
reg [8:0]                   ref_cnt             ;       // 刷新时钟周期计数器
reg                         flag_ref            ;       // 刷新标志,表示刷新模块内部正处于刷新阶段/**************************************************************************/
/******************************* Main Code ********************************/
/**************************************************************************/
// ref_cnt:初始化结束开始计数,计满即清零
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)ref_cnt <= 'd0;else if(ref_cnt >= DELAY_7_8US)ref_cnt <= 'd0;else if(flag_init_end == 1'b1)ref_cnt <= ref_cnt + 1'b1;
end// flag_ref:刷新结束后清零,仲裁允许刷新时进入刷新状态
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)flag_ref <= 1'b0;else if(flag_ref_end == 1'b1)flag_ref <= 1'b0;else if(ref_en == 1'b1)flag_ref <= 1'b1;
end// cmd_cnt:刷新状态下保持自加
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)cmd_cnt <= 'd0;else if(flag_ref == 1'b1)cmd_cnt <= cmd_cnt + 1'b1;elsecmd_cnt <= 'd0;
end// aref_cmd
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)aref_cmd <= CMD_NOP;elsecase(cmd_cnt)1:          aref_cmd <=  CMD_PRE;2:          aref_cmd <=  CMD_AREF;default:    aref_cmd <=  CMD_NOP;endcase
endassign  flag_ref_end    =   (cmd_cnt >= 'd5) ? 1'b1 : 1'b0;
assign  sdram_addr  =   13'b0_0100_0000_0000;
assign  ref_req =   (ref_cnt >= DELAY_7_8US) ?  1'b1 : 1'b0;endmodule 

3.2.2 sdram_top.v

  修改 sdram_top.v 源码,在里面加上仲裁状态机(暂时先不考虑读和写):

module sdram_top
(// system signalsinput 				    sclk	    ,       // 板载系统时钟 50MHzinput                   s_rst_n     ,       // 复位信号,低电平有效// SDRAM Interfacesoutput  wire            sdram_clk   ,output  wire            sdram_cke   ,output  wire            sdram_cs_n  ,output  wire            sdram_cas_n ,output  wire            sdram_ras_n ,output  wire            sdram_we_n  ,output  wire [1:0]      sdram_bank  ,output  wire [12:0]     sdram_addr  ,output  wire [1:0]      sdram_dqm   ,inout        [15:0]     sdram_dq
);/**************************************************************************/
/***************** Define Parameter and Internal Signals ******************/
/**************************************************************************/
localparam          IDLE    =   5'b0_0001   ;   // 空闲状态
localparam          ARBIT   =   5'b0_0010   ;   // 仲裁状态
localparam          AREF    =   5'b0_0100   ;   // 刷新状态// init module
wire                        flag_init_end   ;
wire    [3:0]               init_cmd        ;
wire    [12:0]              init_addr       ;// 仲裁模块
reg     [4:0]               state           ;// refresh module
wire                        ref_req         ;   // 刷新请求(刷新模块产生)
wire                        flag_ref_end    ;   // 刷新结束标志(刷新模块产生)
reg                         ref_en          ;   // 刷新使能(仲裁模块产生)
wire    [3:0]               ref_cmd         ;
wire    [12:0]              ref_addr        ;/**************************************************************************/
/******************************* Main Code ********************************/
/**************************************************************************/
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)state <= IDLE;else case(state)IDLE:if(flag_init_end == 1'b1)state <= ARBIT;elsestate <= IDLE;ARBIT:if(ref_en == 1'b1)state <= AREF;elsestate <= ARBIT;AREF:if(flag_ref_end == 1'b1)state <= ARBIT;elsestate <= AREF;default:state <= IDLE;endcase
end// ref_en
always  @(posedge sclk or negedge s_rst_n)
beginif(s_rst_n == 1'b0)ref_en <= 1'b0;else if(state == ARBIT && ref_req == 1'b1)ref_en <= 1'b1;elseref_en <= 1'b0;
endassign  sdram_cke       =   1'b1;
assign  sdram_addr      =   (state == IDLE) ? init_addr : ref_addr;
assign  {sdram_cs_n, sdram_ras_n, sdram_cas_n, sdram_we_n} =    (state == IDLE) ? init_cmd : ref_cmd;
assign  sdram_dqm       =   2'b00;
assign  sdram_clk       =   ~sclk;     	// sdram 命令生成时钟与 sdram 命令采集时钟反向,保证命令采集时命令已经稳定生成sdram_init sdram_init_inst
(// system signals.sclk	        (sclk),             // 板载系统时钟 50MHz.s_rst_n        (s_rst_n),          // 复位信号,低电平有效// others.cmd_reg        (init_cmd),         // 输出的命令(即 CS、RAS、CAS、WE 这四位).sdram_addr     (init_addr),        // SDRAM 地址.flag_init_end  (flag_init_end)     // 初始化结束标志
);sdram_aref sdram_aref_inst
(// system signals.sclk	        (sclk),             // 板载系统时钟 50MHz.s_rst_n        (s_rst_n),          // 复位信号,低电平有效// communicate with ARBIT.ref_en         (ref_en),.ref_req        (ref_req),.flag_ref_end   (flag_ref_end),     // 刷新结束标志// others.aref_cmd       (ref_cmd),          // 刷新命令.sdram_addr     (ref_addr),.flag_init_end  (flag_init_end)
);endmodule 

  tb_sdram_top.v 与 sdram_model_plus 仿真插件无需修改,可直接使用。

3.3 Modelsim仿真

  检查单次刷新操作的时序波形,无异常。这里注意一下,有一个潜在隐患,即根据手册上给出的时序图,刷新操作中给出 Auto Refresh 命令后保持的 NOP 命令时长至少应为 66ns,也就是 4 个时钟周期(4 * 20ns = 80ns > 66ns),而跟着教程敲出来的代码在给出 Auto Refresh 命令后 2 个时钟周期就结束了刷新操作,退出刷新状态。对该问题已在代码中做了相应修改,可根据仿真波形图进行查验:
在这里插入图片描述
  刷新周期 7.8us 一次,15us 就是两次,细化到时间轴上,两次刷新间隔 215990 ns - 208190ns = 7800ns = 7.8us,满足设计要求:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/RZC035av.shtml

相关文章

手把手带你实现SDRAM控制器(带Verilog代码)

上篇博客&#xff0c;我们了解了SDRAM的控制命令以及寻址方式&#xff0c;SDRAM芯片需要配合专门的控制电路使用才能发挥功能&#xff0c;这一节我们将一步步分析&#xff0c;使用Verilog搭建一个SDRAM驱动控制器。 目录 学习目标 问题分析 初始化模块 信息收集 模块接口确…

SDRAM 控制器(一)

1、基础知识 SDRAM&#xff08;synchronous Dynamic Random &#xff09;&#xff0c;同步动态随机存储器&#xff0c;同步指内存工作需要同步时钟&#xff0c;内存的命令的发送和数据的接收都以它为标准。动态是指需要不断地刷新来保证数据不丢失&#xff08;电容存储&#xf…

操作系统面试题(二十一):什么是DMA

DMA DMA&#xff08;Direct Memory Access 直接内存访问&#xff09; DMA意味着CPU授予I/O模块权限不涉及在不涉及CPU的情况下依然可以读取/写入内存&#xff0c;即DMA不需要CPUde支持 DMAC&#xff08;DMA 控制器&#xff09; 控制直接内存访问的过程 DMA的优点&#xff1a…

操作系统面试题:虚拟内存是什么,解决了什么问题,如何映射?

虚拟内存是什么&#xff1f; 虚拟内存别称虚拟存储器&#xff08;Virtual Memory&#xff09;。电脑中所运行的程序均需经由内存执行&#xff0c;若执行的程序占用内存很大或很多&#xff0c;则会导致内存消耗殆尽。为解决该问题&#xff0c;Windows中运用了虚拟内存技术&…

Linux面试题(34道)

1、Linux中各个目录的作用 1&#xff09;/ 根目录 2&#xff09;/boot 引导程序&#xff0c;内核等存放的目录 3&#xff09;/sbin 超级用户可以使用的命令的存放目录 4&#xff09;/bin 普通用户可以使用的命令的存放目录 5&#xff09;/lib 根目录下的所程序的共享库目录 6&…

【游戏客户端面试题干货】-- 2021年度最新游戏客户端面试干货(操作系统篇)

【游戏客户端面试题干货】-- 2021年度最新游戏客户端面试干货(操作系统篇&#xff09; 大家好&#xff0c;我是Lampard~~ 经过一番艰苦奋战之后&#xff0c;我终于是进入了心仪的公司。 今天给大家分享一下我在之前精心准备的一套面试知识。 今天和大家分享的是操作系统相关的面…

操作系统和网络(一):计算机网络常见面试题

计算机网络常见面试题总结 1. OSI &#xff0c; TCP/IP &#xff0c;五层协议的体系结构 OSI分层&#xff08;7层&#xff09; &#xff1a;物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP分层&#xff08;4层&#xff09; &#xff1a;网络接…

【Java实习生】每日面试题打卡——操作系统篇

临近秋招&#xff0c;备战暑期实习&#xff0c;祝大家每天进步亿点点&#xff01;Day15本篇总结的是 操作系统 相关的面试题&#xff0c;后续会每日更新~ 1、请分别简单说一说进程和线程以及它们的区别? 根本区别&#xff1a;进程是操作系统资源分配的基本单位&#xff0c;而…

操作系统面试题(一)

请你说一下进程与线程的概念&#xff0c;以及为什么要有进程线程&#xff0c;其中有什么区别&#xff0c;他们各自又是怎么同步的 参考回答&#xff1a; 基本概念&#xff1a; 进程是对运行时程序的封装&#xff0c;是系统进行资源调度和分配的的基本单位&#xff0c;实现了…

操作系统面试常问——for考研复试面试

关于操作系统的一些面试常问问题 前言&#xff1a; 本人22考研党已上岸&#xff0c;发一些复试准备整理的资料作为对考研准备的一个收尾。由于近几年基本都是线上复试&#xff0c;线上的话会更加注重概念的考察&#xff0c;本人在复试准备期间搜集了面试题&#xff0c;整理了…

操作系统面试题(三)

请你来说一说协程 参考回答&#xff1a; 1、概念&#xff1a; 协程&#xff0c;又称微线程&#xff0c;纤程&#xff0c;英文名Coroutine。协程看上去也是子程序&#xff0c;但执行过程中&#xff0c;在子程序内部可中断&#xff0c;然后转而执行别的子程序&#xff0c;在适…

操作系统面试题(十四):什么是虚拟内存?

虚拟内存&#xff08;virtual Memory&#xff09; 日常生活中&#xff0c;当我们使用电脑的时候&#xff0c;尤其是windows电脑&#xff0c;经常会打开许多软件&#xff0c;这些软件占用的内存已经远远大于计算机的物理内存。之所以会这样&#xff0c;就是因为虚拟内存的存在 …

操作系统面试题:设备管理

管理什么设备&#xff1f; 除cpu,内存外的所有设备 怎么管理设备&#xff1f; 通过将物理设备映射成逻辑设备 为什么要把物理设备映射成逻辑设备&#xff1f; 物理设备是I/O系统中实际安装的设备&#xff0c;物理名通常是字符串或者ID 而逻辑设备的逻辑名比较好记 如何理解…

操作系统面试问题汇总(超详细)

操作系统的组成 1、驱动程序是最底层的、直接控制和监视各类硬件的部分&#xff0c;它们的职责是隐藏硬件的具体细节&#xff0c;并向其他部分提供一个抽象的、通用的接口。 2、内核是操作系统之最内核部分&#xff0c;通常运行在最高特权级&#xff0c;负责提供基础性、结构性…

操作系统面试题(二)

请你讲述一下互斥锁&#xff08;mutex&#xff09;机制&#xff0c;以及互斥锁和读写锁的区别 参考回答&#xff1a; 1、互斥锁和读写锁区别&#xff1a; 互斥锁&#xff1a;mutex&#xff0c;用于保证在任何时刻&#xff0c;都只能有一个线程访问该对象。当获取锁操作失败时…

几率大的杂乱+操作系统面试题(含答案)

其他面试题类型汇总&#xff1a; Java校招极大几率出的面试题&#xff08;含答案&#xff09;----汇总 几率大的网络安全面试题&#xff08;含答案&#xff09; 几率大的多线程面试题&#xff08;含答案&#xff09; 几率大的源码底层原理&#xff0c;杂食面试题&#xff08;含…

操作系统常见面试题

文章目录 进程和线程进程和线程的区别协程与线程的区别进程与线程的切换流程什么是虚拟地址空间为什么虚拟地址空间切换后感觉程序变慢进程间通信方式线程&#xff08;进程&#xff09;间同步方式线程的分类协程&#xff08;纤程&#xff09;线程和协程的区别 进程&#xff08;…

这可能最全的操作系统面试题

文章目录 操作系统简介篇解释一下什么是操作系统操作系统的主要功能软件访问硬件的几种方式解释一下操作系统的主要目的是什么操作系统的种类有哪些为什么 Linux 系统下的应用程序不能直接在 Windows 下运行操作系统结构单体系统分层系统微内核客户-服务器模式 为什么称为陷入内…

操作系统面试题(史上最全、持续更新)

尼恩面试宝典专题40&#xff1a;操作系统面试题&#xff08;史上最全、持续更新&#xff09; 本文版本说明&#xff1a;V28 《尼恩面试宝典》升级规划为&#xff1a; 后续基本上&#xff0c;每一个月&#xff0c;都会发布一次&#xff0c;最新版本&#xff0c;可以联系构师尼…

操作系统面试题总结(2022最新版)

关于作者 &#x1f436; 程序猿周周 ⌨️ 短视频小厂BUG攻城狮 &#x1f93a; 如果文章对你有帮助&#xff0c;记得关注、点赞、收藏&#xff0c;一键三连哦&#xff0c;你的支持将成为我最大的动力 本文是《后端面试小册子》系列的第 4️⃣ 篇文章&#xff0c;该系列将整理和梳…