首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > WinCE >

eboot中NBL1的 nand.c中的 CorrectECC8Data函数有什么作用?解决方法

2012-05-16 
eboot中NBL1的 nand.c中的 CorrectECC8Data函数有什么作用?最近在看wince5.0 的bootloader的block0image即

eboot中NBL1的 nand.c中的 CorrectECC8Data函数有什么作用?
最近在看wince5.0 的bootloader的block0image即nboot的源代码。。在NBL1的nand.c文件中有个CorrectECC8Data(unsigned char *pEncodingBaseAddr)。。这个函数如果检测到了不可矫正的位错误就会返回1。。。。返回1时。。NAND_Read函数就返回false。。。然后NBL1读取NBL2就失败了。。但是我把NAND_Read函数那边retrun flase;屏蔽掉后系统能读到NBL2。。。也能正常启动。。。我用的flash是三星的K9GAG08U0M...(4k+128byte)页大小的。。
现在我的问题是:
1、不是说存放block0image的flash的第一块是保证是可用块的。。那还需要ecc校验吗?
2、那我把那个ecc校验的代码按代码注释的地方屏蔽掉后。。系统可以正常启动。。那这个校验有什么作用呢?
望大家给个指点。。小弟感激不尽。。。

C/C++ code
//NBL1中读取Nbl2的代码//K9GAG08U0M为mlc的flash    NAND_Init();    Read_DeviceID(0, &ucDID, &ucHID);      Uart_SendString("Device ID : 0x");    Uart_SendBYTE(ucDID, 1);    Uart_SendString("Hidden ID : 0x");    Uart_SendBYTE(ucHID, 1);    if ((ucDID == 0xd5 && ucHID == 0x14) || (ucDID == 0xd5 && ucHID == 0x94) || (ucDID == 0xd7 && ucHID == 0x55)  // for MLC        || (ucDID == 0xd3 && ucHID == 0x10) || (ucDID == 0xd7 && ucHID == 0xd5))  // for SLC    {        b4KPage = TRUE;        uNumOfLoadPage = LOAD_PAGE_SIZE/2;    }    // Turn the LEDs off.//    Led_Display(LED_OFF);//    pBuf = (unsigned char *)LOAD_ADDRESS_PHYSICAL;//    while(1);    // MLC    // Page 0, 1 : Steploader    // Page 2 ~ 5 : empty page    // Page 6 ~ PAGES_PER_BLOCK-3 : effective page    // read pages with 0, 1 and 6 to PAGES_PER_BLOCK-3#ifdef SUPPORTSLC    nPage = LOAD_IMAGE_PAGE_OFFSET;#endif#ifdef SUPPORTMLC    nPage = 10;#endif    for (nCnt = 0; nCnt < uNumOfLoadPage; nCnt++)    {        if (nPage >= (NAND_PAGE_PER_BLOCK-2) || (NAND_Read(0, nPage, pBuf, b4KPage) == FALSE))        {            // Uncorrectable ECC Error            Uart_SendString("ECC Error @ Page 0x");            Uart_SendBYTE(nPage, 1);            //Led_Display(0x9);            while(1); //NAND_Read 返回false 后就直接死循环        }        nPage++;        if (b4KPage == TRUE)            pBuf += NAND_BYTE_PER_PAGE*2;        else            pBuf += NAND_BYTE_PER_PAGE;    }



C/C++ code
//NAND_Read函数和 CorrectECC8Data函数的实现。。。//BOOL NAND_Read(DWORD dwBank, DWORD dwPage, unsigned char *pBuf, BOOL b4KPage){    DWORD SpareDataDummy;    DWORD dwOffset;    DWORD dwCnt;    DWORD dwSpareAddress = 2048 + 1;    //include Bad block    unsigned char uSctCnt;    BOOL bRet = TRUE;    if (b4KPage == TRUE) uSctCnt = 8;    else uSctCnt = 4;    rNFCONF = ( rNFCONF&~(0x3<<23) ) |(2<<30)|(1<<23)|(0x7<<12)|(0x7<<8)|(0x7<<4);    rNFCONT = ( rNFCONT&~(0x1<<18) ) |(0<<18)|(0<<11)|(0<<10)|(0<<9)|(1<<6)|(1<<0); // Init NFCONT        rNFSTAT |= ((1<<6)|(1<<5)|(1<<4));    NAND_Reset(dwBank);        NF_MECC_Lock(); // Main ECC Lock    NF_CE_L(dwBank);    rNFSTAT |= (1<<4); // RnB Clear    NF_CMD(CMD_READ);    NF_SET_ADDR(dwPage, 0x00);    NF_CMD(CMD_READ_CONFIRM);    NF_DETECT_RB();    rNFSTAT |= (1<<4); // RnB Clear    //READ Spare ECC Data    for(dwCnt = 0; dwCnt < uSctCnt; dwCnt++) {        NF_MECC_Lock(); // Main ECC Lock        rNFSTAT |= (1<<4); // RnB Clear        if(!dwCnt) {            NF_CMD(CMD_READ);            NF_SET_ADDR(dwPage, 0);            NF_CMD(CMD_READ_CONFIRM);            NF_DETECT_RB();            rNFSTAT |= (1<<4); // RnB Clear                    }        else        {            dwOffset = dwCnt * 512;            NF_CMD(CMD_RANDOM_DATA_OUTPUT);            NF_ADDR(dwOffset&0xFF);            NF_ADDR((dwOffset>>8)&0xFF);            NF_CMD(CMD_RANDOM_DATA_OUTPUT_CONFIRM);        }        NF_MECC_UnLock();     // Main ECC Unlock        NF_MECC_Reset();     // Initialize ECC         //read 512byte        _Read_512Byte(pBuf + 512*dwCnt);                if (b4KPage == TRUE)                        dwOffset = 4096 + (dwCnt * 13);                else                        dwOffset = 2048 + (dwCnt * 13);        NF_CMD(CMD_RANDOM_DATA_OUTPUT);        NF_ADDR(dwOffset&0xFF);        NF_ADDR((dwOffset>>8)&0xFF);        NF_CMD(CMD_RANDOM_DATA_OUTPUT_CONFIRM);        //read Spare ECC Data                SpareDataDummy = NF_DATA_R4();        SpareDataDummy = NF_DATA_R4();        SpareDataDummy = NF_DATA_R4();        SpareDataDummy = NF_DATA_R();        NF_MECC_Lock(); // Main ECC Lock        while(!(rNFSTAT&(1<<6)));     // Check decoding done         rNFSTAT = rNFSTAT | (1<<6);   // Decoding done Clear        while( rNF8ECCERR0 & (unsigned int)(1<<31) ) ; // 8bit ECC Decoding Busy Check.        if(CorrectECC8Data((pBuf + 512*dwCnt))) {        //    return FALSE; //这边注释掉后NBL1就可以正常读取NBL2。。且NBL2能正常执行。。读取eboot 并启动系统。。。//这边注释掉后CorrectECC8Data函数对于不能纠正的bit错误就没有返回了。。//如果数据有错没纠正。。那系统为什么还能启动?        }            }    NF_CE_H(dwBank);        return TRUE;}int CorrectECC8Data(unsigned char *pEncodingBaseAddr){        unsigned int i,uErrorByte[9];    unsigned char uErrorBit[9];    unsigned int uErrorType;            uErrorType = (rNF8ECCERR0>>25)&0xf;// Searching Error Type //How many Error bits does exist?        uErrorByte[1] = rNF8ECCERR0&0x3ff;// Searching Error Byte //Where is the error byte?    uErrorByte[2] = (rNF8ECCERR0>>15)&0x3ff;        uErrorByte[3] = (rNF8ECCERR1)&0x3ff;    uErrorByte[4] = (rNF8ECCERR1>>11)&0x3ff;        uErrorByte[5] = (rNF8ECCERR1>>22)&0x3ff;        uErrorByte[6] = (rNF8ECCERR2)&0x3ff;    uErrorByte[7] = (rNF8ECCERR2>>11)&0x3ff;    uErrorByte[8] = (rNF8ECCERR2>>22)&0x3ff;        uErrorBit[1] = rNFMLC8BITPT0&0xff;// Searching Error Bit //Where is the error bit?    uErrorBit[2] = (rNFMLC8BITPT0>>8)&0xff;    uErrorBit[3] = (rNFMLC8BITPT0>>16)&0xff;    uErrorBit[4] = (rNFMLC8BITPT0>>24)&0xff;        uErrorBit[5] = rNFMLC8BITPT1&0xff;    uErrorBit[6] = (rNFMLC8BITPT1>>8)&0xff;    uErrorBit[7] = (rNFMLC8BITPT1>>16)&0xff;    uErrorBit[8] = (rNFMLC8BITPT1>>24)&0xff;        if(uErrorType == 0x0) {        return 0;    }    if(uErrorType == 0x9) {        return 1;    }    for(i=1;i<=uErrorType ;i++)        {        if(uErrorByte[i] < 512)                pEncodingBaseAddr[uErrorByte[i]]^=uErrorBit[i];        else        {;    }                }    return 0;    } 





[解决办法]
抱歉, 看了一下CODE, 發覺你的是MLC, 基本上, MLC 與 SLC 在處理 ECC 的做法不太一樣, 所以要先請確定你的 CODE 有設定正確的 MLC.

還有就是 Write & Read 是成對的, 你是用相同的程式做寫嗎?? 還是寫的時候沒放 ECC 資訊, 或是錯的 ECC.

Paul, Chao @ Techware

热点排行