杰理 SDK 文档中心
首页
首页
  • 项目概览

    • AD23N SDK 概述与芯片平台
    • 工程结构与模块划分
  • 快速开始

    • 开发环境搭建与工具链
    • 编译构建指南
    • 烧录与固件升级工具
  • 应用框架与产品工作流

    • 应用入口与模式调度
    • 音乐播放应用
    • MIDI 解码与键盘演奏
    • 录音应用
    • LINEIN 与扩音应用
    • USB 从设备应用
    • 待机、软关机与空闲检测
    • 公共 UI 与 LED 显示
  • 音频子系统

    • 音频解码器框架
    • 音频编码器框架
    • 音效算法库
    • 音频管理与输出通路
  • 存储与文件系统

    • 文件系统层
    • NOR Flash 与虚拟机存储
    • 设备与设备管理
  • 系统服务与运行时

    • 消息机制与事件分发
    • 按键扫描与输入处理
    • 电源管理与低功耗控制
    • 定时器与系统任务
  • 外设驱动与平台

    • CPU 平台与启动流程
    • USB 协议栈与主机/设备驱动
    • SPI 与通用外设接口
  • 固件升级与构建工具

    • 固件升级机制
    • 编译后处理与镜像打包
    • 构建系统与命令行工具

编译构建指南

本指南介绍 fw-AD23N_GP-MCU_SDK 的完整编译构建流程,包括环境搭建、Code::Blocks 图形化编译、Makefile 命令行编译、编译产物与后处理,以及常见编译错误的排查方法。

Purpose and Scope

本页覆盖 AD23N SDK 从源码到固件的完整构建链路:

  • 编译工具链的安装与环境变量配置(Windows / Linux / macOS)
  • 两种编译方式:Code::Blocks 图形化编译与 Makefile 命令行编译
  • 顶层 sdk/Makefile 的构建系统设计:工具链探测、编译参数、特性宏、头文件搜索路径
  • 编译产物(sdk.elf)与 post_build 后处理流程
  • 常见编译错误与性能调优建议

以下相关主题由同级页面分别介绍,不在本页展开:

  • 固件烧录、生产烧写与 OTA 升级,请参见「烧录与升级」页面
  • SDK 目录结构与各应用代码入口,请参见「工程结构」页面
  • app_config.h 功能开关等运行时配置,请参见「配置说明」页面

概述

fw-AD23N_GP-MCU_SDK 是杰理科技为 AD23N 系列芯片(AD232A / AD232S / AD235A / AD236A / AD236B / AD238A / AD238B)提供的通用 MCU SDK。该 SDK 以 Release 形式发布源码与预编译库(include_lib/liba/ 下的 .a 文件),开发者通过 make 或 Code::Blocks 将应用源码、BSP 源码与预编译库链接为最终固件。

构建系统围绕以下设计意图构建:

  1. 跨平台统一入口:sdk/Makefile 通过检测 OS 环境变量自动切换 Windows 与 Linux 工具链路径,同一份 Makefile 在两个平台均可直接使用。
  2. LTO(Link-Time Optimization)链接:编译与链接统一使用 clang 系工具链(clang + lto-wrapper),通过 -flto 实现跨编译单元的全局优化,这对内存紧张的 MCU 工程至关重要。
  3. 功能宏裁剪:通过 DEFINES 中大量的 -DHAS_xxx 宏控制音频解码器、编码器、音效算法、文件系统等模块的编译,实现按需裁剪、节省代码空间。
  4. 后处理自动生成固件:链接完成后自动执行 app/post_build/sh59/ 下的下载/打包脚本,产出可直接烧录的固件文件。

注意:本仓库是 SDK Release 版本,需配合对应命名规则的库文件(lib.a)才能完成链接。

架构

构建流水线架构

flowchart TD
    subgraph sg_Env["构建环境层"]
        CB["Code::Blocks IDE<br/>AD23N_mbox_flash.cbp"]
        MK["make 命令行<br/>make_prompt.bat / bash"]
    end

    subgraph sg_Toolchain["杰理编译工具链 (clang / pi32v2)"]
        CC["clang<br/>-target pi32v2 -mcpu=r3v2"]
        LD["lto-wrapper<br/>LTO 链接"]
        AR["llvm-ar / lto-ar<br/>静态库"]
    end

    subgraph sg_Src["源码与库输入"]
        APP["app/src + app/bsp<br/>应用与 BSP 源码"]
        LIB["include_lib/liba<br/>预编译库 .a"]
        HDR["include_lib 头文件<br/>系统头文件"]
    end

    subgraph sg_Out["编译产物层"]
        ELF["sdk.elf<br/>app/post_build/sh59/"]
        POST["post_build 脚本<br/>download.bat / download.sh"]
        FW["固件文件<br/>可烧录镜像"]
    end

    CB --> MK
    MK --> CC
    CC --> LD
    APP --> CC
    HDR --> CC
    LIB --> LD
    LD --> ELF
    ELF --> POST
    POST --> FW
    AR --> LD

各层职责说明:

  • 构建环境层:开发者通过 Code::Blocks 工程(.cbp)或 Makefile 两种入口发起构建。Code::Blocks 底层同样调用杰理工具链,Makefile 方式更适合脚本化、CI 化构建。
  • 工具链层:Makefile 中 CC/LD/AR 指向 clang、lto-wrapper、llvm-ar(Linux 为 lto-ar),目标架构为 pi32v2、CPU 为 r3v2(详见 sdk/Makefile)。
  • 源码与库输入层:应用/BSP 源码与 include_lib 下的预编译库共同参与编译链接,头文件通过 INCLUDES 中的 -I 参数注入编译命令。
  • 编译产物层:链接产物为 app/post_build/sh59/sdk.elf,随后 post_build 脚本(Windows 为 download.bat,Linux 为 download.sh)将其处理为最终固件(详见 sdk/Makefile)。

平台探测与工具链切换

Makefile 的第一项关键设计是平台自动探测:通过 ifeq ($(OS), Windows_NT) 分支为 Windows 与 Linux 分别配置工具链路径、后处理脚本与额外的编译宏(详见 sdk/Makefile):

配置项WindowsLinux
TOOL_DIRC:/JL/pi32/bin/opt/jieli/pi32v2/bin
CC / CXXclang.execlang
LDpi32v2-lto-wrapper.exelto-wrapper
ARllvm-ar.exelto-ar
SYS_LIB_DIRC:/JL/pi32/pi32v2-lib/r3$(TOOL_DIR)/../lib/r3
SYS_INC_DIRC:/JL/pi32/pi32v2-include$(TOOL_DIR)/../include
EXT_CFLAGS空-D__SHELL__
后处理脚本download.bat(经 fixbat.exe 修正 UTF-8→GBK 编码)download.sh

设计意图:EXT_CFLAGS 在 Linux 下追加 -D__SHELL__,是为了让 download.c 等后处理相关源码在无 Windows 批处理环境的平台上正确编译;Windows 下则用 fixbat.exe 处理批处理脚本的中文编码问题。

环境搭建

前提条件

根据目标开发平台选择编译环境(详见 README.md):

系统说明
Windows推荐使用 Code::Blocks IDE 编译,或双击 sdk/make_prompt.bat 进入预配置的命令行环境
LinuxMakefile 命令行编译(需自行改写 download_bat.c 脚本适配 Linux 环境)
macOS需自行配置交叉编译工具链

安装编译工具链

  1. 从 杰理编译工具链下载页 下载并安装工具链。
  2. Linux 用户可从 pkgman.jieliapp.com 获取,解压到 /opt/jieli 目录,并确保 /opt/jieli/pi32/bin/clang 存在。
  3. 安装完成后验证:
# 验证工具链是否安装成功
clang --version

Linux 特别注意事项(详见 sdk/Makefile):工具链解压后需保证 /opt/jieli/common/bin/clang 存在(注意目录层次);同时需确认 ulimit -n 足够大(建议大于 8096),否则链接阶段可能因打开文件过多而失败,可通过 ulimit -n 8096 调大。

烧录与音频辅助工具

工具用途
USB 升级工具将固件烧录到目标板(量产场景使用生产烧写工具)
音频工具打包、音频文件转换、MIDI 等通用音频工具

编译方式一:Code::Blocks(推荐 Windows 用户)

  1. 确保已安装杰理编译工具链。
  2. 双击打开 sdk/ 根目录下的工程文件 AD23N_mbox_flash.cbp(该工程面向 AD23N 全系列,覆盖小音箱 / 语音玩具 / MIDI 琴应用,详见 README.md)。
  3. 点击 Build → Build(快捷键 Ctrl+F9)执行编译。
  4. 编译成功后,在 app/post_build/sh59/ 目录下生成固件。

编译方式二:Makefile 命令行

所有命令均在 sdk/ 目录下执行(详见 README.md):

# Windows 用户:双击 sdk/make_prompt.bat 打开命令行环境
# 该脚本已设置好所有环境变量和 make 的路径

# 编译(-j4 表示 4 个并行任务)
make -j4

# 显示编译详细过程
make VERBOSE=1 -j4

# 清理编译临时文件(清除 objs/ 等中间产物)
make clean

# Linux 用户(需先按前述步骤安装工具链到 /opt/jieli)
cd sdk
make -j`nproc`

Makefile 目标速查:

目标作用
make / make -jN编译并生成固件(-jN 指定并行任务数)
make VERBOSE=1输出完整编译命令行,便于排查参数问题
make clean清除编译临时文件

核心流程

一次完整构建的执行过程

sequenceDiagram
    participant Dev as 开发者
    participant Make as Makefile 入口
    participant CC as clang (pi32v2/r3v2)
    participant LD as lto-wrapper
    participant Post as post_build 脚本
    participant FW as 固件产物

    Dev->>Make: make -j4
    activate Make
    Make->>Make: 探测 OS 选择工具链与脚本
    Make->>Make: 展开 DEFINES / INCLUDES / 源码列表
    loop 每个 .c 源文件
        Make->>CC: clang -target pi32v2 -mcpu=r3v2 -flto -Oz -g
        CC-->>Make: 生成 LTO 中间对象 (objs/)
    end
    Make->>LD: 链接所有对象 + include_lib/liba/*.a
    activate LD
    LD-->>Make: app/post_build/sh59/sdk.elf
    deactivate LD
    Make->>Post: 执行 download.bat / download.sh
    activate Post
    Post->>Post: fixbat(UTF-8→GBK) / 打包处理
    Post-->>FW: 生成可烧录固件
    deactivate Post
    Make-->>Dev: 构建完成
    deactivate Make

关键步骤说明:

  1. 平台探测:Makefile 依据 $(OS) 选择 Windows/Linux 工具链路径、EXT_CFLAGS 与后处理脚本,并将 TOOL_DIR 加入 PATH。
  2. 参数展开:CFLAGS(架构、优化等级)、DEFINES(功能宏)、INCLUDES(-I 头文件路径)、c_SRC_FILES(需编译的 .c 文件列表)组成最终编译命令。
  3. 编译:每个 .c 文件经 clang 以 -target pi32v2 -mcpu=r3v2 交叉编译,启用 -flto 生成 LTO 中间表示,产物落入 objs/(BUILD_DIR)。
  4. 链接:lto-wrapper 将所有对象与 include_lib/liba/ 预编译库做 LTO 全局优化后链接,输出 app/post_build/sh59/sdk.elf(OUT_ELF)。
  5. 后处理:执行 download.bat(Windows,先经 fixbat.exe 修正编码)或 download.sh(Linux),将 ELF 转换为最终固件。

编译参数与特性宏

CFLAGS 的核心参数(详见 sdk/Makefile):

参数含义
-target pi32v2指定交叉编译目标架构为 pi32v2
-mcpu=r3v2指定 CPU 内核为 r3v2(对应 AD23N 系列 DSP 内核)
-flto启用链接时优化,跨编译单元全局优化
-Oz面向代码体积的优化(MCU Flash 有限,优先减小体积)
-g生成调试信息
-fno-common禁止公共块合并,规避未初始化全局变量链接歧义
-fprefer-gnu-section为函数/数据生成独立 section,配合链接脚本裁剪无用代码
-Wundef / -Wuninitialized启用未定义宏、未初始化变量告警

DEFINES 中的特性宏(节选,完整列表见 sdk/Makefile):

宏作用
-DCPU_SH59=1指定芯片平台为 SH59(AD23N 内部代号)
-DFPGA=0关闭 FPGA 仿真模式,按量产芯片编译
-DROM_SECURE_BOOT启用安全启动
-DHAS_MP3_DECODER / -DHAS_WAV_DECODER / -DHAS_MIDI_DECODER 等按需启用各音频解码器
-DHAS_MP3_ENCODER / -DHAS_UMP3_ENCODER / -DHAS_A_ENCODER按需启用录音编码器
-DHAS_ANS_EN / -DHAS_ECHO_EN / -DHAS_VOICE_PITCH_EN / -DHAS_VOICE_CHANGER_EN / -DHAS_PCM_EQ_FLOAT_EN启用音效算法(降噪/混响/变调/变声/浮点 EQ)
-DHAS_NORFS_EN / -DHAS_FATFS_EN / -DHAS_FREEFS_EN启用文件系统(NorFs/FATFS/FreeFs)
-DHAS_UPDATE_EN=1启用固件升级(OTA 双备份)
-DHAS_USB_EN=0关闭 USB 功能
-DNOFLOAT禁用浮点运算路径(音频算法多为定点实现)

使用示例

示例一:从零开始克隆并编译

以下命令序列来自 README.md 的快速开始章节:

# 克隆仓库并进入 SDK 目录
git clone https://gitee.com/Jieli-Tech/AD23N.git
cd AD23N/sdk

# 方式一:Code::Blocks 图形化编译
# 1. 双击打开 AD23N_mbox_flash.cbp
# 2. 点击 Build → Build(Ctrl+F9)

# 方式二:Makefile 命令行编译
# Windows 用户先双击 make_prompt.bat 打开命令行环境
make -j4

# 显示编译详情(排查参数问题时使用)
make VERBOSE=1 -j4

Source: README.md

示例二:Makefile 平台探测逻辑

以下代码展示了 Makefile 如何根据操作系统切换工具链(摘自 sdk/Makefile):

# 工具路径设置
ifeq ($(OS), Windows_NT)
# Windows 下工具链位置
TOOL_DIR := C:/JL/pi32/bin
CC    := clang.exe
CXX   := clang.exe
LD    := pi32v2-lto-wrapper.exe
AR    := llvm-ar.exe
MKDIR := mkdir_win -p
RM    := rm -rf

SYS_LIB_DIR := C:/JL/pi32/pi32v2-lib/r3
SYS_INC_DIR := C:/JL/pi32/pi32v2-include
EXT_CFLAGS  := # Windows 下不需要 -D__SHELL__
export PATH:=$(TOOL_DIR);$(PATH)

## 后处理脚本
FIXBAT          := tools/utils/fixbat.exe # 用于处理 utf8->gbk 编码问题
POST_SCRIPT     := app/post_build/sh59/download.bat
RUN_POST_SCRIPT := app\\post_build\\sh59\\download.bat
else
# Linux 下工具链位置
TOOL_DIR := /opt/jieli/pi32v2/bin
CC    := clang
CXX   := clang
LD    := lto-wrapper
AR    := lto-ar
MKDIR := mkdir -p
RM    := rm -rf
export OBJDUMP := $(TOOL_DIR)/objdump
export OBJCOPY := $(TOOL_DIR)/objcopy
export OBJSIZEDUMP := $(TOOL_DIR)/objsizedump

SYS_LIB_DIR := $(TOOL_DIR)/../lib/r3
SYS_INC_DIR := $(TOOL_DIR)/../include
EXT_CFLAGS  := -D__SHELL__ # Linux 下需要这个保证正确处理 download.c
export PATH:=$(TOOL_DIR):$(PATH)

## 后处理脚本
FIXBAT          := touch # Linux下不需要处理 bat 编码问题
POST_SCRIPT     := app/post_build/sh59/download.sh
RUN_POST_SCRIPT := bash $(POST_SCRIPT)
endif

CC  := $(TOOL_DIR)/$(CC)
CXX := $(TOOL_DIR)/$(CXX)
LD  := $(TOOL_DIR)/$(LD)
AR  := $(TOOL_DIR)/$(AR)

Source: sdk/Makefile

代码解读:ifeq ($(OS), Windows_NT) 是 GNU Make 的条件分支语法。Windows 下工具链位于 C:/JL/pi32/bin(由安装包固定路径),并导出 OBJDUMP/OBJCOPY/OBJSIZEDUMP 供后处理脚本使用;Linux 下工具链位于 /opt/jieli/pi32v2/bin,且通过 -D__SHELL__ 宏适配无批处理环境。FIXBAT 在 Windows 下指向 fixbat.exe 修正 download.bat 的 UTF-8→GBK 编码,Linux 下退化为 touch(空操作),体现了"同一套 Makefile 双平台复用"的设计目标。

示例三:编译参数与输出定义

以下代码片段展示了输出文件与核心编译参数的定义方式(摘自 sdk/Makefile):

# 输出文件设置
OUT_ELF   := app/post_build/sh59/sdk.elf
OBJ_FILE  := $(OUT_ELF).objs.txt
# 编译路径设置
BUILD_DIR := objs

# 编译参数设置
CFLAGS := \
	-target pi32v2 \
	-mcpu=r3v2 \
	-integrated-as \
	-flto \
	-Wuninitialized \
	-Wno-invalid-noreturn \
	-fno-common \
	-integrated-as \
	-Oz \
	-g \
	-flto \
	-fallow-pointer-null \
	-fprefer-gnu-section \
	-Wno-shift-negative-value \
	-Wundef \

Source: sdk/Makefile

代码解读:OUT_ELF 直接指向 post_build 目录,使后处理脚本可以就地处理链接产物;BUILD_DIR := objs 将中间对象集中存放,make clean 只需删除该目录。CFLAGS 中的 -mcpu=r3v2 与 -target pi32v2 是杰理芯片专用架构参数,-flto 出现两次是历史遗留写法(等价于一次启用),-Oz 表明该 SDK 对固件体积的重视程度高于运行速度。

配置选项

Makefile 核心变量

变量类型默认值说明
CC / CXXstringclang / clang.exeC/C++ 编译器(按平台自动选择)
LDstringlto-wrapper / pi32v2-lto-wrapper.exeLTO 链接器
ARstringlto-ar / llvm-ar.exe静态库打包工具
TOOL_DIRstring/opt/jieli/pi32v2/bin 或 C:/JL/pi32/bin工具链根目录
SYS_LIB_DIRstring$(TOOL_DIR)/../lib/r3系统运行库目录(r3 内核)
SYS_INC_DIRstring$(TOOL_DIR)/../include系统头文件目录
EXT_CFLAGSstring-D__SHELL__(Linux)平台附加宏定义
OUT_ELFstringapp/post_build/sh59/sdk.elf链接产物路径
BUILD_DIRstringobjs中间对象输出目录
POST_SCRIPTstringdownload.bat / download.sh后处理脚本路径
VERBOSEbool关闭make VERBOSE=1 输出详细编译命令

特性宏(DEFINES)裁剪

完整的特性宏列表定义于 sdk/Makefile,开发者可通过增删 -DHAS_xxx 控制编译进固件的模块,例如:

  • 解码器家族:HAS_A_DECODER、HAS_MP3_ST_DECODER、HAS_UMP3_DECODER、HAS_WAV_DECODER、HAS_F1A_DECODER、HAS_MIDI_DECODER、HAS_MIDI_KEYBOARD_DECODER,其中 HAS_MAX_F1A_NUMBER=2 限制 F1A 解码路数。
  • 编码器家族:HAS_MP3_ENCODER、HAS_UMP3_ENCODER、HAS_A_ENCODER。
  • 音效:HAS_ANS_EN(降噪)、HAS_SPEED_EN(变速)、HAS_ECHO_EN(混响)、HOWLING_EN(啸叫抑制)。
  • 外设与存储:HAS_EXT_FLASH_EN、HAS_SDMMC_EN、HAS_HW_SRC_MODULE=1、HAS_NORFS_EN、HAS_FATFS_EN、HAS_FREEFS_EN、SIMPLE_FATFS_ENABLE=0、SYS_VM_EN=0。
  • 系统:ROM_SECURE_BOOT(安全启动)、HAS_UPDATE_EN=1(升级)、SPEAKER_EN、AUX_EN、ENCODER_EN、AUDIO_ADC_EN=1。

应用层功能开关(如 app_config.h)与 Makefile 宏是两个层面:Makefile 宏决定模块是否参与编译链接,app_config.h 决定运行时行为。

故障模式、边界情况与并发

常见编译错误及排查

以下错误表来自 README.md 的常见编译错误章节:

错误提示解决方法
clang: command not found未安装杰理编译工具链,或环境变量未配置(检查 TOOL_DIR 是否正确加入 PATH)
cannot find -lxxx缺少对应的 .a 库文件,检查 include_lib/liba/ 目录是否与当前芯片型号匹配
make: command not foundWindows 下使用 tools/make_prompt.bat 打开预配置的编译命令环境
链接错误检查 Makefile 的 target 是否匹配当前芯片型号(-mcpu=r3v2、CPU_SH59 等)

Linux 特有边界条件

  • ulimit -n 限制:LTO 链接阶段会同时打开大量文件(对象 + 库 + 头文件),若 ulimit -n 小于 8096 可能链接失败,需执行 ulimit -n 8096(详见 sdk/Makefile)。
  • 工具链目录层次:Linux 安装时必须保证 /opt/jieli/common/bin/clang 存在,注意是 common 层级而非 pi32v2 层级,否则 Makefile 找不到编译器。
  • 后处理脚本差异:download_bat.c 是按 Windows 批处理环境编写的,Linux 下需自行改写适配(README 明确提示)。

并行编译的并发注意

make -jN 将多个编译任务并行执行。由于 objs/ 目录内每个源文件生成独立目标文件,并行编译本身是安全的;但若在并行模式下同时执行 make clean 或修改源码列表,可能产生竞态(中间文件被删除/重建),建议:编译与清理操作串行执行,CI 脚本中先 make clean 再 make -jN。

性能与运维建议

  • 加速编译:使用 make -j4(或 -j + 本机 CPU 核数),README 明确推荐该方式(详见 README.md)。
  • 定位编译问题:make VERBOSE=1 输出完整命令行,可直接检查 -I 路径、宏定义与链接库参数是否正确。
  • 固件体积控制:通过裁剪 DEFINES 中的 -DHAS_xxx 宏关闭不需要的模块,配合 -Oz 与 -flto 可显著减小固件体积;若需确认空间占用,Linux 下可借助 OBJSIZEDUMP 工具(Makefile 已导出)。
  • CI 集成:Linux 环境 + Makefile 是最适合 CI 的构建方式,脚本化构建建议固定 TOOL_DIR=/opt/jieli/pi32v2/bin 并预先调大 ulimit -n。

扩展点

  • 新增应用工程:基于现有 AD23N_mbox_flash.cbp 工程与 app/src/ 中的应用代码修改,配置对应用例即可(README.md)。新增 .c 文件需追加到 Makefile 的 c_SRC_FILES 列表,或将应用目录加入 INCLUDES。
  • 切换芯片型号:SDK 已为全系列预配置统一编译入口,在配置中选择对应芯片型号即可;注意核对 -mcpu 与 CPU_SH59 宏是否匹配目标型号。
  • 定制后处理:修改 app/post_build/sh59/ 下的 download.bat / download.sh,可定制固件打包、校验、重命名等步骤;FIXBAT 机制保证 Windows 脚本编码正确。
  • 功能裁剪:增删 DEFINES 中的特性宏是最常用的扩展手段,需同步确认 include_lib/liba/ 中存在对应预编译库(否则报 cannot find -lxxx)。

相关链接

  • README.md — 完整开发指南
  • sdk/Makefile — 顶层构建脚本
  • 杰理在线文档中心
  • 杰理编译工具链下载
  • SDK 版本历史(PDF)
  • 烧录与升级工具文档(ISD 配置说明)
Prev
开发环境搭建与工具链
Next
烧录与固件升级工具