韦一之内存控制器,2440地址空间,NOR flash和SDRAM(012课)
大部分内容来自韦东山老师视频及博客:https://blog.csdn.net/thisway_diy/article/details/79389530
一个可参考的很好很详细的博客文档:https://www.cnblogs.com/biaohc/p/6346878.html
内存接口和内存控制器
内存控制器的时钟信号由HCLK时钟信号提供,假设设置的HCLK的值为100M,1clock = 10ns,后续有些时序计算要用到。
S3C2440是个片上系统,有GPIO控制器(接有GPIO管脚),有串口控制器 (接有TXD RXD引脚)。
配置GPIO控制器相应的寄存器,即可让引脚输出高低电平;配置UART控制器相应的寄存器,即可让引脚输出波形。前者相对简单,类似门电路,后者相对复杂,属于协议类接口。类似的协议类接口还有iic、iis、spi等。
对于CPU是不管什么接口的,它只写相应的寄存器,由控制器根据寄存器的配置去控制具体的引脚。
那么CPU是如何访问各个不同的寄存器的呢?
GPIO(门电路),uart(协议类接口)都是通过寄存器控制,寄存器都是内存有地址,继而必须引入一个内存控制器。
作用:cpu发出地址给内存控制器,内存控制器根据地址选择不同模块,(进行操作)把数据发给模块或者从模块中取出数据,最终可以返回数据给CPU。
上面这两个是一类,GPIO/门电路接口、协议类接口,都不会把地址输出到外部。
但是还有一类:内存类接口,会把地址输出到外部,比如Nor Flash、网卡、SDRAM。
cpu给内存控制器,cpu-内存控制线传出的地址直接给内存类设备(芯片)(如nor flash,网卡,内存)
也就是芯片有地址线控制的,接到arm的addr[]线那种
而上面两种cpu给出的地址仅仅就是为了寻找控制寄存器的。
注意:nandflash不同哦!不属于内存接口!
gpio,iic,uart以及片外的nor等都是cpu统一编址,但是nand不是,并不会用到上述那种芯片的addr[]地址线!
在原理图上它的地址线并没有连接到CPU,因此它不参与CPU的统一编址。但它的数据线也接到了数据总线上,为了防止干扰,它肯定也有一个片选信号(CE)。这个片选信号不是内存控制器直接给,而是nand控制器发出,只有当CPU访问Nand Flash时,(cpu发出的地址控制到了nand控制器其中的某个寄存器),nand控制器才会发出片选信号使能nand芯片的片选,让其接收数据总线上的数据。
SDRAM、DM9000网卡、Nor Flash都接在JZ2440的数据总线和地址总线上,CPU把数据和地址发送出去,然后内存控制器根据片选信号选择相应的设备接收地址和数据信号,互不干扰。
地址线可能会接很多设备,是通过片选选定的,片选是如何产生呢?!!!!
cpu把地址(片选也是地址决定的,包含的)发给内存控制器,内存控制器根据不同的地址决定发出哪个片选信号。(也就是让芯片的那个引脚作用)
这个地址信号和外接的芯片(其实是和arm芯片的片选引脚)怎么对应呢,哪个地址内容对应哪个片选引脚作用?
S3C2440将1GB的外部存储地址空间分成了8个BANKS
每个BANK的地址空间为128M,总共1GB(8 BANKs)
(外部存取器地址总共就1GB地址空间,再之上的40000000-FFFFFFFF的3g空间是外设寄存器如GPH0CON等的地址空间,其实也并没有都用完。总共4G,这是由32位机器32个地址线决定的,)
可编程控制的总线位宽(8/16/32bit),不过BANK0只能选择两种位宽(16/32bit)。
总共8个BANK,BANK0-BANK5可以外接ROM,SRAM等,BANK6-BANK7除可以支持ROM, SRAM外还支持SDRAM等。
S3C2440芯片性质决定了,SDRAM类型的内存条只能焊在 Bank6~Bank7上,最大支持内存 256M,即0x30000000–0x3FFFFFFF !!!!!!!!
当选择Nor Flash启动时,发出的地址信号范围是0-0x08000000范围呢,就会让nGCS0引脚处于低电平,硬件中就是Nor Flash被选中。
这是由内存控制器根据cpu提供的地址发出片选信号的。
内存控制器根据不同的地址地址范围,发出不同的片选引脚,只有被片选引脚选中的芯片才能正常工作,不被选中的芯片就像不存在一样,不工作。
cpu给出32位的地址后,内存控制器根据地址发出片选信号和addr0-addr26(共27地址线)。(虽然是32位,但只有27个地址线,够用。)
为什么呢?
比如,0x00000000 -0x08000000,为128M,即每一个片选信号可以选择的空间是128M=2^27,也就需要A0、A1……A26,共27根地址线。外加一个片选线就行了。
补充:
1) 关于nor 和nand,两种不同的启动过程,!!参考第008课的博客内容!!!!
2) 视频中没讲到的重点内容:
我们常说的寄存器的地址位于哪里呢?
2440总共能够寻址的4GB空间,除了0-40000000这个1GB的范围是本节所讲的外设内存地址空间,再就是CPU内部使用的这些特殊功能寄存器地址空间(地址范围为0x4800 0000–0x5FFF FFFF),其余的地址空间没有使用!!
S3C2440A的ARM核内还有31个通用寄存器和6个程序状态寄存器(r0那些),该部分没有被编入我们通常所说的地址空间、即32位地址之中;通过逻辑电路直接给出操作地址(不是很明白???)。 这些寄存器只有通过汇编语言才可以访问;访问时,直接使用他们的名字即可。
下图可能是摘抄自别的板子的外设的内存分配:
值得注意的是nor都是从0地址开始的。SDRAM的3FF FFFF 共 26根地址线,也就是 2^6=64 2^20=1M 那么就是 64M。
我们的板子,提到外部内存设备,貌似就是三个:sdram,DM9000网卡,nor flash。也就是说这三个公用地址总线和数据总线,通过片选分时复用。
CPU是怎样发出地址信号的呢?下面这两个读写指令!!!!!!!!!就会让cpu把32位的地址发给内存控制器。
CPU是大爷,只需要发出指令,把地址给了内存控制器,内存控制器就会跑断腿做一系列操作。
不同位宽设备的连接
注意,个人理解,nbit指的是芯片内部一个地址对应n位,也就是n/8字节。跟这个芯片的存储大小是无关的。换句话说,n位的含义:芯片一次可以对外提供n位数据。
对于不同位数设备,CPU发出的地址是相同的,不过是因为接线空出(0/1地址线)使得rom接收到的地址不同,但最终得到的第几个字节是一样的。
假设CUP执行:
MOV R0, #3 @去地址为3的内存上
LDRB R1, [R0] @ 从内存为3的地址上,读出一个字节
假如传递一个32位的数据时
MOV R0, #4
LDR R1, [R0] @LDR代表读4字节,去地址4读四个字节(4,5,6,7)
执行过程如下:
8bitROM: 当CPU发出地址(000100),内存控制器会把000100,000101,000110,000111处的地址转发给ROM,ROM会把得到的地址000100,000101,000110,000111,上的数据返回给内存控制器,内存控制器会把得到的4个8bit的数据组装成一个32位的数据返回给CPU。
16bitROM: 当CPU发出地址(000100),内存控制器会把00010,00011处的地址转发给ROM,ROM会把得到的地址00010,00011,上的数据返回给内存控制器,内存控制器会把得到的2个16bit的数据组装成一个32位的数据返回给CPU。
32bitROM: 当CPU发出地址(000100),内存控制器会把0001处的地址发送给ROM,ROM会把得到的地址0001上的数据返回给内存控制器,内存控制器会把得到的1个32bit数据返回给CPU。
(cpu只是发给内存控制器一个地址码???应该不是把????那内存控制器怎么知道cpu要的是多少字节的?????)
(内存控制器知道自己接的是多少位的设备??????它怎么知道发几次地址出去?????????)
怎样确定芯片的访问地址:
- 根据片选信号确定基地址,
- 根据芯片所接地址线确定范围
(比stm32简单呀,stm32还得考虑哪个片选线,片选线参与地址的计算,这里直接查出基地址就行了)
实例:
Nor Flash 使用的是片选0(nGCS0),基地址为0,用到A20,A19……A1,A0共21条地址线,所以地址范围为0x00000000 ~ 0x1FFFFF也就是2M的空间大小。
网卡(Net)使用的是片选4(nGCS4),基地址为0x20000000,地址线用了一个laddr2,但是这里还要用到laddr0判断读取的是高8位还是低8位(??????参考网卡dm9000章节) 。所以说共用到A2,A0共2根地址线,所以地址范围为0x20000000 ~ 0x20000005(ob101),(基址由所接片选线确定)。看数据线有16个知道是16位设备!!!!
(片选线不属于地址线中的一根,单独的)(ob表示二进制,)
SDRAM使用的是片选6(nGCS6),基地址为0x30000000。
SDRAM用了17个地址线(加上a0a1),这样计算地址范围难道是128k?(因为本来能访问的地址范围其实就是芯片的内存大小)
而我们用的SDRAM芯片是64M,显然不对。因为这里特殊,SDRAM发出的地址信号会分为列地址行地址,访问一次要发两次地址信号,地址线用两次(参考对应章节)。
内存类设备(地址+数据总线)时序图
信号之间是怎样一起工作的,以Nor Flash 为例。
2440和Nor Flash 之间有地址线,数据线,还有各种数据线连接。
下图是2440内存控制器的读写时序(对应手册图5-12 ngcs timing diagram):
下图是Nor Flash芯片的读时序。
芯片建议的时间,每个参数的参考范围可以通过芯片的AC CHARACTERISTICS得到。
我们需要做的就是设置S3C2440的Nor Flash控制器(应该也就是内存控制器)时序去满足Nor Flash芯片的时序。
易错点:上图中Taa max 70是什么意思呢?这里标注的是芯片的特性!!!!
指的是这段时间最大可能需要70那么久,所以控制器控制的这段时间要大于70。
而不是说,控制器给的这段时间最大是70。
Taa表示的是addr信号发出多久后data数据才有效,芯片需要taa这段时间准备,而准备时间可能最大需要到70ns,所以控制器得比这个时间长!
Tdf 表示在Tdf内数据不稳定,也就是不允许访问其他芯片,30ns。一般不需要理会这个,因为再次访问的时候,还需要时序前面的Taa。等到稳定的时候,数据已经稳定了。
编程:
为了简单我们把地址数据(Addresses),片选信号(CE#),读信号(OE#),同时发出,然后让它们都等待70ns(等待信号有效)。对应S3C2440的Nor Flash控制器的读时序图,需要让地址信号A[24:0]、片选信号nGCS、读信号nOE同时发出,保持Tacc大于等于70ns。
Nor Flash是接在BANKCON0上的,因此只需要设置BANKCON0即可。
( 当选择外接SDRAM时,地址才会被拆分为BANK地址,行地址,列地址。如果不是的话地址会一次性发出去。)
可以看到Tacc上电初始值是111,对应14个clocks。系统上电采用12MHz的晶振,HCLK=12MHz,Tacc=(1000/12*14)≈1166ns,这个值很大,几乎可以满足所有Nor Flash的要求,这的意思也就是上电后设置最大值可以读取所有的nor flash,不至于程序不能运行。我们可以调小,大于70ns即可,否则性能太弱了。
实际中,我们启动后,将HCLK设置为100MHz,T=1000/100=10ns,Tacc需要大于等于70ns,因此设置Tacc等于101,8个clocks即可。
参考其他资料:
BANK0~BANK5 只需要设置BWSCON和BANKCONx这两个寄存器
BANK6~BANK7 外接SDRAM时,除BWSCON和BANKCONx还要设置REFRESH,BANKSIZE, MRSRB6, MRSRB7等4个寄存器。
BWSCON:总线宽度和等待控制寄存器
(韦老师这里没有设置,因为使用默认值即可)
STx:对于SDRAM,此位为0。对于SRAM,此位为1。
WS1: 内存芯片驱动的非常慢,当CPU发出信息后,内存芯片在规定时间内未准备好。此时可以先CPU发出一个等待信号。wait信号是内存芯片向2440CPU发出的。
补充:SRAM使用UB/LB什么意思?(因为我们课程没有外接sram,没有讲这个)
搜索资料,大概如下:
在16位宽的数据线上分开访问高/低字节时要用到。当用SRAM时配置了外部存储器的宽度为16位时,如果程序需要以8位宽度访问外部存储器时,如果要单独写一个字节,就需要处理器有高、低字节选通的控制线,这两条信号线会由硬件自动产生。这样不但可以访问字,还可以访问字节。
(下文sdram配置寄存器的部分详细介绍了这个)
后续插入一个内容:
sdram需要初始化才能读写,实际是配置些寄存器满足时序。
nor flash呢?
要读些nor flash也是要配置寄存器满足时序的,我们前面的代码中都没有配置,因为nor只需要配置bank0的寄存器,只有两个需要设置,默认值却都可以工作,所以没有配置。
而是直接可读: volatile unsigned short *p = (volatile unsigned short *)(base + offset); return *p;
(寄存器配置见内存控制器章节,nor和sdram同属于内存控制器管理,用一套寄存器。只不过sdram寄存器设置更复杂,需要专门初始化用来配置时序)
但是我们的代码放在nor可以直接启动,貌似xip片内执行代码就不需要配置时序了??????
(可能也是因为不需要配置就可以读吧,毕竟CPU也是要从nor中读取指令运行的。)eXecute In Place,即芯片内执行,指应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。flash内执行是指nor flash 不需要初始化,可以直接在flash内执行代码。但往往只执行部分代码,比如初始化RAM.
(注:**片内执行不是说程序在存储器内执行哦,CPU的基本功能就是取指、译码和执行。norflash能在芯片内执行,就是指CPU的取指模块能够直接从norflash中把指令取出来,供后面的译码和执行模块使用。**)那么为什么norflash可以实现XIP,而nandflash就不可以呢?
芯片内执行主要是是看芯片可不可以线性存储代码(假如硬件支持芯片接口),只要能保证芯片的存储空间是线性的(也就是无坏块),都可以片上执行
在读取Flash时候,容易出现“位翻转(bitconvert)
在Flash的位翻转(一个bit位发生翻转)现象上,NAND的出现几率要比NorFlash大得多。这个问题在Flash存储关键文件时是致命的,所以在使用NandFlash时建议同时使用EDC/ECC等校验算法。 ”
但是,如果能保证不出错,也还是可以进行XIP,可以在其上执行代码的:
“所谓XIP,就是CODE是在FLASH上直接运行. NANDFLASH只是不适合做XIP,但并不是不能做XIP“
部分摘自原文链接:https://blog.csdn.net/yjzh_td/article/details/72870044
在前面uart实验的源码基础上,新建init.c和init.h两个文件。在init.c里面只需要设置BANKCON0寄存器即可。
#include "s3c2440_soc.h"
void bank0_tacc_set(int val)
{BANKCON0 = val << 8;
}
写一个测试程序:
#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h"int main(void)
{unsigned char c;uart0_init();puts("Enter the Tacc val: \n\r");while(1){c = getchar();putchar(c);if (c >= '0' && c <= '7'){bank0_tacc_set(c - '0');led_test();}else{puts("Error, val should between 0~7\n\r");puts("Enter the Tacc val: \n\r");}}return 0;
}
在主函数里面,通过串口获取输入的值,传入bank0_tacc_set()函数里,设置Tacc,然后再读取Nor Flash上的闪灯程序。
这个程序设置的是nor的访问时序,这个程序必须烧到nor中同时是nor启动才有效果!!板子在nor上面执行这些程序的时候,效率会发生变化。
实验效果:
输入0~4,Tacc小于70ns,无法读取Nor Flash上数据,LED不能闪烁。
输入4~7,Tacc大于70ns,可以读取Nor Flash上数据,LED不断闪烁,且值越小越快(区别不明显)。
Nor flash知识点
补:https://www.cnblogs.com/053179hu/p/10635601.html
在这里详细介绍一下nor flash吧,韦老师课程中没有详细介绍。
NOR Flash最早是由Intel公司于1988年开发出的,是现在市场上两种主要的非易失性存储器之一,它的出现彻底改变了存储器市场上由EPROM(Erasable Programmable Read-Only-Memory电可编程序只读存储器)和EEPROM(电可擦只读存储器Electrically Erasable Programmable Read - Only Memory)一统天下的局面。NOR Flash最大特点是支持XIP(Execute On Chip),既程序可以直接在NOR flash的片内执行,在NOR Flash中的代码运行时不需要重定位复制到RAM内。NOR Flash的地址线和数据线分开,数据的读取和RAM很类似,只要能够提供数据地址,数据总线就能正确给出数据。不过不能直接对它进行写操作,执行写操作之前需要先发送固定的命令序列,然后发送写操作的地址和数据。
NOR Flash存储器的最小访问单元一般分为8位和16位的,也有一些NOR Flash器件同时支持8位和16位模式,这种Flash的位宽可以在设计硬件时选择,当芯片的BYTE#引脚接为高电平,芯片工作在位宽16位模式,BYTE#引脚设为低电平时,芯片工作在位宽8位模式。
NOR Flash一般有多个扇区,扇区是NOR Flash擦除的最小单位,Nor Flash中每个扇区的大小也不是固定的,扇区的排放一般分为两种模式Top Boot part 和Bottom Boot part 。这两种形式的区别是小块的扇区在NOR Flash芯片中放置的位置不同,Bottom Boot类型的NOR Flash小块地址位于芯片0地址,而Top Boot part类型的NOR Flash小块地址位于芯片的高地址上。
内存控制器的时钟信号由HCLK时钟信号提供,假设设置的HCLK的值为100M,1clock = 10ns。注意,开机时时钟是12MHZ,如果我们在start.s中设置了时钟那么常用的HCLK是100MHZ。
NOR Flash的读操作:
unsigned int nor_read_word(unsigned int base, unsigned int offset)
{volatile unsigned short *p = (volatile unsigned short *)(base + offset);return *p;
}unsigned int nor_dat(unsigned int offset)
{return nor_read_word(NOR_FLASH_BASE, offset);
}
NOR Flash的扇区擦除:
擦除NOR Flash扇区时,应先发送相应的命令,发送命令的顺序如下:
第1个总线周期:往555地址中写入AA
第2个总线周期:往2AA地址中写入55
第3个总线周期:往555地址中写入80
第4个总线周期:往555地址中写入AA
第5个总线周期:往2AA地址中写入55
第6个总线周期:往要擦除的扇区写入30
void nor_write_word(unsigned int base, unsigned int offset, unsigned int val)
{volatile unsigned short *p = (volatile unsigned short *)(base + offset);*p = val;
}/* offset是基于cpu的角度看到 */
void nor_cmd(unsigned int offset, unsigned int cmd)
{nor_write_word(NOR_FLASH_BASE, offset, cmd);
}/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */
void wait_ready(unsigned int addr)
{unsigned int val;unsigned int pre;pre = nor_dat(addr);val = nor_dat(addr);while ((val & (1<<6)) != (pre & (1<<6))){pre = val;val = nor_dat(addr); }
}void erase_nor_flash_sector(unsigned int addr)
{printf("erasing ...\n\r");nor_cmd(0x555<<1, 0xaa); /* 解锁 */nor_cmd(0x2aa<<1, 0x55); nor_cmd(0x555<<1, 0x80); /* erase sector */nor_cmd(0x555<<1, 0xaa); /* 解锁 */nor_cmd(0x2aa<<1, 0x55); nor_cmd(addr, 0x30); /* 发出扇区地址 */wait_ready(addr); /* 等待操作完成 */
}
CPU外接NOR Flash,实际上就是将NOR Flash地址映射为CPU的统一编址。由于nor_cmd函数的offset是基于CPU的角度看到地址,而芯片手册上NOR Flash写入命令的地址从NOR Flash的实际物理地址,NOR Flash是16位的,它的0地址应该对应CPU的0地址和1地址。因此,NOR Flash的物理地址从CPU的角度来看,地址值应该是NOR Flash角度来看的两倍,所以在向某地址写入命令时,要将NOR Flash角度来看的地址右移一位。
擦除是把内容都写成1!!!!!!!!!!
NOR Flash的写操作:
void write_nor_flash(unsigned int addr,unsigned int val)
{/* 烧写 */nor_cmd(0x555<<1, 0xaa); /* 解锁 */nor_cmd(0x2aa<<1, 0x55); nor_cmd(0x555<<1, 0xa0); /* program */nor_cmd(addr, val);/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */wait_ready(addr);
}
写操作时值得注意的是,只有写入的目标的地址内容为0xff时,数据才能正确的写入,因此,一般情况下NOR Flash在写入时要对扇区进行擦除操作。
NOR Flash在写入数据时只能将地址中的某位由1变0,而不能将某位由0变1。
假设NOR Flash某地址中存放字符a(0x61),如果未进行擦除前向该地址中写入字符G(0x47),最后该地址内容为A(0x41),发生错误,和我们预期不同。原因如下:
字符a化为二进制—>1100001
字符G化为二进制—>1000111
由于写入时数据位只能由0变为1,最终结果100001,相当于执行原始数据和新写入数据进行&操作。
SDRAM知识、原理图
SDRAM参考文档: 高手进阶,终极内存技术指南——完整/进阶版
一个很好的博客文档:https://www.cnblogs.com/biaohc/p/6346878.html
CPU是大爷,只需要发出指令,把地址给了内存控制器,内存控制器就会跑断腿做一系列操作。
SDRAM总共有4个块(Banks),可以认为每个块就是一个表格,里面的每个格子表示的是16bit数据。
问题1:怎样访问里面的某个格子呢?
首先发出一个片选信号,选中整个芯片;
发出Bank地址,选择是哪一个Bank(块,即表格);
发出行地址;
最后发出列地址,才能选中是个格子;
问题2:那么多的信号有谁发出呢?
由内存控制器发出,所以我们需要设置内存控制器,CPU只是简单的执行读写内存的命令,其他的都交给内存控制起来处理。换句话说,CPU将数据或地址发给内存控制器,内存控制器再去访问外部的SDRAM。
要控制sdram,设置内存控制器的寄存器是核心内容,寄存器配置好了,时序会自动搞定。
例如:
LDR R0,=0x30000000
LDR R1,[R0]
CPU把0x30000000这个地址发给内存控制器,内存控制器根据这个地址,判断属于哪个范围,然后发出相应的片选信号。
**内存控制器根据类型(比如SDRAM)**拆分成三部分:发出Bank地址、发出行地址、发出列地址。(不同于sram nor 网卡等的地方!!!)
对于上面的三个,怎样拆分呢?
行地址线有几条,列地址线有几条,都要设置内存控制器里面相关寄存器。
先看原理图:
隐藏了很多重点知识点:
1) 开发板中使用两片16位的SDRAM芯片并联组成32位的位宽,与CPU的32根数据线(DATA0—DATA31)相连。
BANK6的起始地址为0x30000000,范围是0x30000000~0x38000000。
但是SDRAM没有都用到,其访问地址为0x30000000~0x33FFFFFF,共64MB!!!!
2) 上面地址线只用了2-14,理论上可以寻址4(bank)乘2的15次方(32位)=128K,怎么会变成64M呢?
因为sdram特殊,地址是分两次送出,分为行地址和列地址,行地址和列地址公用地址线!
先送出行地址(实际地址线个数那么多位),然后送出列地址,列地址不会占用全部地址线的,占用多少根线呢?是有sdram芯片决定的,我们的是9bit的列地址,所以在程序中寄存器BWSCON的SCAN[1:0]设为0b01表示9位。
所以可寻址的范围就是4(bank)乘2的(15+9)次方=2^26=64M。
SDRAM芯片K4s5m632的行地址数为13,列地址数为9,所以当nSRAS信号有时,ADDR2—ADDR14上发出是行地址信号,它对应32位地址空间的b可23m]:当nSCAS信号有效时,ADDR2—ADDR10上发出的是列地址信号,它对应32位地址空间的bit[0:2];由于BANK6以32位的宽度外接DRAM,ADDR0、ADDR1恒为0,不参与译码。
不用设置行地址吗????控制器知道我们外面接的sdram是用多少地址线吗???
我猜,它是知道的,因为寄存器BANKSIZE中我们有BK76MAP[2:0]:设置BANK6的大小,设为了64M。
补:看一下sdram芯片手册的行列地址的说明:
我们的芯片是:
算起来也就是32M,两片加起来就是64M。
3) 为什么使用ADDR24,ADDR25作为sdram中L-Bank的选择信号。这个地址线怎么选定的呢?
我的理解:行地址线和列地址线的选择没有通过一个专门的IO线去区分。
sdram地址范围:0x30000000~0x33FFFFFF。正好地址中bit24-25是两位,可作为四位的选择。CPU通过给出的地址中这两位的数据,就可以正好区分四个BANK。
4) 其余一些看不懂的控制线是什么意思呢??
据我查看,2440内存控制器的相关寄存器并没有配置这些引脚的,这些引脚好像也不是GPIO,应该是sdram专用的把,它们会自动的按照时序发出信号,我们不用管。
(注:sdram就是内存,不可能想着像单片机自己控制io引脚去控制它!!都是芯片有控制器才能搞定!
而且SDRAM需要一直动态刷新。SDRAM不像静态内存SRAM那么可靠,在使用过程中需要不断去刷新,否则里面的数据会丢失,所以寄存器设置中还有个刷新寄存器。)
由于存储芯片位宽为16位,一次可以进行两个字节的读取。但是,通常操作系统里最小寻址单位是1字节,因此内存控制器必须要保证可以访问内存里每一个字节。UDQM ,LDQM分别代表16位数据的高,低字节读取信号,当读取数据时,LDQM /UDQM分别用来控制16位数据中高低字节能否被读取,当LDQM /UDQM为低电平时,对应的高/低字节就可以被读取,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被读取。当向内存里写入数据时,LDQM /UDQM控制数据能否被写入,当LDQM /UDQM为低电平时,对应的高/低字节就可以被写入,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被写入。通过对LDQM /UDQM信号的控制可以控制对两个存储芯片存储数据,由于两个存储单元的地址线是通用的,他们都能接收到CPU发出的地址信号,但是,发给两个存储单元的LDQM /UDQM信号是不同的,以此来区分一个字的高低字节。
S3C2440A为32位CPU,也就是说其数据总线和地址总线宽度都是32位(可以理解为32根线一端连接CPU内部,另外一端连接向内存控制器),那么内存数据的输入/输出端也要保证是32位总线,MINI2440上采用两片16位宽总线内存芯片并联构成32位总线。其中一个芯片连接到CPU数据总线的低16位,另外一个芯片连接到数据总线上的高16位,并联成32位总线,因此两个芯片的输入/输出总线连接到CPU总线上的不同管脚上。
更详细的文档https://www.cnblogs.com/biaohc/p/6346878.html
寄存器设置
不论是nor还是sdram,用的都是同一个内存控制器。不论说到nor控制器还是sdram控制器,其实都是这一套内存控制器,公用一套寄存器。
不过是不同的bank对应的con控制寄存器BANKCONx不同。
内存控制器共有13个寄存器:
BANK0–BANK5只需要设置BWSCON和BANKCONx(x为0~5)两个寄存器;
BANK6、BANK7外接SDRAM时,除BWSCON和BANKCONx(x为6、7)外,还要设置REFRESH、BANKSIZE、MRSRB6、MRSRB7等4个寄存器。
下面依次介绍寄存器:
① BWSCON:总线宽度和等待控制寄存器
上面配置nor的时候也讲过,可以结合看。
WAIT信号是芯片向2440发出的,芯片非常慢的时候,cpu发出读写命令后,内存控制器开始操作引脚,在那些时序图规定的时间之内外部芯片还是没有没准备好,就可以发这个信号给内存控制器!!!让它多给大时间。但是我们的原理图没用到这个信号,所以不用管。
关于ST6引脚,是给SRAM用的,我们是sdram,不用。
(如果不想看下面那么多,就用上面这句话来选择就行了!!!)
nWBE和nBE怎么选择呢?
参考:https://blog.csdn.net/liukun321/article/details/5595569
nWE, nWBE, nBE三者之间的关系:
(1)nWE为写使能信号。
(2)nWBE为“写字节使能(write byte enable)”信号,而nBE 为高/低字节选择信号。
nWBE与nBE共用引脚,可以通过对相关寄存器设置来进行功能选择。重点来了:
听老师的视频讲解,貌似nWBE为写字节使能信号,而nBE是读/写字节使能信号(包括了nWBE的功能了)!!
我们的sdram内存是32位的,(两个16位的拼起来也是算32位!!!),如果想去写某个字节的时候,控制器传给内存芯片的也是32位的数据,就需要写字节使能信号控制写在哪里了。但是想读某个字节的时候,不用管这么多,把32位的数据都收上来,内存控制器会挑出我们感兴趣的字节,所以并不需要芯片屏蔽某些位,也就用不着nBE了!!!!!
为什么sram用呢?
我猜想,虽然都是一个内存控制器,不过接的bank不同,对应寄存器设置也不同,bank6-7用来接sdram,可能功能就是强大一点吧,像上面nor的配置那样,ban0-5需要配置的寄存器少,功能可能没那么强大,sram读字节的时候也要自己来用这个nBE信号了。
(3)什么时候需要nWBE而不是nWE?
nWE和nWBE都带有写使能的功能。但既然有nWE,为什么还需要nWBE?这是因为,当使用几片储存芯片进行数据位扩展时,有时需要对芯片分开写数据,此时可使用nWBE。
(比如仅有一片8bit的ROM,因此仅需要nWE,而不需要nWBE。用了2片8bit的ROM,如果不使用nWBE,则写操作是对2片ROM同时进行的,这样,当执行写字节指令时可能会破坏另一芯片中的数据。注意nWBE的信号是自动产生的。从这个角度来说,nWBE有字节数据屏蔽的功能。)
从原理图中我们也可以看到用的是nWBE引脚。
两个16位的sdram分别接了LnWBE[0-1]和LnWBE[2-3],怎么协调呢,我估计呀,相关时序控制都是控制器自己就完成了。如果就一个sdram,32位的,可能芯片上也是LnWBE[0-3]这四个引脚。一样的操控方式。
②BANKCONx:控制寄存器
MT[16:15]:用于设置本BANK外接的是ROM/SRAM还是SDRAM。
SRAM:0b00,SDRAM:0b11(开发板使用的是SDRAM)。
只有这里设置为sdram后,地址才会被拆分成行地址列地址!
当MT[16:15]设置为00时,此寄存器与BANKC0N0、BANKCON5类似。对于bankcon0-5寄存器,bit16-15是空,不用管。我们这里省略给出BANKC0N0的,只给BANKC0N6。
而对于sdram,设置BANKC0N6的时候,除了MT[16:15],只需要设置后面这三个位就可以了!超简便。
先发行地址,再发列地址,中间肯定是有个delay时间的,即是trcd位。
问:为什么这里就是HCLK,100mhz了呢?????我记得前面有个地方计算用的是晶振大小12Mhz。
③ 刷新控制寄存器REFRESH(REFRESHCONTROLREGISTER)
(1)REFEN[23]:0=禁止SDRAM的刷新功能,1:开启SDRAM的刷新功能(设置开启SDRAM的刷新功能)。
(2)TREFMD[22]:SDRAM的刷新模式,0=CBR/AutoRefresh,1=SelfRefresh(一般在系统休眠时使用),我们设置默认值,自动刷新。
(3)Trp[21:20]:根据芯片手册设为0即可。芯片手册会推荐一个值,假设是max 20ns,根据系统的时钟算出需要设置成00,2clock就行了,上电默认是最大的,4clock。
(4)Tsrc[19:18]:根据芯片手册设为默认值0b01即可。和上面同理,在芯片手册搜索这个Trp/Trc看看人家有没有典型值就行了,不用深究什么意思了。(查到Trc是70ns,按照上图的说法Tsrc就是70-20=50ns了)。
(5)RefreshCounter[10:0]:即R_CNT
SDRAM的刷新周期在SDRAM的数据手册上有标明,在本开发板使用的SDRAM:K4S561632的数据手册上,可看见这么一行“64msrefreshpenod(8KCycle)所以,刷新周期=64ms/8192=7.8125us。
Refreshcount=2^11+1-100x7.8=1269=0x4F5。
因此,本开发板中REFRESH设为0x8404F5。
④ BANKSIZE寄存器
⑤ 模式设置寄存器MRSR
能修改的只有位CL[6:4],这是SDRAM时序的一个时间参数,表示发出行、列地址后,等一会才返回数据,等多久呢?看芯片手册,可以等2/3个clock,这是可编程的**,我们在寄存器这里设置了这个值,它是会传递给sdram芯片的!sdram中有一个寄存器会保存这个时间值,以后会在收到列地址后再等这段时间才会向2440返回数据。**
(这些知识就来源于上面推荐的《高手进阶,终极内存技术指南——完整/进阶版》)
CL可以取值为0b0l0(2 clocks)或0b011(3 clocks)。
本开发板取最保守的值0b010,所以MRSRB6的值为0x20。
(补:SRAM可以立刻返回数据的,sdram是个性能不怎么样的芯片,要等一会时间才可以)
SDRAM测试程序
init.c:
#include "s3c2440_soc.h"void sdram_init(void)
{BWSCON = 0x22000000;BANKCON6 = 0x18001;BANKCON7 = 0x18001;REFRESH = 0x008404f5;BANKSIZE = 0xb1;MRSRB6 = 0x20;MRSRB7 = 0x20;
}//测试SDRAM地址
int sdram_test(void)
{volatile unsigned char *p = (volatile unsigned char *)0x30000000;int i;// write sdramfor (i = 0; i < 1000; i++)p[i] = 0x55;// read sdramfor (i = 0; i < 1000; i++)if (p[i] != 0x55)return -1;return 0;
}
main.c:
int main(void)
{uart0_init();sdram_init();if (sdram_test() == 0)led_test();//如果测试成功,LED闪烁return 0;
}
实验结果:
LED按预期闪烁,屏蔽掉sdram_init()后,LED不闪烁。
韦一之内存控制器,2440地址空间,NOR flash和SDRAM(012课)相关推荐
- 韦东山ARM第一期作业(三)内存控制器和SDRAM
文章目录 01 - 作业所在路径 02 - 作业描述 03 - 作业解答 01 - 作业所在路径 ARM裸机1期加强版\源码文档图片\文档图片\第012课_内存控制器与SDRAM 02 - 作业描 ...
- s3c2440内存控制器与SDRAM基本测试
前面我们实验的LED和串口程序,是cpu发送地址给特定的寄存器,在寄存器中写相应的位,达到控制要求. 第一类是GPIO门电路如LED,第二类是协议类如串口,这些都不是cpu直接给地址信息,而是通过寄存 ...
- 内存控制器与SDRAM_内存接口概念
辅线1_硬件知识_内存接口概念 如图是S3C2440是个片上系统,有GPIO控制器(接有GPIO管脚),有串口控制器 (接有TXD RXD引脚). 配置GPIO控制器相应的寄存器,即可让引脚输出高低电 ...
- assembly 输出ab中所有数_罗克韦尔(AB)PLC控制器选型(2)-CompactLogix 5370
前面的文章我们介绍过AB的大型PLC--ControlLogix的选型(参考:罗克韦尔(AB)PLC控制器怎样选型(1)). 今天这篇文章,我们来认识下AB的中型PLC产品--CompactLogix ...
- 新1期_012课_内存控制器与SDRAM
一.基础知识 各种外设有各自的控制器.例如GPIO控制器可控制GPIO输入输出,UART 控制器可以控制不同脉冲的产生 等.而CPU的作用是向各种控制器写入数据,CPU是通过地址线区别不同的外设控制器 ...
- 七彩虹 pci内存控制器 感叹号 蓝屏 DPC_WATCHDOG_VIOLATION
最近自己组装台电脑玩, 出现过几次蓝屏 代码 DPC_WATCHDOG_VIOLATION 打开设备管理器 发现好几个黄色感叹号的 点开显示没有兼容驱动(忘记截图了) 大概有 pci内存控制器, sm ...
- Memory Population Guidelines for Intel 3rd Gen Xeon Scalable Processors——内存控制器
Memory Population Guidelines for Intel 3rd Gen Xeon Scalable Processors 英特尔的第三代至强可扩展处理器采用全新的内存控制器架构. ...
- 内存控制器(以位宽为16的NOR FLASH举例)
CPU 执行的指令: "ldr r0,[某个地址 A]",ldr 是装载 4个字节,这是从这个地址里读取某个数据存到 r0 里去. A 地址的 1 字节数据. A+1 地址的 1 ...
- ThinkPad T61 安装XP系统后总是提示“PC内存控制器”的问题
由于使用XP的习惯问题,以及使用VISTA的资源占用问题,因此我很是忠情于XP.但是在T61的本上每次安装好系统后,总是"PCI内存控制器"在硬件列表中出现感叹号,从网上也找不到驱 ...
最新文章
- Spring MVC 到 Spring BOOT 的简化之路
- R语言使用lmPerm包应用于线性模型的置换方法(置换检验、permutation tests)、使用lm模型构建简单线性回归模型、使用lmp函数生成置换检验回归分析模型
- 采购订单的审批状态异常的处理,审批状态为:预审批或是处理中的单据
- python三十:time模块
- getChars的用法
- JavaScript作用域学习笔记(ife2015spring学习心得)
- hssfworkbook 单元格合并后宽度不生效_Excel表格“假”合并,有多牛?
- ITCAST-C# 委托
- IIS识别Json文件
- php oracle 无查询结果,php - Oracle Insert查询不起作用,也不会抛出任何错误 - 堆栈内存溢出...
- weakhashmap_Java WeakHashMap keySet()方法与示例
- 2021年Q2母婴行业季度洞察报告
- 对齐输出(信息学奥赛一本通-T1003)
- 查看Linux下端口占用情况的命令
- 11-17网页基础--表单
- 白话Word2Vec
- php 格式化js文件,vscode编辑器在php文件中的html/js格式化解决方案
- 【后缀数组】bzoj2217 Secretary
- 现代软件工程——第一周博客作业
- 后端开发都应该掌握的Redis基础
热门文章
- 将一句话里的单词进行倒置,标点符号不倒换P228
- 信息论与信道编码之BPSK误码率公式推导
- Python大蟒蛇平台是干什么用的?
- 管理系统:登录成功后可以选择自己的角色,并查看角色的工作任务(使用多态和抽象类来完成)...
- 2017-滴滴出行-安全岗笔试
- 软件开发人/月成本估算方法
- linux只W25Q256驱动,使用m25p80,支持w25q系列nor flash
- 淘宝宝贝详情页模板,自动生成宝贝描述模板,淘宝详情页一键生成,切换
- C语言程序的运行与调试过程
- centos 6.3下rarlinux 与wireshark的安装