扩音器应用 voice_enhanced
voice_enhanced(扩音器)应用是 AD24N SDK 中面向 SH58 平台的音频放大/扩音类应用,本页记录其构建产物配置(post_build)与链接脚本(app_ld.c)等仓库内可验证的实现细节。
Purpose and Scope
本页覆盖 voice_enhanced 扩音器应用在 AD24N 仓库中的可验证内容:
- post_build 目录结构(
sdk/app/post_build/sh58/voice_enhanced/)及其中各文件的角色; - 应用链接脚本
app_ld.c的内存布局、段(section)划分,特别是音频算法(AEC/NS/NLP/FFT)专用段的设计意图; - 下载/烧录与写保护相关工具(
isd_download.exe、fw_add.exe、flash_write_protect/)的配套关系。
以下主题不属于本页范围,请参见对应页面:
- 音频算法(AEC、NS、NLP)本身的实现细节,请参见音频处理相关页面;
- 其他应用的 post_build 配置(如 dir_a、dir_song 等资源打包的通用机制),请参见构建系统页面;
- SH58 芯片底层外设驱动,请参见芯片驱动页面。
说明:本仓库中
voice_enhanced主要以 post_build 配置文件形态存在;应用主源码(app 目录下的 .c 实现)未在本仓库可检索路径中直接发现,因此本页基于链接脚本与目录结构进行源文件级说明,涉及应用行为的部分会明确标注依据。
Overview
voice_enhanced 即"扩音器"应用,其典型形态是一台独立扩音设备:内置麦克风采集人声,经过回声消除(AEC)、降噪(NS)、噪声门(Noise Gate)等前端处理后由功放输出。在 AD24N SDK 中,该应用对应的构建产物配置位于:
sdk/app/post_build/sh58/voice_enhanced/
该目录是固件构建的**后处理(post_build)**环节:链接脚本(app_ld.c)决定应用代码/数据的物理内存布局,下载工具(isd_download.exe、fw_add.exe)负责把多份内容(语音、诗歌、故事、歌曲、MIDI、提示音等)打包成可烧录的固件,flash_write_protect/ 负责对 Flash 分区做写保护配置。
仓库中可验证的目录/文件清单如下:
| 文件/目录 | 角色(依据文件名与目录结构) |
|---|---|
app_ld.c | 应用链接脚本:定义 app_code / ram0 / boot_ram 内存区域与段布局(已读取验证) |
download_bat.c | 下载批处理配置源(未读取,见"源材料说明") |
isd_config_ini.c | ISD 下载工具配置文件源(未读取,见"源材料说明") |
isd_download.exe | ISD 下载工具可执行程序 |
fw_add.exe | 固件追加/打包工具可执行程序 |
flash_wp_tool.exe | Flash 写保护工具 |
flash_write_protect/ | 写保护配置目录(含 v3.x 表格、bin 参数、批处理脚本) |
dir_a、dir_bin_f1x、dir_eng、dir_ex_flash | 资源目录:A 盘、F1x bin、英文、外置 Flash 资源 |
dir_midi、dir_notice、dir_poetry、dir_song、dir_story | 内容目录:MIDI、提示音、诗歌、歌曲、故事 |
Architecture
flowchart TD
subgraph sg_Src["源码与资源"]
AppC["应用源码 (*.c)"]
ResA["dir_a / dir_eng / dir_poetry<br/>dir_story / dir_song / dir_midi / dir_notice"]
Ld["app_ld.c 链接脚本"]
end
subgraph sg_Build["构建阶段"]
Compile["编译 + 链接<br/>(按 app_ld.c 布局)"]
FwAdd["fw_add.exe 固件打包"]
end
subgraph sg_Post["post_build 后处理"]
IsdCfg["isd_config_ini.c 下载配置"]
Download["isd_download.exe 下载"]
Wp["flash_write_protect/ 写保护"]
end
subgraph sg_Out["目标产物"]
Flash["Flash 固件<br/>(含资源分区)"]
end
AppC --> Compile
Ld --> Compile
ResA --> FwAdd
Compile --> FwAdd
FwAdd --> IsdCfg
IsdCfg --> Download
Download --> Flash
Wp --> Flash
架构说明
链接层(app_ld.c):为编译产物划定物理内存——
app_code代码区(起始 0xC000100,长度 64M-0x100)、ram0数据区、boot_ram启动区;并在ram0内进一步划分音频算法专用段(.ans_data_sec、.ans_bss_sec)、低功耗 overlay 段、缓存段等。这是扩音器实时音频链路能在限定 RAM 内运行的关键。资源层(dir_ 目录)*:扩音器需要播放的语音内容(诗歌、故事、歌曲、MIDI、提示音、英文语音等)按目录组织,由打包工具合成进固件资源区,最终由
isd_download.exe写入 Flash。下载/保护层:
isd_config_ini.c为下载工具提供分区/地址配置;flash_write_protect/生成写保护参数(flash_params_v3.bin),防止关键分区(如 boot、资源索引)被误写。
源材料说明:本页仅直接读取了
app_ld.c(前 120 行)并获取了目录清单;download_bat.c、isd_config_ini.c及工具程序的具体内容未在本页源材料中展开,其角色描述基于文件名与目录结构推断,请以仓库实际内容为准。
链接脚本分析:app_ld.c
app_ld.c 是 voice_enhanced 应用在 SH58 平台上的链接脚本,通过 C 预处理 + 链接器指令混合编写,先 #include 芯片导出的符号(maskrom_stubs.ld)与缓存配置(app_icache.h),再定义内存区域与段布局。
内存区域定义
// *INDENT-OFF*
#include "maskrom_stubs.ld"
#include "app_icache.h"
//config
UPDATA_SIZE = 0x200;
UPDATA_BEG = _MASK_EXPORT_MEM_BEGIN - UPDATA_SIZE;
_BOOT_RAM_SIZE = 0x2C;
_BOOT_RAM_BEGIN = _MASK_EXPORT_MEM_BEGIN - _BOOT_RAM_SIZE;
MEMORY
{
app_code(rx) : ORIGIN = 0xC000100, LENGTH = 64M-0x100
ram0(rw) : ORIGIN = _RAM_LIMIT_L - ICACHE_RAM_TO_RAM, LENGTH = _BOOT_RAM_BEGIN - _RAM_LIMIT_L + ICACHE_RAM_TO_RAM
boot_ram(rw) : ORIGIN = _BOOT_RAM_BEGIN, LENGTH = _BOOT_RAM_SIZE
}
Source: app_ld.c
设计意图解读:
app_code从 0xC000100 起始:在 Mask ROM 导出内存之前预留UPDATA_SIZE (0x200)作为升级/更新区域,UPDATA_BEG紧贴 Mask 导出内存低端,保证升级数据区与运行时代码区互不重叠。boot_ram只有 0x2C 字节:紧贴_MASK_EXPORT_MEM_BEGIN放置启动引导数据(.boot_info),这是芯片上电后最先被 Mask ROM 读取的区域,因此必须固定且极小。ram0由_RAM_LIMIT_L与 ICache 配置推导:RAM 上边界减去 ICache 占用的 RAM 即为数据区起点,说明该应用启用了 L1/L2/L3 指令缓存,缓存区占用了一块 RAM 顶部空间。
数据段与缓存段
. = ORIGIN(ram0);
.data ALIGN(4) : SUBALIGN(4)
{
PROVIDE(data_buf_start = .);
*(.data*)
*(.*.data)
cache_Lx_code_text_begin = .;
*(.common)
*(.mic_capless_tab)
*(.fat_buf)
*(.fat_tmp_buf)
*(.*.text.cache.L1)
*(.*.text.cache.L2)
*(.*.text.cache.L3)
. = ALIGN(4);
} > ram0
Source: app_ld.c
关键点:
.mic_capless_tab是无电容麦克风(Capless MIC)校准表段——扩音器直接内置 MIC,省去耦合电容的硬件方案需要软件校准表,该段被单独收集。.fat_buf/.fat_tmp_buf是 FAT 文件系统缓冲区段,对应扩音器读取 Flash 中的语音/歌曲资源(U 盘模式或本地资源分区)。.*.text.cache.L1/L2/L3把标注了缓存级别的热代码段集中放置,由cache_Lx_code_text_begin起始地址统一管理,实现指令缓存命中优化。
低功耗 overlay 段
.lowpower_overlay ALIGN(4) : SUBALIGN(4)
{
lowpower_buf_start = .;
*(.power_driver.data.overlay);
*(.power_driver.text.cache.L1.overlay);
*(.power_driver.data.bss.overlay);
lowpower_buf_end = .;
} > ram0
Source: app_ld.c
扩音器是电池供电设备,低功耗唤醒路径(power_driver)必须常驻 RAM 且可被覆盖(overlay)复用。lowpower_buf_start 到 lowpower_buf_end 之间定义了低功耗驱动的代码/数据/ BSS overlay,在进入低功耗时加载、退出后释放,从而在不增加物理 RAM 的前提下保证唤醒逻辑可用。
音频算法专用段(ANS:AEC/NS/NLP/FFT)
.ans_data_sec ALIGN(4):
{
ans_data_start = .;
*(.aec_data)
*(.ns_data)
*(.nlp_data)
*(.fft_data)
*(.noisegate_data)
ans_data_end = .;
} > ram0
.ans_bss_sec ALIGN(4):
{
ans_bss_start = .;
. = ALIGN(32);
*(.aec_bss)
*(.ns_bss)
*(.nlp_bss)
*(.fft_bss)
ans_bss_end = .;
} > ram0
这是扩音器应用最核心的布局设计:
- 把 AEC(回声消除)、NS(降噪)、NLP(非线性处理)、FFT、Noise Gate(噪声门) 的 data/bss 集中到连续区间,
ans_data_start/end、ans_bss_start/end符号供算法库在启动时按需初始化与回收。 .ans_bss_sec强制 32 字节对齐,满足 FFT/滤波算法的 DMA 与 SIMD 对齐要求。- 集中分段便于在资源紧张时整体调整大小,也便于查看各算法占用的内存水位(ans_data 与 ans_bss 的 end-start 即内存占用)。
栈与系统 BSS
.bss ALIGN(4) (NOLOAD) : SUBALIGN(4)
{
PROVIDE(bss_buf_start = .);
. = ALIGN(4);
_cpu0_sstack_begin = .;
. = ALIGN(4);
*(.intr_stack)
. = ALIGN(4);
*(.stack_magic);
. = ALIGN(4);
. += 0x200;
*(.stack)
. = ALIGN(4);
*(.stack_magic0);
. = ALIGN(4);
_cpu0_sstack_end = .;
...
*(.usb_h_dma)
*(.DAC_BUFFER)
*(.AUDIO_ADC_BUFFER)
} > ram0
Source: app_ld.c
设计要点:
- 主栈前后各放置
stack_magic/stack_magic0哨兵值,运行时检测栈溢出——扩音器长时间运行的稳定性依赖这一机制。 .usb_h_dma、.DAC_BUFFER、.AUDIO_ADC_BUFFER是外设 DMA 缓冲区段:DAC 输出与 ADC(MIC 采集)缓冲区被单独收拢,便于做 Cache 一致性/对齐管理。
构建产物配置与下载流程
post_build 目录的角色
AD24N 的固件构建分为多个阶段:应用源码编译链接生成 app 固件后,进入 post_build 后处理,将应用固件与各类资源(诗歌、故事、歌曲、MIDI、提示音、英文语音)合成为最终可下载的固件。voice_enhanced 的 post_build 目录按内容类型拆分资源子目录,便于维护不同语种/不同内容包的产品变体:
flowchart LR
subgraph sg_Res["资源输入"]
A["dir_a(A 盘)"]
B["dir_eng(英文语音)"]
C["dir_poetry / dir_story"]
D["dir_song / dir_midi / dir_notice"]
E["dir_ex_flash(外置 Flash)"]
F["dir_bin_f1x(F1x bin)"]
end
subgraph sg_Tools["打包与下载工具"]
Fw["fw_add.exe"]
Isd["isd_config_ini.c + isd_download.exe"]
Wp["flash_write_protect/(写保护)"]
end
subgraph sg_Out2["Flash 布局"]
App["应用固件区"]
ResPart["资源分区"]
WpPart["写保护参数区"]
end
A --> Fw
B --> Fw
C --> Fw
D --> Fw
E --> Fw
F --> Fw
Fw --> Isd
Isd --> App
Isd --> ResPart
Wp --> WpPart
下载与写保护
isd_download.exe是 ISD 方案的固件下载工具,isd_config_ini.c为其提供配置(分区地址、烧录项等,具体字段见仓库源文件)。fw_add.exe用于把多个 bin/资源追加合并为单一固件镜像。flash_write_protect/目录包含0xC8671A_v3.xlsx、0xEF4017_v3.xlsx等 Flash 型号参数表、flash_params_v3.bin参数文件与flash_list_to_bin_v3.bat批处理脚本,flash_wp_tool.exe负责将写保护配置写入 Flash,防止升级区、Boot 区被误擦写。
配置选项
以下为链接脚本 app_ld.c 中可直接调整的内存配置项(来源:app_ld.c):
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
UPDATA_SIZE | 符号 | 0x200 | 升级/更新区域大小,位于 Mask 导出内存之前 |
_BOOT_RAM_SIZE | 符号 | 0x2C | 启动引导 RAM 大小 |
app_code ORIGIN | 内存区 | 0xC000100 | 应用代码起始地址 |
app_code LENGTH | 内存区 | 64M-0x100 | 应用代码可用长度 |
ram0 ORIGIN | 内存区 | _RAM_LIMIT_L - ICACHE_RAM_TO_RAM | 数据 RAM 起始(随 ICache 配置推导) |
ram0 LENGTH | 内存区 | _BOOT_RAM_BEGIN - _RAM_LIMIT_L + ICACHE_RAM_TO_RAM | 数据 RAM 长度 |
| 主栈大小 | 段内 | 0x200 | .stack 前预留的栈空间 |
.ans_bss_sec 对齐 | 段属性 | ALIGN(32) | 音频算法 BSS 的 32 字节对齐要求 |
调整 UPDATA_SIZE 或 ram0 边界会影响升级区与运行时 RAM 的平衡;_BOOT_RAM_SIZE 由 Mask ROM 约定,不建议修改。
失败模式与边界情况
基于链接脚本可推断的失败模式(源材料为 app_ld.c):
- RAM 溢出:
ans_data_sec/ans_bss_sec与.bss同处ram0,若算法内存增大导致ans_bss_end越过ram0上界,链接阶段会报错——这是算法选型/降采样率配置时的首要约束。 - 栈溢出:主栈夹在
stack_magic/stack_magic0之间,运行时可检测栈被踩踏;扩音器长时间播放/录音时若中断嵌套过深(如 USB + DAC + ADC 同时工作),可能触发哨兵被改写。 - 升级区冲突:
UPDATA_BEG与代码区起点相邻,若 app 固件过大侵入0xC000100之前的区域,会导致升级数据被覆盖。 - 资源不足/烧录失败:资源分区由
isd_download.exe写入,若dir_*内容总量超过 Flash 容量,下载阶段失败;写保护参数若与 Flash 型号不匹配(如0xC8671A与0xEF4017两种型号),flash_wp_tool.exe可能拒绝写入。
性能与运维注意事项
- 指令缓存:热代码通过
.*.text.cache.L1/L2/L3集中放置并由cache_Lx_code_text_begin管理,调整缓存等级标注可优化实时音频路径的取指命中率。 - 低功耗 overlay:
power_driver的 overlay 使低功耗唤醒路径与运行期算法共用 RAM,进入/退出低功耗的切换开销是唤醒时延的主要来源。 - DMA 缓冲区:
DAC_BUFFER、AUDIO_ADC_BUFFER、usb_h_dma集中放置便于 Cache 一致性维护;修改缓冲区大小时需同步核对 DMA 描述符配置。
扩展点
- 新增内容包:在 post_build 目录下按
dir_*模式新建目录(如dir_english2),并在下载/打包配置中登记即可扩展语音内容。 - 调整内存水位:修改
app_ld.c中ans_data_sec/ans_bss_sec的成员(如增减noisegate_data)或ram0边界,可适配不同算法配置。 - 更换 Flash 型号:在
flash_write_protect/中按0xC8671A_v3.xlsx的格式新增型号参数表,并用flash_list_to_bin_v3.bat重新生成flash_params_v3.bin。
相关链接
- app_ld.c(链接脚本)
- download_bat.c(下载批处理配置源)
- isd_config_ini.c(ISD 下载配置源)
- flash_write_protect/ 目录(写保护配置)
- 音频算法(AEC/NS/NLP)实现:见音频处理相关页面
- 构建系统与资源打包通用机制:见构建系统相关页面