Linux下NAND FLASH驱动开发
info->sel_reg = regs + S3C2410_NFCONF;
info->sel_bit = S3C2410_NFCONF_nFCE;
chip->cmd_ctrl = s3c2410_nand_hwcontrol ;
chip->dev_ready = s3c2410_nand_devready ;
break;
。。。。。。
}
chip->IO_ADDR_R = chip->IO_ADDR_W;
nmtd->info = info;
nmtd->mtd.priv = chip;
nmtd->mtd.owner = THIS_MODULE;
nmtd->set = set;
if (hardware_ecc) {
chip->ecc.calculate = s3c2410_nand_calculate_ecc ;
chip->ecc.correct = s3c2410_nand_correct_data ;
/* 此处,多数情况下,你所用的 Nand Flash 的控制器,都是支持硬件 ECC 的,所以,此处设置硬件 ECC(HW_ECC) ,也是充分利用硬件的特性,而如果此处不用硬件去做的 ECC 的话,那么下面也会去设置成 NAND_ECC_SOFT ,系统会用默认的软件去做 ECC 校验,相比之下,比硬件 ECC 的效率就低很多,而你的 nand flash 的读写,也会相应地要慢不少 */
chip->ecc.mode = NAND_ECC_HW;
switch (info->cpu_type) {
case TYPE_S3C2410:
chip->ecc.hwctl = s3c2410_nand_enable_hwecc ;
chip->ecc.calculate = s3c2410_nand_calculate_ecc;
break;
。。。。。
}
} else {
chip->ecc.mode = NAND_ECC_SOFT;
}
if (set->ecc_layout != NULL)
chip->ecc.layout = set->ecc_layout;
if (set->disable_ecc)
chip->ecc.mode = NAND_ECC_NONE;
}
而我们要实现的底层函数,也就是上面蓝色标出来的一些函数而已:
( 1 ) s3c2410_nand_write_buf 和 s3c2410_nand_read_buf :这是两个最基本的操作函数,其功能,就是往你的 nand flash 的控制器中的 FIFO 读写数据。一般情况下,是 MTD 上层的操作,比如要读取一页的数据,那么在发送完相关的读命令和等待时间之后,就会调用到你底层的 read_buf ,去 nand Flash 的 FIFO 中,一点点把我们要的数据,读取出来,放到我们制定的内存的缓存中去。写操作也是类似,将我们内存中的数据,写到 Nand Flash 的 FIFO 中去。具体的数据流向,参考上面的图 4 。
( 2 ) s3c2410_nand_select_chip : 实现 Nand Flash 的片选。
( 3 ) s3c2410_nand_hwcontrol :给底层发送命令或地址,或者设置具体操作的模式,都是通过此函数。
( 4 ) s3c2410_nand_devready : Nand Flash 的一些操作,比如读一页数据,写入(编程)一页数据,擦除一个块,都是需要一定时间的,在命发送完成后,就是硬件开始忙着工作的时候了,而硬件什么时候完成这些操作,什么时候不忙了,变就绪了,就是通过这个函数去检查状态的。一般具体实现都是去读硬件的一个状态寄存器,其中某一位是否是 1 ,对应着是出于“就绪 / 不忙”还是“忙”的状态。这个寄存器,也就是我们前面分析时序图中的 R/B# 。
( 5 ) s3c2410_nand_enable_hwecc : 在硬件支持的前提下,前面设置了硬件 ECC 的话,要实现这个函数,用于每次在读写操作前,通过设置对应的硬件寄存器的某些位,使得启用硬件 ECC ,这样在读写操作完成后,就可以去读取硬件校验产生出来的 ECC 数值了。
( 6 ) s3c2410_nand_calculate_ecc :如果是上面提到的硬件 ECC 的话,就不用我们用软件去实现校验算法了,而是直接去读取硬件产生的 ECC 数值就可以了。
( 7 ) s3c2410_nand_correct_data :当实际操作过程中,读取出来的数据所对应的硬件或软件计算出来的 ECC ,和从 oob 中读出来的 ECC 不一样的时候,就是说明数据有误了,就需要调用此函数去纠正错误。对于现在 SLC 常见的 ECC 算法来说,可以发现 2 位,纠正 1 位。如果错误大于 1 位,那么就无法纠正回来了。一般情况下,出错超过 1 位的,好像几率不大。至少我看到的不是很大。更复杂的情况和更加注重数据安全的情况下,一般是需要另外实现更高效和检错和纠错能力更强的 ECC 算法的。
当然,除了这些你必须实现的函数之外,在你更加熟悉整个框架之后,你可以根据你自己的 nand flash 的特点,去实现其他一些原先用系统默认但是效率不高的函数,而用自己的更高效率的函数替代他们,以提升你的 nand flash 的整体性能和效率。
评论