
杰里AC63这颗芯片在国产蓝牙耳机方案里出货量相当大尤其是中低端TWS和头戴式产品线很多白牌和中小品牌都在用它。但网上关于它的开发资料一直比较零散官方SDK包下载下来之后新手往往不知道从哪个文件开始看、编译环境怎么搭、烧录工具怎么配、OTA又该怎么接。我前后用fw-AC63_BT_SDK v2.4.0做过几个量产项目从环境搭建到功能裁剪再到OTA升级都踩过一轮坑这里把整个流程完整梳理一遍尽量把每一步背后的原因也讲清楚让第一次接触这套SDK的人能少走弯路。1. 先搞清楚AC63这颗芯片和SDK的定位1.1 AC63在杰理产品线里处于什么位置杰理的蓝牙音频芯片大致分几个档位AC63属于中端主力内核是32位RISC架构带DSP指令扩展主频可以跑到160MHz左右。它和低端的AC69系列比主要优势在于支持更复杂的音频算法和更大的Flash容量和高端带ANC的AC70系列比它又砍掉了主动降噪的硬件加速单元成本更低。所以AC63的典型应用场景就是普通TWS耳机、颈挂式耳机、入门级头戴耳机这类不需要ANC、但对音质和连接稳定性有一定要求的产品。选型的时候有个经验如果你的产品只需要SBC解码、不需要本地播放、不需要复杂的EQ调节AC69其实就够了但一旦你要做AAC解码、要做多段EQ、要跑一些简单的音效算法AC63的算力和内存才撑得住。这个判断很重要因为选错芯片后面再改方案PCB要重画、SDK要重配代价很大。1.2 fw-AC63_BT_SDK v2.4.0的目录结构说明了什么拿到SDK压缩包解压之后根目录下大概有这么几个关键文件夹apps/存放各个应用工程的入口比如soundbox、earphone这些每个工程有自己的board配置和app逻辑。include_lib/所有公共头文件按模块分目录比如bt、audio、system、driver。lib/预编译好的静态库杰理把核心协议栈和算法都封装成.a文件了不开放源码。cpu/芯片相关的启动代码、链接脚本、中断向量表。tools/编译脚本、烧录工具、配置工具这是新手最容易忽略但最要命的部分。理解这个结构的关键在于你写的代码主要在apps/里你调用的接口在include_lib/里但真正决定系统怎么跑起来的是cpu/和lib/里的东西。很多人一上来就去改lib里的东西那是改不了的只能通过配置和回调去影响它的行为。1.3 为什么v2.4.0这个版本值得单独说SDK版本迭代很快v2.4.0算是比较稳定的一个长期维护版本它对AC63系列的支持比较完整OTA框架也相对成熟。我对比过v2.3.x和v2.4.0后者在蓝牙连接稳定性上做了不少优化尤其是多设备切换和回连速度这块。另外v2.4.0的OTA分区表设计更清晰升级失败的回滚机制也更可靠。如果你手上拿的是更老的版本建议直接换到v2.4.0省得后面遇到一些已经修掉的bug还要自己打补丁。2. 编译环境搭建别在第一步就卡住2.1 工具链的选择和安装路径的坑杰理AC63用的是基于GCC的交叉编译工具链SDK包里一般会附带或者从官方渠道下载对应版本。这里第一个坑就是安装路径不能有中文和空格。我见过有人把工具链装在D:\开发工具\杰理\下面编译脚本直接报找不到编译器。原因是Makefile里调用工具链的路径没有做引号转义空格会被当成参数分隔符。正确的做法是装在纯英文、无空格的路径下比如C:\JL_Toolchain\或者/opt/jl_toolchain/。Windows下建议用短路径Linux下注意权限工具链目录要给可执行权限。安装完之后验证一下# Linux/Mac export PATH$PATH:/opt/jl_toolchain/bin jl-gcc --version # Windows (在SDK提供的编译终端里) jl-gcc --version能正常输出版本号就说明工具链没问题。2.2 编译脚本的调用逻辑SDK根目录下一般有个build.sh或者Makefile但真正干活的是tools/下面的脚本。以常见的用法为例编译一个耳机工程大概是这样的# 进入SDK根目录 cd fw-AC63_BT_SDK # 清理之前的编译产物 ./build.sh clean # 编译指定工程比如earphone ./build.sh earphone这里要注意build.sh后面的参数是工程名对应apps/下面的目录名。如果你自己新建了一个工程需要在脚本里注册一下否则编译脚本找不到。编译过程中会在工程目录下生成obj/和out/文件夹最终产物是.bin或者.ufw文件这个文件就是后面要烧录到芯片里的固件。2.3 常见编译报错和排查思路新手最常遇到的几个报错报错信息根本原因解决办法jl-gcc: command not found工具链没装或PATH没配检查工具链路径重新export PATHNo such file or directory: xxx.h头文件路径没配对检查工程Makefile里的include路径region xxx overflowed代码或数据超出Flash/RAM分区裁剪功能或调整链接脚本分区大小undefined reference to xxx库文件没链接或函数声明不匹配检查lib目录下对应的.a文件是否加入链接其中region overflowed这个坑最隐蔽因为有时候你只加了几行代码就报这个错实际上是因为某个数组定义太大把RAM占满了。这时候要用size命令看一下各个段的大小jl-size out/earphone.elf输出里text是代码段data是已初始化数据bss是未初始化数据。如果bss特别大多半是某个全局数组惹的祸。3. 工程配置board文件和功能裁剪的门道3.1 board配置文件决定了硬件怎么跑每个工程目录下都有一个board文件夹里面通常有board_config.h和board_ac63xx.c这类文件。这个文件是软件和硬件之间的桥梁引脚定义、时钟配置、外设开关都在这里。举个例子你要配置按键得先看原理图上按键接在哪个GPIO然后在board_config.h里找到对应的宏#define TCFG_KEY_IO_PORT IO_PORTA_01 #define TCFG_KEY_IO_LEVEL 0 // 0表示低电平有效如果这里配错了按键要么没反应要么一直触发。我遇到过一次按键一直触发的问题查了半天发现是原理图上按键接的是PA02但配置里写的是PA01两个引脚挨着看走眼了。3.2 功能裁剪把不需要的模块关掉AC63的Flash和RAM资源有限SDK默认把很多功能都打开了实际项目里用不到的要关掉否则编译出来体积太大甚至放不下。常见的裁剪项音频解码格式如果只做SBC就把AAC、aptX相关的宏关掉。音效模块不需要EQ、DRC的就关掉能省不少代码空间。提示音如果产品不用提示音把提示音相关的表和播放逻辑都去掉。OTA功能如果产品不打算做OTA可以关掉但建议保留后面加比一开始就做麻烦得多。裁剪的地方主要在board_config.h和工程自己的app_config.h里找到对应的#define改成0或者注释掉。改完之后一定要重新编译看体积变化# 编译后查看固件大小 ls -lh out/earphone.bin对比裁剪前后的体积心里有个数。3.3 时钟和功耗配置的取舍AC63支持多种时钟源内部RC、外部晶振、PLL。蓝牙音频产品一般用外部晶振因为RC的精度不够会影响蓝牙连接稳定性。晶振频率通常是24MHz配置在board_config.h里#define TCFG_CRYSTAL_OSC_FREQ 24000000功耗方面如果产品是带电池的要关注休眠电流。SDK里有低功耗模式但开启之后唤醒响应会变慢需要根据产品形态权衡。TWS耳机一般要求待机电流在微安级别这时候要把不用的外设时钟全部关掉GPIO配置成高阻或者下拉避免漏电。4. 蓝牙功能开发从配对到音频传输4.1 蓝牙协议栈的初始化流程SDK把蓝牙协议栈封装在lib/里你不需要关心底层HCI怎么跑但要知道初始化的顺序。典型的流程是系统时钟初始化蓝牙协议栈初始化bt_init()注册回调函数连接、断开、音频流事件进入主循环回调函数是核心所有蓝牙事件都通过回调通知应用层。比如连接成功、连接断开、播放暂停这些都在回调里处理。SDK里一般有一个bt_event_handler之类的函数你在这个函数里根据事件类型做不同处理。static int bt_event_handler(int event, void *param) { switch (event) { case BT_EVENT_CONNECTED: // 连接成功可以开始音频传输 break; case BT_EVENT_DISCONNECTED: // 断开连接回到可配对状态 break; case BT_EVENT_A2DP_START: // 音频流开始 break; default: break; } return 0; }4.2 配对和回连的逻辑设计配对和回连是用户体验的关键。AC63支持配对信息存储下次开机自动回连上次的设备。这里有几个细节回连优先级如果存储了多个设备要决定先回连哪个。一般是最近连接的优先。回连超时回连不能无限等一般设个5到10秒超时了还没连上就进入可被发现状态。配对模式进入方式常见的是长按按键或者开盖自动进入这个逻辑要在应用层写清楚。我做过一个项目用户反馈回连太慢查下来是因为回连时先尝试了所有存储设备每个都等超时。后来改成只尝试最近的一个超时时间从10秒缩到3秒体验就好多了。4.3 音频通路的配置音频通路涉及几个环节蓝牙接收、解码、DAC输出。SDK里这些都有现成的接口但配置不对就会出现无声、杂音、断断续续的问题。关键配置项采样率蓝牙A2DP一般用44.1kHz或48kHz要和DAC的采样率匹配。声道立体声还是单声道根据产品形态定。音量曲线SDK里有默认的音量表但不同喇叭灵敏度不一样需要根据实测调整。调试音频的时候我习惯先用一个固定的测试音频比如1kHz正弦波来验证通路确认能正常出声之后再调音效。这样能把问题范围缩小不会一上来就被各种音效参数搞晕。5. OTA升级量产产品绕不开的一环5.1 OTA的整体架构AC63的OTA方案是双分区设计Flash里划出两块区域一块跑当前固件一块用来存新固件。升级流程大致是手机APP通过蓝牙把新固件传给耳机耳机把新固件写到备份分区校验固件完整性重启bootloader切换到新分区如果新固件启动失败回滚到旧分区这个机制的好处是升级过程中断电也不会变砖因为旧固件还在。但前提是分区表要配对bootloader要能正确识别两个分区。5.2 分区表的配置分区表一般在cpu/目录下的链接脚本或者专门的配置文件里。典型的AC63分区大概是分区名起始地址大小用途bootloader0x00000032KB启动引导app0x008000400KB当前固件ota_backup0x068000400KB备份固件config0x0C800016KB配对信息等分区大小要根据固件实际体积来定留够余量。如果app分区太小编译出来的固件放不下就得裁剪功能或者换更大Flash的芯片。5.3 OTA升级过程中的坑OTA这块我踩过的坑最多说几个典型的坑一升级到一半断开连接。原因是蓝牙传输速率不稳定固件包太大传太久。解决办法是把固件包压缩或者分片传输时加确认重传机制。坑二升级后无法回连。因为新固件里的配对信息格式变了旧数据不兼容。解决办法是升级前把配对信息迁移到新格式或者升级后清除旧配对信息让用户重新配对。坑三回滚不生效。检查bootloader里的回滚逻辑确认新固件启动失败时确实会切回旧分区。有时候是标志位没写对bootloader以为新固件启动成功了。提示OTA功能一定要在项目早期就集成进来不要等到量产前才加。因为OTA涉及分区表、bootloader、应用层三部分的配合后期加会牵一发动全身。6. 调试与量产从实验室到产线6.1 常用调试手段AC63支持串口打印调试信息这是最直接的调试方式。在board_config.h里打开串口调试宏#define TCFG_UART_DEBUG_ENABLE 1 #define TCFG_UART_DEBUG_PORT UART0 #define TCFG_UART_DEBUG_BAUDRATE 115200然后接上USB转串口模块用串口助手就能看到打印信息。打印信息里会包含蓝牙事件、音频状态、错误码等排查问题很有用。除了串口还可以用GPIO翻转来测时间。比如在某个函数入口拉高一个GPIO出口拉低用示波器看波形就能知道这个函数执行了多久。这个方法在优化音频延迟的时候特别有用。6.2 产线烧录和测试量产的时候不可能一个个手动烧录要用产线工具批量烧。杰理提供了产线烧录工具支持一拖多。烧录文件就是编译出来的.bin或者.ufw。产线测试一般包括蓝牙连接测试能不能正常被搜索到、能不能连接音频测试播放测试音频检查左右声道、音量、失真按键测试每个按键功能是否正常电池测试充电电流、放电电流、电量显示这些测试项在SDK里一般有对应的测试模式产线工具会调用这些模式自动跑一遍。6.3 版本管理和固件追溯量产之后最怕的是固件版本混乱出了问题不知道是哪个版本。我的做法是在固件里写一个版本号每次编译自动生成包含日期和Git提交号。这样拿到一个固件就能知道它是哪次提交编译出来的。版本号可以放在一个固定的Flash地址或者通过蓝牙上报给手机APP。产线烧录的时候记录每个设备的版本号后面有问题可以追溯。7. 一些零散但重要的经验7.1 关于SDK升级杰理会不定期更新SDK修复bug或者加新功能。但不要盲目升级因为新SDK可能改了接口或者配置方式你之前的代码要跟着改。我的做法是项目开发阶段用最新稳定版量产之后除非有严重bug否则不升级。升级前一定要在分支上做验证没问题再合并。7.2 关于内存管理AC63的RAM不大动态内存分配要谨慎。SDK里一般有自己的内存管理接口比如malloc的封装。但频繁分配释放容易产生碎片建议在初始化阶段就把需要的内存分配好运行过程中尽量不动态分配。7.3 关于蓝牙兼容性不同手机品牌的蓝牙协议栈实现有差异有些手机在A2DP连接后会有额外的AT命令交互如果耳机没正确响应可能会出现只有Handsfree没有A2DP的情况。这个问题的根源在于耳机端的协议栈要同时支持HFP和A2DP并且在连接时正确协商。SDK里一般有兼容性配置项遇到特定品牌手机的问题可以针对性调整。7.4 关于功耗优化如果产品是电池供电功耗优化要贯穿整个开发过程。几个关键点不用的外设时钟全部关掉GPIO不用的时候配置成高阻或者根据电路决定上下拉蓝牙连接间隔适当加大能省电但会影响响应速度音频播放时的功耗和音量有关音量越大功耗越高实测下来AC63在正常播放音乐时电流大概在10mA左右待机可以做到1mA以下深度休眠可以到几十微安。具体数值和配置、外设、喇叭阻抗都有关系要以实测为准。7.5 关于开发文档和社区杰理的官方文档不算特别详细很多细节要靠看代码和问FAE。我的习惯是拿到SDK先把apps/里自带的示例工程跑通然后对照着示例改。遇到问题先搜SDK里的注释和宏定义大部分问题都能找到线索。实在搞不定的再找FAE但问的时候要把现象、复现步骤、已经试过的方法说清楚这样FAE才能快速定位。这套流程走下来从零到能跑通一个基本的蓝牙耳机功能大概需要一到两周。如果之前有嵌入式开发经验会更快一些。关键是要有耐心AC63的SDK封装程度比较高很多地方看起来是黑盒但只要你理解了它的架构和配置逻辑后面就是按部就班地填功能了。