nand flash裸機程式

2021-06-20 12:20:05 字數 2730 閱讀 6725

開發板:mini2440

nand flash:k9f2g08u0b2,56m

《arm處理器裸機開發實戰---機制而非策略》

知識點梳理

頁的絕對位址與相對位址

在nand.c中有乙個函式void rdnf2sdram(),它的功能是將nand flah的內容複製到sdram,如下:

nand flash的頁讀取函式原型是void nf_readpage(unsigned int block,unsigned int page,unsigned char *dstaddr),它的功能是從nand flash的第block塊的第page頁讀取1頁(對於k9f2g來說,1頁等於2kb)的內容,存放到指標dstaddr所指的位址處。有的人可能就會說了,既然nf_readpage可以讀取1頁的資料到指定的位址處,而sdram的位址是0x30000000,那直接可以使用它將nand flash的**複製到sdram去啊,答案當然是可以啊!但是有個前提,複製到sdram的內容必須在2kb以內,一旦超過了2kb,那就需要借用rdnf2sdram()函式了,相信這樣解釋就能明白這兩個函式的區別於聯絡了。

再說說絕對位址與相對位址,首先知道k9f2g有2048個塊,每個塊有64個頁,每頁有2k位元組。我們平常所說的第幾塊第幾頁就是相對位址,比如第2塊第3頁是相對位址。而絕對位址=塊號*64+頁號,例如前邊的第2塊第3頁換成絕對位址就是131(131=2*64+3)。

下面解釋一下rdnf2sdram()函式:

114行:在nand flash內的起始位址,這裡的4096表示的是位元組,k9f2g記憶體大小是256mbyte,這裡之所以令start_addr=4096,是因為咱們在nand.lds檔案中,將main.c檔案的位址定義在了4096處。如下圖:

如果at(4096)改為at(5120),那麼這裡start_addr就等於5120。還要注意這裡4096byte也就是4kb,為什麼把他定義在nand flash的4kb之後呢,因為硬體電路會自動將nand flash裡的前4kb的內容搬移到stepping stone中去執行,如果定義在3kb之後,main.c函式直接就執行了,**還用複製。

116行:定義了一共讀取nand flash多少位元組,這裡定義的是1m,當然小小的乙個main.c**也就是不到2kb。

117-123行:這才是該函式的關鍵。因為nf_readpage函式是以頁為單位進行讀取的,每次讀取2kb資料,因此,資料指標的移動是頁對齊的,即每次移動一頁。

從介面電路可以看到,位址線和資料線是復用的,介面線寬是8位,因此每次只能傳送乙個位元組,又因為nand flash的位址是28位的,需要5個位址週期才能將位址傳送完畢,如圖1所示。傳送完位址後,nand flash內部的位址解碼電路會自動將收到的位址進行組合,不需要我們關心,但是需要注意傳送的順序,按照先傳送低位址,再傳送高位址的順序傳送。

位址線[a28:a18]

[a17:a12]

[a11:a0]

位址表示

塊位址頁位址

頁內偏移位址

對於k9f2g來說,它有2048個塊,故用11根位址線定址(2^11=2048);每個塊有64頁,故用6根位址線定址(2^6=64);每頁有2048位元組的資料和64位元組的資訊,也就是說它有2112位元組,故用12根位址線定址。理解了這裡的話就很容易明白下面的傳送位址了。

為什麼是這樣呢?由於頁讀取和寫入函式均是以頁為單位進行的,所以每次都要在頁的第0個位元組開始,也就是說頁內偏移位址為0,所以對位址線的低12位設為0即可,如第93行,94行。

第95行,此時處於第3個位址週期因此需要傳送blockpage(此時blockpage是頁的絕對位址)的a12-a19位,因此,將blockpage與0xff相與即可。一定要注意頁的絕對位址是a28-a12共同表示的,與a11-a0無關。

第96行,此時處於第3個位址週期因此需要傳送blockpage(此時blockpage是頁的絕對位址)的a20-a27位,因此,將blockpage右移8位,與0xff相與即可。

第97行,此時處於第3個位址週期因此需要傳送blockpage(此時blockpage是頁的絕對位址)的a28位,從圖1可以看到,此時雖然是傳送8位,但是只有第0位是有效的,其他位無效。因此,將blockpage右移16位,然後再與0x1相與,只保留第0位。

nand.lds**解釋:

如果**小於4096位元組,那麼開發板啟動後它們被自動複製進「steppingstone」中;本例項的目的就是把一部分**存放在nand flash位址4096之後,當程式啟動通過nand flash控制器將它們讀出來、執行。nand.lds就是實現這個目的的,即連線指令碼nand.lds把**分為兩部分,nand.lds**如下:

第2行表示head.o、init.o、nand.o這3個檔案的執行位址為0,它們在生成的映像檔案中的偏移位址也為0(從0開始存放)

第3行表示main.o的執行位址為0x30000000,它在生成的映像檔案中的偏移位址為4096。

此時生成的bin檔案大小為4.10kb。

如果將第3行的at(4096)去掉,其他的檔案程式不變的話,make生成的bin檔案大小為1.7kb。這樣子對比就可以看出來at真的起作用了。

mini2440開發板的時鐘

fin=12mhz fclk=400mhz hclk=100mhz pclk=50mhz

所以fclk:hclk:pclk=1:4:8,clkdiv_val=5

mdiv=127 pdiv=2 sdiv=1

本實驗一共包含6個檔案,分別為makefile,head.s,init.c,main.c,nand.c,nand.lds,最後會把檔案源**全部貼出來。

**原始檔

Nand Flash 裸機程式

硬體平台 jz2440 實現功能 初始化 nand flash 和 sdram,並將 從 nand flash 拷貝到 sdram。start.s 上電初始化 nand 與sdram nand.c nand flash 初始化函式 sdram.c sdram 初始化函式 leds.c led 閃爍 ...

裸機系列 nandflash

看了好久的nandflash 手冊以及其他方面的一些資料,因為英語不好,所以手冊看的有點暈,幸好網路資源的豐富。總結一下我所理解的nandflash 操作,基於一些其他的原因,暫時不繼續進行裸機程式設計,只是把所有的理解詳細的寫下來。1.首先對於nandflash 程式設計有三個方面 1.nandf...

uarts裸機程式

硬體平台 jz2440 實現功能 向串列埠軟體實現輸出putchar函式 start.s 設定堆疊,關閉看門狗,初始化時鐘,初始化sdram init.c 初始化函式 uart.c 初始化串列埠暫存器 uart.h main.c start.s原始碼 extern main text global ...