• <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
            數據加載中……

            學習 ARM 系列 -- FS2410 開發板上的內存搬移實驗

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

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

               @ 文件 head.s
               @ 作用: 關閉看門狗、設置內存、向 SDRAM 搬移 Nand Flash 的前 4K 代碼、設置堆棧、
               @ 調用已經搬移到 SDRAM 的 main 函數
               .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)技術就是最常見的抗干擾技術,實際上是一個
               可清零的定時計數器。
              
               @ 文件 memory.s
               @ 初始化內存控制寄存器
               .global memory_setup       @ 導出 memory_setup, 使其對鏈接器可見
               memory_setup:
                mov  r1, #0x48000000     @ BWSCON 內存控制寄存器地址
                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的數據掩碼引腳,對SDRAM,此位為0;對SRAM,此位為1
                  b.WSx:是否使用存儲器的WAIT信號,通常設為0
                  c.DWx:使用兩位來設置存儲器的位寬:00-8位,01-16位,10-32位,11-保留。
                  d.比較特殊的是BANK0對應的4位,它們由硬件跳線決定,只讀。
                  e.對于本開發板,使用兩片容量為32Mbyte、位寬為16的SDRAM組成容量為64Mbyte、
                    位寬為32的存儲器,所以其BWSCON相應位為:0010。對于本開發板,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時,還需要設置兩個參數:
                     Trcd([3:2]):RAS to CAS delay,設為推薦值0b01
                     SCAN([1:0]):SDRAM的列地址位數,本開發板的SDRAM列地址位數為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的數
                  據手冊上有標明,在本開發板使用的SDRAM HY57V561620CT-H的數據手冊上,可看見
                  這么一行“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 */
               /* 作用 循環點亮開發板上的 D9、D10、D11、D12 四個發光二極管 */
               #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); /* 如何設置此二寄存器使二極管發光,前一*/
                     GPFDAT = 0x0;               /* 篇隨筆(FS2401 發光二極管循環點亮) */
                                                        /* 里有介紹*/
                     // for delay
                     for(j=0;j<50000;++j) ;
                   }
                 }
               }

               # Makefile
               # 編譯上述三個代碼文件, 并鏈接生成的目標文件,
               # 再將目標文件(ELF格式)轉換成二進制格式文件
               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 的
                    # 起始地址, 更多細節請參考 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
               一下開發板, 欣賞您的實驗成果吧

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

            評論

            # re: 學習 ARM 系列 -- FS2410 開發板上的內存搬移實驗  回復  更多評論   

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

            # re: 學習 ARM 系列 -- FS2410 開發板上的內存搬移實驗  回復  更多評論   

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

            # re: 學習 ARM 系列 -- FS2410 開發板上的內存搬移實驗  回復  更多評論   

            ldr pc, =main @ call main in SDRAM

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

            # re: 學習 ARM 系列 -- FS2410 開發板上的內存搬移實驗  回復  更多評論   

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

            ldr pc, 0x30000000 + main_addr

            這實際上是跳到 SDRAM 里的 main 處并執行 main 調用
            2008-07-31 17:10 | Normandy
            伊人久久无码中文字幕| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 亚洲精品99久久久久中文字幕| 国产精久久一区二区三区| 久久婷婷色综合一区二区| 麻豆久久久9性大片| 国产精品久久毛片完整版| 久久综合久久伊人| 国内精品久久久久久99| 久久久99精品一区二区| 久久99国产乱子伦精品免费| 久久97久久97精品免视看| 无码精品久久久久久人妻中字| 2020最新久久久视精品爱| 色妞色综合久久夜夜| 青青草国产97免久久费观看| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 国产精品女同久久久久电影院 | 国产福利电影一区二区三区,免费久久久久久久精 | 久久狠狠一本精品综合网| 色综合久久久久久久久五月| 久久久久久国产a免费观看不卡| 亚洲色婷婷综合久久| 噜噜噜色噜噜噜久久| 人妻中文久久久久| 久久国产成人午夜AV影院| 久久国产乱子精品免费女| 亚洲精品午夜国产VA久久成人| 久久影视综合亚洲| 久久久精品视频免费观看| 亚洲国产精品久久久久婷婷软件 | 99久久国产亚洲综合精品| 久久精品国产精品亚洲人人 | 国产成人精品久久亚洲| 国产成人综合久久综合| 久久不射电影网| 97热久久免费频精品99| 久久狠狠色狠狠色综合| 91精品国产综合久久四虎久久无码一级| 欧美黑人激情性久久| 久久99精品久久只有精品|