04:2440---内存控制器

目录

一:介绍

1:引入

2:概念 

3:通信

A:片选信号

B:片选信号的地址空间范围 ​​​​

4:地址线

A:不同位数的接法

B:访问原理

C:访问地址

5:时序

1:NOR FLASH

 A:2440NOR FLASH时序 

B:原理/时序图

C:寄存器

6:SDARM

A:访问方式

B:原理图

C:BWSCON

D:BANKCON6

E:REFRESH

F:ANKSIZE

G:MRSR

二:代码

1:NOR FLASH

2:SDARM 


 

一:介绍

1:引入

        操作GPIO: 我们可以编写程序,让CPU去访问里面的寄存器

         eg:GPFCON配置寄存器 . 可以设置这个寄存器,把某个引脚设置为输出或者输入; GPFDATA数据寄存器, 可以设置某个引脚发出高低电平. 

        UART一样我们可以写程序让CPU访问某些特定的寄存器.

         对于CPU来说,我不关心你这些具体的接口,我只是去操作某个寄存器。我CPU把某些值写给某些寄存器,由这些对应的控制器发出特定的波形。所以这个时候我们的内存控制器就来了

2:概念 

        CPU发出的地址信号并不会传到外面来(eg:GPIO口)。CPU只是用地址来选择里面的不同寄存器。然后CPU把数据发给里面的寄存器,至于这些数据,这些地址会起什么作用,完全由里面的控制器决定。CPU发出来这些信号呢,并不会直接的输出到外部电路去。凡事都有例外(内存接口).

        内存接口:对于这种接口的设备CPU发出来的地址,可以直接传给这些设备。

        在原理图种也可以看到 数据信号CPU发出的地址和数据直接传给这个芯片

       

         内存控制器作用:

3:通信

A:片选信号

        内存控制器根据CPU发出的地址,设置不同的片选引脚,只有被选中的芯片才会工作,没有选中的芯片不会影的他

        

        只有使得某个片选引脚输出低电平的时候,对应的芯片才会开始工作,

SDRAM: 

        在SDRAM中只有LnWE, 所以LnWE负责写入数据和读取数据

NOR FLASH

        LnOE:拉低负责读取数据, LnWE负责写入数据

DM900:

        LnOE:拉低负责读取数据, LnWE负责写入数据

        CPU根据指令发出地址信号,内存控制器来根据这些地址来决定选中哪一些芯片。

B:片选信号的地址空间范围 ​​​​

每个片选引脚相隔134217758位, 当地址处于某一个范围的时候, 对于的片选信号才会有效----见4地址线C:访问地址

至少需要A0~A27条地址线:

        内存的存储单元个数=2^地址线的条数,因此计算内存的总地址线数的公式为: 地址线的条数=log2(内存的存储单元个数.

        CPU有32位地址线, 但是内存控制器他的能力只能控制27位地址线

        只有使得某个片选引脚输出低电平的时候,对应的芯片才会开始工作, 

4:地址线

A:不同位数的接法

8位

CPU的A0接到芯片的A0

16位

        当使用两个8位的芯片拼接(DATA0-7接一个芯片,DATA8-15接一个芯片,也就是组成了一个16位的芯片)的时候,CPU的A1接芯片的A0(CPU的A0用来判断高8位有效还是低8位有效) 

CPU的A1接的位芯片的A0

32位

CPU的A2接到芯片的A0 

B:访问原理

          CPU把地址发送给内存控制器,  内存控制器找到了相应地址的内存类设备(ROM),  内存类设备(ROM)返回数据给内存控制器, 内存控制器找到了储存单元种的数据发送给CPU.

         内存控制器所发出的地址线, 有一部分接到了芯片上. 有一部分没有接接到芯片上。

        接到了芯片上的这些引脚呢用来确定,读取这个芯片上哪一个单元,把这个单元返回给内存控制器。而内存控制器呢,会使用那些没有接的引脚来确定从这个单元中取出哪一个字节返回给CPU

eg:

C:访问地址

5:时序

1:NOR FLASH

我们这里面只研究读时序

 A:2440NOR FLASH时序 

        Taa: 发出add后时间DATA才有效,  可以看到max时间为70ns, 如果在70ns之内访问数据,数据可能不太稳定, 导致我们读取数据错误.  

        Tce: 和上面的差不多, 片选信号的max为70 

        所以我们为了简单可以把地址,片选,读写,数据信号以70ns一起发出

B:原理/时序图

        我们可以看到NOR FLASH有21根地址信号(但是CPU只连接芯片的20根), 16个数据信号, 以及片选限号NCS0,  和写信号LnWE读信号LnOE

        我们可以计算一下我们这个2440NOR FLASH内存的大小

2^21/1024/1024=2MB

        先发出地址信号,经过Tacs时间发出片选信号(nGCS),然后经过Tcos时间发出读信号,过一会数据才有效,把数据读走,然后把读信号释放掉,把片选信号释放掉,然后才开始新的地址周期 
        Tacs ,Tcos,Tacc,Tacp...这些需要根据不同的芯片来进行设置

        因为J2440可以接不同类型的内存类芯片,这些内存内芯片性能不同,所以所用的时间周期也不同。

C:寄存器

在上次种我们把HCLK该为了100MHZ

他默认为14clocks(14*10=140>70), 所以每次时序都可以正常的运行

6:SDARM

A:访问方式

        不像NOR FLSAH一样直接发送地址, SDRAM拆分地址在发送

B:原理图

        SDARM是由2个16为的芯片组合而成, 成为32位的芯片。 故内存大小 

2^32=4294967296bit=4194304KB=4096MB=4GB

        挂载在BANK6上,片选引脚为nGCS6

C:BWSCON

        因为我们的SDRAM只挂载在BANK6上, 所以我们只关系BANK6。

        DW6: 我们的bank是32位的所以选择---10

        WS6: WAIT是由芯片发送给CPU的信号, 以前的芯片准备数据慢, 在CPU给内存控制器发送地址后。内存控制器给给芯片发送各种信号,准备采集数据,但是芯片如果还没有准备好数据可以给CPU发送WAIT信号。最大的宽限时间。 等待信号的使能,由于现在的内存速度足够快,在读数据时不需要内存控制器等待,选择0。

        ST6:BANK6的带宽,选择32位

BWSCON=0x02000000

D:BANKCON6

 

        MT: 我们使用的位SDRAM,使用选择11

        Trcd:这个域的配置表示的是发送行有效命令到列有效命令之间的时间间隔。在发送列读写命令时必须要与行有效命令有一个间隔,这个间隔被定义为tRCD,即RAS to CAS Delay(RAS至CAS延迟),可以理解为行选通周期,这应该是根据芯片存储阵列电子元件响应时间(从一种状态到另一种状态变化的过程)所制定的延迟。

我们使用HCLK为10ns,所以选择00

        SCAN:列地址的位数 选择01 --9位

BANKCON6=0x00018001

E:REFRESH

        之所以称为DRAM,就是因为它要不断进行刷新(Refresh)才能保留住数据,因此它是DRAM最重要的操作

        REFRE:肯定要使能刷新操作。---1

        

        TREFMD:刷新操作分为两种:自动刷新(Auto Refresh,简称AR)与自刷新(Self Refresh,简称SR)。对于AR, SDRAM内部有一个行地址生成器(也称刷新计数器)用来自动的依次生成行地址。SR则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是STR(Suspend to RAM,休眠挂起于内存)。这里不使用低功耗模式,故TREFMD=0B,使用自动刷新。-----0

        

        Trp:预充电时间。其实就是读取不同行之间的时间间隔。L-Bank关闭现有工作行,准备打开新行的操作就是预充电(Precharge)。在发出预充电命令之后,要经过一段时间才能允许发送RAS行有效命令打开新的工作行,这个间隔被称为tRP(Precharge command Period,预充电有效周期)。-----00即20ns

        

        Tsrc:--01        Trc我们取70ns, Trp我们设置的为20ns, 所以Tsrc=Trc-Trp=70-20=50ns

        Refresh Conuter:我们根据SDARM芯片的Refresh period(刷新周期)的值确定刷新计数器的值。

64ms/8192bit=7.8ms

Refresh count = 2^11 + 1  100x7.8 = 1269=0x4f5---以为我们使用的HCLK为100MHZ

REFRESH=0x008404f5

F:ANKSIZE

BURST_EN:使能突发传输

突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元(列)的数量就是突发长度(Burst Lengths,简称BL)。

        BURST_EN :使能他,一次访问多个字节
         SCKE_EN :使用时钟使能休眠模式
ANKSIZE=0x000000b1

G:MRSR

 CL:

 

        WBL:突发长度选择固定,第二个值为reserved,也没得选


        TM:只能选00B


        CL:CL是SDRAM很重要的参数

        在选定列地址后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据I/O通道(DQ)输出到内存总线上了。但是在CAS发出之后,仍要经过一定的时间才能有数据输出,从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为CL(CAS Latency,CAS潜伏期)。由于CL只在读取时出现,所以CL又被称为读取潜伏期(RL,Read Latency)。CL的单位与tRCD一样,为时钟周期数,具体耗时由时钟频率决定。

        设置CL为2个时钟周期。CL=010B。


        BT:只能选0


        BL:只能选0

MRSR=0x00000020

二:代码

1:NOR FLASH

/* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8  */
    ldr r0, =0x4C000018
	ldr r1, =(0<<9)
	str r1, [r0]
        
    ldr r0, =0x4C000014
	ldr r1, =0x5
	str r1, [r0]

/* 设置CPU工作于异步模式 */
	mrc p15,0,r0,c1,c0,0
	orr r0,r0,#0xc0000000   //R1_nF:OR:R1_iA
	mcr p15,0,r0,c1,c0,0

/*设置MPLLCON*/
	ldr r0, =0x4C000004
	ldr r1, =(92<<12)|(1<<4)|(1<<0)
	str r1, [r0]

	/* 一旦设置PLL, 就会锁定lock time直到PLL输出稳定
	 * 然后CPU工作于新的频率FCLK
	 */
	

 /*设置内存: sp栈* 我们判断是nor启动还是nand启动/

	mov r1, #0
	ldr r0, [r1] /* 读出原来的值备份 */
	str r1, [r1] /* 0->[0] */ 
	ldr r2, [r1] /* r2=[0] */
	cmp r1, r2   /* r1==r2? 如果相等表示是NAND启动 */
	ldr sp, =0x40000000+4096 /* 先假设是nor启动 */
	moveq sp, #4096  /* nand启动 */
	streq r0, [r1]   /* 恢复原来的值 */
	

	
	 bl main


halt:
	b halt


#define ULCON0 (*((volatile unsigned int*)0x50000000))
#define UCON0 (*((volatile unsigned int*)0x50000004))
#define UBRDIV0 (*((volatile unsigned int*)0x50000028))
#define GPHCON (*((volatile unsigned int*)0x56000070))
#define GPHUP (*((volatile unsigned int*)0x56000078))
#define UFCON0 (*((volatile unsigned int*)0x50000008))
#define UTRSTAT0 (*((volatile unsigned int*)0x50000010))
#define UTXH0 (*((volatile unsigned char*)0x50000020))
#define URXH0 (*((volatile unsigned char*)0x50000024))
#define BANKCON0 (*((volatile unsigned int*)0x48000004))
#define GPFCON (*((volatile unsigned int*)0x56000050))
#define GPFDAT (*((volatile unsigned int*)0x56000054))

int LED_on()
{	/*设置寄存器 点亮LED2*/

	/*设置输出模式*/
	GPFCON = 0x400;
	/*输出低电平*/
	GPFDAT = 0;
	return 0;
}

void init_nc_tacc(int val)
{

	BANKCON0 = val << 8;

}
void UART_init()
{
	/*引脚设置*/
	GPHCON &= ~((3 << 4) | (3 << 6));
	GPHCON |= ((2 << 4) | (2 << 6));

	GPHUP &= ~((1 << 2) | (1 << 3));  /* 使能内部上拉 */

	/*设置波特率---设置波特率位115200*/
	/*
	 UBRDIVn = (int)(selected clock / (baudrate x 16) ) –1
	 我们使用我们的FCLK作为我们的时钟源--在汇编中是50MHZ
	UBRDIVn=(5000 0000 /(115200*16))-1=26
	*/
	UCON0 = 0x00000005;
	UBRDIV0 = 26;

	/*数据格式*/
	ULCON0 = 0x00000003;  //不能写为这个ULCON0 |= (3 << 1)因为还要关注其他位;/*数据位=8,停止位=1,无奇偶校验 8n1*/
}
int putchar(int c)
{
	/*发送数据*/
	while ((UTRSTAT0 & (1 << 2)) == 0); //while (!(UTRSTAT0 & (1 << 2)));
	

	UTXH0 = (unsigned char)c;
}

int getchar(void)
{
	/*接收数据*/
	while ((UTRSTAT0 & (1 << 0)) == 0); //while (!(UTRSTAT0 & (1 << 0)));
	

	return URXH0;
}

int puts(const char* s)
{
	while (*s)
	{
		putchar(*s);
		s++;
	}

}


#include "uart.h"
#include "sc2440_so.h"
#include "NOR.h"
#include "led.h"
int main(void)
{
	unsigned char  c;

	UART_init();
	puts("Please enter the numbesr:\n\r");

	while (1)
	{
		c = getchar();
		putchar(c);
		if (c >= '0' && c <= '7')
		{
			init_nc_tacc(c-'0');
			LED_on();

		}
		else
		{
				puts("Error: The number you entered is not between 0 and 7\n\r");
				puts("Please rewrite input\n\r");
		}

		
	}
	return 0;
}


init_nc_tacc(c-'0');和init_nc_tacc(c);的区别

在编程中,init_nc_tacc(c-'0'); 和 init_nc_tacc(c); 的区别取决于 init_nc_tacc 函数如何定义和 c 的数据类型。

  1. 如果 c 是一个字符型变量(如 char,并且代表一个数字字符(例如 '1''2''3' 等):

    • c-'0' 通常用于将字符型数字转换为实际的整数。在ASCII编码中,数字字符 '0' 到 '9' 是连续的,因此通过减去 '0'(其ASCII值为48)可以将字符型数字转换为整数。例如,如果 c 是 '3'c-'0' 将得到整数 3
    • init_nc_tacc(c-'0'); 会将转换后的整数传递给函数。
    • init_nc_tacc(c); 则会将字符型变量传递给函数。
  2. 如果 c 不是代表数字的字符,那么 c-'0' 可能没有明确的意义,并且可能不会得到预期的结果。

  3. 如果 init_nc_tacc 函数对字符和整数有不同的处理逻辑,那么两个调用会有不同的效果。

  4. 如果 c 是其他数据类型,比如已经是一个整数,那么 c-'0' 就没有意义,并且可能导致编译错误或不可预测的行为。

2:SDARM 

代码大致和NOR FLASH不变, 我们这里只展示改变的

#include "sc2440_so.h"
void SDARMA_init(void)
{
	BWSCON = 0x02000000;
	BANKCON6 = 0x00018001;
	BANKCON7 = 0x00018001;
	REFRESH = 0x008404f5;
	ANKSIZE = 0x000000b1;
	MRSRB6 = 0X00000020;
	MRSRB7 = 0X00000020;
}
int init_test(void)
{	
	//片选引脚为nGCS6
	volatile unsigned char* p = (volatile unsigned char*)0X30000000;
	int i;
	//write 操作
	for (i = 0; i < 1000; i++)
	{
		p[i] = 0x55;
	}
	//读操作
	for (i = 0; i < 1000; i++)
	{
		if (p[i] != 0x55) {
			return -1;
		}
	}
	return 0;

}

#include "uart.h"
#include "sc2440_so.h"
#include "NOR.h"
#include "led.h"
int main(void)
{
	unsigned char c;

	UART_init();
	
	puts("Please enter the numbesr:\n\r");
	
	while (1)
	{
		c = getchar();
		putchar(c);
		if (c == '1') {
			SDARMA_init();
			
			if(init_test() == 0)
			{
				LED_on();
	
			}
		}
		else
		{
			puts("Error: Please retype:\n\r");
		}
	}
	return 0;
}

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

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

相关文章

【Linux系统编程】操作系统详解(什么是操作系统?为什么会存在操作系统?设计操作系统的目的是什么?)

目录 一、前言 二、 什么是操作系统 &#x1f4a6;操作系统的引入 &#x1f4a6;操作系统的概念理解 &#x1f4a6;操作系统设计的目的与定位 &#x1f4a6;总结 二、操作系统之上之下分别有什么 三、深度理解操作系统的“管理” &#x1f4a6;场景理解 &#x1f4a6;操…

视频文件+EasyDarwin做摄像机模拟器模拟RTSP流很方便,还能做成系统服务,方法与流程

之前我看到过一家人工智能做算法的企业&#xff0c;用EasyDarwinFFMPEG做了一个摄像机的模拟器&#xff0c;方法大概是&#xff1a; 用ffmpeg读取mp4等类型的视频文件&#xff08;当然ffmpeg啥都能读取&#xff09;&#xff0c;再以RTSP协议的形式推送给EasyDarwin&#xff1b…

不会提问不打紧,不敢提问才要命

最近在星球里回答了球友提出来的一些问题&#xff0c;我都给了回复&#xff0c;不经过在明确问题、探索问题的过程&#xff0c;对我启发挺大&#xff0c;特此来记录下感受和感悟。 缘起 最近新加入球友提的问题&#xff0c;有几次&#xff0c;我第一时间没看懂&#xff0c;甚…

【沐风老师】3DMAX快速地板屋顶墙面铺设插件使用方法详解

3DMAX快速地板屋顶墙面铺设插件使用教程 3DMAX快速地板屋顶墙面铺设插件&#xff0c;一键生成各种地板、墙面纹理模型&#xff0c;是一款非常实用的室内设计和建筑建模插件。 【适用版本】 3dMax7或更新版本 【安装方法】 该插件无需安装&#xff0c;直接在建模过程中使用&a…

【leetcode】62. 不同路径

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; …

如何减少40%的Docker构建时间

随着Docker的普及&#xff0c;许多公司的产品会将组件构建为Docker镜像。但随着时间的推移&#xff0c;一些镜像变得越来越大&#xff0c;对应的CI构建也变得越来越慢。 如果能在喝完一杯咖啡的时间&#xff08;不超过5分钟&#xff09;内完成构建&#xff0c;将是一个理想状态…

关于高斯核是实现尺度空间变换的唯一性思考

受到自己的启发&#xff0c;唯一性证明有了思路&#xff1a; 谁的一阶导数是自己&#xff0c;exp&#xff08;x&#xff09;&#xff0c;只有是自己&#xff0c;才能保持自己在其中。 为什么不能是exp&#xff08;x&#xff09;呢&#xff1f;不变导致图像不会模糊&#xff0…

二叉树:leetcode1457. 二叉树中的伪回文路径

给你一棵二叉树&#xff0c;每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的&#xff0c;当它满足&#xff1a;路径经过的所有节点值的排列中&#xff0c;存在一个回文序列。 请你返回从根到叶子节点的所有路径中 伪回文 路径的数目。 给定二叉树的节点数目…

【LeetCode 热题 HOT 100】题解笔记 —— Day02

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

「媒体邀约」三农,农业类媒体资源有哪些?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 农业在我国国民经济中的地位是基础&#xff0c;农业是国民经济建设和发展的基础产业&#xff0c;因此围绕三农发展有很多的公司和企业&#xff0c;每年全国都有大大小小关于农业的展览&a…

浅谈联网汽车安全漏洞

“智能网联汽车存在内生共性问题&#xff0c;即软硬件的漏洞后门&#xff0c;基于此进行的网络攻击可以直接带来勒索、盗窃、大规模车辆恶意操控风险&#xff0c;还有数据泄露等网络安全事件。如果内生的漏洞后门问题不解决&#xff0c;系统自身难保&#xff0c;很难谈系统安全…

Oracle Linux 9.3 发布

导读Oracle Linux 9 系列发布了第 3 个版本更新&#xff0c;支持 64 位 Intel 和 AMD (x86_64) 以及 64 位 Arm (aarch64) 平台。与所有的 Oracle Linux 版本一样&#xff0c;此版本与相应 RHEL 版本 100% 应用二进制兼容。 对于 x86_64 和 aarch64 架构&#xff0c;Oracle Li…

HT97220与HT97230耳机放大器芯片对比

HT97230有两个不同开启时间(tON)版本&#xff0c;版本A、C和E的导通时间tON为5.5ms&#xff0c;用于耳机驱动&#xff1b;B和D则具有130ms的tON&#xff0c;用于机顶盒设计&#xff08;目前仅提供A版本&#xff0c;其他版本需预定&#xff09;。内部电荷泵对输入电源反相&#…

校园虚拟化部署与横向扩展统一存储

项目背景 这所隶属教育部直属重点大学&#xff0c;学校设有11个学科体系&#xff0c;现有本硕博学生共29000余人&#xff0c;为积极响应“中国教育现代化2023战略部署”&#xff0c;校方制定教育信息化2.0发展目标&#xff0c;通过平台融合&#xff0c;数据驱动、技术赋能等措…

开发测试利器之Fiddler网络调试工具详细安装使用教程(包含汉化脚本)

一、Fiddler简介 Fiddler 是一款功能强大的网络调试工具&#xff0c;可以帮助开发人员和测试人员分析和调试网络流量。它通过截取计算机和服务器之间的HTTP/HTTPS请求&#xff0c;并提供详细的请求和响应信息来帮助我们理解和诊断网络通信。 Fiddler 可以用于各种用途&#x…

qgis配的样式保存到postgis中

--查看图层与样式的关联关系 SELECT * FROM layer_styles; 先从postgis导入数据到qgis中&#xff0c;没有样式 在qgis设置样式后&#xff0c;将样式保存到数据库 再次查询数据库表样式&#xff0c;刚才的样式就进来了 再次从数据库加载图层时会自带上样式

accelerate的使用说明

1 多卡(GPU)使用方法 终端输入指令&#xff0c;生成问答页面 accelerate config 这个方法也是可以的 2 后面修改直接找到这个yaml文件进行修改即可 cd ~/.cache/huggingface/accelerate vim default_config.yaml 进入vim进行修改 3 单卡(GPU)使用方法 vim default_config.…

内衣洗衣机怎么选?内衣洗衣机便宜好用的牌子推荐

相信不少用户并不太在意衣服和内衣裤裤能不能同时洗&#xff0c;每次清洗都是把内衣裤与其他衣服一起放入洗衣机清洗&#xff0c;其实内衣裤不能直接跟大件的衣物一起放入洗衣机洗的&#xff0c;很容易会造成我们皮肤的瘙痒&#xff0c;我们大部分时间都在户外&#xff0c;暴露…

sCrypt 在英国伦敦 Exeter 大学讲学

6月5日&#xff0c;sCrypt CEO晓晖和他的两位同事在英国伦敦Exeter大学举行了一场精彩的讲座。刘晓晖向听众们详细介绍了sCrypt智能合约开平台&#xff0c;并演示了如何使用sCrypt来开发基于比特币的智能合约。他用生动形象的语言&#xff0c;深入浅出地解释了这个领域复杂而又…

Arch Linux 安装 dwm 窗口管理器

窗口管理器是管理桌面上各种窗口的组件&#xff0c;主要功能有&#xff1a;窗口堆叠方式&#xff0c;窗口移动规则等。大多数人接触到的是堆叠式窗口管理器&#xff0c;一个窗口可以叠放在其他窗口之上&#xff0c;调整窗口的主要方式是鼠标。而dwm&#xff08;Dynamic Window …