XVF3800 默认核资源使用分析(下): 构建差异、数据流与工程建议

2026-10-26 14:58:05 吴昊 2

上篇给出核分配模型,中篇给出 xobjdump 实测与内存推算。本篇收尾:UA 与 INT 两种构建的核心差异、音频数据流与逻辑核的对应关系、加功能时的工程建议,以及全部数值的复现命令与常见误读澄清。


一、UA 与 INT 构建的核心差异

项目UA 构建(USB Audio)INT 构建(I2S/SPI 从机)
tile[0] 裸金属核pp 3 + mic 1 + usb_buffer 1 + XUD 1pp 3 + mic 1
tile[0] FreeRTOS 核2(appconfNUM_FREE_RTOS_CORES = 2)4(= 4,其中 1—2 个兼作 SPI/I2C 从机控制核)
tile[1] 核面完全相同(aec 4 + audio 1 + i2s 1 + reserved 1 + rtos 1)同左
tile[0] 剩余 RAM≈ 9.8 KB≈ 33.5 KB
tile[1] 剩余 RAM≈ 4.3 KB≈ 32.4 KB
典型用途USB 会议音箱 / 麦克风外部主控 MCU 通过 I2C/SPI 控制

规律很清晰:无论哪种构建,两个 tile 都被精确填满到 8 核——XMOS 在分配时是「核数守恒」的,UA 构建把 INT 构建里空闲的 2 个 RTOS 核让给了 USB 栈。

二、数据流与核归属

图片关键词

[图 1 音频数据流与逻辑核的对应关系(UA 构建):整条链路共用 8 个核]

跨 tile 的帧传递通过 intertile 通道(xn 中声明的 port 7 链路)完成;SHF 库采用 split_post 结构,把 AEC 放在 tile[1]、后处理放在 tile[0],让两边的 H 组核各自吃满帧预算。

两个官方客户钩子的执行位置值得注意:far_end_dsp() 在 tile[1] i2s_task 的发送回调内执行;post_shf_dsp() / beam_selection() 在 tile[1] audio_manager_task 内执行。它们都挤占所在核的帧内时间,而不是跑在 reserved_core 上;reserved_core 是独立完整的 1 个核,适合放轮询型、常驻型的自定义逻辑(此前 UART 扩展方案正是复用它)。


三、工程含义与建议

1. 不要指望「再开一个核」。两个 tile 静态 8/8 占满,新增常驻逻辑的可行路径只有:

  • 复用 tile[1] reserved_core(推荐,1 个完整核,栈仅 24 B 起步);

  • 把轻量处理塞进 far_end_dsp() / post_shf_dsp() 钩子(共享核,须核算帧内耗时);

  • 降低采样率或关闭某些功能(如 bypass 模式)换取空闲时间。

2. UA 构建的 tile[1] RAM 只剩约 4.3 KB。往数据面加大缓冲、加日志、加大栈都可能直接链接失败或运行时溢出;确需大缓冲可评估 INT 构建,或启用 RESERVE_USER_MEMORY 预留的 17 KB 区域(该区域默认以 user_reserved[] 数组形式占位在 BSS 中)。

3. 评估 MIPS 余量看两个量:SHF 框架每帧统计 idle_time_ticks / min_idle_time_ticks(shf_wrapper.c),与 SHF_FRAME_TIME_TICKS 相比即得到 H 组的余量;核是否「忙」则可用 core_burn 模式(boot 时置魔法字 0x90C0FFEE)做压力对照。

4. 读资源报告的姿势:用 xobjdump -t --resources 一次拿到汇总与分段符号表;线程/内存结论以 -t 符号(maxcores / nstackwords)+ --size 推算为准。--resources 汇总中 tile[0] 描述主应用(可信);tile[1] 描述引导桩,评估主应用时须按中篇 1.4 节方法重算。


四、复现命令清单

# ① 资源汇总 + 分段符号表(推荐合用,可看清每个 Loadable 的内容)
xobjdump -t --resources application_xvf3800_ua-io48-lin.xe
# 输出结构:Loadable 1 tile[0](引导桩 348 B)→ Loadable 1 tile[1](引导桩 96 B)
#           → Loadable 2 tile[0](主应用)→ Loadable 2 tile[1](主应用)→ 资源汇总
# 注意:汇总中 tile[0] = 主应用;tile[1] = 引导桩(评估主应用须按中篇 1.4 重算)

# ② 导出符号表并检索每个作业的核数与栈
xobjdump -t application_xvf3800_ua-io48-lin.xe > syms.txt
# 在 syms.txt 中检索:
#   main_tile0.maxcores / main_tile1.maxcores
#   __xcore_ugs_shim_*.maxcores
#   *.nstackwords

# ③ 各 loadable 精确大小
xobjdump --size application_xvf3800_ua-io48-lin.xe

# ④ tile[1] 剩余内存推算(UA 构建)
#   剩余 = 524288 − (0x0FCCF8 − 0x80000) − 0x88C×4 = 4.3 KB

以上所有数值均基于 v3.2.1 源码与配套官方二进制包实测得出,可通过本节命令完整复现。


五、常见误读澄清

现象正确理解
thread usage 8+ 带加号工具声明「这是上限且可能不精确」;结合 maxcores 链 = 8 且单 tile 只有 8 核,实际就是 8
unused threads: 0静态分析结论:没有任何空闲核,与源码 PAR_JOBS 一致,并非「系统卡死」
tile[1] 报告 program 只有 6104 B那 5 行描述的是 tile[1] 的引导桩(Loadable 1,各固件逐字节相同,故数值恒定),不是主应用;主应用数据须用 --size + Loadable 2 的 nstackwords 重算(见中篇 1.4 节)
channel end usage 4+仅为静态下限;通道端在运行时由 chan_alloc() 动态分配,不能据此判断通道端紧张与否
reserved_core 看起来「闲置」它是被 PJOB 永久占用的 1 个核(每 1 秒醒一次),核位本身不参与调度分配;这正是它可以被改造成自定义任务的原因
注释里的「1 spare」已过时:当前 PAR_JOBS 下 tile[1] 为 8/8
首页
产品
新闻
联系