XVF3800 默认核资源使用分析(中): xobjdump 实测与内存推算
上篇确认了两个 tile 的 8 个逻辑核全部占满。本篇用 xobjdump 对官方固件逐一实测:--resources 汇总怎么读、tile[1] 那 5 行数字的真实含义,以及每 tile 512 KB SRAM 的推算方法。
一、xobjdump 实测结果
1.1 --resources 原始输出(UA 构建 ua-io48-lin)
Application id number: 0x00000000 tile[0] (node "0", tile 0) stack usage, upper bound: 12748 tile[0] (node "0", tile 0) program size, upper bound: 501508 tile[0] (node "0", tile 0) free memory, lower bound: 10032 tile[0] (node "0", tile 0) thread usage, upper bound: 8+ tile[0] (node "0", tile 0) unused threads, lower bound: 0 tile[0] (node "0", tile 0) timer count, upper bound: 4 (unused: 6) tile[0] (node "0", tile 0) channel end usage, upper bound: 4+ (unused: 28) tile[0] uses port XS1_PORT_1F/1E/1H/1J/1K/1I/8A/8B ← USB 物理端口 tile[1] (node "0", tile 1) stack usage, upper bound: 356 ← 引导桩(见 1.3) tile[1] (node "0", tile 1) program size, upper bound: 6104 ← 引导桩(见 1.3) tile[1] (node "0", tile 1) free memory, lower bound: 517828 ← 引导桩(见 1.3) tile[1] (node "0", tile 1) thread usage, upper bound: 1 ← 引导桩(见 1.3) Node "0" system frequency (Hz) = 800000000
1.2 逐项解读(tile[0])
| 报告项 | 数值 | 解读 |
|---|---|---|
| stack usage | 12748 B | = main_tile0.nstackwords(12600 B)+ 148 B 开销,即 8 个核的栈合计 |
| program size | 501508 B | 代码 + 数据 + BSS(含 23 KB FreeRTOS 堆、USB 缓冲、SHF 后处理状态) |
| free memory | 10032 B | 524288 − 501508 − 12748,仅剩 1.9% |
| thread usage | 8+ | 「+」表示含无法静态确定的部分;由 maxcores 链恰好 = 8 可确认就是 8,unused = 0 |
| timer / chanend | 4(上限)/ 4+ | 每 tile 共 10 个硬件定时器已用 4 个;通道端是静态下限,运行时由 chan_alloc() 动态申请,实际占用远高于此(通道端总数 32/tile) |
| ports | 1E/1F/1H/1J/1K/1I/8A/8B | 即 xn 文件中的 8 个 USB 端口;PDM/I2C/SPI 等端口经核间接访问,工具未逐一列出 |
| system frequency | 800 MHz | PLL 配置 0x0000c702,参考时钟分频 7(24 MHz 晶振) |
1.3 -t 符号表证据
从 xobjdump -t 输出中检索关键符号(节选):
0x00000008 ... main_tile0.maxcores ← tile[0] 需 8 核 0x00000003 ... __xcore_interrupt_permitted_ugs_pp_task.maxcores 0x00000001 ... __xcore_ugs_shim_mic_array_task.maxcores 0x00000001 ... __xcore_ugs_shim_usb_buffer.maxcores 0x00000001 ... __xcore_ugs_shim_wrap_XUD_Main.maxcores 0x00000002 ... __xcore_ugs_shim_tile_common_start_rtos_app.maxcores 0x00000008 ... main_tile1.maxcores ← tile[1] 需 8 核 0x00000004 ... __xcore_ugs_shim_aec_task.maxcores 0x00000001 ... __xcore_ugs_shim_audio_manager_task.maxcores 0x00000001 ... __xcore_ugs_shim_i2s_task.maxcores 0x00000001 ... __xcore_ugs_shim_reserved_core.maxcores 0x00000001 ... __xcore_ugs_shim_tile_common_start_rtos_app.maxcores
与上篇第 4 节源码逐项吻合:两个 tile 的静态核需求都是 8,占用率 100%。对 INT 构建(intdev-lr48-lin-i2c)做同样分析:tile[0] 变为 pp_task 3 + mic_array 1 + rtos 4 = 8,tile[1] 不变,结论一致。
1.4 tile[1] 那 5 行数字的真实含义:它们描述的是引导桩
推荐命令:xobjdump -t --resources(两个选项合用)。-t 会把 .xe 内的每个 Loadable 分段单独列出符号表,这时能看到关键结构——每个 tile 有两个 Loadable:
| Loadable | 内容 | tile[0] | tile[1] |
|---|---|---|---|
| Loadable 1 | 引导桩:_start + _DoSyscall + 交换寄存器读写等十几个函数,负责被引导/接收主镜像 | 348 B | 96 B |
| Loadable 2 | 主应用:全部业务代码(main_tile0/XUD/pp_task、main_tile1/aec_task…) | 501387 B | 511104 B |
对照 --resources 汇总即可对号入座:
tile[0]汇总 = Loadable 2(主应用):program 501508 ≈--size的 501387;thread 8+ 对应main_tile0.maxcores = 8;stack 12748 ≈main_tile0.nstackwords(3166 字)× 4 B = 12664 加系统开销。tile[0] 数据可信。tile[1]汇总 = Loadable 1(引导桩):thread usage 1 恰好等于桩内全部函数的 maxcores = 1;chanend 2、timer 1 也是桩级别的量;program 6104 B 与 96 B 的桩体同量级(含引导运行时开销)。主应用main_tile1.maxcores = 8完全没有体现在这 5 行里。23 个固件
tile[1]数值完全相同的原因:所有构建的tile[1]引导桩由工具链生成、逐字节相同,于是统计结果自然恒定——不是工具失真,而是统计对象根本不是主应用。
因此 tile[1] 的真实内存/核数必须从 Loadable 2 的符号表推算。--resources 的 tile[1] 汇总并非「错误数据」,但不能用来评估主应用的资源占用,工程上请忽略。
tile[1] 内存推算方法(同样适用于任何 XMOS 双 loadable 固件):
剩余 RAM = 524288 −(最高 BSS 结束地址 − 0x80000)− main_tile1.nstackwords × 4
| 构建 | 最高符号地址 | 已用(代码+数据+BSS) | 栈 | 剩余 |
|---|---|---|---|---|
| UA(ua-io48-lin) | _dfu_ctx @ 0x0FCCF8 | 511224 B | 8752 B(0x88C 字) | ≈ 4.3 KB |
| INT(intdev-lr48-lin-i2c) | ucHeap @ 0x0F5DC8 | 482760 B | 8360 B(0x82A 字) | ≈ 32.4 KB |
用同一方法验算 tile[0](UA):524288 − 501508 − 12748 = 10032 B,与工具自报值完全一致,说明该算法可靠(按符号地址估算存在数百字节级的对齐误差)。
1.5 内存与镜像构成

[图 1 每 tile 512 KB SRAM 占用:UA 构建 tile[1] 只剩 4.2 KB,INT 构建余量宽松得多]
| Loadable | tile | text | data | bss | 合计 |
|---|---|---|---|---|---|
| Loadable 1(引导桩) | tile[0] | 304 | 44 | 0 | 348 |
| Loadable 1(引导桩) | tile[1] | 64 | 32 | 0 | 96 |
| Loadable 2(主应用) | tile[0] | 358972 | 107179 | 35236 | 501387 |
| Loadable 2(主应用) | tile[1] | 411296 | 26452 | 73356 | 511104 |