简介:这份PDF资料面向从事Airoha洛达AB1568蓝牙耳机固件与应用开发的工程师,系统梳理从硬件启动到应用层功能实现的完整知识链路,适合具备一定嵌入式基础、希望快速上手该芯片平台的中高级开发者。资源包内仅含1个PDF文件,大小约9.58MB,以图文并茂的工程分析文档形式呈现,便于按目录检索查阅。目前已有374人学习关注。内容围绕headset工程展开,涵盖上电后执行函数、mk文件中的宏定义、app活动行为开启、ANC模式切换、LED呼吸灯样式修改、充电参数监测、超时时间设置、事件发送与删除、Airoha API使用参考、回调函数注册调用、自动关机与配对时间配置、开机提示电量、清除配对列表、链路丢失重连、UI Shell框架、SideTone与音频路径设置、DUT模式测RF、硬件复位及PEQ设定等二十余个专题,可帮助读者建立对该平台开发流程的整体认知,并作为日常调试与功能扩展的查阅手册。
1. 拿到 AB1568 的 headset 工程,先别急着改代码
翻开源码包,第一眼看到的是apps下并列的bootloader和headset两个工程目录,加上GCC下一堆.mk文件,很多人会直接打开main.c往下读。我踩过的坑是:读了半天发现改的宏根本没生效,因为编译的根本不是你以为的那个 mk。AB1568 这套 SDK 的工程组织方式是「一份芯片代码、多套板级配置」,ab1565_ab1568_evk开发板和最终头戴耳机产品共用同一套源码树,靠编译命令切换 mk 文件来决定哪些宏参与条件编译。所以这份工程分析资料真正的价值不在于教你写蓝牙协议栈,而在于把「上电到跑起来」这条链路上的每个开关位置标出来:bootloader 的BL_FOTA_ENABLE、应用层的MTK_ANC_ENABLE、按键行为映射表、NVKEY 的固化路径。适合已经能烧录固件、但一改功能就翻车的中级开发者,也适合刚接手这套 SDK、需要快速建立全局地图的人。下面按「先定位、再改功能、最后固化」的顺序拆。
2. 上电链路与宏定位:先搞清楚代码从哪跑起来
2.1 上电后真正执行的第一段代码
上电不是直接进headset工程的main。芯片先跑apps/bootloader下的main函数,这一段负责最基础的搬运和升级判断,然后才跳转到应用工程。这里有个条件编译的坑:bl_fota_process这个函数只有在BL_FOTA_ENABLE宏被定义时才会被编进固件,而宏定义的位置不在源码里,在GCC目录下对应的 mk 文件中。也就是说,你在.c文件里搜BL_FOTA_ENABLE只能搜到#ifdef,搜不到#define,这是正常的。
应用工程的入口在apps/headset/main.c,进去后第一件正事是调用apps_inits,它把各个应用模块的初始化串起来。理解这条链路的意义在于:当你发现某个功能「上电后没反应」,排查顺序应该是 bootloader 是否放行 → 应用 main 是否执行到 →apps_inits里对应模块是否被初始化,而不是一头扎进业务函数。
2.2 用 build.sh list 反查宏定义在哪个 mk
这是整套 SDK 里最省时间的一条命令。不要靠猜,直接让构建脚本告诉你:
# 在 SDK 根目录执行,列出所有可编译工程及其对应的 mk 文件 ./build.sh list输出里会看到类似ab1568_evk板子下headset_ref_desgin工程对应的是feature_68_evk这个 mk 文件。确认之后再去GCC目录打开它:
# 进入 GCC 目录,定位到实际参与编译的 mk cd GCC grep -n "MTK_ANC_ENABLE\|BL_FOTA_ENABLE" feature_68_evk.mk逻辑说明:build.sh list的作用是把「工程名 → 板级 → mk 文件」的映射打印出来,避免你改了feature_68_evk.mk却发现编译的是另一个板子的配置。参数上没什么可调的,关键是看懂输出里的板子名和工程名两列。新增宏定义也直接写进这个 mk,格式照抄相邻行即可,注意条件编译宏一般成对出现(XXX_ENABLE配XXX_DISABLE的默认值),只加一个容易在别的分支里被覆盖。
提示:改完 mk 一定要
clean再build,增量编译对 mk 变更的依赖追踪并不可靠,这是血泪经验。
2.3 UI Shell 活动框架:事件是怎么被分发的
apps_inits里会调用ui_shell_start_activity,为每个活动在活动堆里申请一个 item。主进程是app_preproc_activity_proc,它负责管理和调配子进程,比如app_home_screen_idle_activity_proc。每个活动进程相当于一个 UI 界面,各自持有独立的事件组。
系统产生事件时是「广播」出去的,所有活动进程都能监听到,但只有事件属于自己事件组时才处理。这解释了为什么你在 home_screen 状态下按键有反应、切到别的界面就失灵——不是按键坏了,是当前活动进程没注册这个事件。排查事件不响应,先确认当前处于哪个 activity,再看该 activity 的事件组里有没有这个事件 ID。
3. ANC 模式切换:从按键到滤波器的完整链路
3.1 四种 ANC 模式与麦克风分工
AB1568 这套方案用 FF 麦(前馈)和 FB 麦(反馈)做音频降噪,FBC 是 FB 的补偿通道,通话降噪则用主麦加 FF 麦。Configtool 上能看到三组参数:ANC(含 FF 和 FB)、FBC、Passthrough。硬件上是 4 个麦克风参与降噪、1 个主说话麦、2 个振动喇叭加 2 个声音喇叭。
四种 ANC 模式对应四组滤波器,每组滤波器都是 FF+FB+FBC 三件套的 L/R 组合:
| 滤波器 | 组成 | 典型用途 |
|---|---|---|
| Filter 1 | FF1(L/R)+FB1(L/R)+FBC1(L/R) | ANC 模式一 |
| Filter 2 | FF2(L/R)+FB2(L/R)+FBC2(L/R) | ANC 模式二 |
| Filter 3 | FF3(L/R)+FB3(L/R)+FBC3(L/R) | ANC 模式三 |
| Filter 4 | FF4(L/R)+FB4(L/R)+FBC4(L/R) | ANC 模式四 |
默认滤波器枚举值要记牢:AUDIO_ANC_CONTROL_ANC_FILTER_DEFAULT值为 1,AUDIO_ANC_CONTROL_PASS_THRU_FILTER_DEFAULT值为 9。这两个值在 log 里会直接出现,看到 1 就是 ANC,看到 9 就是通透。
3.2 按键行为映射到 key_action
目标是在 home_screen 下用按键切 ANC。链路是:按键事件 → 进入_proc_key_event_group处理 → 所有 ANC 行为统一走app_home_screen_process_anc_and_pass_through。前提是MTK_ANC_ENABLE已开启,在feature_68_evk.mk里确认。
key_action的四个取值决定了切换逻辑:
KEY_PASS_THROUGH:通透模式开/关KEY_ANC:ANC 开/关KEY_SWITCH_ANC_AND_PASSTHROUGH:全关 → 通透开 → ANC 开KEY_BETWEEN_ANC_PASSTHROUGH:通透开 ↔ ANC 开
把物理按键绑到某个key_action,改的是customerized_key_config.c。比如三连击 POWER 键绑KEY_SWITCH_ANC_AND_PASSTHROUGH,改完编译烧录,按键会有提示音。
3.3 有提示音却没降噪效果:参数没写进去
这是新手最常卡住的地方。三连击有提示音,说明按键事件和key_action都通了,但听不到降噪差异,原因是 ANC 参数根本没写进耳机。用 Configtool 打开工程的download文件夹,会看到 ANC 模式里参数是空的。
解决路径:把声学调好的 ANC 参数(.nvr文件)通过 Configtool 的 Import NVR 功能导入,或者直接在 tool 上调整。先 Write NV 再 Reset,FF、FB、FBC、AiroThru 参数才真正写进耳机。写完再循环三连击,能听出不同模式的降噪差异,才算切换成功。
代码层面,KEY_SWITCH_ANC_AND_PASSTHROUGH会改变target_anc_type和target_filter_id,再传入app_anc_service_enable执行。看 log 时过滤anc_result,三个模式循环切换时能清楚看到滤波器 ID 在变。
3.4 把 ANC 参数固化进代码
参数只在 NV 里,换一台机器烧录就没了,量产必须固化。流程是:先clean再build生成最新download,用 Configtool 打开download,导入声学 NVR,再用 Special_Export 导出变更,会生成 4 个文件(含syskey.xml和filesystem.bin)。如果用 Save 方式保存成download,生成 3 个文件,其中syskey和bin与前者一致。
关键一步:编译时是多个 XML 一起生成 bin 的。以ab1568_evk为例,xml 1 有 7 个 KeyID,xml 2 有 4 个,xml 3 是剩下的全部。把syskey.xml里变更的参数逐个更新到这三个nvkey.xml——有的替换、没有的添加。注意 ANC 参数的 KeyID 在0xEE00~0xEEFF区间,这部分在nvkey.xml里原本没有,必须手动加。同时替换filesystem.bin,重新编译,再用 Configtool 打开download确认 ANC 参数已变成 NVR 里的配置,就说明固化成功。
3.5 NVR 数值解析:高低字节反转
看 NVR 原始值容易被绕晕。以0xE1E5 = 10FF 1400 D8DC D8DC为例,规则是高字节在前、低字节在后,解析时先反转再换算:
10FF反转成FF10,十六进制转十进制得 65296,减去 65536 得 -240,对应 component gain -2.4dB1400反转成0014,转十进制得 20,对应 component gain 0.2dB
这个换算在核对 ANC Default Setting 的 Component Gain 校准时必用,算错一位数降噪曲线就偏了。
4. 事件、超时与电源管理:那些容易配错的参数
4.1 ui_shell 事件三件套
事件管理有三个核心函数,用错一个就是内存泄漏或事件丢失:
// 发送事件:把事件投递到 UI Shell 事件队列 ui_shell_send_event(false, EVENT_PRIORITY_HIGH, event_id, group_id, sizeof(payload), &payload, 0, timeout_ms); // 删除事件:按 event_id 从队列移除尚未处理的事件 ui_shell_remove_event(event_id); // 接收事件:在活动进程的 init 里注册输入消息处理 ui_shell_init_input_msg(activity_handle, handler_func);逻辑说明:ui_shell_send_event的参数里,第一个布尔值表示是否立即发送,group_id决定哪个活动进程能收到,timeout_ms是事件在队列里的存活时间,超时未处理会被丢弃。ui_shell_remove_event常用于「用户快速连按,取消上一次待处理的切换」,不删会积压。ui_shell_init_input_msg必须在活动进程初始化阶段调用,晚于事件到达就收不到。
参数上最容易错的是timeout_ms:设太短,事件在忙时被丢;设太长,取消逻辑失效。我一般按业务最坏处理耗时乘 2 来给。
4.2 超时、自动关机与配对时间
自动关机配置和配对时间设置都落在超时参数上。自动关机本质是一个空闲计时器,超时后触发关机事件;配对时间窗口决定耳机在未连接状态下保持可被发现多久。这两个值配错的表现很典型:自动关机太短,用户听歌中途断连;配对窗口太短,手机搜不到耳机。
开机提示电量依赖电量监测模块在启动阶段读到的电压值,和充电参数监测共用同一套 ADC 采样。监测充电参数时要关注采样周期和滤波,采样太密增加功耗,太疏则过充保护响应慢。
清除配对列表和链路丢失重连是一对:清列表后设备进入可配对状态,链路丢失重连则依赖保存的配对信息做回连。清列表的代码路径要确认同时清了 NV 里的绑定信息,只清内存的话重启又回来了。
4.3 SideTone、音频路径与 PEQ
SideTone 是通话时让自己听到自己声音的量,设太大像回声、设太小说话没底,通常在 Configtool 里按 dB 调。音频路径设置分 Line-in 和 BT 两种通路,切换时要同步切 ANC 的输入源,否则降噪作用在错误的通路上。PEQ 设定方法按频段给增益,调音时先定目标曲线再逐段逼近,别一上来就拉满。
5. 避坑排查:五个真实翻车现场
现象一:改了宏但行为没变。原因:改的 mk 不是实际参与编译的那个,或者没 clean。解决:先./build.sh list确认工程对应的 mk,改完强制 clean 再 build,编译日志里搜宏名确认生效。
现象二:按键有提示音但 ANC 无效果。原因:ANC 参数没写进 NV,download里 ANC 模式为空。解决:Import NVR 后 Write NV + Reset,再验证;量产则走 Special_Export 固化到nvkey.xml和filesystem.bin。
现象三:事件偶发丢失。原因:ui_shell_send_event的timeout_ms太短,或group_id填错导致目标活动进程收不到。解决:按最坏处理耗时乘 2 设超时,核对group_id与目标 activity 一致,必要时用ui_shell_remove_event清理积压。
现象四:NVR 数值对不上。原因:忘了高低字节反转,或减 65536 的负数处理漏了。解决:严格按「反转 → 转十进制 → 负数减 65536」三步走,拿已知 dB 值反推验证一遍。
现象五:FOTA 升级后 NV 参数丢失。原因:只更新了固件没同步 NVKEY,或NVKEY_Setting.c里的写入函数没覆盖新增 KeyID。解决:FOTA 包同时带 NV 变更,用 Special_Export 导出后核对NVKEY_Setting.c的写入范围,0xEE00~0xEEFF这类新增区间要显式补。
6. 产测与调试通道:DUT、RACE 与 USB log 的配合
功能调通只是第一步,能不能量产看产测链路。DUT 模式测 RF 是射频校准的入口,进入后配合仪器测发射功率和频偏;产测测试模式覆盖按键、LED、充电、麦克风等硬件项。AT+CMD 命令和 RACE/RAW 指令是两条控制通道,AT 转 Race 的格式转换要按固定帧头来,格式错一位设备就不响应。
USB 口通信/打 log 是排查利器,配置好串口参数后,log 里能直接看到anc_result、事件 ID、NV 读写结果。设置设备信息(名称、地址等)也走这条通道。读耳机现有 NVKEY 时,先确认NVKEY_Setting.c里注册的 KeyID 列表,再用工具读,读出来和 Configtool 显示对不上,多半是 KeyID 区间没对齐。
我现在的习惯是:任何一次 ANC 参数变更,都强制走一遍「Import NVR → Write NV → Reset → 听感验证 → Special_Export → 更新 nvkey.xml → clean build → Configtool 复核」这条完整链路,少一步后面量产就得多花一天返工。产测阶段尤其别省 USB log,黑匣子一样的日志能省掉大量猜测。希望帮到你。
本文还有配套的精品资源,点击获取