5.4.5. 设计说明

5.4.5.1. Baremetal 源码说明

相关模块

源码路径

Application

bsp/examples_bare/mtd.c

mtd

bsp/artinchip/drv_bare/mtd/

SFUD

bsp/peripheral/spinor_sfud
bsp/artinchip/drv_bare/spinor/sfud_port.c

qspi

bsp/artinchip/hal/qspi/hal_qspi.c

注解

客户可以参考 bsp/examples_bare/mtd.c , bsp/examples_bare/test-spinor/spinor.c进行测试开发

5.4.5.2. Baremetal 层次关系

../../../_images/bar_spinor.png

注解

客户开发项目,在 MTD 层上开发, SFUD 层上开发因为地址设置不当可能会破坏 spl、os 分区的数据。

5.4.5.3. Baremetal 关键流程

5.4.5.3.1. SPI NOR 初始化流程

mtd_probe //bsp/artinchip/drv_bare/mtd/mtd_probe.c
|-> sfud_probe(AIC_BOOTLOADER_SPINOR_QSPI_ID); //bsp/artinchip/drv_bare/spinor/sfud_port.c
    |-> get_qspi_by_index(spi_bus);   //获取aic_qspi_bus对象
    |-> hal_qspi_master_init(&qspi->handle, &cfg);  //初始化qspi配置
    |-> hal_qspi_master_dma_config(&qspi->handle, &dmacfg); //初始化DMA
    |-> hal_qspi_master_set_bus_freq(&qspi->handle, qspi->bus_hz);  //配置时钟
    |-> sfud_device_init(&qspi->attached_flash);  //bsp/peripheral/spinor_sfud/src/sfud.c
        |-> hardware_init(flash);
        |-> sfud_spi_port_init(flash); //bsp/artinchip/drv_bare/spinor/sfud_port.c
            |-> flash->spi.wr = spi_write_read; //提供读写接口
            |-> flash->spi.qspi_read = (void *)qspi_read; //提供快速读取接口
        |-> read_jedec_id(flash); //读取设备id
        |-> sfud_read_sfdp(flash);  //自动识别SPI NOR
    |-> sfud_qspi_fast_read_enable(&qspi->attached_flash, 4); //使能快速读取模式
    |-> part = mtd_parts_parse(NOR_MTD_PARTS); //解析分区信息
    |-> mtd->ops.erase = sfud_mtd_erase;
    |-> mtd->ops.read = sfud_mtd_read;
    |-> mtd->ops.write = sfud_mtd_write;
    |-> mtd_add_device(mtd);  //添加mtd分区

5.4.5.3.2. SPI NOR 读数据流程

mtd_read //bsp/artinchip/drv_bare/mtd/mtdcore.c
  |-> sfud_mtd_read(); //bsp/artinchip/drv_bare/spinor/sfud_port.c
      |-> sfud_read(flash, start, dolen, data); //bsp/peripheral/spinor_sfud/src/sfud.c
          |-> sfud_read_data(flash, addr, dolen, p);
              |-> qspi_read(); //bsp/artinchip/drv_bare/spinor/sfud_port.c

5.4.5.4. Baremetal 应用接口设计

5.4.5.4.1. mtd_probe

函数原型

int mtd_probe(void);

功能说明

初始化所有mtd设备

返回值

0: 成功
其他: 失败

注意事项

只有初始化mtd设备之后, 才能正常使用其它函数

5.4.5.4.2. mtd_add_device

函数原型

int mtd_add_device(struct mtd_dev *mtd);

功能说明

增加mtd设备

参数定义

struct mtd_dev *mtd
mtd 设备对象

返回值

0: 成功
其他: 失败

注意事项

5.4.5.4.3. mtd_get_device_count

函数原型

u32 mtd_get_device_count(void);

功能说明

获取注册的mtd设备个数

返回值

注册的mtd设备个数

注意事项

5.4.5.4.4. mtd_get_device_by_id

函数原型

struct mtd_dev *mtd_get_device_by_id(u32 id);

功能说明

通过索引号获取mtd设备句柄

返回值

mtd设备句柄
为空:失败

注意事项

5.4.5.4.5. mtd_get_device

函数原型

struct mtd_dev *mtd_get_device(const char *name);

功能说明

通过分区名获取mtd设备句柄

参数定义

char *name
mtd 分区名

返回值

mtd设备句柄
为空:失败

注意事项

5.4.5.4.6. 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 对齐

5.4.5.4.7. 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 对齐

5.4.5.4.8. 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 对齐

5.4.5.5. RTOS 源码说明

相关模块

源码路径

mtd

kernel/rt-thread/components/drivers/mtd/mtd_nor.c

spinand

bsp/peripheral/spinor_sfud
bsp/artinchip/drv/spinor/spinor_sfud.c

qspi

bsp/artinchip/drv/qspi/drv_qspi.c

5.4.5.6. RTOS 层次关系

../../../_images/rtt_spinor.png

图 5.34 SPI NOR 驱动框架

注解

mtd 设备用来挂载 Littlefs 文件系统,blk 设备用来挂载 FatFS 文件系统。

5.4.5.7. RTOS 关键流程

5.4.5.7.1. SPI NOR 初始化流程

rt_hw_spi_flash_with_sfud_init //bsp/artinchip/drv/spinor/spinor_sfud.c
|-> aic_qspi_bus_attach_device("qspi0", SPI_FLASH_DEVICE_NAME, 0, 4, RT_NULL, RT_NULL);//创建 qspi 总线
|-> rt_sfud_flash_probe(USING_NOR_FLASH_DEV_NAME,SPI_FLASH_DEVICE_NAME) //kernel/rt-thread/components/drivers/spi/spi_flash_sfud.c
    |-> rt_sfud_flash_probe_ex(spi_flash_dev_name, spi_dev_name, &cfg, RT_NULL);
        |-> rt_qspi_configure(qspi_dev, qspi_cfg);
        |-> sfud_device_init(sfud_dev)
            |-> hardware_init(flash);
            |-> sfud_spi_port_init(flash); ////kernel/rt-thread/components/drivers/spi/spi_flash_sfud.c
            |-> flash->spi.wr = spi_write_read; //提供读写接口
            |-> flash->spi.qspi_read = (void *)qspi_read; //提供快速读取接口
          |-> read_jedec_id(flash); //读取设备id
          |-> sfud_read_sfdp(flash);  //自动识别SPI NOR
        |-> sfud_qspi_fast_read_enable(sfud_dev, qspi_dev->config.qspi_dl_width);
        |->  rt_device_register(&(rtt_dev->flash_device), spi_flash_dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);