【ChipIntelli 系列】认识 Flash 分区表、实战自定义用户数据管理(NV DATA)、音频分区(voice.bin) & 计算可用音频空间

一、名词解释

打开烧录软件,可以看到下面的固件分区表:

image

图 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的最高地址区域。

💡 关于分区的几个关键点

  1. 分区非固定:这是一个具体应用的分区方案,并非芯片出厂固定。你可以使用官方工具“自动分配”或手动调整起始地址和大小来满足自己项目的需求。

  2. 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

关键特点

  1. 固定格式选择:虽然代码显示可选择多种格式,但实际固定为MP3(set fmt=4)

  2. 低比特率转换:16kbps CBR,适合嵌入式系统

  3. 采样率降低:重采样到16kHz,减少文件大小

  4. 特殊文件处理:识别并处理编号为65535的配置文件

  5. 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/

 

posted @ 2026-01-30 11:11  FBshark  阅读(119)  评论(0)    收藏  举报