S3C2440的裸奔--內存篇


大,爲什麼要在規定的小空間裏和自己過不去呢!開發板上也一樣,之前一直在一個4K大的Stepping stone裏打轉轉,
可惜了那64MB的內存了。那麼,今天就到擁有更廣闊的天地裏折騰一番吧。

    s3c2440對外引出了27根地址線ADDR0~ADDR26,最多能尋址2的27次方,也就是128MB,但實際上s3c2440能夠
尋址1G的地址空間,這是因爲它還有8根片選信號線nGCS0~nGCS7,每根信號線對應一個128MB地址空間,這個空間被稱作
BANK,所以s3c2440共有8個BANK -- BANK0~BANK7,當訪問某個BANK時,其對應的nGCS信號引腳電平拉低,這和單
片機上的擴展IO的操作類同。s3c2440是32位的芯片,理論上支持2的32次方,即4GB的地址空間,除去上面8個BANK用掉的
1GB地址空間外,特殊功能寄存器佔用了0x48000000~0x5b00001c這段地址空間,其它的地址空間沒有被使用。
    
    BANK0~BANK5可以連接ROM和SRAM類型的存儲器,BANK6~BANK7可以連接ROM、SRAM、SDRAM類型的存儲器,
最大支持256MB,mini2440將兩片32MB,16bits位寬的SDRAM連接在了BANK6和BANK7上,並聯構成64MB、32位寬的
內存。

    在處理SDRAM內部的數據時需要先指定行,再指定列,即可訪問到需要的數據,由行和列構成的矩陣稱爲存儲陣列,
大家一般會把它叫作"L-BANK",但SDRAM裏面不會只有一個存儲陣列,這是因爲如果只做一個存儲陣列會造成嚴重的尋址
衝突並大幅度降低內存效率。所以一般人們都將內存分爲4個存儲陣列(這也是SDRAM規範中的最高L-BANK數量),訪問時
每次只能訪問一個,具體訪問那個L-BANK可以通過內存的兩個外接引腳BA0和BA1來決定,mini2440將addr24連接BA0、
addr25連接BA1,通過地址線24和地址線25來選擇存儲單元的4個L-BANK。

    SDRAM只有13根地址線A0~A12,只能尋址8MB(2的13次方)的內存空間,由於每個內存內部劃分成四個L-BANK,所以
通過addr24和addr25的配合,就可以尋址一個內存芯片的全部空間。開發板上一共有兩片並聯的32MB的SDRAM,每發送一次
地址信號,兩片芯片都可以同時接收到,之後其中一片返回低16bits的數據,另一片返回高16bits的數據。下面是內存芯片和
cpu的引腳的連接表:


--------------------------------------------------------------------------------------------------------------------cpu引腳          內存芯片引腳    描述--------------------------------------------------------------------------------------------------------------------A2~A14       A0~A12       地址線--------------------------------------------------------------------------------------------------------------------D0~D31       DQ0~DQ31     數據線,其中一片的DQ0~DQ15連接D0~D15,另一片的DQ0~DQ15連接D16~D31--------------------------------------------------------------------------------------------------------------------A24,A25      BA0,BA1      L-BANK選擇信號--------------------------------------------------------------------------------------------------------------------DQM0~DQM3    LDQM,UDQM    高低字節數據掩碼信號--------------------------------------------------------------------------------------------------------------------SCKE         SCKE         輸入時鐘有效信號--------------------------------------------------------------------------------------------------------------------SCLK         SCLK         輸入時鐘--------------------------------------------------------------------------------------------------------------------nSCS0        nSCS         片選信號(和nGCS6是同一個引腳,只是功能不同)--------------------------------------------------------------------------------------------------------------------nSRAS        nSRAS        行地址選通信號--------------------------------------------------------------------------------------------------------------------nSCAS        nSCAS        列地址選通信號--------------------------------------------------------------------------------------------------------------------nWE          nWE          寫入有效信號--------------------------------------------------------------------------------------------------------------------

 



存儲控制器的寄存器部分這裏略過。    

    下面是啓動代碼:
 

@*************************************************************************@ File:head.S@ 功能:關閉看門狗,初始化時鐘,初始化內存,將Stepping stone的數據@複製到SDRAM,  然後跳到內存中繼續運行main函數,循環點亮led燈。@*************************************************************************       @看門狗寄存器.equ        WTCON,       0x53000000     @看門狗控制寄存器.equ        WTDAT,       0x53000004     @看門狗數據寄存器.equ        WTCNT,       0x53000008     @看門狗計數寄存器@系統時鐘寄存器.equ        LOCKTIME,    0x4c000000     @變頻鎖定時間寄存器.equ        MPLLCON,     0x4c000004     @MPLL寄存器.equ        CLKDIVN,     0x4c000014     @分頻比寄存器@內存寄存器.equ        MEM_CTL_BASE,       0x48000000.equ        SDRAM_BASE,         0x30000000  @定義64MB內存開始的地址.equ        SDRAM_END,          0x34000000  @定義64MB內存結束的地址.text.global _start_start:        bl    disable_watch_dog               @ 關閉WATCHDOG,否則CPU會不斷重啓        bl    init_clock                      @初始化系統時鐘        bl    memsetup                        @ 設置存儲控制器        bl    copy2sdram                      @ 複製代碼到SDRAM中        ldr   pc, =on_sdram                   @ 跳到SDRAM中繼續執行on_sdram:            ldr   sp, =SDRAM_END                  @ 設置堆棧,堆棧由高地址向低地址生長            bl    mainhalt_loop:            b    halt_loopdisable_watch_dog:        mov   r1, #WTCON        mov   r2, #0x0                        @ 往WATCHDOG寄存器寫0即可        str   r2, [r1]        mov   pc, lr                          @ 返回init_clock:            @ 設置鎖頻時間        ldr   r0, =LOCKTIME                   @取得LOCKTIME寄存器地址        ldr   r1, =0x00ffffff                 @設置鎖定時間        str   r1, [r0]                        @將r1中的數據寫入r0           @設置FCLK,HCLK,PCLK三者之間的比例,本來還需要設置CAMDIVN寄存器,        @但這裏設置成1:4:8,所以CAMDIVN使用默認值就可以了!        ldr   r0, =CLKDIVN                    @取得CLKDIVN寄存器地址        mov   r1, #0x05                       @設定比例        str   r1, [r0]                @修改CPU總線模式        mrc   p15, 0, r1, c1, c0, 0        orr   r1, r1, #0xc0000000        mcr   p15, 0, r1, c1, c0, 0        @倍頻到400MHz          ldr   r0, =MPLLCON                    @MPLL控制寄存器        ldr   r1, =0x0005c011        str   r1, [r0]        mov   pc, lr                          @ 返回copy2sdram:            @ 將Steppingstone的4K數據全部複製到SDRAM中去            @ Steppingstone起始地址爲0x00000000,SDRAM中起始地址爲0x30000000            mov   r1, #0            ldr   r2, =SDRAM_BASE            mov   r3, #4*1024copyloop:              ldr   r4, [r1],#4                     @ 從Steppingstone讀取4字節的數據,並讓源地址加4            str   r4, [r2],#4                     @ 將此4字節的數據複製到SDRAM中,並讓目地地址加4            cmp   r1, r3                          @ 判斷是否完成:源地址等於Steppingstone的未地址?            bne   copyloop                        @ 若沒有複製完,繼續            mov   pc, lr                          @ 返回memsetup:            @ 設置存儲控制器以便使用SDRAM等外設           mov   r1, #MEM_CTL_BASE               @ 存儲控制器的13個寄存器的開始地址           adrl  r2, mem_cfg_val                 @ 這13個值的起始存儲地址           add   r3, r1, #52                     @ 13*4 = 54initmemloop:              ldr   r4, [r2], #4                    @ 讀取設置值,並讓r2加4           str   r4, [r1], #4                    @ 將此值寫入寄存器,並讓r1加4           cmp   r1, r3                          @ 判斷是否設置完所有13個寄存器           bne   initmemloop                     @ 若沒有寫成,繼續            mov   pc, lr                          @ 返回@4字節對齊.align 4  mem_cfg_val:    @ 存儲控制器13個寄存器的設置值    .long   0x22000000      @ BWSCON    .long   0x00000700      @ BANKCON0    .long   0x00000700      @ BANKCON1    .long   0x00000700      @ BANKCON2    .long   0x00000700      @ BANKCON3      .long   0x00000700      @ BANKCON4    .long   0x00000700      @ BANKCON5    .long   0x00018005      @ BANKCON6    .long   0x00018005      @ BANKCON7    .long   0x008E04F5      @ REFRESH    .long   0x000000B1      @ BANKSIZE    .long   0x00000030      @ MRSRB6    .long   0x00000030      @ MRSRB7@******************************************************************************

 





C程序還是使用上次那個leds.c程序,這裏就不再列出代碼了!
然後是編譯用的Makefile.


#******************************************************************************#Makefile#******************************************************************************sdram.bin : head.S  leds.c    arm-linux-gcc  -c -o head.o head.S    arm-linux-gcc -c -o leds.o leds.c    arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf    arm-linux-objcopy -O binary -S sdram_elf sdram.bin    arm-linux-objdump -D -m arm  sdram_elf > sdram.disclean:    rm -f   sdram.dis sdram.bin sdram_elf *.o#****************************************************************************** 

 



編譯之後得到sdram.bin,下載到開發板上運行。可以看到led閃爍的速度比上次慢了很多,


這是因爲外部的SDRAM的性能比內部的SRAM差很多。但內部的SRAM只有4k,如果程序大於4k,


就需要想辦法將存儲在NAND中的代碼複製到SDRAM中去運行。


注意:上面的代碼只是把SRAM中的代碼複製到SDRAM中運行,並不是將NAND Flash中的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章