RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

講講Micrium全家桶的uC-CRC算法

麥克泰技術(shù) ? 來源:嵌入式Lee ? 2023-05-04 10:47 ? 次閱讀

前言

我們這一篇來講講Micrium全家桶的uC-CRC。該代碼庫提供了CRC算法進(jìn)行錯(cuò)誤檢測EDC,使用HAMMING算法實(shí)現(xiàn)ECC錯(cuò)誤糾正。ECC算法在NAND的TFL中使用。

修改版本,去掉對uC-LIB,uC-CPU等的依賴,可以直接單獨(dú)使用,方便移植。

文件介紹

│  LICENSE
│  NOTICE
│  readme.md
│
├─Cfg
│  └─Template
│          crc_cfg.h
│
├─Ports
│  ├─ARM
│  │  └─IAR
│  │          ecc_hamming_a.asm
│  │          edc_crc_a.asm
│  │
│  └─ARM-Cortex-M3
│      └─IAR
│              ecc_hamming_a.asm
│              edc_crc_a.asm
│
└─Source
        crc_util.c
        crc_util.h
        ecc.h
        ecc_hamming.c
        ecc_hamming.h
        edc_crc.c
        edc_crc.h

文件 說明
LICENSE/NOTICE/readme.md LICENSE使用的APACHE-2.0
crc_cfg.h 配置文件
ecc_hamming_a.asm 使用匯編實(shí)現(xiàn)
Hamming_ParCalcBitWord_32
默認(rèn)提供了ARM和ARM-Cortex-M3架構(gòu)IAR編譯器的版本
crc_cfg.h中#defineEDC_CRC_CFG_OPTIMIZE_ASM_ENDEF_ENABLED時(shí)使用,默認(rèn)不使
edc_crc_a.asm 使用匯編實(shí)現(xiàn)
CRC_ChkSumCalcTbl_16Bit
CRC_ChkSumCalcTbl_16Bit_ref
CRC_ChkSumCalcTbl_32Bit
CRC_ChkSumCalcTbl_32Bit_ref
默認(rèn)提供了ARM和ARM-Cortex-M3架構(gòu)IAR編譯器的版本
crc_cfg.h中#defineEDC_CRC_CFG_OPTIMIZE_ASM_ENDEF_ENABLED時(shí)使用,默認(rèn)不使用
crc_util.c/h 實(shí)現(xiàn)CRCUtil_PopCnt_32
算法來自于http://en.wikipedia.org/wiki/Hamming_weight
ecc_hamming.c/h Ecc算法代碼
edc_crc.c/h Crc算法代碼

添加代碼到自己的工程

添加uC-CRCCfgTemplatecrc_cfg.h

uC-CRCSource下所有文件到自己的工程目錄uC-CRC下

b8c922d6-e708-11ed-ab56-dac502259ad0.png

并配置頭文件包含路徑uC-CRC

b8e022b0-e708-11ed-ab56-dac502259ad0.png

依賴

文件 內(nèi)容
cpu.h
cpu_core.h
lib_def.h
lib_mem.h
CPU_BOOLEAN
CPU_INT08U
CPU_INT16U
CPU_INT32U
CPU_ADDR
CPU_DATA
CPU_SIZE_T
CPU_WORD_SIZE_32
DEF_NO
DEF_YES
DEF_DISABLED
DEF_ENABLED
DEF_INVALID
DEF_VALID
DEF_OCTET_NBR_BITS
DEF_BIT
DEF_BIT_00~DEF_BIT_12
DEF_BIT_13
DEF_BIT_15
DEF_BIT_17
DEF_BIT_19
DEF_BIT_21
DEF_BIT_23
DEF_BIT_25
DEF_BIT_27
DEF_BIT_29
DEF_BIT_31
DEF_BIT_SET
DEF_BIT_IS_SET
CPU_SW_EXCEPTION
MEM_VAL_COPY_GET_INT32U
MEM_VAL_COPY_GET_INTU
MEM_VAL_COPY_SET_INT32U
Mem_Clr

修改代碼

注釋掉crc_util.h下的

#include 


#include 

改為

#include 

注釋掉ecc.h下的

#include 


#include 

注釋掉ecc_hamming.h下的

#include 


#include 


#include 


#include 

注釋掉edc_crc.h下的

#include 


#include 


#include 

注釋掉

ecc_hamming.c下的

Mem_Clr((void *)p_ecc, HAMMING_LEN_OCTET_ECC); /* Init ECC buf for err(s) (see Note #6).               */

改為

memset((void *)p_ecc, 0, HAMMING_LEN_OCTET_ECC);

前面添加

#include 

crc_cfg.h中實(shí)現(xiàn)以下依賴

/*
*********************************************************************************************************
*                                                 PORT
*
* Note(s) : (1) 以下添加依賴部分移植
*               
*
*********************************************************************************************************
*/


                                                        /* ------------------ CPU WORD-ENDIAN ORDER ------------------- */
#define  CPU_ENDIAN_TYPE_NONE                      0u
#define  CPU_ENDIAN_TYPE_BIG                       1u   /* Big-   endian word order (see Note #1a).                     */
#define  CPU_ENDIAN_TYPE_LITTLE                    2u   /* Little-endian word order (see Note #1b).                     */


#define  CPU_CFG_ENDIAN_TYPE            CPU_ENDIAN_TYPE_LITTLE


typedef  unsigned  char        CPU_BOOLEAN;                     /*  8-bit boolean or logical                            */
typedef  unsigned  char        CPU_INT08U;                      /*  8-bit unsigned integer                              */
typedef  unsigned  short       CPU_INT16U;                      /* 16-bit unsigned integer                              */
typedef  unsigned  int         CPU_INT32U;                      /* 32-bit unsigned integer                              */
typedef  CPU_INT32U  CPU_ADDR;                                  /* CPU address type based on address bus size.          */
typedef  CPU_INT32U  CPU_DATA;                                  /* CPU data    type based on data    bus size.          */
typedef  CPU_ADDR    CPU_SIZE_T;                                /* Defines CPU standard 'size_t'   size.                */


#define  CPU_WORD_SIZE_32                                   4u   /* 32-bit word size (in octets).                                */




                                                                /* ----------------- BOOLEAN DEFINES ------------------ */
#define  DEF_NO                                            0u
#define  DEF_YES                                           1u
#define  DEF_DISABLED                                      0u
#define  DEF_ENABLED                                       1u
#define  DEF_INVALID                                       0u
#define  DEF_VALID                                         1u


#define  DEF_OCTET_NBR_BITS                                8u
#define  DEF_BIT(bit)                                                   (1uL << (bit))


                                                                /* ------------------- BIT DEFINES -------------------- */
#define  DEF_BIT_00                                     0x01u
#define  DEF_BIT_01                                     0x02u
#define  DEF_BIT_02                                     0x04u
#define  DEF_BIT_03                                     0x08u
#define  DEF_BIT_04                                     0x10u
#define  DEF_BIT_05                                     0x20u
#define  DEF_BIT_06                                     0x40u
#define  DEF_BIT_07                                     0x80u
#define  DEF_BIT_08                                   0x0100u
#define  DEF_BIT_09                                   0x0200u
#define  DEF_BIT_10                                   0x0400u
#define  DEF_BIT_11                                   0x0800u
#define  DEF_BIT_12                                   0x1000u
#define  DEF_BIT_13                                   0x2000u
#define  DEF_BIT_15                                   0x8000u
#define  DEF_BIT_17                               0x00020000u
#define  DEF_BIT_19                               0x00080000u
#define  DEF_BIT_21                               0x00200000u
#define  DEF_BIT_23                               0x00800000u
#define  DEF_BIT_25                               0x02000000u
#define  DEF_BIT_27                               0x08000000u
#define  DEF_BIT_29                               0x20000000u
#define  DEF_BIT_31                               0x80000000u




#define  DEF_BIT_SET(val, mask)                        ((val) = ((val) | (mask)))


#define  DEF_BIT_IS_SET(val, mask)                    (((((val) & (mask)) == (mask)) && ((mask) != 0u)) ? (DEF_YES) : (DEF_NO))


#define  CPU_SW_EXCEPTION(err_rtn_val)              do {                    
                                                        ;                    
                                                    } while (1)




#define  MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src)   do {                                                                             
                                                                   CPU_INT08U  *destptr = (CPU_INT08U *)(addr_dest);                            
                                                                   CPU_INT08U  *srcptr  = (CPU_INT08U *)(addr_src);                             
                                                                   (*((destptr) + 0))   = (*((srcptr) + 0));                                    
                                                                   (*((destptr) + 1))   = (*((srcptr) + 1));                                    
                                                                   (*((destptr) + 2))   = (*((srcptr) + 2));                                    
                                                                   (*((destptr) + 3))   = (*((srcptr) + 3)); } while (0)                        


#define  MEM_VAL_COPY_GET_INTU(addr_dest, addr_src, val_size)    do {                                                                                  
                                                                            CPU_SIZE_T  _i;                                                                   
                                                                                                                                                              
                                                                            for (_i = 0; _i < (val_size); _i++) {                                             
                                                                                (*(((CPU_INT08U *)(addr_dest)) + _i)) = (*(((CPU_INT08U *)(addr_src)) + _i)); 
                                                                            }                                                                                 
                                                                        } while (0)


#define  MEM_VAL_COPY_SET_INT32U(addr_dest, addr_src)    MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src)

測試

ECC

用戶代碼中#include ”ecc_hamming.h”

調(diào)用以下接口

Hamming_Calc

Hamming_Chk

Hamming_Correct

詳見test.c

#include 
#include 
#include "ecc_hamming.h"


typedef struct
{
  ECC_ERR err;
  char* str;
}err_str;


err_str s_err_str[]=
{
  {ECC_ERR_NONE,"No error."},
  {ECC_ERR_CORRECTABLE,"Correctable error detected in data."},
  {ECC_ERR_ECC_CORRECTABLE,"Correctable error detected in ECC."},
  {ECC_ERR_INVALID_ARG,"Argument passed invalid value. "},
  {ECC_ERR_INVALID_LEN,"Len argument passed invalid length."},
  {ECC_ERR_NULL_PTR,"Pointer argument passed NULL pointer."},
  {ECC_ERR_UNCORRECTABLE,"Uncorrectable error detected in data."}
};
    
uint8_t s_buffer[33];
uint8_t s_ecc[4];


int ecc_main(int argc, char* argv[])
{
  CPU_INT08U ecc[4];
  ECC_ERR_LOC err_loc[2]={{0,0},{0,0}};
  ECC_ERR err;
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    s_buffer[i] = i+1;
  }
  
  /* 打印原始數(shù)據(jù) */
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    if(i % 16 == 0)
    {
      printf("
");
    }
    printf("%#x ",s_buffer[i]);
  }
  printf("
");
  
  CPU_SIZE_T len = (sizeof(s_buffer)/sizeof(s_buffer[0]));
  CPU_SIZE_T len_buf     = (len / 32)*32;
  CPU_SIZE_T len_buf_ext = len % 32;
  CPU_INT08U* p_buf_ext   = (CPU_INT08U *)s_buffer + len_buf;
  Hamming_Calc(s_buffer,len_buf,p_buf_ext,len_buf_ext,s_ecc,&err);
  if(ECC_ERR_NONE != err)
  {
    printf("Hamming_Calc err:%d
",err);
    return -1;
  }
  printf("Hamming_Calc:ecc %#x %#x %#x %#x
",s_ecc[0],s_ecc[1],s_ecc[2],s_ecc[3]);
  
/*
 *  1位數(shù)據(jù)錯(cuò)誤
 */
  /* DATA注入錯(cuò)誤 */
  printf("
[DATA err test]
");
  s_buffer[0] ^= 0x80;
  
  /* 打印錯(cuò)誤數(shù)據(jù) */
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    if(i % 16 == 0)
    {
      printf("
");
    }
    printf("%#x ",s_buffer[i]);
  }
  printf("
");
  
  if(ECC_FAULT == Hamming_Chk(s_buffer,len_buf,p_buf_ext,len_buf_ext,s_ecc,err_loc,sizeof(err_loc)/sizeof(err_loc[0]),&err))
  {
    printf("Hamming_Chk err:%d
",err);
    return -2;
  }
  printf("Hamming_Chk:loc B[%d].b[%d] B[%d].b[%d]
",err_loc[0].LocOctet,err_loc[0].LocBit,err_loc[1].LocOctet,err_loc[1].LocBit);
  printf("%s",s_err_str[err].str);
  
  Hamming_Correct(s_buffer,len_buf,p_buf_ext,len_buf_ext,s_ecc,&err);
  /* 打印修復(fù)后的數(shù)據(jù) */
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    if(i % 16 == 0)
    {
      printf("
");
    }
    printf("%#x ",s_buffer[i]);
  }
  printf("
");
  printf("Hamming_Correct:ecc %#x %#x %#x %#x
",s_ecc[0],s_ecc[1],s_ecc[2],s_ecc[3]);
  printf("%s",s_err_str[err].str);
/*
 *  1位ECC錯(cuò)誤
 */
  /* DATA注入錯(cuò)誤 */
  printf("
[ECC err test]
");
  s_ecc[1] ^= 0x02;
  
  /* 打印錯(cuò)誤數(shù)據(jù) */
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    if(i % 16 == 0)
    {
      printf("
");
    }
    printf("%#x ",s_buffer[i]);
  }
  printf("
");
  
  if(ECC_FAULT == Hamming_Chk(s_buffer,len_buf,p_buf_ext,len_buf_ext,s_ecc,err_loc,sizeof(err_loc)/sizeof(err_loc[0]),&err))
  {
    printf("Hamming_Chk err:%d
",err);
    return -2;
  }
  printf("Hamming_Chk:loc B[%d].b[%d] B[%d].b[%d]
",err_loc[0].LocOctet,err_loc[0].LocBit,err_loc[1].LocOctet,err_loc[1].LocBit);
  printf("%s",s_err_str[err].str);
  
  Hamming_Correct(s_buffer,len_buf,p_buf_ext,len_buf_ext,s_ecc,&err);


  /* 打印修復(fù)后的數(shù)據(jù) */
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    if(i % 16 == 0)
    {
      printf("
");
    }
    printf("%#x ",s_buffer[i]);
  }
  printf("
");
  printf("Hamming_Correct:ecc %#x %#x %#x %#x
",s_ecc[0],s_ecc[1],s_ecc[2],s_ecc[3]);
  printf("%s",s_err_str[err].str);
/*
 *  2位數(shù)據(jù)錯(cuò)誤
 */
  /* DATA注入錯(cuò)誤 */
  printf("
[2DATA err test]
");
  s_buffer[2] ^= 0x04;
  s_buffer[5] ^= 0x10;
  
  /* 打印錯(cuò)誤數(shù)據(jù) */
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    if(i % 16 == 0)
    {
      printf("
");
    }
    printf("%#x ",s_buffer[i]);
  }
  printf("
");
  
  if(ECC_FAULT == Hamming_Chk(s_buffer,len_buf,p_buf_ext,len_buf_ext,s_ecc,err_loc,sizeof(err_loc)/sizeof(err_loc[0]),&err))
  {
    printf("Hamming_Chk err:%d
",err);
    return -2;
  }
  printf("Hamming_Chk:loc B[%d].b[%d] B[%d].b[%d]
",err_loc[0].LocOctet,err_loc[0].LocBit,err_loc[1].LocOctet,err_loc[1].LocBit);
  printf("%s",s_err_str[err].str);
  
  Hamming_Correct(s_buffer,len_buf,p_buf_ext,len_buf_ext,s_ecc,&err);
  /* 打印修復(fù)后的數(shù)據(jù) */
  for(int i=0; i< sizeof(s_buffer)/sizeof(s_buffer[0]); i++)
  {
    if(i % 16 == 0)
    {
      printf("
");
    }
    printf("%#x ",s_buffer[i]);
  }
  printf("
");
  printf("Hamming_Correct:ecc %#x %#x %#x %#x
",ecc[0],ecc[1],ecc[2],ecc[3]);
  printf("%s",s_err_str[err].str);
  return 0;
}

測試結(jié)果如下可以看到,1位的數(shù)據(jù)錯(cuò)誤校正過來了,ECC編碼本身的1位錯(cuò)誤認(rèn)為是不可校正錯(cuò)誤,兩位數(shù)據(jù)錯(cuò)誤也是不可校正錯(cuò)誤

b90d9b5a-e708-11ed-ab56-dac502259ad0.png

CRC

接口如下,下篇再單講

CRC_Open_16Bit
CRC_WrBlock_16Bit
CRC_WrOctet_16Bit
CRC_Close_16Bit


CRC_Open_32Bit
CRC_WrBlock_32Bit
CRC_WrOctet_32Bit
CRC_Close_32Bit


CRC_Reflect_08Bit
CRC_Reflect_16Bit
CRC_Reflect_32Bit


CRC_ChkSumCalc_16Bit
CRC_ChkSumCalc_32Bit

漢明碼

冗余位

假設(shè)有m位數(shù)據(jù),至少要添加n位冗余位才能檢測出錯(cuò)誤(只考慮只有1個(gè)bit錯(cuò)誤的情況)。

m位數(shù)據(jù),n位冗余數(shù)據(jù)錯(cuò)1位的情況有m+n種,還有一種情況是無錯(cuò)。

需要用n位冗余位去標(biāo)志是哪一位錯(cuò)了,所以要滿足2^n >= m+n+1。

奇偶校驗(yàn)

奇校驗(yàn):數(shù)據(jù)和校驗(yàn)位一起,1的個(gè)數(shù)為奇數(shù)

偶校驗(yàn):數(shù)據(jù)和校驗(yàn)位一起,1的個(gè)數(shù)為偶數(shù)

奇偶校驗(yàn)只能發(fā)現(xiàn)奇數(shù)個(gè)位翻轉(zhuǎn),因?yàn)榕紨?shù)個(gè)位翻轉(zhuǎn)奇偶性不變。

漢明碼

即奇偶校驗(yàn)的升級,組合。

先根據(jù)2^n >= m+n+1計(jì)算需要多少個(gè)校驗(yàn)位,

然后確認(rèn)校驗(yàn)位的位置在2^n索引位上(索引從1開始)。

比如7位數(shù)據(jù)需要4位校驗(yàn)位,2^4 >= 7+4+1,一共11位,從1~11編號索引

寫為二進(jìn)制

0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011

將bit0是1的劃分為一組 0001 0011 0101 0111 1001 1011

即1 3 57 9 11, 將對應(yīng)數(shù)據(jù)位奇校驗(yàn),放在2^0校驗(yàn)位

將bit1是1的劃分為一組 0010 0011 0110 0111 1010 1011

即2 3 6 7 10 11, 將對應(yīng)數(shù)據(jù)位奇校驗(yàn),放在2^1校驗(yàn)位

將bit2是1的劃分為一組 0100 0101 0110 0111

即4 56 7, 將對應(yīng)數(shù)據(jù)位奇校驗(yàn),放在2^2校驗(yàn)位

將bit3是1的劃分為一組 0100 0101 0110 0111

即8 9 10 11, 將對應(yīng)數(shù)據(jù)位奇校驗(yàn),放在2^3校驗(yàn)位

糾錯(cuò),如果2^0校驗(yàn)位不對bit0寫1,如果2^1校驗(yàn)位不對bit1寫1,得到的二進(jìn)制數(shù)就是出錯(cuò)位的的索引。

比如以上如果bit5翻轉(zhuǎn)了,索引5是在2^0和2^2組的所以,是101,即索引5的數(shù)據(jù)有錯(cuò)。

漢明距離

在一個(gè)碼組集合中,任意兩個(gè)碼字之間對應(yīng)位上碼元取值不同的位的數(shù)目定義為這兩個(gè)碼字之間的漢明距離d。例如:(00)與(01)的距離是1,(110)和(101)的距離是2。在一個(gè)碼組集合中,任意兩個(gè)編碼之間漢明距離的最小值稱為這個(gè)碼組的最小漢明距離。最小漢明距離越大,碼組越具有抗干擾能力,即差異越大,冗余越多。即編碼只用了一部分,剩余的空著,如果出現(xiàn)了錯(cuò)誤則肯定是變成了空著的編碼。

比如兩位的編碼實(shí)際可以編碼為00 01 10 11,但是我們只用00代表A,10代表B,

那么收到01后,我們知道出錯(cuò)了,那么是哪個(gè)出錯(cuò)了呢,00變?yōu)?1需要變化1位,10變?yōu)?1需要變化2位,所以所以我們更傾向于是00變化了一位即是A出錯(cuò)了,

所以我們可以認(rèn)為00和01都代表A

10 11 都代表B

這樣實(shí)際就是用冗余來提高抗干擾能力,我們粗暴的發(fā)兩次也是冗余,但是冗余太多了浪費(fèi)空間,所以可以選擇不冗余這么多,這個(gè)漢明距離d就是冗余的多少,d越大冗余越大,d越小冗余越小。

l當(dāng)碼組用于檢測錯(cuò)誤時(shí),設(shè)可檢測e個(gè)位的錯(cuò)誤,則d ≥ e + 1

l若碼組用于糾錯(cuò),設(shè)可糾錯(cuò)t個(gè)位的錯(cuò)誤,則 d ≥ 2 ? t + 1

即AB之間的距離至少是1才能區(qū)分AB, 剩余的空間2t劃分一半,靠近A的一半t認(rèn)為是A,靠近B的一半t認(rèn)為是B。

l如果碼組用于糾正t個(gè)錯(cuò),檢測e個(gè)錯(cuò),則d ≥ e + t + 1

NAND中的硬件ECC

這里以W25N01GVZEIG芯片為例,不同芯片略有差異

b94780fe-e708-11ed-ab56-dac502259ad0.png

一個(gè)PAGE大大小是2112字節(jié)其中用戶區(qū)域2048字節(jié)+額外區(qū)域64字節(jié)

將PAGE的用戶區(qū)域和額外區(qū)域都分成4份即Sector,

則512字節(jié)用戶區(qū)域?qū)?yīng)16字節(jié)額外區(qū)域。

16字節(jié)額外區(qū)域如上圖

0- 1 :2字節(jié)位壞塊標(biāo)記

2- 3 :2字節(jié)用戶數(shù)據(jù)II

4-7 : 4字節(jié)用戶數(shù)據(jù)I

8-D: 6字節(jié)前面Sector數(shù)據(jù)的ECC校驗(yàn)值

E-F:4-D對應(yīng)的10字節(jié)的ECC校驗(yàn)值

問題:ECC for Sector 0本身有誤碼可以通過ECC for Spare檢測出來,但是如果ECC for Spare本身有誤碼呢?

芯片自帶的ECC校驗(yàn)使能通過寄存器配置(有些型號是默認(rèn)使能的)

b97395a4-e708-11ed-ab56-dac502259ad0.png

b9984a70-e708-11ed-ab56-dac502259ad0.png

寫數(shù)據(jù)時(shí)自動(dòng)計(jì)算ECC并更新到64字節(jié)額外區(qū)域,讀數(shù)據(jù)時(shí)自動(dòng)校驗(yàn)ECC并進(jìn)行校正,返回校正完后的正確值。

讀數(shù)據(jù)時(shí)可以讀狀態(tài)寄存器確認(rèn)ECC狀態(tài)

b9ba679a-e708-11ed-ab56-dac502259ad0.png

b9ecf976-e708-11ed-ab56-dac502259ad0.png

NAND中的軟件ECC

256字節(jié)2048位,檢測1位錯(cuò)誤理論上只需要12位校驗(yàn)位即可,

2^12 >= 2048 + 12 + 1。

但是實(shí)際一半是糾正1位錯(cuò)誤,檢測2位錯(cuò)誤

所以d ≥ e + t + 1=4

漢明距離至少要是4.

NAND實(shí)際應(yīng)用中是按照行列分別校驗(yàn)的

按照一個(gè)字節(jié)8位x256字節(jié)

組成256x8,256行8列的矩陣

256行 16個(gè)校驗(yàn)位

8列 6個(gè)校驗(yàn)位

總共22位,3個(gè)字節(jié),剩余兩個(gè)bit未用放在高位

如下所示

ba1e5386-e708-11ed-ab56-dac502259ad0.png

ba476410-e708-11ed-ab56-dac502259ad0.png

待辦

以上Micrium和Linux的實(shí)現(xiàn)實(shí)際都沒有實(shí)現(xiàn)檢測ECC碼自身錯(cuò)誤的情況,都只能校正數(shù)據(jù)的1位錯(cuò)誤,對于ECC碼本身錯(cuò)誤一位認(rèn)為是不可校正錯(cuò)誤,這里后續(xù)可以考慮優(yōu)化。

總結(jié)

以上介紹了Micrium全家桶的uC-CRC組件,并修改成無其他依賴,比較好移植使用。其中的ECC在NAND中使用,所以重點(diǎn)進(jìn)行了介紹。不僅僅介紹代碼庫的使用,同時(shí)也分析了原理,只有理論結(jié)合實(shí)踐才能真的用好。CRC部分下次可以單獨(dú)再講講。




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • ECC
    ECC
    +關(guān)注

    關(guān)注

    0

    文章

    97

    瀏覽量

    20556
  • CRC算法
    +關(guān)注

    關(guān)注

    0

    文章

    15

    瀏覽量

    8849
  • EDC
    EDC
    +關(guān)注

    關(guān)注

    0

    文章

    8

    瀏覽量

    3782

原文標(biāo)題:Micrium全家桶之uC-CRC: 0x01 ECC

文章出處:【微信號:麥克泰技術(shù),微信公眾號:麥克泰技術(shù)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Micrium全家uC-FS: 0x02 NAND FTL算法原理詳解

    uC-FS的NAND驅(qū)動(dòng)實(shí)現(xiàn)基于一篇論文:《KAST: K-Associative Sector Translation for NAND Flash Memory in Real-Time Systems》所以有必要先介紹下該論文的內(nèi)容,以便后面理解代碼的實(shí)現(xiàn)。
    的頭像 發(fā)表于 06-08 10:55 ?1590次閱讀
    <b class='flag-5'>Micrium</b><b class='flag-5'>全家</b><b class='flag-5'>桶</b>之<b class='flag-5'>uC</b>-FS: 0x02 NAND FTL<b class='flag-5'>算法</b>原理詳解

    Micrium全家uC-FS: 0x01 NAND FTL

    這一篇我們來講講Micrium全家uC-FS。文件系統(tǒng)是一個(gè)比較龐大的組件,我們以從下往上的順序介紹,即先以一個(gè)具體的設(shè)備:NAND為例
    的頭像 發(fā)表于 06-08 10:58 ?1827次閱讀
    <b class='flag-5'>Micrium</b><b class='flag-5'>全家</b><b class='flag-5'>桶</b>之<b class='flag-5'>uC</b>-FS: 0x01 NAND FTL

    Micrium全家uC-CRC: 0x02 CRC

    前一篇我們講了Micrium全家uC-CRC: 0x01 ECC:https://mp.weixin.qq.com/s/FKVvzwL7wzxLJCkx3gOdJQ。ECC常用于N
    的頭像 發(fā)表于 06-08 11:00 ?1182次閱讀
    <b class='flag-5'>Micrium</b><b class='flag-5'>全家</b><b class='flag-5'>桶</b>之<b class='flag-5'>uC-CRC</b>: 0x02 <b class='flag-5'>CRC</b>

    Micrium全家uC-CRC: 0x01 ECC

    我們這一篇來講講Micrium全家uC-CRC。該代碼庫提供了CRC
    的頭像 發(fā)表于 06-08 11:04 ?1192次閱讀
    <b class='flag-5'>Micrium</b><b class='flag-5'>全家</b><b class='flag-5'>桶</b>之<b class='flag-5'>uC-CRC</b>: 0x01 ECC

    這段CRC算法是什么意思

    雖說懂原理,但是這算法還不理解/*******************************************************************//**//*DS18B20
    發(fā)表于 04-25 15:17

    相比React全家選擇Vue2有何優(yōu)劣?

    相比 React 全家,選擇 Vue2 有何優(yōu)劣?
    發(fā)表于 06-01 05:55

    CRC算法原理及C語言實(shí)現(xiàn)

    CRC算法原理及C語言實(shí)現(xiàn):本文從理論上推導(dǎo)出CRC 算法實(shí)現(xiàn)原理,給出三種分別適應(yīng)不同計(jì)算機(jī)或微控制器硬件環(huán)境的C 語言程序。讀者更能根據(jù)本算法
    發(fā)表于 09-23 23:38 ?31次下載

    LTE系統(tǒng)的CRC校驗(yàn)算法及DSP實(shí)現(xiàn)

    通過對兩種常用CRC校驗(yàn)算法的研究分析,為TD-LTE測試儀表系統(tǒng)選擇了一種最優(yōu)的CRC校驗(yàn)算法,并在TMS320C64xDSP中實(shí)現(xiàn)。將CRC
    發(fā)表于 02-23 14:58 ?30次下載

    基于SATAⅡ協(xié)議的CRC32并行算法的研究

    在介紹CRC校驗(yàn)原理和傳統(tǒng)CRC32串行比特算法的基礎(chǔ)上,由串行比特型算法推導(dǎo)出一種CRC32并行算法
    發(fā)表于 11-07 16:19 ?54次下載
    基于SATAⅡ協(xié)議的<b class='flag-5'>CRC</b>32并行<b class='flag-5'>算法</b>的研究

    在FPGA上實(shí)現(xiàn)CRC算法的程序

    Xilinx FPGA工程例子源碼:在FPGA上實(shí)現(xiàn)CRC算法的程序
    發(fā)表于 06-07 15:07 ?28次下載

    16位CRC校驗(yàn)原理與算法分析

    16位CRC校驗(yàn)原理與算法分析,感興趣的小伙伴們可以看看。
    發(fā)表于 10-10 14:55 ?11次下載

    嵌入式開發(fā)的crc算法知識(shí)精選

    CRC校驗(yàn)(循環(huán)冗余校驗(yàn))是數(shù)據(jù)通訊中最常采用的校驗(yàn)方式。在嵌入式軟件開發(fā)中,經(jīng)常要用到CRC 算法對各種數(shù)據(jù)進(jìn)行校驗(yàn)。因此,掌握基本的CRC算法
    的頭像 發(fā)表于 11-08 11:28 ?4435次閱讀
    嵌入式開發(fā)的<b class='flag-5'>crc</b><b class='flag-5'>算法</b>知識(shí)精選

    加拿大肯德基推出比特幣全家顧客可以用比特幣支付

    最新,把加密貨幣作為公關(guān)噱頭的主流事例就是,KFC加拿大公司推出了一個(gè)新的菜單,即比特幣全家,顧客可以允許用比特幣(BTC)支付。
    發(fā)表于 10-31 14:29 ?1981次閱讀

    如何使用SMART編寫CRC的校驗(yàn)算法程序

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何使用SMART編寫CRC的校驗(yàn)算法程序。
    發(fā)表于 10-24 08:00 ?4次下載
    如何使用SMART編寫<b class='flag-5'>CRC</b>的校驗(yàn)<b class='flag-5'>算法</b>程序

    云米家電推出AI智能產(chǎn)品“全家

    當(dāng)剛需家電升級為智能家電后,想要有放松時(shí)刻就不用在絞盡腦汁想去什么旅游景點(diǎn),訂什么五星酒店,因?yàn)樵诩抑心塬@得神級舒適體驗(yàn),無需在到處奔波。云米家電秉承著“讓家變得更智能”,傾心推出的AI智能產(chǎn)品“全家”,打造一屋子高科技,居家就能感受“黑科技”帶來的便利,也讓生活更加精
    的頭像 發(fā)表于 04-08 09:36 ?1487次閱讀
    RM新时代网站-首页