Baremetal 设计说明
27 Nov 2024
Read time: 5 minute(s)
Baremetal 源码说明
相关模块 | 源码路径 |
---|---|
Application | bsp/examples_bare/mtd.c 用户可以参考此文件进行测试开发。 |
mtd | bsp/artinchip/drv_bare/mtd/ |
spinand |
bsp/peripheral/spinand
bsp/artinchip/drv_bare/spinand/spinand_port.c
bsp/artinchip/drv_bare/spinand/spinand_mtd.c
|
qspi | bsp/artinchip/hal/qspi/hal_qspi.c |
其它重要文件 | bsp/examples_bare/test-spinand/spinand.c |
Baremetal 层次关系
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 应用接口设计
函数原型 | int mtd_probe(void); |
功能说明 | 初始化所有 mtd 设备 |
返回值 |
0: 成功
其他: 失败
|
注意事项 | 只有初始化 mtd 设备之后, 才能正常使用其它函数 |
函数原型 | int mtd_add_device(struct mtd_dev *mtd); |
功能说明 | 增加 mtd 设备 |
参数定义 |
struct mtd_dev *mtd
mtd 设备对象
|
返回值 |
0: 成功
其他: 失败
|
注意事项 | - |
函数原型 | u32 mtd_get_device_count(void); |
功能说明 | 获取注册的 mtd 设备个数 |
返回值 |
注册的 mtd 设备个数
|
注意事项 | - |
函数原型 | struct mtd_dev *mtd_get_device_by_id(u32 id); |
功能说明 | 通过索引号获取 mtd 设备句柄 |
返回值 |
mtd 设备句柄
为空:失败
|
注意事项 | - |
函数原型 | struct mtd_dev *mtd_get_device(const char *name); |
功能说明 | 通过分区名获取 mtd 设备句柄 |
参数定义 |
char *name
mtd 分区名
|
返回值 |
mtd 设备句柄
为空:失败
|
注意事项 | - |
函数原型 | 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 对齐,在读取数据的过程中,如果遇到了坏块,会自动寻找下一个好块,继续读取数据 |
函数原型 | int mtd_erase(struct mtd_dev *mtd, u32 offset, u32 len); |
功能说明 | 擦除 mtd 分区某块区域的数据 |
参数定义 |
struct mtd_dev *mtd
mtd 分区设备句柄
u32 offset
偏移值
u32 len
擦除数据长度
|
返回值 |
0: 成功
其他: 失败
|
注意事项 | offset 必须与 block 对齐 |
函数原型 | 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 对齐,在写入数据的过程中,如果遇到了坏块,会自动寻找下一个好块,继续写入数据 |
函数原型 | int mtd_block_isbad(struct mtd_dev *mtd, u32 offset); |
功能说明 | 判断指定的块是否是坏块 |
参数定义 |
struct mtd_dev *mtd
mtd 分区设备句柄
u32 offset
偏移值
|
返回值 |
1: 坏块
0: 正常块
其他: 失败
|
注意事项 | offset 必须与 block 大小对齐 |
函数原型 | int mtd_block_markbad(struct mtd_dev *mtd, u32 offset); |
功能说明 | 标记指定的块为坏块 |
参数定义 |
struct mtd_dev *mtd
mtd 分区设备句柄
u32 offset
偏移值
|
返回值 |
0: 成功
其他: 失败
|
注意事项 | offset 必须与 block 大小对齐 |
函数原型 | 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 对齐 |