JZ2440 第6章 存儲控制器

本章目標:

    瞭解S3C2410/S3C2440地址空間的佈局
    掌握如何通過總線形式訪問擴展的外設,比如內存、NOR Flash、網卡等
····································································································
    總線的使用方法是嵌入式低層開發的基礎,瞭解它之後,再根據外設的具體特性,就可以驅動外設了。

6.1 使用存儲控制器訪問外設的原理

6.1.1 S3C2410/S3C2440的地址空間

    S3C2410/S3C2440的“存儲控制器”提供了訪問外部設備所需要的信息,它有如下特性:
① 支持小字節序、大字節序(通過軟件選擇);
② 每個BANK的地址空間爲128MB,總共1GB(8 BANKs);
③ 可編程控制的總線位寬(8/16/32-bit),不過BANK0只能選擇兩種位寬(16/32-bit);
④ 總共8個BANK,BANK0~BANK5可以支持外接ROM、SRAM等,BANK6~BANK7除了可以支持
    ROM、SRAM外,還支持SDRAM等;
⑤ BANK0~BANK6共7個BANK的起始地址是固定的;
⑥ BANK7的起始地址可編程選擇;
⑦ BANK6、BANK7的地址空間大小是可編程控制的;
⑧ 每個的訪問週期均可編程控制;
⑨ 可以通過外部的“wait”信號延長總線的訪問週期;
⑩ 在外接SDRAM時,支持自刷新(self-refresh)和省電模式(power down mode)。
    S3C2410/S3C2440對外引出的27根地址線ADDR0~ADDR26的訪問範圍只有128MB,CPU對外
還引出了8根片選信號nGCS0~nGCS7,對應於BANK0~BANK7,當訪問BANKx的地址空間時,
nGCSx引腳輸出低電平用來選中外接的設備。這8個BANK的地址空間如下圖6.1所示:
 
     S3C2410/S3C2440作爲32位的CPU,可以使用的地址範圍理論上達到4GB。除去上述用於連接外設
的1GB地址空間外,還有一部分是CPU內部寄存器的地址,剩下的地址空間沒有使用。
    S3C2410/S3C2440的寄存器地址範圍都處於0x480 0000~0x5ff ffff,各功能部件的寄存器大體相同,
如下表所示:


6.1.2 存儲控制器與外設的關係

    本書所用開發板使用了存儲控制器的BANK0~BANK6,分別外接瞭如下設備:
NOR Flash、IDE接口、10M網卡CS8900A、100M網卡DM9000、擴展串口芯片16C2550、
SDRAM,連線方式如下圖6.2所示。
    外設的訪問地址 = 地址線確定的地址 + BANK的起始地址
比如:擴展串口。
    (1)它使用nGCS5,起始地址爲0x2800 0000。
    (2)nCSA=ADDR24||nGCS5,nCSB=!ADDR24||nGCS5。當ADDR24和nGCS5均爲低電平
時選中擴展串口A;當ADDR24爲高電平、nGCS5爲低電平時,選中擴展串口B。
    (3)CPU的ADDR0~ADDR2連接到擴展串口的A0~A2,所以訪問空間爲8字節。
    綜上所述,擴展串口A的訪問空間爲:0x2800 0000~0x2800 0007;擴展串口B的
訪問空間爲:0x2900 0000~0x2900 0007(bit24爲1)。
圖4.2:

    BANK0~BANK5的連接方式都是類似的,BANK6連接SDRAM時複雜一點,CPU提供了一
組用於SDRAM的信號。
① SDRAM時鐘有效信號SCKE;
② SDRAM時鐘信號SCLK0/SCLK1;
③ 數據掩碼信號DQM0/DQM1/DQM2/DQM3;
④ SDRAM片選信號nSCS0(它與nGCS6是同一引腳的兩個功能);
⑤ SDRAM行地址選通脈衝信號nSRAS;
⑥ SDRAM列地址選通脈衝信號nSCAS;
⑦ 寫允許信號nWE(它不是專用於SDRAM的)。
    SDRAM的內部是一個存儲陣列,如同表格一樣,將數據填進去。
    SDRAM的尋址基本原理:先指定一個行,在指定一個列,就可以準確地找到所需要的單元格。
這個單元格被稱爲存儲單元。這個表格(存儲陣列)就是邏輯Bank(簡稱L-Bank),SDRAM一般含有
4個L-BANK。
    SDRAM的邏輯結構如圖6.3所示。

    可以想象,對SDRAM的訪問可以分爲如下4個步驟
    (1)CPU發出的片選信號nSCS0有效,它選中SDRAM芯片;
    (2)SDRAM中有4個L-Bank,需要兩根地址信號來選中其中一個,從圖6.2可知使用ADDR24、
ADDR25作爲L-Bank的選擇信號;
    (3)對被選中的芯片進行統一行、列(存儲單元)尋址;
    根據SDRAM芯片的列地址線數目設置CPU的相關寄存器後,CPU就會從32位地址中自動分出
L-Bank選擇信號、行地址信號、列地址信號,然後先後發出行地址信號、列地址信號。L-Bank選
擇信號在發出行地址信號的同時發出,並維持到列地址信號結束。
    在圖6.2中,行地址、列地址公用地址線ADDR2~ADDR14(BANK6位寬爲32,ADDR0/1沒有使
用),使用nSRAS、nSCAS兩個信號來區分它們。比如本開發板中,使用兩根地址線ADDR24、
ADDR25作爲L-Bank的選擇信號;SDRAM芯片K4S561632的行地址數爲13,列地址數爲9,所以
當nSRAS信號有效時,ADDR2~ADDR14上發出的是行地址信號,它對應32位地址空間的bit[23:11];
當nSCAS信號有效時,ADDR2~ADDR10上發出的是列地址信號,它對應32位地址空間的bit[10:2]。
由於圖6.2中BANK6以32位的寬度連接SDRAM,ADDR0、ADDR1恆爲0,不參與譯碼。
    (4)找到存儲單元后,被選中的芯片就要進行統一的數據傳輸了。
    開發板中使用兩片16位的SDRAM芯片並聯組成32位的位寬,與CPU的32根數據線(DATA0~DATA31)相連。
    BANK6的起始地址爲0x3000 0000,所以SDRAM的訪問地址爲0x3000 0000~0x33ff ffff,共64MB。
    對圖6.2中連接的外設,它們的訪問地址(物理地址)如表6.2所示。

 6.1.3 存儲控制器的寄存器使用方法

    存儲控制器共有13個寄存器,BANK0~BANK5只需要設置BWSCON和BANKCONx(x爲0~5)兩個
寄存器:BANK6和BANK7外接SDRAM時,除BWSCON和BANKCONx(x爲6、7)外,還要設置REFRESH、
BANKSIZE、MRSRB6、MRSRB7等4個寄存器。下面分類說明:
    1.位寬和等待控制寄存器BWSCON
    每4位控制一個BANK,最高4位對應BANK7、接下來4位對應BANK6,以此類推。
    (1)STx:啓動/禁止SDRAM的數據掩碼引腳,對於SDRAM, 此位爲0;對於SRAM,此位爲1;
    (2)WSx:是否使用存儲器的WAIT信號,通常設爲0;
    (3)DWx:使用兩位來設置相應BANK的位寬:
    0b00:8位,0b01:16位,0b10:32位,0b11:保留;
       BANK0比較特殊,只支持16和32位兩種位寬,它沒有ST0和WS0,DW0([2:1])只讀——由硬件跳線決定:
    0b01:16位,0b10:32位;
        對於本開發板,沒有使用BANK7,根據表6.1可以確定BWSCON的值爲:0x2201 1110。
    2.BANK控制寄存器BANKCONx(x爲0~5)
    這幾個寄存器用來控制BANK0~BANK5外接設備的訪問時序,使用默認的0x0700即可滿足
本開發板所接各外設的要求。
    3.BANK控制寄存器BANKCONx(x爲6~7)
    在8個BANK中,只有BANK6和BANK7可以外接SRAM或SDRAM,所以BANKCON6~
BANKCON7與BANKCON0~BANKCON5有點不同。
    (1)MT([16:15]):用於設置本BANK外接的是ROM/SRAM還是SDRAM。
    當MT = 0b00:時,接SRAM,此寄存器與BANKCON0~BANKOCN5類似;
    當MT = 0b11:時,接SDRAM,此寄存器其他值如下設置。
    (2)Trcd([3:2]):RAS to CAS delay,設爲推薦值0b01。
    (3)SCAN([1:0]):SDRAM的列地址位數,對於本開發板使用的SDRAM K4S561632,
列地址位數爲9,所以SCAN = 0b01。如果使用其他型號的SDRAM,需要查看數據手冊來
決定SCAN的取值。0b00:8位;0b01:9位;0b10:10位。
    綜上所述,本開發板中BANKCON6、7均設爲0x0001 8005。
    4.刷新控制寄存器REFRESH:設爲0x008c 0000 + R_CNT
    (1)REFEN([23]):0 = 禁止SDRAM的刷新功能,1 = 開啓SDRAM的刷新功能。
    (2)TREFMD([22]):SDRAM的刷新模式,0 = CBR/Auto Refresh,1 = Self Refresh(一般在系統休眠時使用)。
    (3)Trp([21:20]):設爲0即可。
    (4)Tsrc([19:18]):設爲默認值0b11即可。
    (5)Refresh Counter([10:0]):即上述的R_CNT,
            R_CNT = 2^11 + 1 - SDRAM時鐘頻率(MHz) * SDRAM刷新週期(us);
        其中SDRAM時鐘頻率就是HCLK,SDRAM的刷新週期在SDRAM數據手冊上有標明,
在本開發板所使用的SDRAM 數據手冊上,可以看見“ 64ms refresh period(8K Cycle)”。所以,
刷新週期 = 64ms/8192 = 7.8125us。
    在未使用PLl時,SDRAM時鐘頻率等於晶振頻率12MHz。
    現在可以計算:R_CNT = 2^11 + 1 - 12*7.8125 = 1955。
    所以,在未使用PLL時,REFRESH = 0x008c 0000 + 195 = 0x008C 07A3。
    5.BANKSIZE寄存器BANKSIZE
    (1)BURST_EN([7])。
            0 = ARM核禁止突發傳輸,1 = ARM核支持突發傳輸。
    (2)SCKE_EN([5])。
            0 = 不使用SCKE信號令SDRAM進入省電模式,1 = 使用SCKEN信號令SDRAM進入省電模式。
    (3)SCLK_EN([4])。
            0 = 時刻發出SCLK信號,1 = 僅在訪問SDRAM期間發出SCLK信號(推薦)。
    (4)BK76MAP([2:0]):設置BANK6/7的大小。
            BANK6/7對應的地址空間與BANK0~5不同:
            BANK0~5的地址空間大小都是固定的128MB,地址範圍是(x * 128M)到(x+1)*128M -1,x表示0~5。
            BANK6/7的大小是可變的,以保持這兩個空間的地址連續,即BANK7的起始地址會隨着
它們的大小變化。
            BK76MAP的取值意義如下:
            0b010 = 128MB/128MB,0b001 = 64MB/64MB,0b000 = 32M/M,
            0b111 = 16M/16M,0b110 = 8M/8M,0b101 = 4M/4M,0b100 = 2M/2M
            本開發板BANK6外接64MB的SDRAM,令[2:0] = 0b001,表示BANK6/7的容量都是64MB,
雖然BANK7沒使用。
    綜上所述,開發板的BANKSIZE寄存器的值可算得0xB1。
    6.SDRAM模式設置寄存器MRSRBx(x爲6~7)
    能修改的只有位CL([6:4]),這是SDRAM時序的一個時間參數:
    [work] 0b000 = 1 clock,0b010 = 2 clocks,0b011 = 3 clocks
    SDRAM K4S561632不支持CL = 1的情況,所以此位取值0b010(CL = 2)或0b011(CL = 3)。
本開發板取最保守值0b011,所以MRSRB6/7的值爲0x30。

6.2 存儲控制器操作實例:使用SDRAM

6.2.1 代碼詳解及程序的複製、跳轉過程

    從NAND Flash啓動CPU時,CPU會通過內部的硬件將NAND Flash開始的4KB數據復
到稱爲“Steppingstone”的4KB的內部RAM中(起始地址爲0),然後跳到地址0開始執行。
    本實例先使用彙編語言設置好存儲控制器,使外接的SDRAM可用;然後把程序從
Steppingstone複製到SDRAM處;最後跳到SDRAM中執行。
    源代碼在/work/hardware/sdram目錄中,包含兩個文件head.S和leds.c。其中leds.c和第5
章中的leds的代碼完全一樣,也是讓3個led從0~7輪流計數。
    重點在head.S,它的作用是設置SDRAM,將程序複製到SDRAM,然後跳到SDRAM
繼續執行。head.S的代碼如下:
    程序是如何通過第15行的“ ldr pc, =on_sdram”指令來完成的
    程序標號“on_sdram”這個地址值在連接程序時被確定爲0x3000 0010(這個是SDRAM的
地址),執行“ldr pc, =on_sdram”後,程序一下子就跳到SDRAM中去了。
    “on_sdram”這個地址值爲什麼等於0x3000 0010?
    Makefile中連接程序的命令爲“arm-linux-ld -Ttext 0x30000000 head.o sdram.o -o
 sdram_elf”,意思就是代碼段的起始地址爲0x3000 0000,即程序的第一條指令(第12行)的
連接地址爲0x3000 0000,第二條指令(第13行)的連接地址爲0x3000 0004,...,第5條指
令(第17行)的連接地址爲0x3000 0010,其程序標號“on_sdram”的值就是0x3000 0010。
    雖然第12~14行指令的連接地址都在SDRAM中,但是由於他們都是位置無關的相對
跳轉指令,所以可以在Steppingstone裏執行。
    Makefile如下(注意第4行,“-Ttext 0x30000000”指定了代碼段的起始地址):
1
sdram.bin : head.S leds.c
2
    arm-linux-gcc -c -o head.o head.S
3
    arm-linux-gcc -c -o leds.o leds.c
4
    arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf
5
    arm-linux-objcopy -O binary -S sdram_elf sdram.bin
6
    arm-linux-objdump -D -m arm sdram_elf > sdram.dis
7
clean:
8
    rm -f sdram.dis sdram.bin sdram_elf *.o
    爲了更形象地瞭解本程序,下面用圖6.4來演示程序的複製、跳轉過程。



6.2.2 實例測試

    在sdram目錄中執行make指令生成可執行文件sdram.bin後,下載到板子上運行。可以
發現與leds程序相比,LED閃爍得更慢,原因是外部SDRAM的性能比內部SRAM差一些。
    把程序從性能更好的內部SRAM移到外部SDRAM中去,是否多此一舉呢?內部SRAM
只有4KB大小,如果程序大於4KB,那麼就不能指望完全利用內部SRAM來運行了,得想
辦法把存儲在NAND Flash中的代碼複製到SDRAM中去。對於NAND Flash中的前4KB,
芯片自動把它複製到內部SRAM中,可以很輕鬆地再把它複製到SDRAM中(實驗代碼中的
函數copy_steppingston_to_sdram就有此功能),要複製4KB後面的代碼需要使用NAND Flash
控制器來讀取NAND Flash,這就是第8章的內容。
附:代碼:
鏈接: https://pan.baidu.com/s/1kV24a9L 密碼: tfab
發佈了20 篇原創文章 · 獲贊 35 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章