Edit online

双 Flash 配置方法

本节介绍双 Flash 方案的配置步骤,包括 Bootloader,RT-Thread,Pinmux 和分区表配置。

Bootloader 配置(bm 命令)

在 bootloader 源码目录下执行 bm 命令进入 menuconfig,打开对应外接 Flash 的 SPI 控制器(QSPI0 和 QSPI2),如下示意图所示:

bm
 │
 └─> Board options
      │
      ├─> Storage Related
      │    │
      │    ├── [*] Using SPI0  ─────────────────────── AIC_USING_QSPI0
      │    │    └─> SPI0 Parameter
      │    │         ├─ (100000000) Max frequency(Hz)
      │    │         └─ Set SPI0 bus width ─> (X) Quad
      │    │
      │    └── [*] Using SPI2  ─────────────────────── AIC_USING_QSPI2
      │         └─> SPI2 Parameter
      │              ├─ (100000000) Max frequency(Hz)
      │              └─ Set SPI2 bus width ─> (X) Quad
      │
      └─> Mem Options
           └─> Support another Flash
                ├─ Number of Flash ──────> (X) support 2 flashes
                └─ Seconed Flash type ───> (X) norflash

对应的 defconfig 配置项:


CONFIG_AIC_USING_QSPI2=y
CONFIG_AIC_QSPI2_BUS_WIDTH_4=y
CONFIG_AIC_QSPI0_DEVICE_SPINOR=y
CONFIG_AIC_QSPI2_DEVICE_SPINOR=y
CONFIG_AIC_FLASH_NUM_TWO=y

RT-Thread 配置(me 命令)

在 RT-Thread 源码目录下执行 me 命令进入 menuconfig ,打开对应外接 Flash 的 SPI 控制器(QSPI0 和 QSPI2),如下示意图所示:


me
 │
 └─> Board options
      │
      ├─> Storage Related
      │    │
      │    ├── [*] Using SPI0  ─────────────────────── AIC_USING_QSPI0
      │    │    └─> SPI0 Parameter
      │    │         ├─ (100000000) Max frequency(Hz)
      │    │         └─ Set SPI0 bus width ─> (X) Quad
      │    │
      │    └── [*] Using SPI2  ─────────────────────── AIC_USING_QSPI2
      │         └─> SPI2 Parameter
      │              ├─ (100000000) Max frequency(Hz)
      │              └─ Set SPI2 bus width ─> (X) Quad
      │
      └─> Mem Options
           └─> Support another Flash
                ├─ Number of Flash ──────> (X) support 2 flashes
                └─ Seconed Flash type ───> (X) norflash

此外还需配置 FAL 第二片 Flash 的设备名称:


me
 └─> RT-Thread Components
      └─> Device virtual file system
           └─> FAL: Flash Abstraction Layer
                └─ (norflash2) The name of the device1 used by FAL

对应的 defconfig 配置项:

CONFIG_AIC_USING_QSPI0=y
CONFIG_AIC_USING_QSPI2=y
CONFIG_AIC_QSPI2_BUS_WIDTH_4=y
CONFIG_AIC_QSPI0_DEVICE_SPINOR=y
CONFIG_AIC_QSPI2_DEVICE_SPINOR=y
CONFIG_AIC_FLASH_NUM_TWO=y
CONFIG_FAL_USING_NOR_FLASH_DEV_NAME1="norflash2"

Pinmux 配置

pinmux.c中配置对应的 SPI 控制器 IO 引脚(QSPI0 和 QSPI2),如下示意图所示:

                        
D13X 芯片
        +------------------------------------------+
        |                                           |
        |   QSPI0 (SPI Controller 0)                |
        |     PB.0 ─── CLK ────────────────>        |
        |     PB.1 ─── CS  ────────────────>  SPI NOR Flash 0
        |     PB.2 ─── D0 (MOSI) ──────────>  (16 MB)
        |     PB.3 ─── D1 (MISO) ──────────>        |
        |     PB.4 ─── D2 (WP) ────────────>        |
        |     PB.5 ─── D3 (HOLD) ──────────>        |
        |                                           |
        |   QSPI2 (SPI Controller 2)                |
        |     PB.6 ─── CLK ────────────────>        |
        |     PB.7 ─── CS  ────────────────>  SPI NOR Flash 1
        |     PB.8 ─── D0 (MOSI) ──────────>  (16 MB)
        |     PB.9 ─── D1 (MISO) ──────────>        |
        |     PB.10 ── D2 (WP) ────────────>        |
        |     PB.11 ── D3 (HOLD) ──────────>        |
        |                                           |
        +------------------------------------------+

Pinmux 代码定义:


/* QSPI0 - PB.0 ~ PB.5 */
#ifdef AIC_USING_QSPI0
    {2, PIN_PULL_UP, 3, "PB.0"},   // CLK,  Function 2
    {2, PIN_PULL_UP, 3, "PB.1"},   // CS,   Function 2
    {2, PIN_PULL_UP, 3, "PB.2"},   // D0,   Function 2
    {2, PIN_PULL_UP, 3, "PB.3"},   // D1,   Function 2
    {2, PIN_PULL_UP, 3, "PB.4"},   // D2,   Function 2
    {2, PIN_PULL_UP, 3, "PB.5"},   // D3,   Function 2
#endif

/* QSPI2 - PB.6 ~ PB.11 */
#ifdef AIC_USING_QSPI2
    {3, PIN_PULL_UP, 7, "PB.6"},   // CLK,  Function 3
    {3, PIN_PULL_UP, 7, "PB.7"},   // CS,   Function 3
    {3, PIN_PULL_UP, 7, "PB.8"},   // D0,   Function 3
    {3, PIN_PULL_UP, 7, "PB.9"},   // D1,   Function 3
    {3, PIN_PULL_UP, 7, "PB.10"},  // D2,   Function 3
    {3, PIN_PULL_UP, 7, "PB.11"},  // D3,   Function 3
#endif

引脚功能对应表:

SPI 控制器 引脚 功能 Pinmux Function
QSPI0 PB.0 CLK 2
QSPI0 PB.1 CS 2
QSPI0 PB.2 D0 (MOSI) 2
QSPI0 PB.3 D1 (MISO) 2
QSPI0 PB.4 D2 (WP) 2
QSPI0 PB.5 D3 (HOLD) 2
QSPI2 PB.6 CLK 3
QSPI2 PB.7 CS 3
QSPI2 PB.8 D0 (MOSI) 3
QSPI2 PB.9 D1 (MISO) 3
QSPI2 PB.10 D2 (WP) 3
QSPI2 PB.11 D3 (HOLD) 3
注:
QSPI2(PB.6 ~ PB.11)与 SDMC0 复用同一组引脚,所以不能同时使用。demo68-nor 使用 SDMC1 而非 SDMC0,因此 QSPI2 可以正常使用。

分区表配置

image_cfg.json 是双 Flash 分区表的核心配置文件,与单 Flash 分区表相比,区别如下:

  • 结构对比:
    • 单 Flash :一个设备 key,media 用 type + device_id
      image_cfg.json (单 Flash)
      │
      ├── "spi-nor": {              <── 只有 1 个设备
      │       "size": "16m",
      │       "partitions": {
      │           spl, env, env_r,
      │           os, rodata, data   <── 所有分区放在同一片 Flash
      │       }
      │   }
      │
      └── "media": {
              "type": "spi-nor",     <── 字符串,单一类型
              "device_id": 0         <── 整数,单一控制器
          }
      
    • 双 Flash : 两个设备 key,media 用 name[] + controller[]
      image_cfg.json (双 Flash)
      │
      ├── "spi-nor0": {              <── 设备 0: QSPI0
      │       "type": "spi-nor",
      │       "size": "16m",
      │       "partitions": {
      │           spl, env, env_r,
      │           os, os_r           <── 系统分区
      │       }
      │   }
      │
      ├── "spi-nor1": {              <── 设备 1: QSPI2
      │       "type": "spi-nor",
      │       "size": "16m",
      │       "partitions": {
      │           extra, rodata,
      │           rodata_r,
      │           data, data_r       <── 数据分区
      │       }
      │   }
      │
      └── "media": {
              "name": ["spi-nor0",   <── 数组,按索引对应
                       "spi-nor1"],
              "controller": [0, 2]   <── 数组,QSPI0 和 QSPI2
          }
      
  • 分区布局对比:

    关键区别:双 Flash 方案将系统关键分区(spl、env、os)放在 QSPI0 挂载的 Flash 上,将数据分区(rodata、data、extra)放在 QSPI2 挂载的 Flash 上,系统分区和数据分区均支持 A/B 双备份机制,便于 OTA 升级回滚。

    
    单 Flash:              				双 Flash:
                                        
     QSPI0 (16MB)                       QSPI0 (16MB)          QSPI2 (16MB)
    +----------------+ 0x000000        +----------------+     +----------------+
    |      spl       |  512K           |      spl       |     |     extra      |
    +----------------+                 +----------------+     +----------------+
    |      env       |  128K           |      env       |     |    rodata      |
    +----------------+                 +----------------+     +----------------+
    |     env_r      |  128K           |     env_r      |     |   rodata_r     |
    +----------------+                 +----------------+     +----------------+
    |       os       |  2M             |       os       |     |     data       |
    +----------------+                 +----------------+     +----------------+
    |     rodata     |  12M            |      os_r      |     |    data_r      |
    +----------------+                 +----------------+     +----------------+
    |      data      |  1M             |    (剩余)       |     |    (剩余)      |
    +----------------+                 +----------------+     +----------------+
      所有分区挤在一片上                系统分区独立          数据分区独立
                                      支持 A/B 升级         支持 A/B 升级