跳转至

通用 SPI 操作外部 Flash 示例*

提示

1. 概述*

本 app 使用驱动通用spi api来操作外部flash,通过测试用例的方式来介绍接口的使用方法,包括读/写/擦/写保护/otp操作。

2. 功能特性*

  • 可参考 app_init() 函数查看如何初始化spi
  • 可参考 flash_complete_test() 函数查看读写擦的调用
  • 可参考 flash_write_protect_test() 函数查看写保护的使用
  • 可参考 flash_otp_test() 函数查看如何操作otp区域的读写擦
  • 可调用 gx_genspi_for_flash_otp_lock() 锁定otp, 此区域之后将无法再进行读写擦操作

3. 目录结构*

app/general_spi_flash
├── app.c
├── app.mk
├── app.name
├── Kconfig
└── README.md
文件 作用
app.c 定义 OVP_APP 结构体,实现标准回调,调用 OVP_REGISTER_APP() 注册
app.mk 编译 app.c,由 CONFIG_GENERAL_SPI_FLASH 控制
app.name 定义 CONFIG_GENERAL_SPI_FLASH 选项,在 menuconfig 中显示 "General spi flash"
Kconfig 空框架,该 App 无额外配置项

4. 配置说明*

该 App 无额外的 Kconfig 子配置和宏定义。只需在 menuconfig 中选择 "General spi flash" 即可。

修改日志级别可调整 app.c 中的 LOG_LVL 宏:

#define LOG_LVL 3   // 0: 无日志, 1: ERROR, 2: WARN, 3: INFO, 4: DEBUG

5. 工作原理*

5.1 初始化流程*

app_init() 中设置spi模块频率,配置管脚复用,初始化spi设备

5.2 主循环*

app_task_loop() 中依次顺序进行测试调用。

6. 使用方法*

注意事项

并不是支持所有的 flash 型号,测试可使用型号 p25q80l 的 NOR Flash,若需支持其它型号可联系国芯微。

需要自行确定硬件连接正常,当前软件使用下面的硬件连接。

GPIO 功能
11 SPI2_CS
12 SPI2_CLK
13 SPI2_MOSI
14 SPI2_MISO

6.1 编译*

# 使用 hello_world 的配置
cp configs/example/app/8006_genspi_app.config .config
make defconfig
make clean; make

6.2 烧录运行*

cd tools/bootx/
./flash_nor.sh 0 -r 1000000

7. 预期输出*

串口0(921600 波特率)输出如下日志:

[APP_GENERAL_SPI_FLASH] [I]  ---- app_init, 776 ----
[APP_GENERAL_SPI_FLASH] [I] cpu freq = 172032000 Hz
[APP_GENERAL_SPI_FLASH] [I] spi freq = 172032000 Hz
spi_hw_init: freq_src=172032000, clk_div=4, speed_hz=43008000
NOR Flash, model: p25q80l, size: 1 MB
[APP_GENERAL_SPI_FLASH] [I] genspi flash init success
[APP_GENERAL_SPI_FLASH] [I] ========== [TEST] comtest start ==========
[APP_GENERAL_SPI_FLASH] [I] >>>>> sflash_test: addr=0x0, len=0x1
[APP_GENERAL_SPI_FLASH] [I] >>>>> sflash_test_success.
[APP_GENERAL_SPI_FLASH] [I] sample_delay best value: 6
[APP_GENERAL_SPI_FLASH] [I] ==============================
......
[APP_GENERAL_SPI_FLASH] [I] ========== [TEST] sample delay test PASS ==========
[APP_GENERAL_SPI_FLASH] [I] ========== [TEST] uid test start ==========
[APP_GENERAL_SPI_FLASH] [I] flash uid len:16, uid:
00000000: 42 50 31 32 35 36 34 0c 00 50 a9 26 56 04 e0 78 | BP12564..P.&V..x
[APP_GENERAL_SPI_FLASH] [I] ========== [TEST] uid test PASS ==========
[APP_GENERAL_SPI_FLASH] [I] ========================================
[APP_GENERAL_SPI_FLASH] [I]   All flash tests completed!
[APP_GENERAL_SPI_FLASH] [I]   Test results summary:
[APP_GENERAL_SPI_FLASH] [I]   --------------------  ------
[APP_GENERAL_SPI_FLASH] [I]   idle                : PASS
[APP_GENERAL_SPI_FLASH] [I]   init                : PASS
[APP_GENERAL_SPI_FLASH] [I]   comtest             : PASS
[APP_GENERAL_SPI_FLASH] [I]   write protect       : PASS
[APP_GENERAL_SPI_FLASH] [I]   otp                 : FAILED
[APP_GENERAL_SPI_FLASH] [I]   sample delay        : PASS
[APP_GENERAL_SPI_FLASH] [I]   uid                 : PASS
[APP_GENERAL_SPI_FLASH] [I]   --------------------  ------
[APP_GENERAL_SPI_FLASH] [I]   Final result        : FAILED
[APP_GENERAL_SPI_FLASH] [I] ========================================

8. 注意事项*

  1. 调用 gx_genspi_for_flash_init() 初始化 flash,speed 设置最好不要超过 43008000(cpu 频率的 ¼),避免 cpu 读取数据不及时
  2. 重点关注 comtest 可以正常读/写/擦操作
  3. otp 可使用 gx_genspi_for_flash_otp_lock() 上锁,但上锁后将无法再次进行读写擦,这可能时测试项失败的原因,属于正常现象。
  4. 写保护可指定从0地址到指定长度区域,但并不是所有长度均可以支持,可在设置后通过 gx_genspi_for_flash_write_protect_status() 获取实际的保护区域长度。