5.28 NAND设备
2026/7/20大约 2 分钟设备驱动驱动NANDFlash坏块ECC
5.28 NAND设备
📚 本节导读
学习时长: 约 40 分钟
难度级别: ⭐⭐⭐⭐⭐
前置知识: C 语言基础、NAND Flash 基础知识、5.1 设备驱动框架、5.27 MTD 设备
🎯 学习目标
- 理解 NAND Flash 的页/块/区(Plane)三级寻址模型
- 掌握
os_nand_device和os_nand_ops核心结构体 - 掌握坏块管理(Bad Block Management)的检测与标记
- 理解硬件 ECC 的配置与控制
- 掌握 Spare 区(OOB)的读写操作
一、概述
NAND 设备是 OneOS 提供的 NAND Flash 存储驱动框架,支持大容量 NAND Flash 芯片的页读写、块擦除、坏块管理、硬件 ECC 等功能。驱动源码位于 drivers/nand/ 目录下,核心头文件为 nand.h。
NAND 设备框架的特点:
- 三级寻址:页(Page)→ 块(Block)→ 区(Plane),支持大容量芯片
- 坏块管理:支持坏块检测(
os_nand_badflag_check)和坏块标记(os_nand_badflag_mark) - 硬件 ECC:支持硬件 ECC 的配置、使能和读取
- Spare 区读写:支持 NAND 特有的 Spare 区(OOB)读写
二、核心数据结构
2.1 NAND 地址结构体
typedef struct {
uint32_t page; /* 页地址 */
uint32_t plane; /* 区地址 */
uint32_t block; /* 块地址 */
} os_nand_addr_t;2.2 NAND 操作函数表 struct os_nand_ops
struct os_nand_ops
{
os_err_t (*read_page)(os_nand_device_t *nand, uint32_t page_addr, uint8_t *buff, uint32_t page_nr);
os_err_t (*write_page)(os_nand_device_t *nand, uint32_t page_addr, const uint8_t *buff, uint32_t page_nr);
os_err_t (*read_spare)(os_nand_device_t *nand, uint32_t page_addr, uint8_t *buff, uint32_t spare_nr);
os_err_t (*write_spare)(os_nand_device_t *nand, uint32_t page_addr, const uint8_t *buff, uint32_t spare_nr);
os_err_t (*erase_block)(os_nand_device_t *nand, uint32_t page_addr);
os_err_t (*config_hardecc)(os_nand_device_t *nand);
os_err_t (*control_hardecc)(os_nand_device_t *nand, os_bool_t enable);
os_err_t (*get_hardecc)(os_nand_device_t *nand, uint32_t *ecc_value);
os_err_t (*get_status)(os_nand_device_t *nand);
};2.3 NAND 设备结构体
struct os_nand_device
{
struct os_device parent;
struct os_nand_config cfg;
const struct os_nand_ops *ops;
uint8_t hardecc_flag;
uint8_t *page_buff;
uint8_t *spare_buff;
};三、关键 API
3.1 注册与页操作
os_err_t os_nand_device_register(os_nand_device_t *nand, const char *name, uint32_t id);
os_err_t os_nand_read_page(os_nand_device_t *nand, uint32_t page_addr, uint8_t *buff, uint32_t page_nr);
os_err_t os_nand_write_page(os_nand_device_t *nand, uint32_t page_addr, const uint8_t *buff, uint32_t page_nr);
os_err_t os_nand_erase_block(os_nand_device_t *nand, uint32_t block_no);3.2 坏块管理
os_err_t os_nand_badflag_check(os_nand_device_t *nand, uint32_t block_no);
os_err_t os_nand_badflag_mark(os_nand_device_t *nand, uint32_t block_no);3.3 Spare 区与高级读写
os_err_t os_nand_read_spare(os_nand_device_t *nand, uint32_t page_addr, uint8_t *buff, uint32_t spare_nr);
os_err_t os_nand_write_spare(os_nand_device_t *nand, uint32_t page_addr, const uint8_t *buff, uint32_t spare_nr);
os_err_t os_nand_read(os_nand_device_t *nand, uint32_t page_addr, uint8_t *buff, uint32_t buff_len, uint8_t *oob, uint32_t oob_len);
os_err_t os_nand_write(os_nand_device_t *nand, uint32_t page_addr, const uint8_t *buff, uint32_t buff_len, const uint8_t *oob, uint32_t oob_len);3.4 地址转换与芯片查询
void nand_page2addr(os_nand_device_t *nand, uint32_t page_addr, os_nand_addr_t *nand_addr);
uint32_t nand_addr2page(os_nand_device_t *nand, os_nand_addr_t *nand_addr);
const struct nand_device_info *get_nand_info_by_id(uint32_t id);四、使用示例
#include <nand.h>
void nand_badblock_demo(void)
{
os_device_t *dev = os_device_open("nand0");
os_nand_device_t *nand = (os_nand_device_t *)dev;
int block;
for (block = 0; block < 1024; block++)
{
if (os_nand_badflag_check(nand, block) != OS_SUCCESS) continue;
uint8_t buf[2048];
os_nand_read_page(nand, block * 64, buf, 1);
break;
}
}📝 本节小结
本节介绍了 NAND Flash 设备驱动,包括三级寻址、坏块管理、硬件 ECC、Spare 区读写等核心功能。