【ChipIntelli 系列】认识 Flash 分区表、实战自定义用户数据管理(NV DATA)、音频分区(voice.bin) & 计算可用音频空间
一、名词解释
打开烧录软件,可以看到下面的固件分区表:

图 ChipIntelli PC串口打包升级工具(PACK_UPDATE_TOOL.exe)的打包界面,
可供用户选择打包的文件,配置各分区预留大小等信息;打包固件时会将信息写到分区表中
先解释几个名词:
- 分区:多个bin文件位于固件中的区域名为【xxx分区】。用户可自定义的分区有 User、ASR、DNN、Voice、UserFile、NV data 6个分区,其他为固定分区。
- 固件:将多个bin文件打包生成的 Firmware_V2.0.0.bin文件,称为【固件】;该bin文件可被烧录到FLASH中,最终被引导程序和应用程序读取使用。
- 应用程序(User分区):编译软件生成的user_code.bin文件,也就是User 分区。
- 固件版本:为了兼顾不同的应用场景,有多种不同格式的固件,例如FW_V1、FW_V2、FW_V3这3种,将来可能会增加版本。
- 分区表:包含固件各个组成部分的地址、大小、版本号等。
- 引导程序:芯片上电后,先读取 FLASH 首地址存放发引导程序并跳转运行,再去指定地址读取分区表,解析分区表得到应用程序地址等信息,再将应用程序拷贝到SRAM运行。以下简称bootloader。
-
各分区分别存放的内容分别为:
| 序号 | 分区名 | 存放内容 |
|---|---|---|
| 1 | User分区 | 存放编译软件生成的,应用程序user_code.bin |
| 2 | ASR分区 | 存放语音识别需要的,语言模型文件集合asr.bin |
| 3 | DNN分区 | 存放语音识别需要的,声学模型文件集合dnn.bin |
| 4 | Voice分区 | 存放语音识别播放提示音需要的,音频文件集合voice.bin |
| 5 | UserFile分区 | 存放命令词信息表等文件集合 user_file.bin |
| 6 | NV data分区 | 存放用户自定义数据,由应用程序初始化和增删改 |
名词详细解释
1、固件(Firmware)¶
-
固件通常命名为Firmware_V2.0.0.bin,Firmware为软件名称,V2.0.0为软件版本。
2、引导程序(Bootloader)¶
-
PC串口打包升级工具(PACK_UPDATE_TOOL.exe)内集成了各个系列芯片的引导程序,即bootloader.bin,打包固件时,会自动把bootloader.bin填充到固件的0地址。
-
每个系列都有1个单独的bootloader.bin,一般同1个系列的所有芯片型号共用1个bootloader.bin。
-
为兼顾不同固件版本,同1个系列也会使用不同bootloader.bin,由升级工具配置选择。
3、固件版本¶
-
现目前支持3种固件版本:FW_V1、FW_V2、FW_V3。可通过PC串口打包升级工具(PACK_UPDATE_TOOL.exe)配置文件选配,打包哪种版本的固件。
-
FW_V1:对应ota V2 方案,使用具备ota 功能的bootloader_a.bin(定义为BOOTloaderA) ,user code分区无备份,wifi ota 时下载BOOTloaderA 到sram 进行升级,wifi管理每个分区的升级逻辑。
- FW_V2:无ota 功能的通用方案;bootloader_b.bin只做引导【定义为BOOTloaderB】,无其他功能;固件分区无备份。
-
FW_V3:对应ota V3 方案,使用只做引导的的BOOTloaderB ,user code分区有备份,wifi ota时,wifi主要透传和管理版本,ota v3方案的代码进行ota升级
-
即FW_V3和FW_V1分区格式一样,只是使用不同的bootloader.bin
- FW_V1和FW_V2,不仅分区格式不同,还使用不同的bootloader.bin
虽然固件版本有3种,但最根本的分区格式只有2种,分区格式1和分区格式2, 格式1是FW_V1、FW_V3等有OTA分区的; 格式2是FW_V2无OTA分区的。
二、📊 CI1306 Flash 分区示例
| 分区名称 | 起始地址 | 预留大小 | 文件路径 | 对应文件 | 说明 |
|---|---|---|---|---|---|
| ASR (用户代码) | 0x4000 |
0x3F000 (252KB) |
./user_code/user_code.bin |
用户应用程序 | 存放用户编写的核心程序代码。 |
| ASR (算法模型) | 0x43000 |
0x2000 (8KB) |
./asr/asr.bin |
语音识别模型 | 存放语音识别(ASR)的算法模型文件。 |
| DNN | 0x45000 |
0x170000 (1.44MB) |
./dnn/dnn.bin |
神经网络模型 | 存放深度神经网络模型,用于更复杂的语音处理。 |
| Voice | 0x1B5000 |
0x190000 (1.56MB) |
./voice/voice.bin |
语音提示音资源 | 存放设备的提示音、应答音等音频资源文件。 |
| UserFile | 0x1CE000 |
0x1000 (4KB) |
./user_file/user_file.bin |
用户配置文件 | 存放用户自定义的配置参数。 |
| ConsumerData (NV) | 0x3FC000 |
0x4000 (16KB) |
无需外部文件 | 非易失性数据 | 存储掉电需要保存的数据,如设备配置、历史记录等。 |
地址与大小说明:
-
地址采用十六进制(
0x开头),大小为十进制。 -
从起始地址
0x4000(即16KB)开始,意味着前16KB(0x0-0x3FFF)可能预留给Bootloader 或系统使用,这在嵌入式芯片中很常见。 -
各分区地址连续,末尾的
ConsumerData分区位于4MB Flash的最高地址区域。
💡 关于分区的几个关键点
-
分区非固定:这是一个具体应用的分区方案,并非芯片出厂固定。你可以使用官方工具“自动分配”或手动调整起始地址和大小来满足自己项目的需求。
-
Bootloader位置:如上所述,分区表未显示的前16KB极有可能是Bootloader区域,负责芯片上电启动和固件升级(OTA)。
三、实战用户数据管理(NV DATA)
1. 概述¶
NV(non-volatile)data 管理模块是用于数据保存到 flash 器件,其特性包括:
- 接口包含初始化、读数据、写数据、删除数据、注册hotid;
- 对意外掉电进行数据恢复,可以使用上次的数据;
- 能够支持数据块独立保存,并且每个数据块大小可自定义,使用ID(32bit数据)的方式区分数据块;
- 方便移植,将RTOS和flash相关操作的函数独立在单独文件内;
- 使用hotid(频繁操作的ID)功能,在节约RAM空间使用的同时,减少对flash的操作;
- 对数据的写入做充分校验,返回错误值,需应用层做重试;
- NVdata的flash擦除块头标记使用4个字节,最低字节可以作为版本号使用,如果版本不同,则会执行对NVdata区域擦除操作;
- 对数据内容进行校验保存,尽量保证数据的正确性。
2. 使用说明
该组件主要包括以下用户接口:
| 函数接口 | 说明 |
|---|---|
| cinv_init | 模块初始化 |
| cinv_item_init | 初始化item |
| cinv_item_read | 读出item数据 |
| cinv_item_write | 写入item数据 |
| cinv_item_delete | 删除item数据 |
| cinv_register_hotid | 注册为hotid |
使用示例:
#include "ci_nvdata_manage.h"
/*定义需要保存data的ID*/
#define NVDATA_ID_VOLUME 0x50000001 /*'VOLU'*/
void nvdata_test(void *p_arg)
{
uint16_t real_len;
uint8_t volume = 0x5;
/* 将NVDATA_ID_VOLUME注册到hotid,使用该方式会加快读取,
但会增加内存使用。对速度要求不高时,可不写该语句 */
cinv_register_hotid(NVDATA_ID_VOLUME);
/* 创建数值型的item,并赋初值0x5,返回值可以判断是否为第一次写入 */
if(CINV_ITEM_UNINIT == cinv_item_init(NVDATA_ID_VOLUME, sizeof(volume), &volume))
{
mprintf("first write\n");
}
/* 读取item值 */
if(CINV_OPER_SUCCESS != cinv_item_read(NVDATA_ID_VOLUME, sizeof(volume), &volume, &real_len))
{
mprintf("read error\n");
while(1);
}
else
{
mprintf("volume = 0x%x, real_len is %d\n", volume, real_len);
volume ++;
}
/* 更新(写入)该item值 */
if(CINV_OPER_SUCCESS != cinv_item_write(NVDATA_ID_VOLUME,real_len, &volume))
{
mprintf("write error\n");
while(1);
}
}
提示
NVDATA_ID_VOLUME等宏需要用户定义
四、音频分区 voice.bin & 计算可用音频空间
当前程序voice预留了约1638KB,所有音频文件重采样为16kbps(2kB/s) MP3后生成 voice.bin,所以最大音频时长大约1638/2=819s左右
扩展:分析生成音频分区对应固件 voice.bin 过程(从 bat 脚本)
在工程\projects\xxx[prj_name]\firmware 目录下, 有一个 合成分区bin文件.bat
其一种作用是——生成分区固件之一——音频分区固件 voice.bin 。
Makefile 中生成 voice.bin 的过程代码如下:
echo 请选择播报音音频格式:
@REM echo 1. adpcm (默认格式,压缩比4:1,音质一般,解码器小,解码运算量小)
@REM echo 2. pcm (无压缩,占用flash空间较大,音质好,无解码器,无解码运算)
@REM echo 3. flac (压缩比大约3:1,音质好,解码器小,解码运算量略大于adpcm)
@REM echo 4. mp3 (压缩比大约10:1,音质较好,解码器较大,解码运算量大)
@REM echo 5. opus (压缩比大约16:1,音频质量一般,解码器小)
@REM set fmt=4
set fmt=4
@REM set /p fmt=default=4:
echo %fmt%
if %fmt% == 1 (
if not exist "adpcm" (
mkdir "adpcm"
)
for /d %%i in (*) do (
echo %%i | findstr "\[.*\].*" > nul && call:to_adpcm adpcm %%i
)
..\%TOOLS_PATH%\group_merge.exe -i adpcm -o ..\voice
) else if %fmt% equ 4 (
if not exist "mp3" (
mkdir "mp3"
)
@REM for /d %%i in (*) do (
@REM echo %%i | findstr "\[.*\].*" > nul && call:to_mp3 mp3 %%i
@REM )
call:to_mp3 mp3 src
@REM ..\%TOOLS_PATH%\group_merge.exe -i mp3 -o ..\voice
..\%TOOLS_PATH%\ci-tool-kit ID3-editor --input-dir mp3
..\%TOOLS_PATH%\ci-tool-kit merge user-file -i mp3 -o mp3
move mp3\mp3.bin .\voice.bin
) else if %fmt% equ 3 (
if not exist "flac" (
mkdir "flac"
)
for /d %%i in (*) do (
echo %%i | findstr "\[.*\].*" > nul && call:to_flac flac %%i
)
..\%TOOLS_PATH%\group_merge.exe -i flac -o ..\voice
) else if %fmt% equ 2 (
if not exist "pcm" (
mkdir "pcm"
)
for /d %%i in (*) do (
echo %%i | findstr "\[.*\].*" > nul && call:to_pcm pcm %%i
)
..\%TOOLS_PATH%\group_merge.exe -i pcm -o ..\voice
) else if %fmt% equ 5 (
if not exist "opus" (
mkdir "opus"
)
@REM for /d %%i in (*) do (
@REM echo %%i | findstr "\[.*\].*" > nul && call:to_opus opus %%i
@REM )
@REM ..\%TOOLS_PATH%\group_merge.exe -i opus -o ..\voice
..\%TOOLS_PATH%\ci-tool-kit merge user-file -i opus -o opus
move opus\opus.bin .\voice.bin
) else (
echo error: 不支持的音频格式
)
cd ..
@echo on
exit /b
:to_pcm
echo %1\%2
if not exist %1\%2 (
mkdir %1\%2
)
for %%j in (%2\*.wav) do (
echo %%j
..\%TOOLS_PATH%\wav_to_adpcm -f wav -i "%%j" -o "%1\%%j"
)
goto:eof
:to_adpcm
echo %1\%2
if not exist %1\%2 (
mkdir %1\%2
)
for %%j in (%2\*.wav) do (
echo %%j
..\%TOOLS_PATH%\wav_to_adpcm -i "%%j" -o "%1\%%j"
)
goto:eof
:to_mp3
@REM echo %1\%2
@REM if not exist %1\%2 (
@REM mkdir %1\%2
@REM )
for %%j in (%2\*) do (
set ttt=%%j
set output_name=%1\!ttt:~4,-4!.mp3
echo !output_name!
set num=!ttt:~5,5!
if !num! == 65535 (
echo !num!
set cfg_in=%%j
set cfg_out=%1\!ttt:~4,-4!.txt
)
@REM ..\!TOOLS_PATH!\wav_to_mp3_flac.exe -f mp3 -i "!ttt!" -o "!output_name!"
@REM ..\!TOOLS_PATH!\lame --silent --cbr -b24 -t --resample 16000 --out-file "!output_name!" "!ttt!"
..\!TOOLS_PATH!\lame --silent --cbr -b16 -t --resample 16000 "!ttt!" "!output_name!"
@REM ..\!TOOLS_PATH!\ci-tool-kit ID3-editor -i !output_name!
)
if exist !cfg_in! (
copy "!cfg_in!" "!cfg_out!"
)
goto:eof
:to_flac
echo %1\%2
if not exist %1\%2 (
mkdir %1\%2
)
for %%j in (%2\*.wav) do (
set ttt=%%j
set output_name=%1\!ttt:~0,-4!.flac
echo !output_name!
..\!TOOLS_PATH!\wav_to_mp3_flac.exe -f flac -r 8000 -i "!ttt!" -o "!output_name!"
)
goto:eof
这段批处理脚本的核心逻辑是:将WAV源文件转换为MP3格式,并进行ID3标签编辑和合并处理。
具体流程如下:
主要逻辑流程
1. 选择音频格式
set fmt=4 // 固定选择MP3格式(注释显示用户可选择1-5,但代码固定为4)
2. MP3处理分支 (if %fmt% equ 4)
创建mp3目录
调用:to_mp3子程序处理音频
执行ID3标签编辑
合并为二进制文件
重命名为voice.bin
3. :to_mp3子程序详细逻辑
A. 文件遍历与转换
for %%j in (%2\*) do ( // 遍历源文件
set ttt=%%j
set output_name=%1\!ttt:~4,-4!.mp3 // 生成输出文件名(截取第4字符后)
// 使用lame编码器转换
..\!TOOLS_PATH!\lame --silent --cbr -b16 -t --resample 16000 "!ttt!" "!output_name!"
)
转换参数说明:
-
--silent:静默模式 -
--cbr -b16:16kbps恒定比特率 -
--resample 16000:重采样到16kHz -
-t:删除非必要信息
B. 特殊文件处理
set num=!ttt:~5,5! // 提取文件名第5-9字符
if !num! == 65535 ( // 如果数字为65535
set cfg_in=%%j // 标记为配置文件
set cfg_out=%1\!ttt:~4,-4!.txt // 生成对应的txt输出路径
)
C. 配置文件复制
if exist !cfg_in! (
copy "!cfg_in!" "!cfg_out!" // 复制配置文件
)
4. 后续处理步骤
A. ID3标签编辑
..\%TOOLS_PATH%\ci-tool-kit ID3-editor --input-dir mp3
-
为所有MP3文件添加/编辑ID3标签
B. 文件合并
..\%TOOLS_PATH%\ci-tool-kit merge user-file -i mp3 -o mp3
-
将MP3文件合并为单个二进制文件
C. 重命名输出
move mp3\mp3.bin .\voice.bin
-
将生成的mp3.bin重命名为voice.bin
关键特点
-
固定格式选择:虽然代码显示可选择多种格式,但实际固定为MP3(
set fmt=4) -
低比特率转换:16kbps CBR,适合嵌入式系统
-
采样率降低:重采样到16kHz,减少文件大小
-
特殊文件处理:识别并处理编号为65535的配置文件
-
ID3标签支持:为音频文件添加元数据
参考资料
1. ChipIntelli 软件部分----存储 API 章节
https://document.chipintelli.com/%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91/SDK/CI13XX%E8%8A%AF%E7%89%87SDK/CI-SDK-Offline/CI13XX_SDK_ASR_Offline_V2.2.0/API%E5%8F%82%E8%80%83/%E5%AD%98%E5%82%A8API/

浙公网安备 33010602011771号