1. 程式人生 > >JZ2440 裸機驅動 第6章 存儲控制器

JZ2440 裸機驅動 第6章 存儲控制器

logs display 裸機 包含 們的 不支持 sel watchdog inux

本章目標: 了解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的代碼如下: 技術分享
 1 @****************************************
 2 @ File:head.S
 3 @ 功能:設置SDRAM,將程序復制到SDRAM,然後跳到SDRAM繼續執行
 4 @****************************************
 5 
 6 .equ    MEM_CTL_BASE,    0x48000000
 7 .equ    SDRAM_BASE,      0x30000000
 8     
 9 .text
10 .global _start
11 _start:
12     bl disable_watch_dog             @關閉WATCHDOG
13     bl memsetup                      @設置存儲控制器
14     bl copy_steppingston_to_sdram    @復制代碼到SDRAM中
15     ldr pc, =on_sdram                @跳到SDRAM中繼續執行
16 on_sdram:
17     ldr sp, =0x34000000              @設置棧
18     bl main
19 halt_loop:
20     b halt_loop
21     
22 disable_watch_dog:
23     @往WATCHDOG寄存器寫0即可
24     mov r1, #0x53000000
25     mov r2, #0x0
26     str r2, [r1]
27     mov pc, lr         @返回
28     
29 copy_steppingstone_to_sdram:
30     @將Steppingstone的4KB數據全部復制到SDRAM中去
31     @Steppingstone起始地址為0x0000 0000,SDRAM中起始地址為0x3000 0000
32         
33     mov r1, #0
34     ldr r2, =SDRAM_BASE
35     mov r3, #4*1024
36 1:
37     ldr r4, [r1], #4    @從Steppingstone(0x0000 0000)讀取4字節的數據,並讓源地址加4
38     str r4, [r2], #4    @將此4字節數據復制到SDRAM中,並讓目的地址加4
39     cmp r1, r3          @判斷是否完成:源地址是否等於Steppingstone的末地址?
40     bne 1b              @若沒有復制完,繼續
41     mov pc, lr          @返回
42     
43 memsetup:
44     @設置存儲控制器以便使用SDRAM等外設
45     
46     mov    r1, #MEM_CTL_BASE    @存儲控制器的13個寄存器的開始地址
47     adr1   r2, mem_cfg_val      @這13個值的起始存儲地址
48     add    r3, r1, #52          @13*4 = 52
49 1:
50     ldr r4, [r2], #4            @讀取“待設置值”,並讓r2加4
51     str r4, [r1], #4            @將此值寫入寄存器,並讓r1加4
52     cmp r1, r3                  @判斷是否設置完所有13個寄存器
53     bne 1b                      @若沒有寫完,繼續
54     mov pc, lr                  @返回
55 
56 
57 .align 4
58 mem_cfg_val:
59     @存儲控制器13個寄存器的設置值
60     .long 0x22011110    @BWSCON
61     .long 0x00000700    @BANKCON0
62     .long 0x00000700    @BANKCON1
63     .long 0x00000700    @BANKCON2
64     .long 0x00000700    @BANKCON3
65     .long 0x00000700    @BANKCON4
66     .long 0x00000700    @BANKCON5
67     .long 0x00018005    @BANKCON6
68     .long 0x00018005    @BANKCON7
69     .long 0x008c07a3    @REFRESH
70     .long 0x000000b1    @BANKSIZE
71     .long 0x00000030    @MRSRB6
72     .long 0x00000030    @MRSRB7
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
Makefile 為了更形象地了解本程序,下面用圖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

JZ2440 裸機驅動 第6章 存儲控制器