首页 / 资讯中心 / 文章详情

嵌入式架构学习2--OpenPineBuds(TODO)

嵌入式架构学习2--OpenPineBuds(TODO) ★ FEATURED ARTICLE
1 OpenPineBuds简介2 下载和编译编译验证通过安装apt install ffmpeg minicom工具链按Dockerfile同版本gcc-arm-none-eabi-9-2019-q4-major-x86_64到/data/toolchain验证9.2.1 20191025构建export PATH/data/toolchain/gcc-arm-none-eabi-9-2019-q4-major/bin:$PATH cd /data/OpenPineBuds make -j32 Topen_source DEBUG1 # 即 build.sh 内容新鲜校验证据verify.py81b9afc Merge pull request #124 -rwxrwxr-x 883K out/open_source/open_source.bin -rwxrwxr-x 16M out/open_source/open_source.elf text 752308 data 151428 bss 292028 dec 1195764 VERIFY_OK BUILD_RC03 代码结构分析apps/ 3.6M 业务main/key_handler/ibrt/anc/audioplayers/battery/cmd platform/ 12M HAL/CMSIS/drivers/best2300p/main/main.cpp启动 services/ 67M 核心bt_app/ibrt_core/app_ibrt/app_tws/audioflinger/ bt_profiles_enhanced/ble_stack/nvrecord/ota/audio_process config/ 1.6M target.mk open_source/tgt_hardware.c/h res/en/*.opus utils/ 932K cqueue/list/kfifo/crc/heap 等基础库 rtos/ 2M rtx/rtx5/freertos默认 RTX5 thirdparty/ userapi 等 611 *.c / 136 *.cpp / 960 *.h关键链路启动platform/main/main.cpp→services/bt_app/besmain.cpp:besmain()初始化 BT/音频/NV/IBRT交互apps/main/key_handler.cpp触摸逻辑双耳右单击播放暂停/双击下一曲/长按ANC开关/三击音量左双击上一曲/三击音量-通过app_ibrt_if_start_user_action()主从同步左右判别apps/main/ibrt.cppCurr_Is_Master/Slave()用耳机内电阻选 L/R非 TWS 主从配对TWSservices/ibrt_core/ app_ibrt/ app_tws/BES IBRT 智能转发音频services/audioflinger/audioflinger.cservices/bt_app/a2dp_codecs/SBC/AAC/LDAC/LHDC/Opus/Scalableapps/audioplayers/ANCapps/anc/src/app_anc.cservices/audio_process/config/suggested_anc_gains.hFF 300/500/700FB 200/350/500ef606_average_coefficients.h为原厂 IIR 基线ANC_FF_ENABLED1 FB1配置config/open_source/target.mkCHIPbest2300p FLASH_SIZE0x400000 TRACE 2000000 ULTRA_LOW_POWER1 DAC_CLASSG1存储services/nvrecord/配对/音量/耳机角色services/nv_section/norflash_api/内存out/open_source/_best1000.ldsROM 48K FLASH 4M RAM ~880K RAMCPFLASH 0x3C000000 RAM 0x20000000 RAMX 0x00200000烧录调试无需硬件已读脚本确认./backup.sh; ./download.sh # 本质bestool write-image out/open_source/open_source.bin --port /dev/ttyACM0/1 ./uart_log.sh # 2Mbps UART log AUDIOcn ./build.sh # 中文提示音config/_default_cfg_src_/res/cn/基本结构就是启动了4个子线程。┌ main (主线程, 建完即等信号)│ osSignalWait: 0x04关机 / 0x08复位│ platform/main/main.cpp:311▼app_init() apps/main/apps.cpp:1889┌────────────┬──────────────┬──────────────┐▼ ▼ ▼ ▼app_thread BesbtThread tws_ctrl(闭源) af_threadperipheral anc_fade(按需)app_thread业务总管。收 KEY/AUDIO/BATTERY/BT/ANC 等 mailbox 消息触摸、LED、电池、ANC 开关、音量策略都在这裁决再往下派发。BesbtThread蓝牙协议栈。跑 evm_queue 事件循环管配对、回连、A2DP/HFP/AVRCP 信令起播停播事件往 app_thread 抛。tws_ctrl闭源库内双耳私链。传 0x8001~ 命令配对同步、按键透传0x8015、主从切换、音量/状态对齐。af_thread音频执行。管 af_stream_open/start/stop按 DMA 节奏回调 bt_sbc_player_more_data 取数经 EQ/DRC 送 DACMIC 通路反向同理。这里主要的就是app_thread不过它就是个空壳分发器业务全在注册进来的 handler 里app_key_handle_processapps/key/app_key.cpp:136KEYapp_audio_handle_processapp_audio.cpp:708AUDIOapp_battery_handle_processapp_battery.cpp:522app_bt_handle_processapp_bt.cpp:3788BTapp_anc_handle_processapp_anc.c:1662ANC等app_thread按mod_id查表调用ret!0才打条 trace。所以“业务总管”是它没错但实现上它是路由表具体干活看各*_handle_process。app_thread路由表里一共 13 个processapp_set_threadhandle注册open_source下部分被裁mod_idprocess 函数文件处理的消息作用KEYapp_key_handle_processapps/key/app_key.cpp按键事件CLICK/DOUBLE/TRIPLE/ULTRA/LONG/LONGLONG触摸分发单双耳/左右判断调 IBRT 动作AUDIOapp_audio_handle_processapps/audioplayers/app_audio.cppAPP_BT_SETTING_OPEN/CLOSE/SETUP/RESTART/CLOSEALL播放器启停A2DP/SCO/lineinpromotionBATTERYapp_battery_handle_processapps/battery/app_battery.cppMEASURE_PERIODIC_FAST/CHARGING/NORMAL、STATUS_UNDERVOLT/NORMAL/OVERVOLT/PDVOLT/CHARGING/INVALID电量采样、充放电状态机、低满电指示BTapp_bt_handle_processservices/bt_app/app_bt.cppAPP_BT_REQ_ACCESS_MODE_SET等建链/配对/回连请求蓝牙业务层配对、回连、profile开关AUDIO_MANAGEapp_bt_stream_manager_handle_process.../app_bt_media_manager.cppSTREAM_MANAGER_START/STOP/SWITCHTO_SCO/STOP_MEDIA/UPDATE_MEDIA/SWAP_SCO/CTRL_VOLUME/TUNE_SAMPLERATEA2DP/SCO 通道仲裁谁抢af_streamANCapp_anc_handle_processapps/anc/src/app_anc.cANC 开关/模式切换事件FF/FB 开关、anc_open/select_coefWNRapp_wnr_internal_event_processapps/anc/src/anc_wnr.c风噪检测内部事件风噪模式切换ANC_WNR0死的MICapp_mic_processapps/mic/app_mic.cppMIC 采集事件MIC 通路管理VOICE_DETECTORapp_voice_detector_processapps/voice_detector/VAD 事件语音唤醒没开死的CMDapp_cmd_handle_processapps/cmd/app_cmd.cpp串口收到的字符串命令转hal_cmd_runPC_CMD_UART0死的OHTERapp_factorymode_processapps/factory/app_factory.cppFACTORYMODE_RUNNING/PASS/FAILED产测模式正常固件不用CUSTOM_FUNCTIONapp_custom_function_processservices/bt_app/app_bt.cpp自定义功能消息预留扩展口VOBvoice_over_ble_handlerservices/ble_app/.../voice_over_ble.cBLE 语音消息BLE 关不用结论open_source实际活着的就是 KEY/AUDIO/BATTERY/BT/AUDIO_MANAGE/ANC/MIC 七个其余是条件编译留的空位。4 蓝牙蓝牙是绝对重点——代码量占大头services/bt_app30文件 两套闭源协议栈库音频和控制全是它的附庸。分层自底向上层位置内容控制器驱动platform/drivers/bt/bt_drv_*.cbest2300p/射频/基带寄存器、BESHCI_Open/Poll收发 HCI 包Host 协议栈闭源.aservices/bt_if_enhanced/libservices/bt_profiles_enhanced/libHCI/L2CAP/RFCOMM/SDP 定时调度co_timer/queue/bufENHANCED_STACK1新栈BT_RF_PREFER2M选包长Profile半开bt_profiles_enhanced/inca2dp/avdtp/avrcp/hfp/hsp/dip/spp/hid/gatt.hA2DP 拉流、AVRCP 播控、HFP 通话、DIP 设备信息业务适配开源可改services/bt_app/besmain.cpp建BesbtThreadevm_queueapp_bt.cpp配对回连app_a2dp.cpp/a2dp_codecs/协商解码app_hfp.cpp通话app_bt_stream.cpp音频通路编排app_bt_media_manager.cppA2DP/SCO 仲裁app_keyhandle.cpp按键映射到 AVRCP/HFPapp_rfcomm_mgr/app_spp/app_sec通道与安全双耳services/ibrt_core app_ibrt app_tws私链同步 Slave Snoop 手机链路libtws_ibrt_*.a闭源跑起来的样子开机 BesbtInit - BesbtThread(evm_queue) - HCI初始化 - 可发现可连接 手机连上 - A2DP signaling - app_a2dp协商codec - media_manager抢到STREAM - bt_sbc_player(START) - af_thread出声AVRCP/HFP走keyhandle上下行 双耳另有一条TWS私链触摸/音量/ANC状态全经它对齐OpenPineBuds 深度分析81b9afc/data/OpenPineBuds已编过883K bin四路并行深挖结论汇总闭源边界已标出。A. 启动/RTOS/内存/构建调用链ROM - Boot_Loader platform/main/startup_main.S:35 - NVIC_InitVectors BootInit copy .data/清.bss SystemInit - _start - rtos/rtx5/rtx_lib.c:693 software_init_hook - osKernelInitialize osThreadNew(main) osKernelStart - main() platform/main/main.cpp:167 - tgt_hardware_setup hwtimer/DMA/norflash/trace pmu/analog/mpu - app_init() apps/main/apps.cpp:1889 - app_os_init - app_thread app_bt_init/af_open/app_audio_open - btdrv_start_bt BesbtInit services/bt_app/besmain.cpp:493 - BesbtThread - besmain():342 BESHCI_Open/357 bt_stack_initilize - while(1) evm_queue bt_process_stack_events BESHCI_Poll注意入口是ENTRY(Boot_Loader)不是Reset_Handler后者只是platform/cmsis/cmsis_nvic.c:71弱别名死循环。RTOS默认RTX经典不是 RTX5。config/common.mk:822CPUm4 - KERNEL?RTXbest2300p 恰 M4rtos/Makefile按RTX/RTX5/FREERTOS切目录垫片include/rtos/*/cmsis_os.h。CORE_DUMP1编入crash_catcherxyzmodemCORE_DUMP_TO_FLASH0所以不占 1M flash。ENHANCED_STACK1切bt_if_enhanced/bt_profiles_enhanced回调模式BesbtThread栈 3326。WATCHER_DOG0看门狗关。内存out/open_source/_best1000.lds:52ROM 0x0 48K | FLASH 0x3C000000 4M | FLASH_NC 0x38.. /FLASHX 0x0C..别名XIP | RAM 0x2000.. /RAMX 0x0020.. | FRAMX顶部22K高频码 | RAMCP顶约128K给CP核overlay。双核MCU-M4跑主固件CP跑RAMCPoverlayA2DP_CP_ACCEL/SCO_CP_ACCEL1经intersys通信。size: text 752308 data 151428 bss 292028。构建build.sh - make -j Topen_source DEBUG1根Makefile:191校验T二次进out/open_source每目录Makefile obj-yscripts/build.mk递归built-in.o --partial链接LDS由scripts/link/best1000.lds.S经CPP-DCHIP_BEST2300P -DFLASH_SIZE.. -DCHIP_HAS_CP生成。B. 蓝牙/IBRT/TWS核心 IBRT在闭源.aservices/ibrt_core/lib/libtws_ibrt_enhanced_stack_*_RTX.a头文件只露状态机。角色services/ibrt_core/inc/app_tws_ibrt.hIBRT_MASTER 0 / SLAVE 1 / UNKNOW 0xffibrt_ctrl_t ~80字段nv_role/current_role/local/peer/mobile_addr/linkKey/handles/tws_mailbox/a2dp_codec/tss_state。nv_role持久左右身份app_ibrt_nvrecord.cpp从nvrecord_env-ibrt_mode载无则UNKNOW首次配对落盘current_role本次谁连手机谁Snoop可app_tws_ibrt_switch_role 0x8006 tss_state翻转。薄封装apps/main/ibrt.cpp:Curr_Is_Master/Slave。配对IBRT_SEARCH_UI1app_ibrt_keyboard.cppDOUBLECLICK直搜ULTRACLICK单耳自由配对FREEMAN vs TWS_PAIRING区分双耳全新 vs 已连TWS再拉手机。用户动作同步app_ibrt_keyboard.cpp:263触摸 - keyboard_notify - tws_ctrl_send_cmd(0x8015 KEYBOARD_REQUEST) - 对端request_handler - app_ibrt_if_start_user_action - SLAVE: app_ibrt_ui_send_user_action(闭源lib)转发 - MASTER: app_ibrt_ui_perform_user_action本地执行 PLAY/PAUSE/FORWARD/BACKWARD-a2dp_handleKey(AVRCP) VOLUP/DN-app_bt_volumesync_volume_info, ANC-app_anc_key命令表app_tws_ibrt_cmd_handler.h:0x8001~8030底层app_tws_ctrl_thread.h:70 tws_ctrl_send_cmd走私链TWS-LINK音频Slave直接Snoop手机ACL/SCOSNIFFER_INIT_CMP/SCO_SNIFFER_EVT区别传统TWS中继。射频功耗BT_RF_PREFER2M只选库后缀_2mEDR优先2M包SNIFFTWS 10s/MOBILE 20s, interval 160/800但SNIFF_MODE_CHECK0关了app_a2dp.o额外检查仍靠ULTRA_LOW_POWER1,NO_SLEEP0。关闭项BLE0 OTA0 TOTA0 GFPS0 GATT_OVER_BR_EDR0 ONE_BRING_TWO0。ble_stack/在但不用无BLE广播/FastPair/TOTA调参通道无蓝牙OTAapps.cpp:OTA按键走不到升级只能记一台手机。C. 音频/ANC/Codec/提示音通路A2DP: 空口AVDTP - services/bt_app/a2dp_codecs/app_a2dp_codecs.cpp:56协商 - apps/audioplayers/a2dp_decoder/解码 - app_bt_stream.cpp:force48k重采样af_codec_tune时钟校正 - [MONO?merge_stereo] - audio_process_run(SW_IIR-HW_FIR-DRC-Limiter-HW_IIR) - af_stream_open(ID_0 PLAYBACK) services/audioflinger/audioflinger.c:1330 - hal_codec_best2300p.c DAC SCO: MIC-ADC-CAPTURE-bt_sco_chain speech_tx(DC/AEC/NS/AGC)-eSCO(CVSD/mSBC) ANC旁路: FF外麦/ FB耳内误差麦 - CODEC HW IIR/FIRtotal_gain直混DAC不经A2DP解码 控制: app_anc.c:907 app_anc_enable-anc_open 1032 af_anc_openANChal_aud.h:250 ANC_FEEDFORWARD/FEEDBACK/TALKTHRU/MUSICCANCLE结构体aud_section.h:aud_item{total_gain,iir_bypass, counter,coef[AUD_IIR_NUM]}。config/suggested_anc_gains.h起点FF 300/500/700FB 200/350/500步进FF100/FB50啸叫回退bypass0在耳典型FF400-600/FB250-400。ANC_FB_CHECK1开anc_fb_check_irq_handler app_anc.c:679防啸。警告ef606_average_coefficients.h自述从1MORE Fit SE开耳固件LZMA提取实测coef{0x5F7070..}解码是文本碎片且gain0开耳无密封不可作ANC基线仅格式参考。ANC_WNR0是ANC风噪检测anc_wnr.h需FFT与通话SPEECH_TX_WNR两回事AUDIO_ANC_FB_MC从误差麦减音乐再做FB与AUDIO_RESAMPLE互斥。open_source:ANC1 FF1 FB1best2300p_ibrt_anc:ANC0反无ANC。Codec/buffer纠偏编译AAC1 LDAC1 LHDC0 DECODER_VER2运行app_a2dp_codecs.cpp:94组能力协商。buffer不是README的100K/140K实a2dp_decoder.cpp:48 76K LDAC /50 72K通用 CP 64K/32K。VOLUME_DEFAULT12仅open_sourcecommon缺省10ibrt_anc 17。提示音config/_default_cfg_src_/res/{en,cn,..}/*.opus实测OggS OpusHead预编码镜像非编译.oconvert.sh只管老SBCffmpeg sbcxxd -i不管Opus现build.sh无AUDIOxx参数README残留老机制。切换services/resources/resources.cpp:gpAudioList/_CN aud_get_reoucenvrecord_env media_language开机apps.cpp:2108 app_play_audio_set_lang恢复加语言加res/lang/第二资源块。D. 应用层触摸apps/main/key_handler.cpp:61 双耳右单击播/停 双击下曲 长按ANC 三击音量左双击上曲 三击音量-单耳双击下曲 长按上曲 三击 四击-仓内只留LONGLONGPRESS-reboot。分支!tws_link_connected走单耳 else is_left_side分左右。检出platform/hal/hal_key.c:58LPRESS1500 LL5000 DBL400 CHECK40 去抖80长按计时发LONG抬起计数CLICKcntDOUBLE/TRIPLE/ULTRA。CFG_HW_GPIOKEY_NUM0即无物理键全触摸复用PWR键。动作单字节IBRT_ACTION_* app_ibrt_keyboard.h:30经B域同步。LED/电池/仓CFG_HW_PLW_NUM2app_status_ind.c:86波形BOTHSCAN红蓝交替300ms CHARGING蓝常亮 FULL灭。CONNECTED_BLUE_LIGHT1则已连蓝500/3000闪否则灭。轮询led_control.cpp:12 1s。SUPPORT_BATTERY_REPORT1apps.cpp:236 app_status_battery_report-HFP indicatorapp_battery.cpp:288低电CHARGENEED 满电FULLshutdown3200-4200mV。无私有仓协议仅pmu_charger_get_status P1_1 ext_detect 50ms*3去抖gfps.cpp:17 TODO charger case证明仓电量未做QXW_TOUCH_INEAR_DET 0入耳检测关出盒未连300tick自动关机。NV旧分支非NEWnvrecord.h:38ddb 9条{addr/linkkey a2dp/hfp_vol profile/a2dp_codectype}env{media_language,ibrt_mode,factory_tester,flag[8]}factory 4K{device_name248,bt/ble/tester_addr,xtal}。无ANC持久键ANC仅内存IBRT通知换系数。保存nv_record_flash_flush mainbak双区关机1714/音频296/睡眠in_sleep恢复apps.cpp:1935 nv_record_init 1936 factory_init 2066 env_init。烧录bestool write-image out/...bin --port /dev/ttyACM0/1 download.sh:11双耳同镜像逐只烧需重插抓rebootbackup.sh read-image各一份uart_log.sh minicom -b 2000000 DEBUG_PORT1 uart0。相对stock改动仓键长按5s强制rebootLLPRESS5000app_key_rebootPOWERON5000、仓内不进DFU、电阻分左右、波特2M、任一入仓切换对端、关HID宣告。
阅读完成 · 觉得有帮助?
咨询建站