• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 60, 文章 - 0, 評論 - 197, 引用 - 0
            數(shù)據(jù)加載中……

            學習 ARM 系列 -- FS2410 開發(fā)板上的內(nèi)存搬移實驗

            一、目的
               通過將 Nand Flash 前 4K 代碼搬移到 SDRAM 中,了解如何初始化并使用 ARM 的內(nèi)存,
               為編寫 ARM bootloader 和搬移內(nèi)核到內(nèi)存作準備。

            二、代碼
               關于如何建立開發(fā)環(huán)境,在我的前一篇隨筆(FS2401 發(fā)光二極管循環(huán)點亮)里有介紹, 請
               參考。要初始化并使用內(nèi)存需要了解一些很鎖碎的細節(jié),上來就講這些知識點未免生澀,不
               如在代碼中穿插講解來的直接。

               @ 文件 head.s
               @ 作用: 關閉看門狗、設置內(nèi)存、向 SDRAM 搬移 Nand Flash 的前 4K 代碼、設置堆棧、
               @ 調(diào)用已經(jīng)搬移到 SDRAM 的 main 函數(shù)
               .text
               .global _start
               _start:
                ldr r0, =0x53000000        @ Close watch-dog
                mov r1, #0x0
                str r1, [r0]
                bl  memory_setup            @ Initialize memory setting
                bl  copy_block_to_sdram   @ Move code to SDRAM
                ldr sp, =0x34000000         @ Set stack pointer
                ldr pc, =main                   @ call main in SDRAM
                
               halt_loop:
                b   halt_loop
              
               copy_block_to_sdram:
                mov r0, #0x0
                mov r1, #0x30000000
                mov r2, #4096
               copy_loop:
                ldmia r0!, {r3-r10}
                stmia r1!, {r3-r10}
                cmp   r0, r2
                blo copy_loop
             
               注:看門狗(Watch Dog Timer,簡稱為WDT)技術(shù)就是最常見的抗干擾技術(shù),實際上是一個
               可清零的定時計數(shù)器。
              
               @ 文件 memory.s
               @ 初始化內(nèi)存控制寄存器
               .global memory_setup       @ 導出 memory_setup, 使其對鏈接器可見
               memory_setup:
                mov  r1, #0x48000000     @ BWSCON 內(nèi)存控制寄存器地址
                adrl r2, mem_cfg_val   
                add  r3, r1, #13*4
               1: 
                @ write initial values to registers
                ldr  r4, [r2], #4
                str  r4, [r1], #4
                cmp  r1, r3
                bne  1b
                mov  pc, lr
                
                .align 4
               mem_cfg_val:
                .long 0x22111110 @ 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 9bit
                .long 0x008e07a3 @ REFRESH
                .long 0x000000b2 @ BANKSIZE
                .long 0x00000030 @ MRSRB6
                .long 0x00000030 @ MRSRB7

               注: 要理解這里的寄存器設置需要看手冊和資料, 這里簡單介紹一下:
               1.BWSCON:對應BANK0-BANK7,每BANK使用4位。這4位分別表示:
                  a.STx:啟動/禁止SDRAM的數(shù)據(jù)掩碼引腳,對SDRAM,此位為0;對SRAM,此位為1
                  b.WSx:是否使用存儲器的WAIT信號,通常設為0
                  c.DWx:使用兩位來設置存儲器的位寬:00-8位,01-16位,10-32位,11-保留。
                  d.比較特殊的是BANK0對應的4位,它們由硬件跳線決定,只讀。
                  e.對于本開發(fā)板,使用兩片容量為32Mbyte、位寬為16的SDRAM組成容量為64Mbyte、
                    位寬為32的存儲器,所以其BWSCON相應位為:0010。對于本開發(fā)板,BWSCON可設為
                    0x22111110:其實我們只需要將BANK6對應的4位設為0010即可,其它的是什么值沒
                    什么影響,這個值是參考手冊上給出的。
               2.BANKCON0-BANKCON5:我們沒用到,使用默認值0x00000700即可
               3.BANKCON6-BANKCON7:設為0x00018005
                  在8個BANK中,只有BANK6和BANK7可以使用SRAM或SDRAM,與BANKCON0-5有點不同:
                  a.MT([16:15]):用于設置本BANK外接的是SRAM還是SDRAM:SRAM-0b00,SDRAM-0b11
                  b.當MT=0b11時,還需要設置兩個參數(shù):
                     Trcd([3:2]):RAS to CAS delay,設為推薦值0b01
                     SCAN([1:0]):SDRAM的列地址位數(shù),本開發(fā)板的SDRAM列地址位數(shù)為9,所以SCAN=0b01
               4.REFRESH(SDRAM refresh control register):
                  其中R_CNT用于控制SDRAM的刷新周期,占用REFRESH寄存器的[10:0]位,它的取值可
                  如下計算(SDRAM時鐘頻率就是HCLK):
                  R_CNT = 2^11 + 1 – SDRAM時鐘頻率(MHz) * SDRAM刷新周期(uS)
                  在未使用PLL時,SDRAM時鐘頻率等于晶振頻率12MHz;SDRAM的刷新周期在SDRAM的數(shù)
                  據(jù)手冊上有標明,在本開發(fā)板使用的SDRAM HY57V561620CT-H的數(shù)據(jù)手冊上,可看見
                  這么一行“8192 refresh cycles / 64ms”:所以,刷新周期=64ms/8192 = 7.8125 uS。

                  對于本實驗,R_CNT = 2^11 + 1 – 12 * 7.8125 = 1955
                  REFRESH=0x008e0000 + 1955 = 0x008e07a3
               5.BANKSIZE:0x000000b2
                  位[7]=1:Enable burst operation
                  位[5]=1:SDRAM power down mode enable
                  位[4]=1:SCLK is active only during the access (recommended)
                  位[2:1]=010 BANK6、BANK7對應的地址空間: 010-128M/128M, 001-64M/64M
               6.MRSRB6、MRSRB7:0x00000030
                  能讓我們修改的只有位[6:4](CL),SDRAM HY57V561620CT-H不支持CL=1的情況,所以
                  位[6:4]取值為010(CL=2)或011(CL=3)


               /* 文件 sdram.c */
               /* 作用 循環(huán)點亮開發(fā)板上的 D9、D10、D11、D12 四個發(fā)光二極管 */
               #define GPFCON (*(volatile unsigned long *)0x56000050) /* GPFCON 端口地址為0x56000050 */
               #define GPFDAT (*(volatile unsigned long *)0x56000054) /* GPFDAT 端口地址為0x56000054 */
              
               int main()
               {
                 int i,j;
                 while(1) {
                   for (i = 0; i <4; ++i) {
                     GPFCON = 0x1<<(8+i*2); /* 如何設置此二寄存器使二極管發(fā)光,前一*/
                     GPFDAT = 0x0;               /* 篇隨筆(FS2401 發(fā)光二極管循環(huán)點亮) */
                                                        /* 里有介紹*/
                     // for delay
                     for(j=0;j<50000;++j) ;
                   }
                 }
               }

               # Makefile
               # 編譯上述三個代碼文件, 并鏈接生成的目標文件,
               # 再將目標文件(ELF格式)轉(zhuǎn)換成二進制格式文件
               sdram:head.s memory.s sdram.c
                    arm-linux-gcc -c -o head.o head.s
                    arm-linux-gcc -c -o memory.o memory.s
                    arm-linux-gcc -c -o sdram.o sdram.c

                    # -Ttext 0x30000000 會使目標文件里 ldr pc, =main 指令里的 pc 加上
                    # 0x30000000 這個基地址,而 #0x30000000 正是我們要將代碼搬到 SDRAM 的
                    # 起始地址, 更多細節(jié)請參考 arm-linux-ld -Ttext 的用法
                    arm-linux-ld  -Ttext 0x30000000 head.o memory.o sdram.o -o sdram_tmp.o
                    arm-linux-objcopy -O binary -S sdram_tmp.o sdram
              clean:
                    rm -f *.o
                    rm -f sdram


            三、編譯、燒寫、測試
               Make 一下就會生成我們要的文件 sdram, 將其通過 JTAG 燒入 Nand Flash 即可,Reset
               一下開發(fā)板, 欣賞您的實驗成果吧

            posted on 2008-01-05 20:56 Normandy 閱讀(2717) 評論(4)  編輯 收藏 引用 所屬分類: Embeded Area

            評論

            # re: 學習 ARM 系列 -- FS2410 開發(fā)板上的內(nèi)存搬移實驗  回復  更多評論   

            好東西啊,支持!
            2008-01-05 21:05 | hukq

            # re: 學習 ARM 系列 -- FS2410 開發(fā)板上的內(nèi)存搬移實驗  回復  更多評論   

            買了本書就是基于三星2410的板子 但是還沒來得及看……共同努力了!
            2008-01-05 22:36 | 江水獸

            # re: 學習 ARM 系列 -- FS2410 開發(fā)板上的內(nèi)存搬移實驗  回復  更多評論   

            ldr pc, =main @ call main in SDRAM

            最近在學這個,問樓主一個問題,為什么這里main是在SDRAM里面的,
            FLASH里面不是也有個main嗎?
            2008-07-31 16:18 | xi_liang

            # re: 學習 ARM 系列 -- FS2410 開發(fā)板上的內(nèi)存搬移實驗  回復  更多評論   

            @xi_liang
            Nand Flash 只是存儲器,其前 4k 被映射到 SRAM (就是 NOR FLASH) 里,所以小于 4k 的程序運行是沒有問題的, 大于 4k 的程序則不行。在執(zhí)行 ldr pc, =main 之前 bl copy_block_to_sdram 把 Nand Flash 里的代碼搬到 SDRAM 里從 0x30000000 處開始的區(qū)域了。而 ldr pc, =main 實際上執(zhí)行的是:

            ldr pc, 0x30000000 + main_addr

            這實際上是跳到 SDRAM 里的 main 處并執(zhí)行 main 調(diào)用
            2008-07-31 17:10 | Normandy
            久久99免费视频| 亚洲欧美成人久久综合中文网| 久久午夜无码鲁丝片秋霞| 人妻系列无码专区久久五月天| 久久天天躁狠狠躁夜夜2020| 久久精品综合网| av无码久久久久不卡免费网站| 久久人人爽人人爽人人av东京热| 国产成人精品综合久久久| 色综合久久中文色婷婷| 伊人久久成人成综合网222| 成人国内精品久久久久影院| 久久人妻少妇嫩草AV蜜桃| 久久99精品国产自在现线小黄鸭 | 久久99精品久久久久久久不卡| 久久综合久久综合久久综合| 国产亚洲精久久久久久无码77777| 久久国产精品久久| 国产亚洲精久久久久久无码77777| 国产激情久久久久影院小草| 久久天天躁狠狠躁夜夜avapp| 色综合久久久久综合99| 精品久久久久久亚洲| 久久久久亚洲精品日久生情| 久久无码精品一区二区三区| 77777亚洲午夜久久多喷| 国产成人无码精品久久久性色 | 久久久久久伊人高潮影院| 国产精品日韩欧美久久综合| 91精品国产91久久久久福利| 亚洲AV无码1区2区久久| 久久久久av无码免费网| 久久亚洲欧洲国产综合| 国内精品久久久久久中文字幕| 韩国免费A级毛片久久| 精品国产青草久久久久福利| 日韩欧美亚洲综合久久影院Ds| 精品无码久久久久久久久久| 精品久久久久国产免费| 国产精品欧美久久久久天天影视 | 久久久久久久波多野结衣高潮 |