S3C2440的SDRAM驅(qū)動(dòng)
SDRAM(Synchronous Dynamic Random Access Memory,同步動(dòng)態(tài)隨機(jī)存儲(chǔ)器)也就是通常所說(shuō)的內(nèi)存。內(nèi)存的工作原理、控制時(shí)序、及相關(guān)控制器的配置方法一直是嵌入式系統(tǒng)學(xué)習(xí)、開(kāi)發(fā)過(guò)程中的一個(gè)難點(diǎn)。我們從其硬件的角度來(lái)分析其原理,然后再引出SDRAM的驅(qū)動(dòng)編寫(xiě)過(guò)程。
本文引用地址:http://butianyuan.cn/article/201611/317482.htm內(nèi)存是代碼的執(zhí)行空間,以PC機(jī)為例,程序是以文件的形式保存在硬盤(pán)里面的,程序在運(yùn)行之前先由操作系統(tǒng)裝載入內(nèi)存中,由于內(nèi)存是RAM(隨機(jī)訪問(wèn)存儲(chǔ)器),可以通過(guò)地址去定位一個(gè)字節(jié)的數(shù)據(jù),CPU在執(zhí)行程序時(shí)將PC的值設(shè)置為程序在內(nèi)存中的開(kāi)始地址,CPU會(huì)依次的從內(nèi)存里取址,譯碼,執(zhí)行,在內(nèi)存沒(méi)有被初始化之前,內(nèi)存好比是未建好的房子,是不能讀取和存儲(chǔ)數(shù)據(jù)的,因此我們要想讓MTOS運(yùn)行在內(nèi)存里必須進(jìn)行內(nèi)存的初始化。
通用存儲(chǔ)設(shè)備:
在介紹內(nèi)存工作原理之前有必要了解下存儲(chǔ)設(shè)備的存儲(chǔ)方式:ROM,RAM
lROM(Read-Only Memory):只讀存儲(chǔ)器,是一種只能讀出事先所存數(shù)據(jù)的固態(tài)半導(dǎo)體存儲(chǔ)器。其特性是一旦儲(chǔ)存資料就無(wú)法再將之改變或刪除。通常用在不需經(jīng)常變更資料的電子或電腦系統(tǒng)中,資料并且不會(huì)因?yàn)?strong>電源關(guān)閉而消失。如:PC里面的BIOS。
lRAM(Random Access Memory):隨機(jī)訪問(wèn)存儲(chǔ)器,存儲(chǔ)單元的內(nèi)容可按需隨意取出或存入,且存取的速度與存儲(chǔ)單元的位置無(wú)關(guān)的存儲(chǔ)器。可以理解為,當(dāng)你給定一個(gè)隨機(jī)有效的訪問(wèn)地址,RAM會(huì)返回其存儲(chǔ)內(nèi)容(隨機(jī)尋址),它訪問(wèn)速度與地址的無(wú)關(guān)。這種存儲(chǔ)器在斷電時(shí)將丟失其存儲(chǔ)內(nèi)容,故主要用于存儲(chǔ)短時(shí)間內(nèi)隨機(jī)訪問(wèn)使用的程序。計(jì)算機(jī)系統(tǒng)里內(nèi)存地址是一個(gè)四字節(jié)對(duì)齊的地址(32位機(jī)),CPU的取指,執(zhí)行,存儲(chǔ)都是通過(guò)地址進(jìn)行的,因此它可以用來(lái)做內(nèi)存。
RAM按照硬件設(shè)計(jì)的不同,隨機(jī)存儲(chǔ)器又分為DRAM(Dynamic RAM)動(dòng)態(tài)隨機(jī)存儲(chǔ)器和SRAM(Static RAM)靜態(tài)隨機(jī)存儲(chǔ)器。
lDRAM:它的基本原件是小電容,電容可以在兩個(gè)極板上短時(shí)間內(nèi)保留電荷,可以通過(guò)兩極之間有無(wú)電壓差代表計(jì)算機(jī)里的0和1,由于電容的物理特性,要定期的為其充電,否則數(shù)據(jù)會(huì)丟失。對(duì)電容的充電過(guò)程叫做刷新,但是制作工藝較簡(jiǎn)單,體積小,便于集成化,經(jīng)常做為計(jì)算機(jī)里內(nèi)存制作原件。比如:PC的內(nèi)存,SDRAM, DDR, DDR2, DDR3等,缺點(diǎn):由于要定期刷新存儲(chǔ)介質(zhì),存取速度較慢。
lSRAM:它是一種具有靜止存取功能的內(nèi)存,不需要刷新電路即能保存它內(nèi)部存儲(chǔ)的數(shù)據(jù)。因此其存取速度快,但是體積較大,功耗大,成本高,常用作存儲(chǔ)容量不高,但存取速度快的場(chǎng)合,比如CPU的L1 cache,L2cache(一級(jí),二級(jí)緩存),寄存器。
為了滿足開(kāi)發(fā)的需要MINI2440在出廠時(shí)搭載了三種存儲(chǔ)介質(zhì):
(1)NOR FLASH(2M):ROM存儲(chǔ)器,通常用來(lái)保存BootLoader,引導(dǎo)系統(tǒng)啟動(dòng)
(2)NAND FLASH(256M,型號(hào)不一樣,Nandflash大小不一樣):保存操作系統(tǒng)映像文件和文件系統(tǒng)
(3)SDRAM(64M):內(nèi)存,執(zhí)行程序
lNORFLASH:它的特點(diǎn)是支持XIP芯片內(nèi)執(zhí)行(eXecute In Place),這樣應(yīng)用程序可以直接在Flash閃存內(nèi)運(yùn)行,不必再把代碼讀到系統(tǒng)RAM中,也就是說(shuō)可以隨機(jī)尋址。NOR FLASH的成本較高。
lNAND FLASH:它能提供極高的單元密度,可以達(dá)到高存儲(chǔ)密度,并且寫(xiě)入和擦除的速度也很快。其成本較低,不支持XIP??勺?strong>嵌入式里的數(shù)據(jù)存儲(chǔ)介質(zhì)。如:手機(jī)存儲(chǔ)卡,SD卡等。
1.1.1S3C2440存儲(chǔ)器地址段(Bank)
S3C2440對(duì)外引出了27根地址線ADDR0~ADDR26,它最多能夠?qū)ぶ?28MB,而S3C2440的尋址空間可以達(dá)到1GB,這是由于S3C2440將1GB的地址空間分成了8個(gè)BANKS(Bank0~Bank7),其中每一個(gè)BANK對(duì)應(yīng)一根片選信號(hào)線nGCS0~nGCS7,當(dāng)訪問(wèn)BANKx的時(shí)候,nGCSx管腳電平拉低,用來(lái)選中外接設(shè)備,S3C2440通過(guò)8根選信號(hào)線和27根地址線,就可以訪問(wèn)1GB。如圖2-48所示。
圖2-48 S3C2440存儲(chǔ)器BANK
如圖所示,左側(cè)圖對(duì)應(yīng)不使用Nandflash啟動(dòng)時(shí)(通過(guò)跳線設(shè)置),存儲(chǔ)器Bank分布圖,通常在這種啟動(dòng)方式里選擇Norflash啟動(dòng),將Norflash焊接在Bank0,系統(tǒng)上電后,CPU從Bank0的開(kāi)始地址0x00000000開(kāi)始取指運(yùn)行。
上圖右側(cè)是選擇從Nandflash引導(dǎo)啟動(dòng)(通過(guò)跳線設(shè)置),系統(tǒng)上電后,CPU會(huì)自動(dòng)將Nandflash里前4K的數(shù)據(jù)復(fù)制到S3C2440內(nèi)部一個(gè)4K大小SRAM類(lèi)型存儲(chǔ)器里(叫做Steppingstone),然后從Steppingstone取指啟動(dòng)。
其中Bank0~Bank5可以焊接ROM或SRAM類(lèi)型存儲(chǔ)器,Bank6~Bank7可以焊接ROM,SRAM,SDRAM類(lèi)型存儲(chǔ)器,也就是說(shuō),S3C2440的SDRAM內(nèi)存應(yīng)該焊接在Bank6~Bank7上,最大支持內(nèi)存256M,Bank0~Bank5通常焊接一些用于引導(dǎo)系統(tǒng)啟動(dòng)小容量ROM,具體焊接什么樣存儲(chǔ)器,多大容量,根據(jù)每個(gè)開(kāi)發(fā)板生產(chǎn)商不同而不同,比如MINI2440開(kāi)發(fā)板將2M的Norflash焊接在了Bank0上,用于存放系統(tǒng)引導(dǎo)程序Bootloader,將兩片32M,16Bit位寬SDRAM內(nèi)存焊接在Bank6和Bank7上,并聯(lián)形成64M,32位內(nèi)存。
由于S3C2440是32位芯片,理論上講可以達(dá)到4GB的尋址范圍,除去上述8個(gè)BANK用于連接外部設(shè)備,還有一部分的地址空間是用于設(shè)備特殊功能寄存器,其余地址沒(méi)有被使用。
表2-14 S3C2440設(shè)備寄存器地址空間
外接設(shè)備 | 起始地址 | 結(jié)束地址 |
存儲(chǔ)控制器 | 0x48000000 | 0x48000030 |
USB Host控制器 | 0x49000000 | 0x49000058 |
中斷控制器 | 0x4A000000 | 0x4A00001C |
DMA | 0x4B000000 | 0x4B0000E0 |
時(shí)鐘和電源管理 | 0x4C000000 | 0x4C000014 |
LCD控制器 | 0x4D000000 | 0x4D000060 |
NAND FLASH控制器 | 0x4E000000 | 0x4E000014 |
攝像頭接口 | 0x4F000000 | 0x4F0000A0 |
UART | 0x50000000 | 0x50008028 |
脈寬調(diào)制計(jì)時(shí)器 | 0x51000000 | 0x51000040 |
USB設(shè)備 | 0x52000140 | 0x5200026F |
WATCHDOG計(jì)時(shí)器 | 0x53000000 | 0x53000008 |
IIC控制器 | 0x54000000 | 0x5400000C |
IIS控制器 | 0x55000000 | 0x55000012 |
I/O端口 | 0x56000000 | 0x560000B0 |
實(shí)時(shí)時(shí)鐘RTC | 0x57000040 | 0x5700008B |
A/D轉(zhuǎn)換器 | 0x58000000 | 0x58000010 |
SPI | 0x59000000 | 0x59000034 |
SD接口 | 0x5A000000 | 0x5A000040 |
AC97音頻編碼接口 | 0x5B000000 | 0x5B00001C |
1.1.2SDRAM內(nèi)存工作原理
SDRAM的內(nèi)部是一個(gè)存儲(chǔ)陣列。陣列就如同表格一樣,將數(shù)據(jù)“填”進(jìn)去。在數(shù)據(jù)讀寫(xiě)時(shí)和表格的檢索原理一樣,先指定一個(gè)行(Row),再指定一個(gè)列(Column),我們就可以準(zhǔn)確地找到所需要的單元格,這就是內(nèi)存芯片尋址的基本原理,如圖2-49所示。
圖2-49內(nèi)存行,列地址尋址示意圖
這個(gè)單元格(存儲(chǔ)陣列)就叫邏輯Bank(Logical Bank,下文簡(jiǎn)稱L-Bank)。由于技術(shù)、成本等原因,不可能只做一個(gè)全容量的L-Bank,而且最重要的是,由于SDRAM的工作原理限制,單一的L-Ban k將會(huì)造成非常嚴(yán)重的尋址沖突,大幅降低內(nèi)存效率。所以人們?cè)赟DRAM內(nèi)部分割成多個(gè)L-Bank,目前基本都是4個(gè)(這也是SDRAM規(guī)范中的最高L-Bank數(shù)量),由此可見(jiàn),在進(jìn)行尋址時(shí)就要先確定是哪個(gè)L-Bank,然后在這個(gè)選定的L-Bank中選擇相應(yīng)的行與列進(jìn)行尋址。因此對(duì)內(nèi)存的訪問(wèn),一次只能是一個(gè)L-Bank工作。如圖2-50:
圖2-50內(nèi)存存儲(chǔ)單元
當(dāng)對(duì)內(nèi)存進(jìn)行操作時(shí)(見(jiàn)下圖),先要確定操作L-Bank,因此要對(duì)L-Bank進(jìn)行選擇。在內(nèi)存芯片的外部管腳上多出了兩個(gè)管腳BA0, BA1,用來(lái)片選4個(gè)L-Bank。如前所述,32位的地址長(zhǎng)度由于其存儲(chǔ)結(jié)構(gòu)特點(diǎn),分成了行地址和列地址。通過(guò)下面的內(nèi)存結(jié)構(gòu)圖可知,內(nèi)存外接管腳地址線只有13根地址線A0~A12,它最多只能尋址8M內(nèi)存空間,到底使用什么機(jī)制來(lái)實(shí)現(xiàn)對(duì)64M內(nèi)存空間進(jìn)行尋址的呢?SDRAM的行地址線和列地址線是分時(shí)復(fù)用的,即地址要分兩次送出,先送出行地址(nSRAS行有效操作),再送出列地址(nSCAS列有效操作)。這樣,可以大幅度減少地址線的數(shù)目,提高器件的性能和制作工藝復(fù)雜度。但尋址過(guò)程也會(huì)因此而變得復(fù)雜。實(shí)際上,現(xiàn)在的SDRAM一般都以L-Bank為基本尋址對(duì)象的。由L-Bank地址線BAn控制L-Bank間的選擇,行地址線和列地址線貫穿連接所有的L-Bank,每個(gè)L-Bank的數(shù)據(jù)的寬度和整個(gè)存儲(chǔ)器的寬度相同,這樣,可以加快數(shù)據(jù)的存儲(chǔ)速度。同時(shí),BAn還可以使未被選中的L-Bank工作于低功耗的模式下,從而降低器件的功耗。
圖2-51 HY57561620內(nèi)部結(jié)構(gòu)圖
開(kāi)發(fā)板內(nèi)存控制器管腳接線(以MINI2440開(kāi)發(fā)板為例):
(1)確定BA0、BA1的接線
表2-15 BA0、BA1接線
Bank Size:外接內(nèi)存容量大?。℉Y57561620是4Mbit*16bit*4Bank*2Chips/8=64MB)
Bus Width:總線寬度 (兩片16位HY57561620,并聯(lián)成32位)
Base Component:?jiǎn)蝹€(gè)芯片容量(bit)(256Mb)
Memory Configration:內(nèi)存配置((4M*16*4banks)*2Chips )
由硬件手冊(cè)Bank Address管腳連接配置表可知,使用A[25:24]兩根地址線作為Bank片選信號(hào),正好兩根接線可以片選每個(gè)存儲(chǔ)單元的4個(gè)BANKS。
(2)確定其它接線
SDRAM內(nèi)存是焊接在BANK6~BANK7上的,其焊接管腳,如圖2-52:
圖2-52 S3C2440 16位寬內(nèi)存芯片
上圖是S3C2440提供的兩片16位芯片并聯(lián)連接示意圖,An是CPU地址總線,其中A2~A14為內(nèi)存芯片尋址總線,之所以地址尋址總線從A2開(kāi)始是因?yàn)閮?nèi)存地址都是按字節(jié)對(duì)齊的,,A24,A25為L(zhǎng)-Bank片選信號(hào),Dn為CPU數(shù)據(jù)總線,其它為對(duì)應(yīng)控制信號(hào)線。
表2-16內(nèi)存芯片各管腳說(shuō)明
外接管腳名 | 內(nèi)接管腳名 | 全稱 | 描述 |
A2~A14 | A0~A12 | Address | 地址線 |
D0 ~D31 | DQ0~DQ31 | Data Input/Output | 數(shù)據(jù)線 |
A24,A25 | BA0,BA1 | Bank Address | L-BANK片選信號(hào) |
DQM0~DQM3 | LDQM, UDQM | Data Input/Output Mask | 高,低字節(jié)數(shù)據(jù)掩碼信號(hào) |
SCKE | SCKE | Clock Enable | 輸入時(shí)鐘有效信號(hào) |
SCLK | SCLK | Clock | 輸入時(shí)鐘 |
nSCS0 | nSCS | General Chip Select | 片選信號(hào)(它與nGCS6是同一管腳的兩個(gè)功能) |
nSRAS | nSRAS | Row Address Strobe | 行地址選通信號(hào) |
nSCAS | nSCAS | Column Address Strobe | 列地址選通信號(hào) |
nWE | newnWE | Write Enable | 寫(xiě)入有效信號(hào) |
我們通過(guò)S3C2440 16位寬內(nèi)存芯片接線圖可以看出,兩片內(nèi)存芯片只有兩個(gè)地方不一樣,LDQM, UDQM和數(shù)據(jù)總線DQn接線方式不一樣。
由于存儲(chǔ)芯片位寬為16位,一次可以進(jìn)行兩個(gè)字節(jié)的讀取。但是,通常操作系統(tǒng)里最小尋址單位是1字節(jié),因此內(nèi)存控制器必須要保證可以訪問(wèn)內(nèi)存里每一個(gè)字節(jié)。UDQM,LDQM分別代表16位數(shù)據(jù)的高,低字節(jié)讀取信號(hào),
當(dāng)讀取數(shù)據(jù)時(shí),LDQM /UDQM分別用來(lái)控制16位數(shù)據(jù)中高低字節(jié)能否被讀取,當(dāng)LDQM /UDQM為低電平時(shí),對(duì)應(yīng)的高/低字節(jié)就可以被讀取,如果LDQM /UDQM為高電平時(shí),對(duì)應(yīng)的高/低字節(jié)就不能被讀取。
當(dāng)向內(nèi)存里寫(xiě)入數(shù)據(jù)時(shí),LDQM /UDQM控制數(shù)據(jù)能否被寫(xiě)入,當(dāng)LDQM /UDQM為低電平時(shí),對(duì)應(yīng)的高/低字節(jié)就可以被寫(xiě)入,如果LDQM /UDQM為高電平時(shí),對(duì)應(yīng)的高/低字節(jié)就不能被寫(xiě)入。通過(guò)對(duì)LDQM /UDQM信號(hào)的控制可以控制對(duì)兩個(gè)存儲(chǔ)芯片存儲(chǔ)數(shù)據(jù),由于兩個(gè)存儲(chǔ)單元的地址線是通用的,他們都能接收到CPU發(fā)出的地址信號(hào),但是,發(fā)給兩個(gè)存儲(chǔ)單元的LDQM /UDQM信號(hào)是不同的,以此來(lái)區(qū)分一個(gè)字的高低字節(jié)。
S3C2440A為32位CPU,也就是說(shuō)其數(shù)據(jù)總線和地址總線寬度都是32位(可以理解為32根線一端連接CPU內(nèi)部,另外一端連接向內(nèi)存控制器),那么內(nèi)存數(shù)據(jù)的輸入/輸出端也要保證是32位總線,MINI2440上采用兩片16位寬總線內(nèi)存芯片并聯(lián)構(gòu)成32位總線。其中一個(gè)芯片連接到CPU數(shù)據(jù)總線的低16位,另外一個(gè)芯片連接到數(shù)據(jù)總線上的高16位,并聯(lián)成32位總線,因此兩個(gè)芯片的輸入/輸出總線連接到CPU總線上的不同管腳上。
1.1.3SDRAM的讀操作
SDRAM進(jìn)行讀操作時(shí),先向地址線上送上要讀取數(shù)據(jù)的地址,通過(guò)前面的知識(shí)了解到,地址被分成3部分,行地址,列地址,L-Bank片選信號(hào)。片選(L-Bank的定址)操作和行有效操作可以同時(shí)進(jìn)行。
在CS、L-Bank定址的同時(shí),RAS(nSRAS行地址選通信號(hào))也處于有效狀態(tài)。此時(shí)An地址線則發(fā)送具體的行地址。A0~A12,共有13根地址線(可表示8192行),A0~A12的不同數(shù)值就確定了具體的行地址。由于行有效的同時(shí)也是相應(yīng)L-Bank有效,所以行有效也可稱為L(zhǎng)-Bank有效。
行地址確定之后,就要對(duì)列地址進(jìn)行尋址了。但是,地址線仍然是行地址所用的A0~A12。沒(méi)錯(cuò),在SDRAM中,行地址與列地址線是復(fù)用的。列地址復(fù)用了A0~A8,共9根(可表示512列)。那么,讀/寫(xiě)的命令是怎么發(fā)出的呢?其實(shí)沒(méi)有一個(gè)信號(hào)是發(fā)送讀或?qū)懙拿鞔_命令的,而是通過(guò)芯片的可寫(xiě)狀態(tài)的控制來(lái)達(dá)到讀/寫(xiě)的目的。顯然WE信號(hào)(nWE)就是一個(gè)關(guān)鍵。WE無(wú)效時(shí),當(dāng)然就是讀取命令。有效時(shí),就是寫(xiě)命令。
SDRAM基本操作命令,通過(guò)各種控制/地址信號(hào)的組合來(lái)完成(H代表高電平,L代表低電平,X表示高,低電平均沒(méi)有影響)。此表中,除了自刷新命令外,所有命令都是默認(rèn)CKE(SCKEl輸入時(shí)鐘頻率有效)有效。列尋址信號(hào)與讀寫(xiě)命令是同時(shí)發(fā)出的。雖然地址線與行尋址共用,但CAS(nSCAS列地址選通信號(hào))信號(hào)則可以區(qū)分開(kāi)行與列尋址的不同,配合A0~A8,A9~A11來(lái)確定具體的列地址。
讀取命令與列地址一塊發(fā)出(當(dāng)WE為低電平是即為寫(xiě)命令)然而,在發(fā)送列讀寫(xiě)命令時(shí)必須要與行有效命令有一個(gè)間隔,這個(gè)間隔被定義為tRCD,即RAS to CAS Delay(RAS至CAS延遲),這個(gè)很好理解,在地址線上送完行地址之后,要等到行地址穩(wěn)定定位后再送出列地址,tRCD是SDRAM的一個(gè)重要時(shí)序參數(shù),相關(guān)數(shù)值參看對(duì)應(yīng)芯片硬件手冊(cè)。通常tRCD以時(shí)鐘周期(tCK,Clock Time)數(shù)為單位,比如筆者M(jìn)INI2440所用內(nèi)存芯片里面寫(xiě)到tRCD為20nst,如果將來(lái)內(nèi)存工作在100MHz,那么RCD至少要為2個(gè)時(shí)鐘周期,RCD=2。
圖2-53SDRAM讀操作時(shí)序圖
在選定列地址后,就已經(jīng)確定了具體的存儲(chǔ)單元,剩下就是等待數(shù)據(jù)通過(guò)數(shù)據(jù)I/O通道(DQ)輸出到內(nèi)存數(shù)據(jù)總線上了。但是在列地址選通信號(hào)CAS發(fā)出之后,仍要經(jīng)過(guò)一定的時(shí)間才能有數(shù)據(jù)輸出,從CAS與讀取命令發(fā)出到第一筆數(shù)據(jù)輸出的這段時(shí)間,被定義為CL(CAS Latency,CAS潛伏期)。由于CL只在讀取時(shí)出現(xiàn),所以CL又被稱為讀取潛伏期(RL,Read Latency)。CL的單位與tRCD一樣,也是時(shí)鐘周期數(shù),具體耗時(shí)由時(shí)鐘頻率決定(筆者官方手冊(cè)CL=3)。不過(guò),CAS并不是在經(jīng)過(guò)CL周期之后才送達(dá)存儲(chǔ)單元。實(shí)際上CAS與RAS一樣是瞬間到達(dá)的。由于芯片體積的原因,存儲(chǔ)單元中的電容容量很小,所以信號(hào)要經(jīng)過(guò)放大來(lái)保證其有效的識(shí)別性,這個(gè)放大/驅(qū)動(dòng)工作由S-AMP負(fù)責(zé)。但它要有一個(gè)準(zhǔn)備時(shí)間才能保證信號(hào)的發(fā)送強(qiáng)度,這段時(shí)間我們稱之為tAC(Access Time from CLK,時(shí)鐘觸發(fā)后的訪問(wèn)時(shí)間)。
1.1.4SDRAM預(yù)充電操作
從存儲(chǔ)體的結(jié)構(gòu)圖上可以看出,原本邏輯狀態(tài)為1的電容在讀取操作后,會(huì)因放電而變?yōu)檫壿?。由于SDRAM的尋址具有獨(dú)占性,所以在進(jìn)行完讀寫(xiě)操作后,如果要對(duì)同一L-Bank的另一行進(jìn)行尋址,就要將原先操作行關(guān)閉,重新發(fā)送行/列地址。在對(duì)原先操作行進(jìn)行關(guān)閉時(shí),DRAM為了在關(guān)閉當(dāng)前行時(shí)保持?jǐn)?shù)據(jù),要對(duì)存儲(chǔ)體中原有的信息進(jìn)行重寫(xiě),這個(gè)充電重寫(xiě)和關(guān)閉操作行過(guò)程叫做預(yù)充電,發(fā)送預(yù)充電信號(hào)時(shí),意味著先執(zhí)行存儲(chǔ)體充電,然后關(guān)閉當(dāng)前L-Bank操作行。預(yù)充電中重寫(xiě)的操作與刷新操作(后面詳細(xì)介紹)一樣,只不過(guò)預(yù)充電不是定期的,而只是在讀操作以后執(zhí)行的。
1.1.5SDRAM突發(fā)操作
突發(fā)(Burst)是指在同一行中相鄰的存儲(chǔ)單元連續(xù)進(jìn)行數(shù)據(jù)傳輸?shù)姆绞剑B續(xù)傳輸所涉及到存儲(chǔ)單元(列)數(shù)量就是突發(fā)長(zhǎng)度(Burst Length,簡(jiǎn)稱BL)。
在目前,由于內(nèi)存控制器一次讀/寫(xiě)P-Bank位寬的數(shù)據(jù),也就是8個(gè)字節(jié),但是在現(xiàn)實(shí)中小于8個(gè)字節(jié)的數(shù)據(jù)很少見(jiàn),所以一般都要經(jīng)過(guò)多個(gè)周期進(jìn)行數(shù)據(jù)的傳輸,上文寫(xiě)到的讀/寫(xiě)操作,都是一次對(duì)一個(gè)存儲(chǔ)單元進(jìn)行尋址,如果要連續(xù)讀/寫(xiě),還要對(duì)當(dāng)前存儲(chǔ)單元的下一單元進(jìn)行尋址,也就是要不斷的發(fā)送列地址與讀/寫(xiě)命令(行地址不變,所以不用再對(duì)地尋址)。雖然由于讀/寫(xiě)延遲相同可以讓數(shù)據(jù)傳輸在I/O端是連續(xù)的,但是它占用了大量的內(nèi)存控制資源,在數(shù)據(jù)進(jìn)行連續(xù)傳輸時(shí)無(wú)法輸入新的命令效率很低。為此,引入了突發(fā)傳輸機(jī)制,只要指定起始列地址與突發(fā)長(zhǎng)度,內(nèi)存就會(huì)依次自動(dòng)對(duì)后面相應(yīng)長(zhǎng)度數(shù)據(jù)的數(shù)據(jù)存儲(chǔ)單元進(jìn)行讀/寫(xiě)操作而不再需要控制器連續(xù)地提供列地址,這樣,除了第一筆數(shù)據(jù)的傳輸需要若干個(gè)周期(主要是之間的延遲,一般的是tRCD + CL)外,其后每個(gè)數(shù)據(jù)只需一個(gè)周期即可。
總結(jié)下:
SDRAM的基本讀操作需要控制線和地址線相配合地發(fā)出一系列命令來(lái)完成。先發(fā)出芯片有效命令(ACTIVE),并鎖定相應(yīng)的L-BANK地址(BA0、BA1給出)和行地址(A0~A12給出)。芯片激活命令后必須等待大于tRCD(SDRAM的RAS到CAS的延遲指標(biāo))時(shí)間后,發(fā)出讀命令。CL(CAS延遲值)個(gè)時(shí)鐘周期后,讀出數(shù)據(jù)依次出現(xiàn)在數(shù)據(jù)總線上。在讀操作的最后,要向SDRAM發(fā)出預(yù)充電(PRECHARGE)命令,以關(guān)閉已經(jīng)激活的L-BANK。等待tRP時(shí)間(PRECHAREG命令后,相隔tRP時(shí)間,才可再次訪問(wèn)該行)后,可以開(kāi)始下一次的讀、寫(xiě)操作。SDRAM的讀操作支持突發(fā)模式(Burst Mode),突發(fā)長(zhǎng)度為1、2、4、8可選。
1.1.6SDRAM寫(xiě)操作
SDRAM的基本寫(xiě)操作也需要控制線和地址線相配合地發(fā)出一系列命令來(lái)完成。先發(fā)出芯片有效命令,并鎖定相應(yīng)的L-BANK地址(BA0、BA1給出)和行地址(A0~A12給出)。芯片有效命令發(fā)出后必須等待大于tRCD的時(shí)間后,發(fā)出寫(xiě)命令數(shù)據(jù),待寫(xiě)入數(shù)據(jù)依次送到DQ(數(shù)據(jù)線)上。在最后一個(gè)數(shù)據(jù)寫(xiě)入后,延遲tWR時(shí)間。發(fā)出預(yù)充電命令,關(guān)閉已經(jīng)激活的頁(yè)。等待tRP時(shí)間后,可以展開(kāi)下一次操作。寫(xiě)操作可以有突發(fā)寫(xiě)和非突發(fā)寫(xiě)兩種。突發(fā)長(zhǎng)度同讀操作。
圖2-54 SDRAM寫(xiě)操作時(shí)序圖
1.1.7SDRAM的刷新
SDRAM之所以成為DRAM就是因?yàn)樗粩噙M(jìn)行刷新(Refresh)才能保留住數(shù)據(jù),因此它是SDRAM最重要的操作。
刷新操作與預(yù)充電中重寫(xiě)的操作一樣,都是用S-AMP先讀再寫(xiě)。但為什么有預(yù)充電操作還要進(jìn)行刷新呢?因?yàn)轭A(yù)充電是對(duì)一個(gè)或所有L-Bank中的工作行操作,并且是不定期的,而刷新則是有固定的周期,依次對(duì)所有行進(jìn)行操作,以保留那些很長(zhǎng)時(shí)間沒(méi)經(jīng)歷重寫(xiě)的存儲(chǔ)體中的數(shù)據(jù)。但與所有L-Bank預(yù)充電不同的是,這里的行是指所有L-Bank中地址相同的行,而預(yù)充電中各L-Bank中的工作行地址并不是一定是相同的。那么要隔多長(zhǎng)時(shí)間重復(fù)一次刷新呢?目前公認(rèn)的標(biāo)準(zhǔn)是,存儲(chǔ)體中電容的數(shù)據(jù)有效保存期上限是64ms(毫秒,1/1000秒),也就是說(shuō)每一行刷新的循環(huán)周期是64ms。這樣刷新時(shí)間間隔就是:64m/行數(shù)s。我們?cè)诳磧?nèi)存規(guī)格時(shí),經(jīng)常會(huì)看到4096 Refresh Cycles/64ms或8192 Refresh Cycles/64ms的標(biāo)識(shí),這里的4096與8192就代表這個(gè)芯片中每個(gè)L-Bank的行數(shù)。刷新命令一次對(duì)一行有效,刷新間隔也是隨總行數(shù)而變化,4096行時(shí)為15.625μs(微秒,1/1000毫秒),8192行時(shí)就為7.8125μs。刷新操作分為兩種:Auto Refresh,簡(jiǎn)稱AR與Self Refresh,簡(jiǎn)稱SR。不論是何種刷新方式,都不需要外部提供行地址信息,因?yàn)檫@是一個(gè)內(nèi)部的自動(dòng)操作。對(duì)于AR,SDRAM內(nèi)部有一個(gè)行地址生成器(也稱刷新計(jì)數(shù)器)用來(lái)自動(dòng)的依次生成行地址。由于刷新是針對(duì)一行中的所有存儲(chǔ)體進(jìn)行,所以無(wú)需列尋址,或者說(shuō)CAS在RAS之前有效。所以,AR又稱CBR(CAS Before RAS,列提前于行定位)式刷新。由于刷新涉及到所有L-Bank,因此在刷新過(guò)程中,所有L-Bank都停止工作,而每次刷新所占用的時(shí)間為9個(gè)時(shí)鐘周期(PC133標(biāo)準(zhǔn)),之后就可進(jìn)入正常的工作狀態(tài),也就是說(shuō)在這9個(gè)時(shí)鐘期間內(nèi),所有工作指令只能等待而無(wú)法執(zhí)行。64ms之后則再次對(duì)同一行進(jìn)行刷新,如此周而復(fù)始進(jìn)行循環(huán)刷新。顯然,刷新操作肯定會(huì)對(duì)SDRAM的性能造成影響,但這是沒(méi)辦法的事情,也是DRAM相對(duì)于SRAM(靜態(tài)內(nèi)存,無(wú)需刷新仍能保留數(shù)據(jù))取得成本優(yōu)勢(shì)的同時(shí)所付出的代價(jià)。SR則主要用于休眠模式低功耗狀態(tài)下的數(shù)據(jù)保存,這方面最著名的應(yīng)用就是STR(Suspend to RAM,休眠掛起于內(nèi)存)。在發(fā)出AR命令時(shí),將CKE置于無(wú)效狀態(tài),就進(jìn)入了SR模式,此時(shí)不再依靠系統(tǒng)時(shí)鐘工作,而是根據(jù)內(nèi)部的時(shí)鐘進(jìn)行刷新操作。在SR期間除了CKE之外的所有外部信號(hào)都是無(wú)效的(無(wú)需外部提供刷新指令),只有重新使CKE有效才能退出自刷新模式并進(jìn)入正常操作狀態(tài)。
SDRAM相關(guān)寄存器:
(1)BWSCON寄存器(BUS WIDTH & WAIT CONTROL REGISTER)
表2-17 SDRAM控制寄存器(BWSCON)
根據(jù)開(kāi)發(fā)板的存儲(chǔ)器配置和芯片型號(hào),設(shè)置每個(gè)BANK焊接芯片的位寬和等待狀態(tài)
BWSCON,每4位對(duì)應(yīng)一個(gè)BANK,這4位分別表示:
lSTx:?jiǎn)?dòng)/禁止SDRAM的數(shù)據(jù)掩碼引腳(UB/LB),SDRAM沒(méi)有高低位掩碼引腳,此位為0,SRAM連接有UB/LB管腳,設(shè)置為1
注:UB/LB數(shù)據(jù)掩碼引腳用來(lái)控制芯片讀取/寫(xiě)入的高字節(jié)和低字節(jié)(對(duì)比硬件手冊(cè)SDRAM和SRAM的接線圖)
lWSx:是否使用存儲(chǔ)器的WAIT信號(hào),通常設(shè)為0
lDWx:設(shè)置焊接存儲(chǔ)器芯片的位寬,筆者開(kāi)發(fā)板使用兩片容量為32M,位寬為16的SDRAM組成64M,32位存儲(chǔ)器,因此DW7,DW6位設(shè)置為0b10,其它BANK不用設(shè)置采用默認(rèn)值即可。
lBANK0對(duì)應(yīng)的是系統(tǒng)引導(dǎo)BANK,這4位比較特殊,它的設(shè)置是由硬件跳線決定的,因此不用設(shè)置
lBWSCON設(shè)置結(jié)果:0x22000000
(2)BANKCON0~BANKCON5 (BANK CONTROL REGISTER)
表2-18 BANKCON0~BANKCON5控制寄存器(BANKCON0~BANKCON5)
這6個(gè)寄存器用來(lái)設(shè)置對(duì)應(yīng)BANK0~BANK5的訪問(wèn)時(shí)序,采用默認(rèn)值0x700即可
(3)BANKCON6~BANKCON7 (BANK CONTROL REGISTER)
表2-19 BANKCON6~BANKCON7控制寄存器(BANKCON6~BANKCON7)
由于內(nèi)存都焊接在這兩個(gè)BANK上,因此內(nèi)存驅(qū)動(dòng)主要是對(duì)這兩個(gè)寄存器進(jìn)行設(shè)置
lMT:設(shè)置BANK6~BANK7的存儲(chǔ)器類(lèi)型,
00=ROM or SRAM 01=保留
10=保留11=SDRAM
內(nèi)存為SDRAM,設(shè)置為0b11,對(duì)應(yīng)的應(yīng)該設(shè)置Trcd和SCAN位,其它位和SDRAM無(wú)關(guān)
lTrcd:RAS to CAS Delay行地址選通到列地址選通延遲,這個(gè)參數(shù)請(qǐng)看后面的內(nèi)存工作原理擴(kuò)展部分解釋?zhuān)P者內(nèi)存芯片為HY57V561620,由其芯片手冊(cè)可知其Trcd為最少20ns,如果內(nèi)存工作在100MHz,則該值至少要為2個(gè)時(shí)鐘周期,通常設(shè)置為3個(gè)時(shí)鐘周期,因此設(shè)置為0b01
lSCAN:SDRAM Column Address Number SDRAM的列地址數(shù),筆者內(nèi)存芯片為HY57V561620,列地址數(shù)為9,設(shè)置為0b01
lBANK6,BANK7設(shè)置結(jié)果為:0x18005
(4)REFRESH (REFRESH CONTROL REGISTER)
表2-20刷新頻率設(shè)置寄存器(REFRESH)
SDRAM的刷新有效,刷新頻率設(shè)置寄存器(刷新)
lREFEN:開(kāi)啟/關(guān)閉刷新功能,設(shè)置為1,開(kāi)啟刷新
lTREFMD:SDRAM刷新模式,0=CBR/AutoRefresh,1=Self Refresh,設(shè)置為0,自動(dòng)刷新
lTrp:行地址選通預(yù)充電時(shí)間,一般設(shè)置為0b00即可
lTsrc:?jiǎn)涡兴⑿聲r(shí)間,設(shè)置為0b11即可。
lRefresh Counter:內(nèi)存存儲(chǔ)單元刷新數(shù),它通過(guò)下面公式計(jì)算出:
Refresh Counter = 2^11 + 1 – SDRAM時(shí)鐘頻率(MHz)* SDRAM刷新周期(uS)
SDRAM的刷新周期,也就是內(nèi)存存儲(chǔ)單元間隔需要多久進(jìn)行一次刷新,前面內(nèi)存工作原理分析可知電容數(shù)據(jù)保存上限為64ms,筆者使用內(nèi)存芯片每個(gè)L-Bank共有8192行,因此每次刷新最大間隔為:64ms/8192 = 7.8125uS,如果內(nèi)存工作在外部晶振頻率12MHz下,Refresh Counter = 1955,如果內(nèi)存工作在100MHz下,那么Refresh Counter = 1269(取大整數(shù))
lREFRESH寄存器設(shè)置為:
0x8e0000 + 1269 = 0x008e04f5(HCLK = 100MHz)
0x8e0000 + 1955 = 0x008e07a3(HCLK = 12MHz)
(5)BANKSIZE寄存器(BANKSIZE REGISTER)
表2-21 BANKSIZE寄存器(BANKSIZE)
設(shè)置內(nèi)存的突發(fā)傳輸模式,省電模式和內(nèi)存容量。
lBURST_EN:是否開(kāi)啟突發(fā)模式,0 = ARM內(nèi)核禁止突發(fā)傳輸1 =開(kāi)啟突發(fā)傳輸,設(shè)置為1,開(kāi)啟突發(fā)傳輸
lSCKE_EN:是否使用SCKE信號(hào)作為省電模式控制信號(hào),0 =不使用SCKE信號(hào)作為省電模式控制信號(hào)1 =使用SCKE信號(hào)作為省電模式控制信號(hào),通常設(shè)置為1
lSCLK_EN: 設(shè)置向存儲(chǔ)器輸入工作頻率,0 =一直輸入SCLK頻率,即使沒(méi)有內(nèi)存操作也會(huì)輸入,1 =僅當(dāng)進(jìn)行內(nèi)存數(shù)據(jù)操作時(shí)才輸入SCLK頻率,通常設(shè)置為1
lBK76MAP:設(shè)置Bank6/7的內(nèi)存容量,筆者使用開(kāi)發(fā)板內(nèi)存為兩片32M內(nèi)存芯片并聯(lián)成64M,它們?nèi)慷纪饨拥紹ank6上,因此選擇0b001
lBANKSIZE寄存器設(shè)置為:0xb1
(6)SDRAM模式設(shè)置寄存器MRSRx (SDRAM MODE REGISTER SET REGISTER)
表2-22 SDRAM模式設(shè)置寄存器(MRSRx)
該寄存器用于設(shè)置CAS潛伏周期,可以手動(dòng)設(shè)置的位只有CL[6:4]位,通過(guò)前面內(nèi)存工作原理可知,筆者使用開(kāi)發(fā)板CL=3,即0b011
lMRSR6,MRSR7設(shè)置為:0x00000030
1.1.8內(nèi)存驅(qū)動(dòng)實(shí)驗(yàn)
設(shè)置該工程加載時(shí)運(yùn)行時(shí)地址為0x30000000,如圖2-55所示:
圖2-55設(shè)置加載時(shí)運(yùn)行時(shí)地址
init.s:本程序文件主要實(shí)現(xiàn)了,關(guān)閉看門(mén)狗,初始化內(nèi)存,拷貝ROM數(shù)據(jù)到內(nèi)存中,然后跳往內(nèi)存中執(zhí)行xmain函數(shù),從xmain函數(shù)返回之后,將全部led點(diǎn)亮,進(jìn)入死循環(huán)。
;
;內(nèi)存初始化實(shí)驗(yàn)
;
AREA Init, CODE, READONLY
ENTRY
start
; close watchdog
ldr r0, = 0x53000000;將看門(mén)狗控制寄存器地址放入r0
mov r1, #0
str r1, [r0];設(shè)置看門(mén)狗控制寄存器的值為0
bl initmem;跳轉(zhuǎn)到initmem代碼段,初始化內(nèi)存
bl copyall;跳轉(zhuǎn)到數(shù)據(jù)拷貝代碼段,將ROM中數(shù)據(jù)拷貝到內(nèi)存中
IMPORT xmain;引入main.c中的xmain函數(shù)
ldr sp, =0x34000000;調(diào)用C程序之前先初始化棧指針
ldr lr, =endxmain;設(shè)置xmain函數(shù)的返回地址
ldr pc, =xmain;跳轉(zhuǎn)到C程序中的xmain函數(shù)的入口處執(zhí)行
endxmain
ldr r0, =0x56000010; LED的GPIO接口配置寄存器
ldr r1, =0x00015400; GPIO配置數(shù)據(jù)
str r1, [r0];設(shè)置GPIO
ldr r0, =0x56000014; LED控制寄存器地址
ldr r1, =0x0;全部LED亮
str r1,[r0]
loop
b loop;死循環(huán)
copyall
IMPORT |Image$$RO$$Base|;引入編譯器Image$$RO$$Base符號(hào)變量
IMPORT |Image$$RW$$Limit|;引入編譯器Image$$RW$$Limit符號(hào)變量
ldr r0, = |Image$$RO$Base|;取得Image$$RO$Base域基址的值
ldr r1, = |Image$$RW$$Limit|;取得Image$$RW$Base域結(jié)束地址的值
ldr r2, =0x0;數(shù)據(jù)拷貝源地址
copyallloop
teq r0,r1;測(cè)試是否拷貝完成
beq quitcopyallloop;拷貝完成,跳往quitcopyallloop退出
ldr r3, [r2], #4;四字節(jié)加載
str r3, [r0], #4;四字節(jié)存儲(chǔ)
b copyallloop;返回繼續(xù)執(zhí)行
quitcopyallloop
mov pc, lr;調(diào)用返回
initmem;內(nèi)存初始化
ldr r0, =0x48000000;加載內(nèi)存相關(guān)寄存器首地址r0
ldr r1, =0x48000034;加載內(nèi)存相關(guān)寄存器尾地址到r1
adr r2, memdata;將寄存器配置數(shù)據(jù)地址段首地址加載到r2
initmemloop
ldr r3, [r2], #4;循環(huán)設(shè)置存寄存器
str r3, [r0], #4
teq r0, r1
bne initmemloop;循環(huán)到最后一個(gè)寄存器時(shí)退出函數(shù)
mov pc,lr
memdata
DCD0x22000000;BWSCON
DCD0x00000700;BANKCON0
DCD0x00000700;BANKCON1
DCD0x00000700;BANKCON2
DCD0x00000700;BANKCON3
DCD0x00000700;BANKCON4
DCD0x00000700;BANKCON5
DCD0x00018005;BANKCON6
DCD0x00018005;BANKCON7
DCD0x008e07a3;REFRESH
DCD0x000000b1;BANKSIZE
DCD0x00000030;MRSRB6
DCD0x00000030;MRSRB7
END
main.c:本程序文件主要實(shí)現(xiàn)led燈的初始化,然后四個(gè)led燈循環(huán)滾動(dòng)亮5遍,xmain函數(shù)返回。
/* C語(yǔ)言函數(shù)*/
/*端口F寄存器預(yù)定義*/
#defineGPBCON(*(volatile unsigned long *)0x56000010)
#defineGPBDAT(*(volatile unsigned long *)0x56000014)
#defineLEDS(1<<5|1<<6|1<<7|1<<8)
#defineDELAYVAL(0x1ffff)
extern int delay(int time);/*聲明外部聲明匯編函數(shù)*/
int i = 5;
int xmain()
{
GPBCON= 0x00015400;//GPF4--GPF7設(shè)置為output
while(i > 0) {
//第一個(gè)LED燈亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8);
delay(DELAYVAL);//調(diào)用匯編語(yǔ)言編寫(xiě)的延時(shí)程序
//第二個(gè)LED燈亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<7|1<<8);
delay(DELAYVAL);//調(diào)用匯編語(yǔ)言編寫(xiě)的延時(shí)程序
//第三個(gè)LED燈亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<8);
delay(DELAYVAL);//調(diào)用匯編語(yǔ)言編寫(xiě)的延時(shí)程序
//第四個(gè)LED燈亮
GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<7);
delay(DELAYVAL);//調(diào)用匯編語(yǔ)言編寫(xiě)的延時(shí)程序
i--;
}
return 0;
}
delay.s:本程序文件主要通常匯編來(lái)實(shí)現(xiàn)延時(shí)功能。
;匯編指令延時(shí)程序
EXPORT delay
AREADELAY,CODE,READONLY;該偽指令定義了一個(gè)代碼段,段名為Init,屬性只讀
;下面是延遲子程序
delay
sub r0,r0,#1;r0=r0-1
cmp r0,#0x0;將r0的值與0相比較
bne delay;比較的結(jié)果不為0(r0不為0),繼續(xù)調(diào)用delay,否則執(zhí)行下一條語(yǔ)句
mov pc,lr;返回
END;程序結(jié)束符
內(nèi)存的初始化也可以用下面的C程序?qū)崿F(xiàn):
C語(yǔ)言版本:
#defineMEM_CTL_BASE0x48000000
#defineMEM_CTL_END0x48000034
/* SDRAM 13個(gè)寄存器的值*/
unsigned longconstmem_cfg_val[]={//聲明數(shù)組存放內(nèi)存控制器設(shè)置數(shù)據(jù)
0x22000000,//BWSCON
0x00000700,//BANKCON0
0x00000700,//BANKCON1
0x00000700,//BANKCON2
0x00000700,//BANKCON3
0x00000700,//BANKCON4
0x00000700,//BANKCON5
0x00018005,//BANKCON6
0x00018005,//BANKCON7
0x008e07a3,//REFRESH(HCLK = 12MHz,該值為0x008e07a3
//HCLK = 100MHz 0x008e04f5)
0x000000b1,//BANKSIZE
0x00000030,//MRSRB6
0x00000030,//MRSRB7
};
void mem_init(void)
{
inti = 0;
unsigned long *p = (unsigned long *)MEM_CTL_BASE;
for(; i < (MEM_CTL_END - MEM_CTL_BASE)/4; i++)
p[i] = mem_cfg_val[i];
}
評(píng)論