Flash存储映射
GR533x封装了一个采用XQSPI总线接口的可擦除外部Flash存储器。该Flash物理上由若干个4 KB大小的Flash 扇区(Sector)组成;逻辑上可根据不同的应用场景,划分为不同用途的存储区域。
图 5为GR533x典型应用场景的Flash存储布局。
- System Configuration Area(SCA):系统配置区,主要用于存储系统启动参数等配置信息。
- User App:Application Firmware存储区域,主要用于存储应用固件 。
- Unused Space:空闲区域,开发者可以自行使用该区域。例如,在DFU升级过程中,使用Unused Space临时存储新的Application Firmware。
- Non-volatile Data Storage(NVDS):非易失性数据存储区域。
- NVDS缺省占用Flash最后两个Sector。开发者也可以根据产品的Flash存储布局,合理配置NVDS的起始地址与所占用的Flash Sector数,具体配置方法参考配置custom_config.h。
- NVDS起始地址需与Flash Sector 起始地址对齐。
SCA
系统配置区(SCA)占用Flash前两个Sector(共8 KB,0x0020_0000 ~ 0x0020_2000),其主要存储系统启动过程使用的标志以及其他系统配置参数。
下载固件时,下载算法或GProgrammer工具会根据Application Firmware中的BUILD_IN_APP_INFO结构体生成 Image Info,并将其与应用固件一并烧写至Flash中(Image Info被存放在SCA中)。系统启动时,Bootloader根据SCA中的启动信息进行校验,校验通过后再跳转至Firmware的入口地址。
BUILD_IN_APP_INFO结构体的定义和配置如下:
该结构体位于SDK_Folder\platform\soc\common\gr_platform.c,其中SDK_Folder为GR533x SDK包根目录。
const APP_INFO_t BUILD_IN_APP_INFO __attribute__((at(APP_INFO_ADDR))) = {
.app_pattern = APP_INFO_PATTERN_VALUE,
.app_info_version = APP_INFO_VERSION,
.chip_ver = CHIP_VER,
.load_addr = APP_CODE_LOAD_ADDR,
.run_addr = APP_CODE_RUN_ADDR,
.app_info_sum = CHECK_SUM,
.check_img = BOOT_CHECK_IMAGE,
.boot_delay = BOOT_LONG_TIME,
.sec_cfg = SECURITY_CFG_VAL,
#ifdef APP_INFO_COMMENTS
.comments = APP_INFO_COMMENTS,
#endif
};
- app_pattern:固定值0x47525858。
- app_info_version:固件信息版本,与APP_INFO_VERSION对应。
- chip_ver:固件对应的芯片版本,与custom_config.h中的CHIP_VER对应。
- load_addr:固件存储地址,与custom_config.h中的APP_CODE_LOAD_ADDR对应。
- run_addr:固件运行地址,与custom_config.h中的APP_CODE_RUN_ADDR对应。
- app_info_sum:固件信息的校验和,由软件自动计算CHECK_SUM。
- check_img:系统启动配置参数,与custom_config.h中的BOOT_CHECK_IMAGE对应。当此参数配置为1时,启动时Bootloader会对固件进行校验。
- boot_delay:启动配置参数,与custom_config.h中的BOOT_LONG_TIME对应。当此参数配置为1时,系统冷启动时将增加1秒延时。
- sec_cfg:安全配置参数,保留值。
- comments:固件描述信息,最大长度为12字节。
SCA的储存布局,如下图所示:
- Boot_Info与Boot_Info Backup存储相同信息,Boot_Info Backup为Boot_Info的备份。
- Boot_Info(32 B)区域中存储Firmware启动信息。系统启动时,Bootloader会根据启动信息进行校验,校验通过后跳转至Firmware的入口地址。
- Boot Config:系统启动配置信息。
- SPI Access Mode:SPI访问方式配置信息。系统固定配置,用户无法修改。
- Run Addr:Firmware运行地址,与BUILD_IN_APP_INFO中的run_addr对应。
- Load Addr:Firmware存储地址,与BUILD_IN_APP_INFO中的load_addr对应。
- CheckSum:Firmware校验和,生成Firmware后,由下载算法自动计算。
- APP Size:Firmware的Size信息,生成Firmware后,由下载算法自动计算。
- Img_Info区域可存储至多10个Firmware信息。当使用GProgrammer下载Firmware或使用DFU升级Firmware时,Firmware信息会被存储至Img_Info区域。
- Comments:Firmware描述信息,最大长度为12个字符。生成Firmware后,下载算法使用Firmware文件名作为Comments信息。
- Boot Info(24 B):Firmware启动信息,与Boot_Info(32 B)的低24 Bytes数据相同。
- Version:Firmware版本信息,与custom_config.h中VERSION对应。
- Pattern:固定值0x4744。
NVDS
非易失数据存储器(NVDS)是一个轻量级逻辑数据存储系统,依赖于Flash硬件抽象层(Flash HAL)。其存储于Flash中,掉电时数据不会丢失。NVDS默认占用Flash最后两个Sector,也可由开发者自行设定占用的Flash Sector数。在NVDS区域中,最后一个扇区用于碎片整理,其余扇区用于数据存储。
NVDS系统适合存储小块数据,例如应用程序的配置参数、校准数据、状态和用户信息等。Bluetooth LE协议栈也会使用NVDS存储设备绑定等参数。
NVDS系统具有以下特性:
- 每个存储项(TAG)都具有唯一标识TAG ID。用户程序可以根据TAG ID对数据内容进行读取和更改操作,而无需关心数据存储的物理地址。
- 针对Flash存储介质的特性进行了优化,支持数据校验、Word对齐、碎片整理和擦写平衡。
- 存储区域的大小和起始地址可配置。NVDS存储区域可配置为若干个Flash Sector;配置的起始地址需按4 KB对齐。
- 开发者可在custom_config.h文件中添加宏NVDS_START_ADDR和更改宏NVDS_NUM_SECTOR,配置NVDS区域的起始地址和占用大小。其中,NVDS_NUM_SECTOR缺省值为1,在NVDS初始化时该值将自动加1 ,即NVDS占用两个Flash Sector。
- Bluetooth LE协议栈与Application共享相同的NVDS存储区域,但TAG ID命名空间被划分为不同类别,开发者只能使用分配给Application的TAG ID命名类别。
- Application必须使用NV_TAG_APP(idx)获取应用程序数据的TAG ID。该TAG ID被用作NVDS API的参数。
- Application不能将idx直接作为NVDS API的参数。idx取值范围为0x4000 ~ 0x7FFF。
-
在Application第一次运行前,开发者可使用工具GProgrammar将Bluetooth LE协议栈和Application所使用的TAG ID初始值写入到NVDS。
- 若开发者不使用GR533x SDK缺省的NVDS区域,而需自行指定NVDS区域,则必须确保GProgrammar中配置的NVDS起始地址配置按4 KB对齐。
NVDS存储数据的格式如下所示:
数据头(Data Header)格式如下表所示。
字节 | 名称 | 描述 |
---|---|---|
0-1 | tag | 数据tag标识 |
2-3 | len | 数据长度 |
4-4 | checksum | 数据头的校验和 |
5-5 | value_cs | 数据的校验和 |
6-7 | reserved | 保留字段 |
GR533x SDK提供了下列NVDS API,可方便开发者操作Flash中的非易失性数据。
函数原型 | 描述 |
---|---|
uint8_t nvds_init(uint32_t start_addr, uint8_t sectors) |
初始化NVDS使用的Flash Sector。 |
uint8_t nvds_get(NvdsTag_t tag, uint16_t *p_len, uint8_t *p_buf) |
从NVDS中读取tag标识对应的数据。 |
uint8_t nvds_put(NvdsTag_t tag, uint16_t len, const uint8_t *p_buf) |
将数据写入到NVDS并使用tag标识。 若为首次写数据,则需创建一个tag 标识。 |
uint8_t nvds_del(NvdsTag_t tag) |
删除NVDS中tag标识对应的数据。 |
uint16_t nvds_tag_length(NvdsTag_t tag) |
获取指定tag标识的数据长度。 |
uint8_t nvds_drv_func_replace(nvds_drv_func_t *p_nvds_drv_func) | 替代直接操作Flash的相关API。 |
uint8_t nvds_func_replace(nvds_func_t *p_nvds_func) | 替代NVDS操作相关API。 |
void nvds_retention_size(uint8_t bond_dev_num) | 为设备绑定信息预留空间,且空间大小由设备绑定数决定。 |
关于NVDS API的详细说明,可参考NVDS头文件SDK_Folder\components\sdk\gr533x_nvds.h。