找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3688|回復(fù): 0
收起左側(cè)

如何調(diào)試nand flash[zt]

[復(fù)制鏈接]
ID:98924 發(fā)表于 2015-12-9 03:01 | 顯示全部樓層 |閱讀模式
一.簡(jiǎn)介
本文介紹了如何調(diào)試nand flash
二. 背景
   2.1.nandflash 結(jié)構(gòu)分類(lèi)
2.1.1 小頁(yè)
    1block = 32page
1page = 512bytes(datafield) + 16bytes(Spare Field)
需要注意的是,對(duì)于flash的讀寫(xiě)都是以一個(gè)page開(kāi)始的,但是在讀寫(xiě)之前必須進(jìn)行flash的擦寫(xiě),而擦寫(xiě)則是以一個(gè)block為單位的。同時(shí)必須提醒的是,512bytes理論上被分為1st half 和2sd half,每個(gè)half各占256個(gè)字節(jié)。
528個(gè)字節(jié)按順序由上而下以列為單位進(jìn)行排列(1列代表一個(gè)Byte。第0行為第0 Byte ,第1行為第1 Byte,以此類(lèi)推,每個(gè)行又由8個(gè)位組成,每個(gè)位表示1個(gè)Byte里面的1bit。
528Bytes按功能分為兩大部分,分別是Data Field和Spare Field,其中Spare Field占528Bytes里的16Bytes,這16Bytes是用于在讀寫(xiě)操作的時(shí)候存放校驗(yàn)碼用的,一般不用做普通數(shù)據(jù)的存儲(chǔ)區(qū),除去這 16Bytes,剩下的512Bytes便是我們用于存放數(shù)據(jù)用的Data Field,所以一個(gè)Page上雖然有528個(gè)Bytes,但我們只按512Bytes進(jìn)行容量的計(jì)算。
讀命令有兩個(gè),分別是 Read1,Read2其中Read1用于讀取Data Field的數(shù)據(jù),而Read2則是用于讀取Spare Field的數(shù)據(jù)。對(duì)于Nand Flash來(lái)說(shuō),讀操作的最小操作單位為Page,也就是說(shuō)當(dāng)我們給定了讀取的起始位置后,讀操作將從該位置開(kāi)始,連續(xù)讀取到本Page的最后一個(gè) Byte為止(可以包括Spare Field)

2.1.2 大頁(yè)
參考小頁(yè)的說(shuō)明

2.2   NANDFLASH校驗(yàn)
由于NAND Flash的工藝不能保證NAND的Memory Array在其生命周期中保持性能的可靠,因此,在NAND的生產(chǎn)中及使用過(guò)程中會(huì)產(chǎn)生壞塊。為了檢測(cè)數(shù)據(jù)的可靠性,在應(yīng)用NAND Flash的系統(tǒng)中一般都會(huì)采用一定的壞區(qū)管理策略,而管理壞區(qū)的前提是能比較可靠的進(jìn)行壞區(qū)檢測(cè)。
  如果操作時(shí)序和電路穩(wěn)定性不存在問(wèn)題的話,NAND Flash出錯(cuò)的時(shí)候一般不會(huì)造成整個(gè)Block或是Page不能讀取或是全部出錯(cuò),而是整個(gè)Page(例如512Bytes)中只有一個(gè)或幾個(gè)bit出錯(cuò)。
  在NAND Flash處理中,一般使用一種比較專(zhuān)用的校驗(yàn)——ECC。ECC能糾正單比特錯(cuò)誤和檢測(cè)雙比特錯(cuò)誤,而且計(jì)算速度很快,但對(duì)1比特以上的錯(cuò)誤無(wú)法糾正,對(duì)2比特以上的錯(cuò)誤不保證能檢測(cè)。
ECC一般每256字節(jié)原始數(shù)據(jù)生成3字節(jié)ECC校驗(yàn)數(shù)據(jù),這三字節(jié)共24比特分成兩部分:6比特的列校驗(yàn)和16比特的行校驗(yàn),多余的兩個(gè)比特置1
當(dāng)往NAND Flash的page中寫(xiě)入數(shù)據(jù)的時(shí)候,每256字節(jié)我們生成一個(gè)ECC校驗(yàn)和,稱(chēng)之為原ECC校驗(yàn)和,保存到PAGE的OOB(out-of-band)數(shù)據(jù)區(qū)中。
當(dāng)從NAND Flash中讀取數(shù)據(jù)的時(shí)候,每256字節(jié)我們生成一個(gè)ECC校驗(yàn)和,稱(chēng)之為新ECC校驗(yàn)和。
校驗(yàn)的時(shí)候,根據(jù)上述ECC生成原理不難推斷:將從OOB區(qū)中讀出的原ECC校驗(yàn)和新ECC校驗(yàn)和按位異或,若結(jié)果為0,則表示不存在錯(cuò)(或是出現(xiàn)了ECC無(wú)法檢測(cè)的錯(cuò)誤);若3個(gè)字節(jié)異或結(jié)果中存在11個(gè)比特位為1,表示存在一個(gè)比特錯(cuò)誤,且可糾正;若3個(gè)字節(jié)異或結(jié)果中只存在1個(gè)比特位為1,表示OOB區(qū)出錯(cuò);其他情況均表示出現(xiàn)了無(wú)法糾正的錯(cuò)誤
2.3   NANDFLASH 壞塊管理
在進(jìn)行數(shù)據(jù)存儲(chǔ)的時(shí)候,我們需要保證數(shù)據(jù)的完整性,而NAND Flash存儲(chǔ)器芯片由于工藝上問(wèn)題,不可避免就會(huì)出現(xiàn)有的Block中就是某個(gè)位或某些位是塊的,就是用塊擦除命令也是無(wú)法擦除的。如果數(shù)據(jù)存儲(chǔ)到這個(gè)壞塊中,就無(wú)法保證該數(shù)據(jù)存儲(chǔ)的完整性。對(duì)于壞塊的管理首先我們要定義一個(gè)壞塊管理表:unsigned char BAD_BLOCK_TABLE [128],此數(shù)組可以存儲(chǔ)1024個(gè)Block狀態(tài),即每一個(gè)字節(jié)存儲(chǔ)8個(gè)Block狀態(tài)。我們要存儲(chǔ)一批數(shù)據(jù)到NAND Flash中去某個(gè)Block時(shí),先執(zhí)行Block擦除操作,然后分析該Block的1st Page和2st Page中的每個(gè)位是否全是FFH,如果全是FFH,則在BadBlockTable數(shù)組當(dāng)前Block對(duì)應(yīng)的字節(jié)位給置0,否則置1。如果是1表示當(dāng)前的塊是不能存儲(chǔ)數(shù)據(jù)的,這時(shí)需要更換下一個(gè)Block來(lái)存儲(chǔ)這些數(shù)據(jù),這樣我們重復(fù)上面的動(dòng)作分析再進(jìn)行分析是否可以存儲(chǔ)數(shù)據(jù),該塊能存儲(chǔ)就存儲(chǔ)到該塊中去。(詳見(jiàn)具體NANDFLASH 手冊(cè))

2.4 DMA 傳送方式
NAND 控制器包含一個(gè)寬度為32 b,深度為4 的緩沖FIFO,用于解決高速總線與低速設(shè)備
之間數(shù)據(jù)傳輸速度的匹配問(wèn)題。為提高總線的傳輸效率,以及控制器設(shè)計(jì)的便利性,NAND
FLASH 在總線上的數(shù)據(jù)傳輸采用DMA 的方式來(lái)完成。譬如在讀取FLASH 一頁(yè)數(shù)據(jù)時(shí),數(shù)
據(jù)持續(xù)寫(xiě)入控制器FIFO,F(xiàn)IFO 滿時(shí)發(fā)出DMA 傳輸?shù)恼?qǐng)求,同時(shí)暫停FLASH 的數(shù)據(jù)讀取,
控制信號(hào)nRE 拉高,直至DMA 響應(yīng)請(qǐng)求即FIFO 不滿時(shí),F(xiàn)LASH 的數(shù)據(jù)傳輸重新開(kāi)始。
當(dāng)選擇應(yīng)用的FLASH 位寬為8,頁(yè)大小為(512+16)B 時(shí),控制器需要發(fā)出(32+1)次4 拍字寬
度的DMA 傳輸請(qǐng)求來(lái)完成數(shù)據(jù)和校驗(yàn)信息的讀取。
控制模塊的上作主要是將總線接口轉(zhuǎn)換的控制信號(hào),按照NAND FLASH 的接口協(xié)議.將片
選、地址、命令、讀寫(xiě)使能按照所配置的時(shí)序要求,發(fā)送到NAND FLASH 中,并且控制數(shù)
據(jù)的傳輸個(gè)數(shù),以及DMA 請(qǐng)求、數(shù)據(jù)傳輸完成中斷、數(shù)據(jù)錯(cuò)誤中斷等系統(tǒng)信號(hào)。
2.5 NANDFLASH 啟動(dòng)
     NANDFLASH 跟NOR FLASH有一個(gè)本質(zhì)的區(qū)別就是NANDFLASH不能執(zhí)行代碼,
而在SDRAM中執(zhí)行程序,所以在系統(tǒng)的啟動(dòng)過(guò)程中有步代碼從NANDFLASH中搬遷到SDRAM中的過(guò)程。隨后會(huì)在7120的實(shí)例中闡明。
二 調(diào)試T3G 7210 NANDFLASH
2.1       系統(tǒng)啟動(dòng)
2.1.1            系統(tǒng)啟動(dòng)流程圖
     第一步:
         
    說(shuō)明:硬件的BOOTLOADER執(zhí)行,執(zhí)行的目的是把NANDFLASH第一個(gè)BLOCK中第一個(gè) 16kbytes 內(nèi)容加載到SCRAM中去執(zhí)行 相關(guān)模塊psboot
第二步:

說(shuō)明:NAND Bootloader 加載到SCRAM中后執(zhí)行,執(zhí)行的目的根據(jù)分區(qū)表把相應(yīng)分區(qū)的內(nèi)容加載到SCRAM中執(zhí)行 相關(guān)模塊psboot
第三步:

說(shuō)明:執(zhí)行Splashscreen 就是開(kāi)機(jī)動(dòng)畫(huà),由于我們是模塊沒(méi)有屏幕這個(gè)模塊并沒(méi)有什么用,
可以把代碼屏蔽掉。
第四步:

說(shuō)明:執(zhí)行完開(kāi)機(jī)動(dòng)畫(huà)后,加載CODE區(qū),開(kāi)始執(zhí)行代碼。
相關(guān)文件說(shuō)明:
   修改啟動(dòng)這塊代碼我們只要關(guān)注psboot psstartup,具體修改文件如下:
   psboot\modules\bootnand\srce\Rest.s   
IF NAND_FLASH_512M_HDW
         ; 32-word ROM Boot loader parameter list
         dcd   0x1234567          ; magic number causes NandFlash boot; 512M flash,
ELSE
         dcd   0x1234576          ; magic number causes NandFlash boot
ENDIF
psboot\modules\bootnand\srce\ link.map
在實(shí)際的調(diào)試的過(guò)程中,發(fā)現(xiàn)在編譯bootnand這個(gè)模塊的時(shí)候ZI區(qū)會(huì)超RAM(請(qǐng)注意UNINIT 這個(gè)關(guān)鍵的屬性值),為了解決這個(gè)問(wèn)題,需要去掉link.map中相應(yīng)的幾個(gè)字段。
#       BUFFER1 0x8000 UNINIT 0x8000
#       {
#                bootnand.o (buffer1)
#       }
#       BUFFER2 0x10000 UNINIT 0x8000
#       {
#                bootnand.o (buffer2)
#       }
psboot\modules\bootnand\output\Makefile
BLOCK_SIZE                  = 16384
psstartup\modules\conf\incl\ config_bootnand.h
#define NANDFLASH_PAGE_SIZE              512
#define NANDFLASH_SPARE_SIZE            16
#define NANDFLASH_PAGES_PER_BLOCK       32
#define NANDFLASH_N_BLOCKS              4096
上面是設(shè)置 NANDFLASH的頁(yè)與塊,這也是大頁(yè)換小頁(yè)第一個(gè)需要改的。
#define NANDFLASH_READ_COMMAND_2_P    0
這個(gè)宏的定義跟讀NANDFLASH發(fā)的指令有關(guān),大家可以在代碼中搜一下就一目了然了。
修改如下函數(shù) 這個(gè)跟NANDFLASH的地址線有關(guān),修改時(shí)可用查看一下NANDFLASH手冊(cè)
static __inline void
platform_page_address (int page, unsigned char address [])
{
#ifdef NAND_FLASH_512M_HDW
    address [0] = 0;
    address [1] = (unsigned char) ((unsigned) page & 0xff);
    address [2] = (unsigned char) (((unsigned) page >> 8) & 0xff);
    address [3] = (unsigned char) (((unsigned) page >> 16) & 0x01);
#else
    address [0] = 0;
    address [1] = 0;
    address [2] = (unsigned char) ((unsigned) page & 0xff);
    address [3] = (unsigned char) (((unsigned) page >> 8) & 0xff);
#endif
}
到現(xiàn)在為止BOOTNAND應(yīng)該可以正常運(yùn)行了,不過(guò)要讓系統(tǒng)的正常運(yùn)行還需要修改一些文件
下面一一道來(lái)。
Pstffs\modules\dntf\incl\dntf.hec
#ifdef NAND_FLASH_512M_HDW
#define NAND_PAGE_SIZE        512
#define NAND_SPARE_SIZE       16
#define NAND_ECC_SIZE         10 //original: 10, fxj,
#define NAND_PAGES_PER_BLOCK 32
#define NAND_BLOCK_SIZE       (NAND_PAGE_SIZE * NAND_PAGES_PER_BLOCK)
#define NAND_NUM_BLOCKS       200 //original 100, fxj,
#define NAND_MIN_VALID_BLOCKS 15
#define NAND_MAX_BAD_BLOCKS   (NAND_NUM_BLOCKS / 10 ) // 10% of size
#else
#define NAND_PAGE_SIZE        2048
#define NAND_SPARE_SIZE       64
#define NAND_ECC_SIZE         10
#define NAND_PAGES_PER_BLOCK 64
#define NAND_BLOCK_SIZE       (NAND_PAGE_SIZE * NAND_PAGES_PER_BLOCK)
#define NAND_NUM_BLOCKS       100
#define NAND_MIN_VALID_BLOCKS 15
#define NAND_MAX_BAD_BLOCKS   (NAND_NUM_BLOCKS / 10 ) // 10% of size
#endif
注意:這個(gè)宏跟NXP的mgrpaging 這個(gè)庫(kù)文件有直接關(guān)系,而我們沒(méi)有這個(gè)庫(kù)的原文件,所以這宏的修改基本來(lái)說(shuō)是沒(méi)有用的,需要NXP的支持。
Pstffs\modules\tffsal\input\dntfecc.c
#ifdef NAND_FLASH_512M_HDW
/** The number of bits in ECCs generated by the NFI */
#define NFI_ECC_BITS           22
#define NFI_ECC_CHUNK_SIZE     0x100
#define NAND_FLASH_PAGE_BYTES 0x200
#else
/** The number of bits in ECCs generated by the NFI */
#define NFI_ECC_BITS           22
#define NFI_ECC_CHUNK_SIZE     0x100
#define NAND_FLASH_PAGE_BYTES 0x800
#endif
修改各OPT中的宏定義。
-DNAND_FLASH_PAGE_BYTES
-DNAND_FLASH_SPARE_BYTES
-DNAND_FLASH_BLOCK_BYTES
-DNAND_FLASH_BLOCKS
-DNAND_FLASH_FS_BASE
-DNAND_FLASH_FS_MEM_BASE
-DNAND_FLASH_FS_BLOCKS
添加相應(yīng)NANDFLASH處理文件,需要填充的幾個(gè)結(jié)構(gòu):
llinit_katSDIReConfTab
llinit_katSDIInitTab
llinit_katNFIInitTab
llinit_NFICmd_Config
llinit_NFIDesConf
修改ECC的算法
compute_page_ecc   
原為:for(j=0; j<8; j++)    //8個(gè)256 大頁(yè)
改為:for(j=0; j<2; j++)   // 2個(gè)256   小頁(yè)
到現(xiàn)在為止,NANDFLASH的驅(qū)動(dòng)也完成,接下來(lái)就是文件系統(tǒng)的配置了,主要關(guān)注
vman5cfg.c 這個(gè)文件
需要注意三個(gè)宏:
#define BBM_RESERVED        88   壞塊的預(yù)留BLOCK數(shù)
MC_VOLMAN_ADD_DEVICE      添加分區(qū)
MC_VOLMAN_ADD_VOLUME     在相應(yīng)分區(qū)上添加根目錄
T3G7210分為2個(gè)分區(qū),3個(gè)跟目錄
NANDFLASH 包含 sysv   app
FTL_NAND    包含 share

        

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表