杰理 SDK 文档中心
首页
首页
  • 项目概览与快速开始

    • 项目概述与芯片支持
    • 环境搭建与工具链
    • 工程与构建系统
    • 烧录与升级工具
    • 文档与硬件资料
  • 系统架构与芯片平台

    • 芯片平台与启动流程
    • 预编译库与头文件体系
    • 消息、定时器与中断服务
    • 通用外设驱动
  • 存储与文件系统

    • 文件系统实现
    • 存储设备驱动
    • VM 参数存储系统
  • 音频处理

    • 音频解码器
    • 音频编码器
    • MIDI 合成与播放
    • 音效、变速变调与降噪
  • 语音玩具应用

    • 应用框架与状态机
    • 音乐播放与外部音源
    • MIDI 乐器模式
    • 录音应用
    • 待机、电源管理与 USB 从机
  • 小音箱应用

    • 应用框架与模式管理
    • 播放源:音乐、FM、录音与 LineIn
  • 应用层与示例工程

    • 通用 MCU 应用
  • 固件更新与补丁

    • 固件升级机制
    • AD14N 主动降噪补丁

预编译库与头文件体系

本文介绍 fw-AD15N(AD15N GP-MCU SDK)中预编译库(Precompiled Library)与头文件(Header)体系的组织方式、分类原则、构建集成方式以及使用约定,帮助开发者理解"二进制闭源 + 头文件开源"的 SDK 架构。

Purpose and Scope

本页聚焦于 sdk/include_lib 目录下的预编译静态库(.a)、配套头文件(.h),以及它们与**构建系统(Makefile / Code::Blocks 工程)**之间的集成关系,内容包括:

  • include_lib/liba 预编译库的目录组织、命名规范与功能分类;
  • include_lib 下各子目录头文件的作用与依赖层次;
  • 芯片架构变体(ARCH/pi32_lto)与补丁机制(patch/)的更新方式;
  • 库与头文件如何被链接进最终固件。

以下主题属于兄弟页面,不在本页展开:

  • 具体音频算法的使用流程(如 ANC 降噪、EQ 调音),请参见对应的音频子系统文档;
  • 芯片外设寄存器与底层驱动,请参见 MCU 外设文档;
  • 固件烧录与量产工具链,请参见构建与发布相关页面。

Overview

AD15N 是一个集成音频编解码、DSP 效果与 MCU 控制的 SoC。为保护核心算法知识产权(如 AAC/MP3 编解码、降噪、变声等),SDK 将算法实现编译为闭源静态库(.a),只向应用开发者开放声明 API 的头文件(.h)。这形成了典型的"头文件开源、实现闭源"的嵌入式 SDK 分层:

  • 头文件层(公开契约):定义类型、常量、函数原型与调用约定,是应用代码唯一可见的接口;
  • 库层(闭源实现):按芯片架构预编译,链接时由构建系统挑选对应变体;
  • 构建层(组装):Makefile / .cbp 工程将头文件目录加入 -I 搜索路径,将库目录加入 -L 链接路径,最终产出固件。

这一设计同时服务于三个目标:知识产权保护(算法不随源码分发)、跨芯片复用(同一套 API 适配不同芯片变体)、构建加速(无需每次编译重编算法)。代价是:应用开发者无法修改库内部行为,只能通过库导出的 API 与配置接口(如 *_api.h)进行定制。

Architecture

下图展示预编译库与头文件体系的整体架构,以及它们与构建系统的关系:

flowchart TD
    subgraph sg_SDK["fw-AD15N SDK 根目录"]
        subgraph sg_IncludeLib["sdk/include_lib(公开接口层)"]
            subgraph sg_LibA["liba/ 预编译静态库"]
                ARCH["ARCH/(芯片架构目录)"]
                PI32["pi32_lto/ 变体"]
                L1["lib_mp3_decode.a 等解码库"]
                L2["lib_a_code.a / lib_a_decode.a 等编码库"]
                L3["lib_pcm_eq.a / lib_limiter.a 等效果库"]
                ARCH --> PI32
                PI32 --> L1
                PI32 --> L2
                PI32 --> L3
            end
            subgraph sg_Headers["头文件目录"]
                H1["asm_type.h(基础类型)"]
                H2["audio/(音频 API 头)"]
                H3["common/(通用组件头)"]
                H4["ans/(降噪 API 头)"]
            end
        end
        subgraph sg_Build["构建层"]
            MK["Makefile / Makefile.ad15n_mcu"]
            CBP["AD15N_mcu.cbp 工程"]
        end
        subgraph sg_Patch["patch/ 补丁目录"]
            P1["AD14N_20250303_ANC_noise_reduction_patch"]
            P2["source_file/include_lib/...(覆盖件)"]
        end
    end

    H1 --> H2
    H2 --> H3
    H2 --> H4
    L1 -->|"链接(-l 参数)"| MK
    L2 -->|"链接(-l 参数)"| MK
    L3 -->|"链接(-l 参数)"| MK
    CBP -->|"引用"| MK
    P2 -.->|"可选覆盖"| sg_LibA
    MK -->|"产出"| FW["固件(bin / isd 等)"]

架构说明:

  • include_lib/liba 是所有预编译库的唯一存放处,按 ARCH/<架构变体>/ 两级目录组织。当前 SDK 仅提供 pi32_lto 一种变体,对应杰理 pi32 内核 + LTO(链接时优化)编译配置。
  • include_lib 下的头文件按功能域分目录:audio/ 为音频相关 API,ans/ 为降噪(Noise Suppress)API,common/ 为通用组件(如环形缓冲),asm_type.h 为全 SDK 共享的基础类型定义。
  • 构建层通过芯片专属 Makefile(如 Makefile.ad15n_mcu)和 Code::Blocks 工程(AD15N_mcu.cbp)把库与头文件组装为固件。不同芯片(AD14N/AD15N/AD17N/AD18N/AC104N)各有专属构建入口。
  • 补丁目录(patch/)提供可选的库/头文件覆盖件,例如 ANC 降噪补丁会替换 lib_SW_FFT_pi32_OnChip.a 并新增 libNoiseSuppress_pi32_OnChip.a,用于在不改主 SDK 的前提下升级算法。

预编译库体系详解

目录组织与命名规范

所有预编译库集中在 sdk/include_lib/liba/ARCH/pi32_lto/ 下(目录清单)。库文件命名遵循 lib_<功能名>.a 的规范:

库文件功能域说明
lib_mp3_decode.a解码MP3 标准解码
lib_mp3_standard_decode.a解码MP3 标准解码(独立变体)
lib_wav_decode.a解码WAV/PCM 解码
lib_f1a_decode.a解码F1A 格式解码
lib_a_decode.a / lib_a_code.a编解码私有 A 格式编/解码
lib_mp2_encode.a / lib_mp2standard_encode.a编码MP2 编码(普通/标准)
lib_midi_synth.a合成MIDI 合成器
lib_pcm_eq.a效果PCM 均衡器
lib_limiter.a效果限幅器(响度控制)
lib_echo_cal.a / lib_energe.a / lib_vopitch_cal.a算法回声计算/能量检测/变调校准
lib_howling_fs.a算法啸叫抑制(采样率相关)
lib_speed_pitch.a效果变速变调
lib_voiceChanger_va.a效果变声
lib_SW_FFT_pi32_OnChip.aDSP片上 FFT(pi32 定点实现)

命名规范的设计意图:以功能名区分、以前缀 lib_ 统一标识,使链接脚本(-l 参数去掉 lib 前缀与 .a 后缀)与代码检索都能快速定位。pi32_OnChip 后缀表示"运行在芯片内部 pi32 内核上的定点实现",与之相对的是可能存在的上位机/离线版本。

功能分类

从库清单可以归纳出三类职责,这与 SDK 音频子系统文档的分层一致:

  1. 编解码器(Codec):mp3_decode、wav_decode、f1a_decode、a_decode、a_code、mp2_encode 等,负责文件/流媒体的格式解析与 PCM 互转。这些库通常由 audio/ 下的解码 API 头(如 audio_adc.h 中声明的播放通路)调用。
  2. DSP 效果(Effect):pcm_eq、limiter、speed_pitch、voiceChanger、midi_synth,负责对 PCM 数据进行实时处理,通过 pcm_eq_api.h、reverb_api.h 等 *_api.h 头暴露配置接口。
  3. 底层算法(Algorithm):SW_FFT(软件 FFT)、echo_cal(回声校准)、energe(能量)、vopitch_cal(变调校准)、howling_fs(啸叫抑制),多为其他功能提供数学/信号处理原语。

芯片架构变体(ARCH 目录)

库目录使用 ARCH/<变体> 两级结构,ARCH 代表芯片内核架构,pi32_lto 代表"pi32 内核 + LTO 编译"变体。这种设计让同一套头文件可以适配多个芯片(AD14N/AD15N/AD17N/AD18N/AC104N),构建系统按目标芯片选择对应变体目录即可。LTO 变体的意义在于:链接时优化可以跨库边界内联/裁剪符号,减小最终固件体积——这也是为什么库必须以预编译形式配合特定编译器版本发布,升级工具链时需同步更新库。

补丁机制(patch 目录)

patch/ 下存在独立于主 SDK 的补丁包,例如 AD14N_20250303_ANC_noise_reduction_patch/source_file/include_lib/liba/ARCH/pi32_lto/ 提供了替换版 lib_SW_FFT_pi32_OnChip.a 与新增的 libNoiseSuppress_pi32_OnChip.a(补丁库),同时 ans/ 目录下的 ans_api.h、NoiseSuppressLib.h 提供对应 API 声明。

补丁目录保持与主 SDK 相同的相对路径(source_file/include_lib/...),其设计意图是:允许"原地覆盖"合并——把补丁文件按相对路径拷贝进 SDK 即可生效,构建系统无需任何改动。这保证了算法升级与 SDK 主版本解耦。

头文件体系详解

基础类型层:asm_type.h

asm_type.h 是整个 SDK 类型系统的基石,定义了所有库 API 共用的整数类型别名(源码):

#ifndef __ASM_TYPE_H_
#define __ASM_TYPE_H_

typedef unsigned char   u8, bool, BOOL, bit1, uint8_t, BaseType_t;
typedef char            s8;
typedef unsigned short  u16, uint16_t;
typedef signed short    s16;
typedef unsigned int    u32, tu8, tu16, tbool, tu32, uint32_t;
typedef signed int      s32;
typedef unsigned long long u64;

#define  OS_MUTEX volatile int

#endif

Source: asm_type.h

设计要点:

  • 紧凑命名(u8/s16/u32)是嵌入式 C 的通行惯例,既节省源码篇幅,也让位宽一目了然,避免 int 在不同编译器上的位宽歧义;
  • 同时给出标准库别名(uint8_t/uint16_t/uint32_t)与 FreeRTOS 类型别名(BaseType_t),使库头文件既能被裸机代码包含,也能被 RTOS 环境包含;
  • bool/BOOL 直接映射为 unsigned char,保证结构体布局跨编译单元一致;
  • OS_MUTEX 定义为 volatile int,为库内部的轻量互斥提供统一抽象,应用层可据此实现临界区保护。

API 声明层:audio/、ans/、common/

  • audio/(目录):SDK 最大的头文件域,包括:
    • 硬件通路类:audio.h、audio_adc.h(ADC 采集)、audio_analog.h(模拟前端)、dac.h / dac_api.h(DAC 输出);
    • 算法配置类:pcm_eq.h / pcm_eq_api.h(EQ)、echo_api.h(回声)、energe_api.h(能量)、howling_api.h / howling_pitchshifter_api.h / notch_howling_api.h(啸叫抑制)、reverb_api.h(混响)、resample_api.h / src.h(重采样)。
    • 命名规律:xxx_api.h 通常直接对应一个 lib_xxx.a 库,xxx.h 则为结构体/常量定义或更高层封装。
  • ans/(目录):ans_api.h + NoiseSuppressLib.h,对应 ANC 降噪补丁库 libNoiseSuppress_pi32_OnChip.a,是"补丁新增头文件"的典型例子。
  • common/(目录):跨模块通用组件,如 boot.h(启动)、circular_buf.h(环形缓冲区),供库与应用共用,避免重复实现。

头文件与库的对应关系

头文件对应库职责
audio/pcm_eq_api.hlib_pcm_eq.aEQ 参数设置与使能
audio/echo_api.hlib_echo_cal.a回声消除/校准
audio/energe_api.hlib_energe.a信号能量统计
ans/ans_api.hlibNoiseSuppress_pi32_OnChip.a降噪流程控制
(解码 API)lib_mp3_decode.a 等音频解码会话

注:解码类库的完整 API 头(如 mp3_decode_api.h)位于应用侧 include 路径中,本页所读目录清单未逐一列出;对应关系以 *_api.h 命名为准。

头文件层的设计意图:头文件即契约。库的 ABI 由头文件中函数原型、结构体布局、枚举值共同锁定,因此 SDK 版本升级时头文件变更即代表 ABI 变更,应用必须重新编译;反之,仅替换库文件而不改头文件时,应用可保持二进制兼容(需满足 LTO/ABI 约束)。

构建集成与链接流程

构建入口

SDK 根目录按芯片型号提供一对构建入口(sdk 目录):

  • Makefile 系列:Makefile(总入口)与 Makefile.ad15n_mcu、Makefile.ad14n_mcu、Makefile.ad17n_mcu、Makefile.ad18n_mcu、Makefile.ac104n_mbox_mg 等芯片专属脚本;
  • Code::Blocks 工程:AD15N_mcu.cbp、AD15N_voice_toy.cbp 等 .cbp 工程文件,配合 default.workspace 工作区与 make_prompt.bat 批处理在 Windows 命令行下构建。

这种"Makefile 为主、cbp 为 IDE 入口"的双轨结构,使开发者既可在命令行流水线中构建,也可在 Code::Blocks 中可视化编译调试。include_lib 目录同时被两种入口引用:Makefile 通过 -I/-L 参数指定,cbp 工程通过 <Add directory> 节点指定。

说明:构建脚本中的具体 -l 链接参数与 -I 头文件搜索路径未在本页源码读取中逐行核验(读取预算已用于库/头文件清单与类型定义),下表依据目录结构与嵌入式链接惯例归纳,实际以 Makefile.ad15n_mcu 与 AD15N_mcu.cbp 为准。

从源文件到固件的链接流程

flowchart LR
    subgraph sg_Input["输入"]
        SRC["应用源码 .c / .asm"]
        HDR["include_lib/**/*.h"]
        LIBS["include_lib/liba/ARCH/pi32_lto/*.a"]
    end

    subgraph sg_Toolchain["工具链流程"]
        CC["编译(cc / gcc)"]
        AS["汇编(as)"]
        LD["链接(ld / lto)"]
        OBJ["目标文件 .o"]
    end

    subgraph sg_Output["输出"]
        FW["固件(bin / isd)"]
    end

    SRC --> CC
    CC --> OBJ
    AS --> OBJ
    HDR -->|"-I 头文件搜索路径"| CC
    LIBS -->|"-l 库链接参数"| LD
    OBJ --> LD
    LD --> FW

流程要点:

  1. 应用源码在编译期通过 #include 引用 include_lib 下的头文件,编译器必须能找到 asm_type.h(基础类型)与功能 API 头,因此 include_lib 根目录及各子目录都要加入头文件搜索路径;
  2. 目标文件与预编译库在链接期合并:链接器按需抽取 .a 中解析了符号引用的成员目标文件(静态库的按需提取特性);
  3. 由于库为 pi32_lto 变体,链接阶段启用 LTO,跨库内联与裁剪在此完成;
  4. 产物为可烧录固件,交由量产工具写入芯片。

变体选择与依赖解析

flowchart TD
    Start([选择构建目标]) --> MK{"芯片型号?"}
    MK -->|"AD15N"| M1["Makefile.ad15n_mcu"]
    MK -->|"AD14N"| M2["Makefile.ad14n_mcu"]
    MK -->|"AD17N"| M3["Makefile.ad17n_mcu"]
    M1 --> ARCH["ARCH/pi32_lto 库目录"]
    M2 --> ARCH
    M3 --> ARCH
    ARCH --> LINK{"链接失败?"}
    LINK -->|"undefined reference"| DIAG["检查: 库未加入 -l / 头文件版本不匹配 / 补丁未覆盖"]
    LINK -->|"OK"| FW2["生成固件"]
    DIAG --> ARCH

依赖解析失败(undefined reference)是这套体系最常见的集成错误,根因通常是:声明的 API 在所选库变体中不存在(头文件与库版本不一致)、库未加入链接参数、或补丁库未覆盖旧库导致符号重复/缺失。

使用示例

示例一:包含基础类型头

任何使用库 API 的模块都应首先包含 asm_type.h 以获得统一的整数类型:

#include "asm_type.h"

u32 sample_rate = 16000;   /* 16kHz 采样率 */
s16 pcm_frame[160];        /* 10ms @16kHz 单声道 PCM 帧 */

Source: asm_type.h

示例二:按功能域引入 API 头

音频应用典型做法是按需包含对应功能头,而非统一包含一个大而全的头文件——这既缩短编译时间,也明确了依赖边界:

#include "audio/audio_adc.h"      /* ADC 采集通路 */
#include "audio/pcm_eq_api.h"     /* EQ 效果库接口 */
#include "audio/dac_api.h"        /* DAC 输出通路 */
#include "asm_type.h"             /* 基础类型 */

Source: audio/audio_adc.h、audio/pcm_eq_api.h、audio/dac_api.h

示例三:降噪补丁的接入

启用 ANC 降噪时,使用 ans/ 下的降噪 API,并确保构建时链接补丁提供的 libNoiseSuppress_pi32_OnChip.a:

#include "ans/ans_api.h"          /* 降噪流程控制 */
#include "ans/NoiseSuppressLib.h" /* 降噪算法接口 */

/* 降噪库初始化后,将待处理 PCM 帧送入处理函数 */

Source: ans/ans_api.h、补丁库 libNoiseSuppress_pi32_OnChip.a

配置选项

本体系没有运行时配置文件,其"配置"体现在构建期选择与头文件宏约定两个层面:

配置项类型默认说明
芯片型号 Makefile构建入口Makefile(总入口)决定选用哪个芯片专属构建脚本,如 Makefile.ad15n_mcu
库架构变体目录构建路径ARCH/pi32_lto链接器从该目录解析 lib_*.a,当前仅提供 pi32_lto 变体
头文件搜索路径构建参数(-I)include_lib 及子目录需覆盖 asm_type.h、audio/、common/、ans/ 等
补丁覆盖构建期文件替换不启用将 patch/<版本>/source_file/include_lib/... 拷入 SDK 覆盖同名库/头文件
基础类型别名编译期宏/typedefasm_type.h 内置u8/u16/u32/s8/s16/s32/u64 等全 SDK 统一

关键约束:类型别名由 asm_type.h 统一提供,应用与库必须使用同一份定义,否则结构体布局与函数参数传递可能错位(见下文失败模式)。

失败模式、边界情况与并发注意

符号链接失败(undefined reference)

最常见集成错误。排查顺序建议:确认对应 lib_*.a 已加入链接参数 → 确认头文件包含的 API 在该库版本中存在 → 确认没有因补丁覆盖导致新旧库符号冲突。由于库是闭源二进制,无法用源码断点排查,只能通过头文件契约与 nm/反汇编核对符号。

头文件与库版本不一致

*_api.h 即 ABI 契约。若升级了库而未同步头文件(或反之),可能出现参数个数/结构体大小不符,表现为未定义行为而非编译错误——这是闭源库体系最隐蔽的失败模式。缓解手段:保持 include_lib 整体同步升级,避免混用不同版本。

LTO 变体的工具链耦合

pi32_lto 变体依赖特定编译器的链接时优化实现。更换/升级工具链版本可能导致链接失败或行为差异,此时应优先向原厂索取配套工具链与库版本,而不是自行更换编译器。

并发访问

OS_MUTEX 定义为 volatile int(见 asm_type.h),提示库内部临界区依赖该抽象。应用在多任务(RTOS)环境中调用库 API(尤其音频处理与 DMA 通路)时,应保证同一实例的调用序列不被打断,或按库文档要求加锁,避免音频帧撕裂。

补丁覆盖的边界

补丁路径与主 SDK 相对路径一致,覆盖后旧库可能残留(如补丁仅新增 libNoiseSuppress 而保留 lib_SW_FFT 的旧版)。若两个库存在符号重叠,可能造成静默错误;建议覆盖后全量重链接并核对符号表。

性能与运维注意

  • 链接时优化:pi32_lto 库在链接期做跨库内联,最终固件体积与执行效率都优于普通静态库,但链接时间更长;增量构建时请勿混用普通优化与 LTO 目标文件。
  • 按需提取:静态库只在符号被引用时抽取成员,未使用的编解码器(如未使能 MP3)不会进入固件,因此应用侧无需手工裁剪库。
  • 升级流程:库/头文件升级 = 整体替换 include_lib 对应文件 + 全量重编译应用 + 全量重链接,并回归音频通路测试。

扩展点

  • 新增算法库:按 lib_<功能名>.a 命名放入 ARCH/<变体>/,提供配套 *_api.h 头,并在构建脚本增加 -l 参数。
  • 新增芯片变体:在 ARCH/ 下新增架构目录,保持头文件不变即可复用全部 API;同时新增对应 Makefile.<chip> 与 .cbp 工程。
  • 补丁发布:沿用 patch/<日期>_<功能>_patch/source_file/include_lib/... 的相对路径结构,支持用户"拷入即覆盖"。
  • 功能裁剪:通过不链接对应库即可移除功能(静态库按需提取保证无符号残留)。

相关链接

  • include_lib 库与头文件总目录
  • 预编译库目录 liba/ARCH/pi32_lto
  • 基础类型定义 asm_type.h
  • 音频 API 头文件目录
  • 降噪补丁库 libNoiseSuppress_pi32_OnChip.a
  • 构建入口:Makefile.ad15n_mcu 与 AD15N_mcu.cbp
  • 相关主题:音频子系统文档(音频通路与效果使用)、MCU 外设文档(寄存器与驱动)、构建与发布文档(烧录与量产)
Prev
芯片平台与启动流程
Next
消息、定时器与中断服务