zoukankan      html  css  js  c++  java
  • 十八、flash 适配(四)

    18.9 硬件 ecc 适配

    18.9.1 配置修改

    根据前面的内容,修改配置:

    查看代码,还需要配置几个选项,在 Kconfig 中没有添加,所以需要添加进去。

    先看下 size、bytes 是做什么用的:

    • CONFIG_SYS_NAND_ECCSIZE:定义了数据的长度,即每多少字节进行 1 次 ECC 校验
    • CONFIG_SYS_NAND_ECCBYTES:生成的 ECC 的字节个数,对于 512 字节可以生成 3 个字节,2048 字节可以生成 4 个字节

    确定一下 nandflash 的每一页的大小:

     可以看到每一页是 2 x 1024 字节,那么CONFIG_SYS_NAND_ECCSIZE 设置成2048, CONFIG_SYS_NAND_ECCBYTES 设置成 4 个字节

    先添加 drivers/mtd/nand/Kconfig 中的代码:

    修改配置:

     18.9.2 代码修改

    硬件 ECC 主要由 nand 控制器进行控制,所以我们只需要操作寄存器即可。先修改一下硬件控制 ECC 的宏:

     1     /** ecc 初始化, 一个是硬件 ECC 校验,一个是软件 ECC 校验 */
     2 #ifdef CONFIG_NAND_HW_ECC
     3     nand->ecc.hwctl = s3c24x0_nand_enable_hwecc;
     4     nand->ecc.calculate = s3c24x0_nand_calculate_ecc;
     5     nand->ecc.correct = s3c24x0_nand_correct_data;
     6     nand->ecc.mode = NAND_ECC_HW;
     7     nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
     8     nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
     9     nand->ecc.strength = 1;
    10 #else
    11     nand->ecc.mode = NAND_ECC_SOFT;
    12 #endif

    接下来来看看芯片手册给我们提供的硬件 ECC 的操作步骤:

     在步骤 1 中很明确的说明需要对 MainECCCLock 开锁,我们放在硬件初始化函数中进行:

    之后就是计算 s3c24x0_nand_calculate_ecc :

     对 ECC 进行校验:

     1 /** 该函数首先把 read_ecc 数组内的 ECC 存入寄存器 NFMECCD0 和寄存器 NFMECCD1 中,这样系统就会自动校验数据,
     2  *  并把状态放入寄存器 NFESTAT0 中,然后读取该寄存器的后 4 位,当为 0 时表示校验正确;
     3  *  当为 1 时表示发生了 1 位错误(该类错误可以校正),
     4  *  我们把它校正过来;当为 2 和 3 时表示发生其他类型的错误,这类错误是无法校正的。
     5  */
     6 static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat,
     7                      u_char *read_ecc, u_char *calc_ecc)
     8 {
     9 #if CONFIG_S3C2440_NAND_HWECC
    10     struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
    11 
    12     uint  meccdata0, meccdata1, estat0, err_byte_addr;
    13     uchar repaired;
    14     int ret = -1;
    15 
    16     meccdata0 = (read_ecc[1] << 16) | read_ecc[0];
    17     meccdata1 = (read_ecc[3] << 16) | read_ecc[2];
    18 
    19     writel(meccdata0, &nand->nfeccd0);
    20     writel(meccdata1, &nand->nfeccd1);
    21 
    22     /** 读取 ecc 得状态 */
    23     estat0 = readl(&nand->nfstat0);
    24     switch (estat0 & 0x3)
    25     {
    26         case 0: /*no error*/
    27             ret = 0;
    28             break;
    29         case 1:
    30             /* 
    31              *1bit error(correctable)
    32              *(nfestat0 >> 7) & 0x7ff    error byte number
    33              *(nfestat0 >> 4) & 0x7      error bit number
    34             */
    35             err_byte_addr = (estat0 >>7 ) & 0x7ff;
    36             repaired = dat[err_byte_addr] ^ (1 << ((estat0 >> 4) & 0x7));
    37             printf("S3C NAND: 1 bit error detected at byte %u. Correcting from 0x%02x to0x%02x...OK
    ",
    38                err_byte_addr, dat[err_byte_addr], repaired);
    39             dat[err_byte_addr] = repaired;
    40             ret = 1;
    41             break;
    42         case 2:  /* Multiple error */
    43         case 3:  /* ECC area error */
    44             printf("S3C NAND: ECC uncorrectable errordetected. Not correctable.
    ");
    45             ret= -1;
    46             break;
    47     }
    48 
    49     return ret;
    50 #else
    51     if (read_ecc[0] == calc_ecc[0] &&
    52         read_ecc[1] == calc_ecc[1] &&
    53         read_ecc[2] == calc_ecc[2])
    54         return 0;
    55 
    56     printf("s3c24x0_nand_correct_data: not implemented
    ");
    57     return -EBADMSG;
    58 #endif
    59 }

    18.9.3 编译测试

    烧写进去后,读写都是 OK 的,但是在擦除的时候报了错,如下:

    追踪代码发现是 BBT,即进行擦除的过程中,会进行坏块检查,会去读取每一页的数据,然后进行 ecc 校验,开 debug 进行测试,测试结果如下:

    加入打印测试:

    nandflash 中有坏块,所以这个问题是非问题。

  • 相关阅读:
    ztree
    SAMEORIGIN
    Unity shader学习之折射
    Unity shader学习之反射
    Unity shader学习之标准的Unity shader
    Unity shader学习之Alpha Test的阴影
    Unity shader学习之阴影,衰减统一处理
    Unity shader学习之阴影
    Unity shader学习之Forward Rendering Path
    AsyncClientUtils
  • 原文地址:https://www.cnblogs.com/kele-dad/p/13179385.html
Copyright © 2011-2022 走看看