双 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=yRT-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 :一个设备 key,media 用
- 分区布局对比:
关键区别:双 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 升级
