下面開始分析
nand flash
時序圖,並以讀操作為例編寫
nand flash
驅動,先看下我們應該發什麼命令讀資料,下面是資料手冊的命令集合:
由上可以看出,要讀取資料,只需要傳送乙個命令週期,發
00h或
01h。
知道了發什麼命令,再來看如何傳送命令,下面是讀命令的時序圖:
上面圖的紅線處,它所在的時刻就是在傳送讀操作的第乙個週期的命令
0x00
之前的那一刻。看下此時紅線所穿過好幾行都對應什麼值,以及進一步理解,為何要那個值。 (
1)穿過的第一行,是
cle,即命令鎖存使能的引腳,將
cle置
1,就說明將要通過
i/o復用埠傳送進入
nand flash
的是命令,而不是位址或者其他型別的資料。只有這樣將
cle置
1,使其有效,才能去通知了內部硬體邏輯,你接下來將收到的是命令,內部硬體邏輯才會將受到的命令放到命令暫存器中,才能實現後面正確的操作,否則,不將
cle置
1使其有效,硬體會無所適從,不知道你傳入的到底是資料還是命令了。 (
2)第二行,是
ce#,那一刻的值是
0。要發命令,就要保證
ce#為低電平,使其有效,也就是片選有效。 (
3)第三行是
we#,意思是寫使能。因為接下來是往
nand flash
裡面寫命令,所以,要使得
we#有效,所以設為低電平。 (
4)第四行,
ale是低電平,而
ale是高電平有效,此時意思就是使其無效。而對應地,前面介紹的,使
cle有效,因為將要資料的是命令,而不是位址。如果在其他某些場合,比如接下來的要輸入位址的時候,就要使其有效,而使
cle無效了。 (
5)第五行,
re#,此時是高電平無效。可以看到,一直到
busy
後才變成低電平有效,因為那時候就開始讀取資料了。 (
6)第六行,就是我們重點要介紹的,復用的輸入輸出
i/o埠了,此刻,還沒有輸入資料,接下來,在不同的階段,會輸入或輸出不同的資料
/位址。 (
7)第七行,
r/b#,
高電平,表示r(
ready)/
就緒,因為到了後面的
busy
階段,硬體內部在第之前接受了外界的讀取命令後,把該頁的資料一點點送到頁暫存器中,這段時間為系統正忙,所以
r/b#
才變成低,表示
busy
忙的狀態。
介紹了紅線處時刻的各個訊號的值,以及為何是這個值之後,後面的各個時刻所對應的不同訊號的各個值也就容易理解了。
知道了讀寫指令的傳送方式,接下來該指定讀寫的位址了,
nand flash
的硬體位址計算很簡單,無偏移量,實體地址=塊號
*塊大小+頁號
*頁大小
+頁內偏移量。
(注意,此處塊號和頁號是非零的,即從
1記起的編號
)這裡列出了資料手冊裡關於位址週期的介紹:
k9f5608
為例,一共
2048
塊,每塊
32頁,每頁
512byte+16byte
,要訪問第
1500
塊第15
頁的150
位元組處的位址,則其實體地址
=1500*16k+15*512+150=0x01771e96
。將其按照位址週期分配如下:
0x01771e96=0000 0001 0111 0111 0001 1110 1001 0110
,分別分配到
3個位址週期即為: 第
1週期,
a0~a7
:1001 0110 = 0x96第2
週期,a9~a16
:1000 1111 = 0x8f第3
週期,a17~a24
:1011 1011 = 0xbb
其中的l*
意思為低電平,由於未用到這些為,資料手冊中強制要求為
0,由上面分析,我們若要訪問
nand
上第1500
塊第15
頁的150
位元組處的位址,就要分
3個週期分別傳遞
0x96
、0x8f
和0xbb
,硬體才能識別。
現在我們再返回去看時序圖,有沒有清晰一些?它的幾個階段是這樣的: 1
、操作準備階段:此處是讀(
read
)操作,所以先發乙個讀命令的
0x00
,表示讓硬體先準備一下,接下來的操作是讀; 2
、傳送乙個週期的列位址,也就是頁內位址。表示我要從乙個頁的什麼位置開始讀取資料。 3
、接下來再傳入兩個行位址,對應的也就是頁號。 4
、然後硬體開始處理所接收的資料,若有第二個命令也是在此時傳送,接下來就是硬體內部自己的事情了,而我們要做的就是等待。 5
、nand flash
內部硬體邏輯負責去按照你的要求,根據傳入的位址找到哪個塊中的哪個頁,然後把整個這一頁的資料,都一點點搬運到頁快取中去。而在此期間,你所能做的事,也就只需要去讀取狀態暫存器,看看對應的位的值,也就是
r/b#
那一位,是1還是
0,0的話,就表示,系統是
busy
,仍在」
忙「(著讀取資料),如果是
1,就說系統已經把整個頁的資料都搬運到頁快取裡去了,你可以接下來讀取你要的資料了。
這裡需要注意的是,
nand flash
是整頁讀寫的,我們傳入的位元組數對硬體讀寫是沒有意義的,只是它讀取整個頁的資料之後,內部資料指標會定位到你剛才所制定的偏移量
150所在的那個位置。 6
、接下來,就是我們自己去獲取資料了,通過先去
nand flash
的控制器中的資料暫存器中寫入你要讀取多少個位元組
(byte)/
字(word)
,然後就可以去
nand flash
的控制器的
fifo
中,一點點讀取你要的資料了。
至此,整個
nand flash
的讀操作就完成了。
對於其他操作,可以根據我上面的分析,一點點自己去看資料手冊,根據裡面的時序圖去分析具體的操作過程,然後對照**,會更加清楚具體是如何實現的。
看到這裡,
nand flash
的驅動程式的編寫應該就有了幾分把握了吧。至於上層軟體,由於我用的是實時作業系統,介面要十分簡潔,就沒有使用
mtd層,我採用的是
yaffs
的direct
nand flash
空閒區的概念,我當時在寫驅動時備受它的折磨。
nand
由於最初硬體設計時候考慮到額外的錯誤校驗等需要空間,專門對應每個頁額外設計了叫做
spare area
的空區域,在其他地方,比如
yaffs
檔案系統中,也叫做
spare
資料,裡面有塊
/頁資訊,
br#其具體用途,總結起來如下: 1
、標記是否是壞快 2
、儲存ecc資料
3、儲存一些和檔案系統相關的資料,如
yaffs
就會用到這些空間儲存一些特定資訊(即上面提到的#br
nand flash
小頁的spare
空間分配標準:
塊裝置驅動之NAND FLASH驅動程式
一.框架總結 二.硬體原理 相比於nor flash。我們能夠清楚的看出引腳少了非常多,主要是輸入輸出引腳進行了復用。如今我說下各引腳的用途。a.ldata0 ldata7這8個引腳為輸入輸出引腳。命令 位址 資料的傳輸都是由這8個引腳實現的 引腳復用,節約引腳 b.rnb 此引腳用來判忙。由於命令...
Linux驅動程式編寫
linux作業系統網路驅動程式編寫 一.linux系統裝置驅動程式概述 1.1 linux裝置驅動程式分類 1.2 編寫驅動程式的一些基本概念 二.linux系統網路裝置驅動程式 2.1 網路驅動程式的結構 2.2 網路驅動程式的基本方法 2.3 網路驅動程式中用到的資料結構 2.4 常用的系統支援...
nand flash驅動的編寫
1 關鍵操作 1 分配nand chip結構體 2 配置結構體的相關成員 3 硬體相關的配置 2 最重要的函式 nand flash初始化函式 int s3c nand init void nand ecc modes這是個列舉型別啊 如果不定義值,那麼預設從0開始順序定義,即nand ecc no...