久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 18529|回復: 6
打印 上一主題 下一主題
收起左側

STM32 ECC校驗的一些心得

[復制鏈接]
跳轉到指定樓層
樓主
ID:76190 發表于 2015-4-5 20:48 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
      STM32FSMC功能支持SRAMNOR FLASHNAND FLASH,是非常方便的。

當然,要STM32F103VC及以上的芯片才支持FSMC功能的。

   在此寫下一些調試使用FMMC調試NAND FLASH的心得及總結,方便以后回顧,也便于大家一起交流學習。

在這里重點寫下的是調試ECC這個功能。

 使用的NAND FLASH芯片K9F2G08U0C

     芯片大小是2Gbit,也就是容量256MB。一塊64頁,一頁2K字節

     一頁2048字節,其中,OOB64字節。

     當然,要能正常使用ECC功能,NAND_FLASH的讀寫正常是前提。這里不作介紹。要ST公司提供的例子里有NAND_FLASH的讀寫例子,一般可參照其配置再結合自己實際使用的NAND_FLASH芯片及電路設計修改。

   保證了能正常讀寫頁功能,以及讀寫OOB區數據功能,即可繼續調試ECC了。

   以下這段話就是來自STM32FSMC使用手冊里關于ECC的介紹

 

   The FSMC NAND Flash controller includes two pieces oferror correction code computation

hardware, one for each NANDFlash memory block.

The ECC can be performed forpage sizes of 256, 512, 1024, 2048, 4096 or 8192 bytes,

depending on the ECCpage sizeconfigured by the user. Depending on the configured page

size, the ECC code will be 22,24, 26, 28, 30 or 32 bits.

To even improve the errorcoverage, the user can read/write the NAND Flash page with a

reduced ECC page size. This ispossible when starting and stopping the ECC computation

after the desired number ofbytes to check. In this case, the ECC code is only calculated for

the bytes written and read.

 

   這里就不講太官方的介紹了。

比如我要使用ECC功能,每512個字節產生一個ECC數據,這樣,當這512字節里出錯有一位錯誤的時候,可以通過ECC來糾正。當然,如果錯了幾個位,就無法糾錯了。雖然當兩個位有錯,也知道,但不知道是哪兩個位出錯,也糾正不了。所以,只要關心怎么找出錯誤,通過ECC怎么糾錯。

 FSMCECC支持每256字節,512字節,1024,。。。8192字節產生一個ECC數據。

調試時使用每512字節產生一個ECC功能。

當寫入512個字節時,產生一個ECC數據,然后,再讀512個字節的時候,也會產生一個ECC數據,通過這兩個數據相異或,產生一個ECC校驗結果,通過這個判斷結果,就可以分析出有沒有錯,錯在哪里,是錯哪一位。當然,知道哪一位錯了,也就可以糾正了。

 

現在具體以實際的NAND_FLASH為例。

K9F2G08U0C這個芯片雖然是每頁2048個字節,也就是4 512字節。按理說直接使用每2048字節產生一個ECC即可校驗,這樣也方便一些。但因為實際使用中,是把這FLASH當作U盤來使用,并使用了fat32文件系統,將其作扇區處理了。一般扇區單位為512個字節。因此,這里就使用每512個字節產生一個ECC

 

FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;

  FSMC_NANDInitStructure.FSMC_Waitfeature =FSMC_Waitfeature_Enable;

  FSMC_NANDInitStructure.FSMC_MemoryDataWidth =FSMC_MemoryDataWidth_8b;

  FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;

 FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;

  FSMC_NANDInitStructure.FSMC_AddressLowMapping= FSMC_AddressLowMapping_Direct;

  FSMC_NANDInitStructure.FSMC_TCLRSetupTime =0x00;

  FSMC_NANDInitStructure.FSMC_TARSetupTime =0x00;

 FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;

  FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct= &p;

 

  FSMC_NANDInit(&FSMC_NANDInitStructure);

 

  /* FSMC NAND Bank Cmd Test */

  FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);

 

  初始化主要為上述幾句指令:

 FSMC_NANDInitStructure.FSMC_ECC =FSMC_ECC_Enable;

 FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;

 

  然后在讀寫NAND_FLASH,即可讀到ECC數據。

 

u32 write_ecc;

u32 read_ecc;

 for(i=0;i<512;i++)

 {

    buffer[i]=i%256;

 }

 

    FSMC_NANDECCCmd(FSMC_Bank2_NAND,ENABLE);

    FSMC_NAND_WritePage(buffer,0,512);

  while(FSMC_GetFlagStatus(FSMC_Bank2_NAND,FSMC_FLAG_FEMPT)==Bit_RESET);

   write_ecc = FSMC_GetECC(FSMC_Bank2_NAND);

   FSMC_NANDECCCmd(FSMC_Bank2_NAND,DISABLE);

//這是寫入512個字節時候讀ECC.

 

    FSMC_NANDECCCmd(FSMC_Bank2_NAND,ENABLE);

         FSMC_NAND_ReadPage(read,0,512);

   while(FSMC_GetFlagStatus(FSMC_Bank2_NAND,FSMC_FLAG_FEMPT)==Bit_RESET);

    read_ecc = FSMC_GetECC(FSMC_Bank2_NAND);

    FSMC_NANDECCCmd(FSMC_Bank2_NAND,DISABLE);

//這是讀512個時候讀取ECC

  

 要保證讀取到正確的ECC數據,要在讀之前先失能下ECC功能,把ECC數據清零,再使用ECC,然后再讀或寫NAND_FLASH。再讀到相應的ECC。讀ECC后記得把ECC失能,以清空ECC數據。 

   這樣就可以讀到write_ecc了。當然,這個數據會讀到的是0,為什么呢,所以很多時候我們測試數據,都是用比較有規律的數據去測試,下面通過幾組數據,來解讀下這個ECC的數據分析 

for(i=0;i<512;i++)

  {

    buffer[i]=0x11;

  }

ECC: 0

 

 

 512個字節里,都是0x11的話,ECC數據是0。然后改變其中某個字節的某個位,再去讀ECC看。

for(i=0;i<512;i++)

  {

    buffer[i]=0x11;

  }

buffer [0]=0x10;

ECC: 0x55555555

這是改了第一個字節的第一個位。(但習慣上從0開始比較習慣,改了第0個字節第0個位)

for(i=0;i<512;i++)

  {

    buffer[i]=0x11;

  }

buffer [0]=0x13;

ECC:0x55555556

改了第1個位

 

 

for(i=0;i<2048;i++)

  {

    buffer[i]=0x11;

  }

buffer [0]=0x15;

ECC:0x55555559

改了第2個位

 

 

for(i=0;i<2048;i++)

  {

    buffer[i]=0x11;

  }

buffer [0]=0x19;

ECC:0x5555555a

 

 

 

 

for(i=0;i<512;i++)

  {

    buffer[i]=0x11;

  }

buffer [511]=0x91;

ECC:0x55aaaaaa;

這里改了第4095個位,也就是(第511個字節的最高位,也就是512個字節里的最高一個位)

 

好了,有了以上這里數據,就可以開始解讀了,就算找不到例子,只要你的NAND_FLASH讀寫正常了,能把這些看懂了,也就可以使用ECC功能了。

 

下面對這幾個ECC數據進行解讀。

 

解讀前先看一下ECC結果寄存器。

   因為我們設置的是512個字節產生一個ECC。那么有效位是023 

也就是前面讀到的ECC數據呢,只要低24位就可以了。

當然,從這里還能看出其它數據。最高是8192字節,占了32位,

4096字節占了30位。

這個規律就是從256字節開始,每增一倍字節數,ECC就多占用兩個位。

按常理說,只要多一個位,就可以表示多一倍的數據了。但是要表示多一個數據,需要到兩個位,那,這里就有點玄機了。

甚至不需要去理解或弄明白它使用是漢明碼,什么BCH碼,只要看明白下這里,一直可以糾錯。因為,不要管它是什么糾錯碼,就跟著這個規律去理解。

512個字節的ECC用了24位,512個字節共有512*8=4096個位。要表示到4096個數,也就是剛好12位就可以了。所以,因此這里的玄機就是ECC數據里,用了2個位來表示一個位的數據。

這時,再看一下關于STM32 ECC的介紹。

When an erroroccurs during the write operation, this error is either correctable or

uncorrectabledepending on the ECC XOR operation:

Case of acorrectable error

The ECC XORoperation contains 11-bit data at 1. And each pair parity is 0x10 or

0x01.

 

忘了說,我們這些測試數據呢,是以寫入0x11為主,然后故意改錯某一個位,再讀出ECC。因為寫入全部的是0x11,因此寫入時產生的ECC0x0。那么再將讀出來的ECC0x0異或,得到的,也就是ECC校驗結果了。

當錯第0個位的時候,校驗結果是0x55555555。取低24位,也就是0x555555

 

對應24位就是

010101010101010101010101

當錯第1個位的時候,校驗結果是0x555556(取低24位)

對應24位就是

010101010101010101010110

當錯第2個位對應的24位是:

010101010101010101011001

當錯第3個位對應的24位是:

010101010101010101011010

…………

當錯第4095個位(也就是第511個字節的最高位) 校驗結果:0xaaaaaa

對應24位是:

101010101010101010101010

 

看到這里,大家估計很容易看出來規律了。

0個位錯誤的24位數據解碼出來12位就是:0000 00000000,也就是0x0,就是第0個位錯誤.

1個位錯誤的24位數據解碼出來12位就是:0000 00000001,也就是0x1,就是第1個位錯誤.

2個位錯誤的24位數據解碼出來12位就是:0000 00000010,也就是0x2,就是第2個位錯誤.

3個位錯誤的24位數據解碼出來12位就是:0000 00000011,也就是0x3,就是第3個錯誤.

4095個位錯誤的24位數據解碼出來12位就是:1111 11111111,也就是0xfff,就是第4095個位錯誤.

 

到了這一步,不知道有沒有明白糾正原理呢。當知道是哪一個是錯誤的了,剩下的就簡單了,就把錯誤的那一位把0變成1,或者把1變成0就行了。

可以寫成一個函數,ecc_data為校驗結果。

 

intcheck_ecc(u32 ecc_data)

{

  u32 temp;

  int i;

  u8 data4;

  u32 location=0;

  temp=ecc_data&0xffffff;//只要24

 

 

  for(i=0;i<24/2;i++)

    {

     data4=(temp>>(i*2))&0x3;

     if(data4==0x01)

        {

        // 如果兩位是0x01,則判斷是0

        }

     else if(data4==0x02)

        {

         // 1 如果兩個是0x10,則判斷是1

         location|=(1<<i);

        }

     else

        {

        // 如果不是兩種其一,剛說明無法糾錯

                   // 既然無法糾錯,其它的,就暫時不關心了

         return -1;

        }

     printf("location:%d..\r\n",location);

 

    }

  return location;

 

}

 

 

當然,如果校驗結果為0x00的時候,說明讀出來的數據是對的。不需要調用這個函數了。調用這個函數時,就可以返回錯誤的位置。

到此,ECC的功能就調試的差不多了。剩下的,就是把那一位糾錯出來就好了。重要的ECC校驗結果出來了,知道是哪一位錯誤了,剩下的還不好辦了。

 

對于NAND_FLASH呢,具體就可以這樣實現了。

一頁是2048個字節加OOB64個字節。

OOB區一般是存放ECC數據,一般如果寫到跑系統的是,用設計ECC layout的。

這里就簡單作個layout吧。簡單地說,就是把ECC放在哪里。

因為這里每512個字節, 產生一個ECC,占4個字節。

1 512字節產生的ECC就放到OOB區里的0x10,0x11,x12,0x13這四個地址里。

2 512字節產生的ECC就放到OOB區里的0x14,0x15,x16,0x17這四個地址里。

3 512字節產生的ECC就放到OOB區里的0x18,0x19,x1a,0x1b這四個地址里。

4 512字節產生的ECC就放到OOB區里的0x1c,0x1d,x1e,0x1f這四個地址里。

    

     這樣,ECC layout就算是設置好了。因此只要在寫入的時候,把ECC相應地存入到OOB區,然后在讀NAND_FLASH的時候,再讀新的ECC數據,和之前寫入到OOB里的ECC進行異或,得到ECC校驗結果。那,ECC的調試,就算告個段落了。

如果有錯誤之處,還請見諒。

特此寫下以便日后可以回顧,而且網上涉及的也比較少,寫出來也讓感興趣的人一起交流學習。


FSMC的使用手冊*(英文的),以及fsmc_nand.c的驅動測試ECC一同上傳到了我的CSDN里了,有需要可下載 STM32 ECC調試及心得.zip (385.02 KB, 下載次數: 76)

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:161913 發表于 2017-1-15 19:10 | 只看該作者
需要這個東西。謝謝分享!
回復

使用道具 舉報

板凳
ID:161913 發表于 2017-1-15 19:16 | 只看該作者
很有用,非常感謝樓主分享。
回復

使用道具 舉報

地板
ID:20697 發表于 2017-10-27 10:33 | 只看該作者
學習了。
有個問題,512字節寫一次,2k的page要寫4次嗎?
回復

使用道具 舉報

5#
ID:20697 發表于 2017-10-27 10:34 | 只看該作者
本帖最后由 hunancjz 于 2017-10-31 14:30 編輯

請問一下ECC如何寫到OOB?
我的理解是,data區分4次寫,得到4個ECC,再把4個ECC寫到OOB。
就是說寫一頁要進行5次寫操作。
這樣理解對嗎?
回復

使用道具 舉報

6#
ID:256228 發表于 2017-12-1 18:24 | 只看該作者
我用的也是 4096Bytes/Page 的NANDFLASH,非常感謝樓主分享解了我的困惑。
回復

使用道具 舉報

7#
ID:396291 發表于 2018-9-10 23:45 | 只看該作者
正在學習這個,謝謝樓主分享
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 夜夜精品视频 | 视频一二区 | 亚洲激情综合 | 日韩在线不卡 | 又黄又色 | 日本a∨精品中文字幕在线 亚洲91视频 | 亚洲精品无 | 免费性视频| 日韩一级 | 国产成人一区在线 | 亚洲一在线 | av成人在线观看 | 欧美成人免费在线 | 精品欧美色视频网站在线观看 | 亚洲一区二区三区四区av | 理论片午午伦夜理片影院 | 亚洲夜夜爽 | 男人的天堂在线视频 | 日韩美女在线看免费观看 | 日韩成人性视频 | 午夜精品一区二区三区在线播放 | 国产a区 | 亚洲福利在线观看 | 国产一区二区在线视频 | 亚洲另类自拍 | 亚洲成人一区二区三区 | 日韩在线免费 | 日韩欧美三级在线 | 成年男女免费视频网站 | 天天综合国产 | 美女黄网| 黄视频免费在线 | 在线超碰 | 久久久久成人精品亚洲国产 | 国产亚洲欧美日韩精品一区二区三区 | 国产精品一区二区三区在线 | 欧美精品成人影院 | 欧美精品成人 | 激情六月丁香婷婷 | 国产精品久久久久久久免费大片 | aaa大片免费观看 |