Edit online

Baremetal 设计说明

Baremetal 源码说明

1. Baremetal 源码说明
相关模块 源码路径
Application bsp/examples_bare/mtd.c
mtd bsp/artinchip/drv_bare/mtd/
spinand bsp/peripheral/spinandbsp/artinchip/drv_bare/spinand/spinand_port.cbsp/artinchip/drv_bare/spinand/spinand_mtd.c
qspi bsp/artinchip/hal/qspi/hal_qspi.c

用户可以参考 bsp/examples_bare/mtd.c 进行测试开发

其它重要文件 bsp/examples_bare/test-spinand/spinand.c

Baremetal 层次关系

Baremetal 层次关系如下所示:
../images/bar_spinand.png
1. Baremetal 层次关系

用户开发项目,在 MTD 层上开发, SPINAND 层上开发可能会破坏 spl、os 分区的数据。

Baremetal 关键流程

  • SPI NAND 初始化流程
    mtd_probe //bsp/artinchip/drv_bare/mtd/mtd_probe.c
    |-> spinand_probe(AIC_BOOTLOADER_SPINAND_QSPI_ID); //bsp/artinchip/drv_bare/spinand/spinand_mtd.c
        |-> get_qspi_by_index(spi_bus);   // 获取 bus 对象
        |-> qspi_configure(qspi, NULL);  //bsp/artinchip/drv_bare/spinand/spinand_port.c
            |-> hal_qspi_master_init(&qspi->handle, &cfg);
            |-> hal_qspi_master_dma_config(&qspi->handle, &dmacfg);
            |-> hal_qspi_master_set_bus_freq(&qspi->handle, qspi->bus_hz);
        |-> spinand_flash_init(flash);  //bsp/peripheral/spinand/spinand.c
            |-> spinand_info_read(flash);
            |-> nand_bbt_init(flash);
        |-> part = mtd_parts_parse(NOR_MTD_PARTS); //解析分区信息
        |-> mtd->ops.erase = sfud_mtd_erase;
        |-> mtd->ops.erase = mtd_spinand_erase;
        |-> mtd->ops.block_isbad = mtd_spinand_block_isbad;
        |-> mtd->ops.block_markbad = mtd_spinand_block_markbad;
        |-> mtd->ops.read = mtd_spinand_read;
        |-> mtd->ops.write = mtd_spinand_write;
        |-> mtd->ops.read_oob = mtd_spinand_read_oob;
        |-> mtd->ops.write_oob = mtd_spinand_write_oob;
        |-> mtd->ops.cont_read = mtd_spinand_continuous_read;
        |-> mtd_add_device(mtd);  //添加 mtd 分区
  • SPI NAND 读数据流程
    mtd_read //bsp/artinchip/drv_bare/mtd/mtdcore.c
    |-> mtd_spinand_read(struct mtd_dev *mtd, u32 offset, u8 *data, u32 len); //bsp/artinchip/drv_bare/spinand/spinand_mtd.c
        |-> spinand_read(flash, data, start, dolen); //bsp/peripheral/spinand/spinand.c
            |-> spinand_block_isbad(flash, blk);
            |-> spinand_read_page(flash, page, p, flash->info->page_size, NULL, 0);
                |-> spinand_load_page_op(flash, page);
                |-> spinand_read_from_cache_op(flash, column, buf, nbytes);

Baremetal 应用接口设计

2. mtd_probe
函数原型 int mtd_probe(void);
功能说明 初始化所有 mtd 设备
返回值 0: 成功;其他: 失败
注意事项 只有初始化 mtd 设备之后, 才能正常使用其它函数
3. mtd_add_device
函数原型 int mtd_add_device(struct mtd_dev *mtd);
功能说明 增加 mtd 设备
参数定义 struct mtd_dev *mtdmtd 设备对象
返回值 0: 成功;其他: 失败
注意事项 -
4. mtd_get_device_count
函数原型 u32 mtd_get_device_count(void);
功能说明 获取注册的 mtd 设备个数
返回值 注册的 mtd 设备个数
注意事项 -
5. mtd_get_device_by_id
函数原型 struct mtd_dev *mtd_get_device_by_id(u32 id);
功能说明 通过索引号获取 mtd 设备句柄
返回值 mtd 设备句柄为空:失败
注意事项 -
6. mtd_get_device
函数原型 struct mtd_dev *mtd_get_device(const char *name);
功能说明 通过分区名获取 mtd 设备句柄
参数定义 char *namemtd 分区名
返回值 mtd 设备句柄为空:失败
注意事项 -
7. mtd_read
函数原型 int mtd_read(struct mtd_dev *mtd, u32 offset, u8 *data, u32 len);
功能说明 读取 mtd 分区数据到缓冲区上
参数定义

struct mtd_dev *mtd:mtd 分区设备句柄;

u32 offset:偏移值;

u8 *data:接收数据缓冲区

u32 len:接收数据长度

返回值 0: 成功;其他: 失败
注意事项 offset 与 page 对齐,在读取数据的过程中,如果遇到了坏块,会自动寻找下一个好块,继续读取数据
8. mtd_erase
函数原型 int mtd_erase(struct mtd_dev *mtd, u32 offset, u32 len);
功能说明 擦除 mtd 分区某块区域的数据
参数定义 struct mtd_dev *mtd:mtd 分区设备句柄;u32 offset:偏移值;u32 len:擦除数据长度
返回值 0: 成功;其他: 失败
注意事项 offset 必须与 block 对齐
9. mtd_write
函数原型 int mtd_write(struct mtd_dev *mtd, u32 offset, u8 *data, u32 len);
功能说明 写入缓冲区上的数据到 mtd 分区上
参数定义

struct mtd_dev *mtd:mtd 分区设备句柄;

u32 offset:偏移值;u8 *data 发送缓冲区地址

u32 len:擦除数据的长度

返回值 0: 成功;其他: 失败
注意事项 offset 与 page 对齐,在写入数据的过程中,如果遇到了坏块,会自动寻找下一个好块,继续写入数据
10. mtd_block_isbad
函数原型 int mtd_block_isbad(struct mtd_dev *mtd, u32 offset);
功能说明 判断指定的块是否是坏块
参数定义 struct mtd_dev *mtd:mtd 分区设备句柄;

u32 offset:偏移值;

返回值 1: 坏块 0: 正常块其他: 失败
注意事项 offset 必须与 block 大小对齐
11. mtd_block_markbad
函数原型 int mtd_block_markbad(struct mtd_dev *mtd, u32 offset);
功能说明 标记指定的块为坏块
参数定义

struct mtd_dev *mtd:mtd 分区设备句柄;

u32 offset:偏移值;

返回值 0: 成功

其他: 失败

注意事项 offset 必须与 block 大小对齐
12. mtd_contread
函数原型 int mtd_contread(struct mtd_dev *mtd, u32 offset, uint8_t *data, u32 len);
功能说明 使用连续读取模式读取 mtd 分区数据到缓冲区上
参数定义 struct mtd_dev *mtd:mtd 分区设备句柄;

u32 offset:偏移值;

u8 *data:接收数据缓冲区

u32 len:接收数据长度

返回值 0: 成功

其他: 失败

注意事项 芯片必须支持连续读取模式, offset 大小与 page 对齐