基於linux2.6.16的nand驅動開發(三)

第三部分:根據sep4020編寫具體nand驅動

sep4020是一款非常好優秀的arm720T芯片,以下介紹一下sep4020的nand驅動編寫

 

1.       sep4020的nand控制器只支持dma搬運,這也是考慮到一般對nand進行讀寫都是一頁一頁的,所以利用dma可以有效的提高效率。

DMA也帶了一個比較重要的問題,DMA的源和目的需要用實地址,因爲DMA不走cpu,在這點上我卡了好久,在linux中久了,什麼都習慣性的填寫虛地址,結果在測試的時候發現dma怎麼都不工作,把所有的東西都看了又看,都沒問題,鬱悶的不行了,最後在張師兄的提醒下才發現DMA不能給虛地址,恍然大悟啊!

 

2. 但是由於直接給DMA又帶來了另外一個問題,在操作系統中,所有的地址都是虛擬地址,如何得到實際物理地址?我記得在當初在內核移植的時候寫過一個函數:

#define __virt_to_bus(x) __virt_to_phys(x) ,跟進去一看解釋是物理地址,虛擬地址的轉換,此時我認爲操作系統的地址轉換就是通過這個來實現的,因此在這裏我直接給DMA賦了一個沒用到的物理空間0x30002000,根據上式則應該對應的虛擬地址是0xc0002000。

我也這麼做了,發現可以實現,但是總是會出現一些莫名其妙的錯誤,我和阿虛都快崩潰了,最後發現其實這種讀法是不正確的,我們在進行同一頁重複性讀取實驗中,10次中有一次不正確,排除了所有其他可能的因素,最後又懷疑到操作系統是不是真的這樣將虛實地址的?操作系統可操作的地址空間應該有4G,如果都是這樣聯繫虛實地址,那豈不是操作系統只能分配我們的SDRAM的8M空間,因此這種想法是錯誤的。最後我們使用了專門用來分配DMA地址的函數dma_alloc_coherent,實驗一切正確,更加驗證了我們的想法。

由於第一次在操作系統中使用dma,我們邊做邊摸索,以後絕對不在dma上再喫這麼多跟頭了,呵呵。

 

3         sep4020中所有的寄存器都是32位的,這點也是和其他芯片的nand控制所不同的,打個比方:我們需要給nand控制器的地址寄存器一個地址,我們是直接將地址賦給這個32位的寄存器,但是對於其他的芯片(比如2410),它的地址寄存器用8位,需要你串行的將地址依次輸入進去,這點是需要我們注意的。

還有就是我們的nand控制器的命令寄存器比較特殊,它有個使能位,芯片手冊推薦配好地址寄存器後,再配命令寄存器,同時使能,但由於儘量不變動linux的內核源碼,我使用的是先按照mtd設備中通用的做法,發命令,發地址,然後在讀寫函數的最後一條指令將nand使能。

 

4.       有一點比較重要,sep4020的nand控制器只能528字節的寫,而在linux中大量採用了先寫512再寫16,甚至有單獨寫16的函數,因此這裏必須做改動。我們採用了先讀後寫的方法,比如寫16字節(寫16肯定是最後的00b區),我們先讀出這一頁的所有528字節,將前面的512取出再接上我們要寫的16字節,這樣湊滿了528字節後寫入。

爲了實現在讀寫的速度更快,我們根據nand的特性進行分析,在寫512字節的時候,那一頁肯定是空白的,未被使用過的,因此它的oob區也肯定是全ff,因此在寫512時我們將後面剩餘的16字節自動填充ff,這樣就省去了從nand讀出的步驟,大大加快了nand寫的速度。

 

5.       奇怪的write_byte

在我們調試的時候曾發現過一個問題,給nand發了一條寫命令0x80,但是此時還未使能,但通過printk發現此時nand控制器一直處於忙狀態,最後通過一步步的鎖定,發現在給nand發了0x80給我們的com寄存器,但是此時printk這個寄存器的值竟然是0x80808080,而我們的第一位恰好是使能位,因此此時由於調用系統的write_byte,com寄存器從本應的0x00000080變成了0x80808080,導致了我們nand控制一直是忙,無法進行下面的操作。最後無奈之下重載了write_byte和read_byte,問題就解決了,很奇怪的是我也跟進去看過系統的代碼,和我的一樣啊,怎麼到它那兒就這樣了呢?現在覺得有可能的是:write_byte的寄存器一般都是8位的,而我們的寄存器是32位的,因此係統連續賦了4次,這僅僅是我的一種猜測,等待以後驗證。

 

6.       編寫中碰上的一些非常傻的問題:

*(unsigned long *)EMI_NAND_COM 和EMI_NAND_COM混淆了,還是指針學的不好。

出現一些很古怪的問題的時候,一定要記得檢查你的頭文件

切記保證你的make menuconfig中的選項正確

 

7.不能將yaffs 中的Turn off debug chunk erase check選上,不然會出現mtd ecc chunk的問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章