<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > FS2410 開(kāi)發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移

          FS2410 開(kāi)發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移

          作者: 時(shí)間:2016-11-10 來(lái)源:網(wǎng)絡(luò) 收藏
          一、目的

          前面做過(guò)一個(gè)實(shí)驗(yàn),搬移 Nand Flash 里的前 4k 代碼到內(nèi)存指定位置,這其實(shí)是把

          本文引用地址:http://www.ex-cimer.com/article/201611/317241.htm

          SRAM 從 0x40000000 開(kāi)始的 4K 代碼復(fù)制到 SDRAM 的指定位置,并沒(méi)有涉及到對(duì) Nand

          Flash 的操作。究其原因,開(kāi)發(fā)板上電后,Nand Flash 開(kāi)始的前 4K 數(shù)據(jù)會(huì)被自動(dòng)復(fù)制到

          SRAM 0x40000000 開(kāi)始的 4K 區(qū)域里,這個(gè)區(qū)域被稱為 "Steppingstone"。那我們這次就來(lái)

          操作 Nand Flash,讀取它 4K 后的代碼到 SDRAM 指定位置,并執(zhí)行 SDRAM 中的代碼。

          二、代碼

          通過(guò)前面做的幾個(gè)實(shí)驗(yàn),我們已經(jīng)熟悉了 ARM 開(kāi)發(fā)的基本流程,這可以讓我們更關(guān)注于

          代碼的邏輯。好,先來(lái)分析文件 head.s:

          @ 文件 head.s

          @ 作用:關(guān)閉看門狗、SDRAM 的初始化設(shè)置、搬移 Nand Flash 4K 以后

          @ 的代碼到 SDRAM 的指定位置、執(zhí)行 SDRAM 中的代碼

          .text

          .global _start

          _start:

          ldr r0, =0x53000000@ Close Watch Dog Timer

          mov r1, #0x0

          str r1, [r0]

          bl memory_setup @ Initialize memory setting

          bl flash_to_sdram@ Copy code to sdram

          ldr sp, =0x34000000@ Set stack pointer

          ldr pc, =main @ execute the code in SDRAM

          @ 文件 mem.s

          @ 作用:SDRAM 的初始化設(shè)置

          @ 關(guān)于初始化的更多細(xì)節(jié),請(qǐng)參考我的前一篇隨筆

          .global memory_setup @ 導(dǎo)出 memory_setup, 使其對(duì)鏈接器可見(jiàn)

          memory_setup:

          mov r1, #0x48000000

          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

          @ 文件 flash.s

          @ 作用:設(shè)置 Nand Flash 的控制寄存器、讀取 Nand Flash

          @ 中的代碼到 SDRAM 的指定位置

          .equ NFCONF, 0x4e000000

          .equ NFCMD, 0x4e000004

          .equ NFADDR, 0x4e000008

          .equ NFDATA, 0x4e00000c

          .equ NFSTAT, 0x4e000010

          .equ NFECC, 0x4e000014

          .global flash_to_sdram

          flash_to_sdram:

          @ Save return addr

          mov r10,lr

          @ Initialize Nand Flash

          mov r0,#NFCONF

          ldr r1,=0xf830

          str r1,[r0]

          @ First reset and enable Nand Flash

          ldr r1,[r0]

          bic r1, r1, #0x800

          str r1,[r0]

          ldr r2,=NFCMD

          mov r3,#0xff

          str r3,[r2]

          @ for delay

          mov r3, #0x0a

          1:

          subs r3, r3, #1

          bne 1b

          @ Wait until Nand Flash bit0 is 1

          wait_nfstat:

          ldr r2,=NFSTAT

          ldr r3,[r2]

          tst r3,#0x01

          beq wait_nfstat

          @ Disable Nand Flash

          ldr r0,=NFCONF

          ldr r1,[r0]

          orr r1,r1,#0x8000

          str r1,[r0]

          @ Initialzie stack

          ldr sp,=4096

          @ Set arguments and call

          @ function nand_read defined in nand_read.c

          ldr r0,=0x30000000

          mov r1,#4096

          mov r2,#1024

          bl nand_read

          @ return

          mov pc,r10

          /* 文件 nand_read.c

          * 作用:從 Nand Flash 中讀取一塊數(shù)據(jù)到 SDRAM 中的指定位置

          */

          #define NFCONF (*(volatile unsigned long *)0x4e000000)

          #define NFCMD (*(volatile unsigned long *)0x4e000004)

          #define NFADDR (*(volatile unsigned long *)0x4e000008)

          #define NFDATA (*(volatile unsigned long *)0x4e00000c)

          #define NFSTAT (*(volatile unsigned long *)0x4e000010)

          #define NFECC (*(volatile unsigned long *)0x4e000014)

          #define NAND_SECTOR_SIZE 512

          #define NAND_BLOCK_MASK 0x1ff

          void wait_idle() {

          int i;

          for (i = 0; i < 50000; ++i) ;

          }

          int nand_read(unsigned char *buf, unsigned long start_addr, int size){

          int i, j;

          /*

          * detect the argument

          */

          if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {

          return -1;

          }

          /* chip Enable */

          NFCONF &= ~0x800;

          for (i=0; i<10; i++) {

          ;

          }

          for (i=start_addr; i < (start_addr + size); i+=NAND_SECTOR_SIZE) {

          NFCMD = 0;

          /* Write Address */

          NFADDR = i & 0xff;

          NFADDR = (i >> 9) & 0xff;

          NFADDR = (i >> 17) & 0xff;

          NFADDR = (i >> 25) & 0xff;

          wait_idle();

          for(j=0; j < NAND_SECTOR_SIZE; j++) {

          *buf++ = (NFDATA & 0xff);

          }

          }

          NFCONF |= 0x800; /* chip disable */

          return 0;

          }

          注:Nand Flash 的設(shè)置和讀取數(shù)據(jù)的主要流程簡(jiǎn)單介紹如下:

          1. NFCONF = 0xf830

          2. 在第一次操作NAND Flash前,通常復(fù)位一下:

          NFCONF &= ~0x800 (使能NAND Flash)

          NFCMD = 0xff (reset命令)

          循環(huán)查詢NFSTAT位0,直到它等于1

          3. NFCMD = 0 (讀命令)

          4. 這步得稍微注意一下,請(qǐng)打開(kāi)K9F1208U0M數(shù)據(jù)手冊(cè)第7頁(yè),那個(gè)表格列出了在地址操

          作的4個(gè)步驟對(duì)應(yīng)的地址線,A8沒(méi)用到:

          NFADDR = addr & 0xff

          NFADDR = (addr>>9) & 0xff (注意了,左移9位,不是8位)

          NFADDR = (addr>>17) & 0xff (左移17位,不是16位)

          NFADDR = (addr>>25) & 0xff (左移25位,不是24位)

          5. 循環(huán)查詢NFSTAT位0,直到它等于1

          6. 連續(xù)讀NFDATA寄存器512次,得到一頁(yè)數(shù)據(jù)(512字節(jié))

          7. NFCONF |= 0x800 (禁止NAND Flash)

          /* 文件 sdram.c

          * 作用:循環(huán)點(diǎn) FS2410 開(kāi)發(fā)板上的 D9、D10、D11、D12

          * 四個(gè)發(fā)光二極管。

          */

          #define GPFCON (*(volatile unsigned long *)0x56000050)

          #define GPFDAT (*(volatile unsigned long *)0x56000054)

          int main()

          {

          int i,j;

          while(1) {

          for (i = 0; i <4; ++i) {

          GPFCON = 0x1<<(8+i*2);

          GPFDAT = 0x0;

          // for delay

          for(j=0;j<50000;++j) ;

          }

          }

          }

          /*

          * 文件 nand.lds (lds 文件是連接腳本)

          */

          SECTIONS {

          first 0x00000000 : { head.o mem.o flash.o nand_read.o }

          second 0x30000000 : AT(4096) { sdram.o }

          }

          注:這個(gè)鏈接腳本是用來(lái)傳給鏈接器的,其作用如下:

          1. 將 head.o 放在 0x00000000 開(kāi)始的地址處, mem.o、flash.o、and_read.o

          依次放在 head.o 后面, 它們的運(yùn)行地址是 0x00000000

          2. 將 sdram.o 放在地址 4096 開(kāi)始處, 但它的運(yùn)行地址是 0x30000000, 運(yùn)行前需要

          從 4096 處復(fù)制到 SDRAM 的 0x300000000 處

          完整的連接腳本文件形式如下:

          SECTIONS {

          ...

          secname start BLOCK(align) (NOLOAD) : AT(ldadr) {contents} >region :phdr =fill

          ...

          }

          并非每個(gè)選項(xiàng)都是必須的,僅從 nand.lds 用到的來(lái)看:

          (1) secname: 段名,對(duì)于 nand.lds, 段名為 first 和 second

          (2) start: 本段的運(yùn)行時(shí)地址,如果沒(méi)有 AT(xxx),則本段的存儲(chǔ)地址也是 start

          (3) AT(ldadr): 定義本段存儲(chǔ)(加載)的地址

          (4) {contents}: 決定哪些內(nèi)容放在本段,可以是整個(gè)目標(biāo)文件,也可是目標(biāo)文件中的某段

          # 文件 Makefile

          # 由代碼文件生成目標(biāo)文件,并依據(jù)連接腳本 nand.lds 連接目標(biāo)文件,

          # 最后將連接生成的目標(biāo)文件轉(zhuǎn)換成二進(jìn)制格式

          sdram:head.s flash.s mem.s sdram.c

          arm-linux-gcc -c -o head.o head.s

          arm-linux-gcc -c -o mem.o mem.s

          arm-linux-gcc -c -o flash.o flash.s

          arm-linux-gcc -c -o nand_read.o nand_read.c

          arm-linux-gcc -c -o sdram.o sdram.c

          arm-linux-ld -Tnand.lds head.o mem.o flash.o nand_read.o sdram.o -o sdram_tmp.o

          arm-linux-objcopy -O binary -S sdram_tmp.o sdram

          clean:

          rm -f *.o

          rm -f sdram

          三、編譯、燒寫、測(cè)試

          Make 一下就會(huì)生成我們要的文件 sdram, 將其通過(guò) JTAG 燒入 Nand Flash ,Reset

          一下開(kāi)發(fā)板, 呵呵,欣賞我們的成果吧!



          關(guān)鍵詞: FS2410NandFlash內(nèi)

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();