SK-TDA4VM: c71x无法与linux同时启动

Part Number: SK-TDA4VM

当前情况是:
1. 同一份 C71x 固件,用 CCS/JTAG 直接加载时,可以正常完成 NUFFT 计算,并且能得到性能结果。
2. 用 Linux remoteproc 从 /lib/firmware/j7-c71_0-fw 启动时,remoteproc 状态是 running,dmesg 里也显示 64800000.dsp is now up。
3. 我已经确认 /lib/firmware/j7-c71_0-fw 就是我编译的固件版本,文件里能 grep 到固件 build tag。
4. Linux 侧通过自定义的 /dev/dsp_shared_mem 映射共享 DDR,能够成功写入数据,并且写入 ready=0xA5A5A5A5 后,Linux 自己读回完全正确。
5. 为了排除 PCIe/XDMA 的影响,我又专门做了一个 manual_feed_dsp 测试程序,完全绕过 PCIe,直接向共享 DDR 写固定测试数据和 ready 标志。Linux 侧读回仍然正确。
6. 但是 DSP 侧阶段标记始终停在 c7000005,对应等待 ready 的循环,没有进入后续计算。
 
共享 DDR 布局如下:
- 0xB8000000: X buffer
- 0xB8040000: Y buffer
- 0xB80A0000: ready flag
- 0xB80FF000: stage marker
1. C7x 固件内存映射与 Linux 保留区域的对应关系
我的设备树使用的是 SDK 自带的 k3-j721e-rtos-memory-map.dtsi,其中为 C71x 保留了:
  • vision_apps_c71_0_dma_memory_region: 0xB2000000, 1 MB (shared-dma-pool, no-map)
  • vision_apps_c71_0_memory_region: 0xB2100000, 95 MB (shared-dma-pool, no-map)
  • vision_apps_shared_region: 0xB8000000, 512 MB (dma-heap-carveout)
我的 C7x 固件链接器完全按照这些范围分配:
  • DDR_C7x_1_IPC = 0xB2000000 (1 MB) → 对应 c71_0_dma_memory_region
  • DDR_C7x_1_RESOURCE_TABLE = 0xB2100000 → 在 c71_0_memory_region 起始处
  • DDR_C7x_1 (代码/BSS) = 0xB2604000 ~ 0xB8000000 → 在 c71_0_memory_region 范围内
  • SHARED_DDR_PCIE = 0xB8000000 (1 MB, .ddrData 段, type=NOLOAD) → 在 vision_apps_shared_region 范围内
2. 资源表位置
资源表 (ti_ipc_remoteproc_ResourceTable) 使用 __attribute__((section(".resource_table"), aligned(4096))) 放置在 .resource_table 段,链接到 0xB2100000。编译后的 .map 文件确认 .resource_table 在 0xB2100000,大小 0x98 字节。remoteproc 启动日志也显示正常加载:
remoteproc remoteproc2: Booting fw image j7-c71_0-fw
k3-dsp-rproc 64800000.dsp: booting DSP core using boot addr = 0xb2200000
remoteproc2#vdev0buffer: assigned reserved memory node vision-apps-c71-dma-memory@b2000000
 
 Linux 用户态程序使用 /dev/mem + mmap() 写入 0xB8000000 时报错 Operation not permitted/proc/iomem 显示该区域为 reserved
b8000000-d7ffffff : System RAM
b8000000-d7ffffff : reserved
该区域在设备树中是 dma-heap-carveout(没有 no-map),所以 Linux 内核可能不允许通过 /dev/mem 直接映射。请问:
对于 dma-heap-carveout 类型的保留区域,用户态程序通过什么方式访问是正确的?是否需要通过 /dev/dma_heap/ 接口?或者我是否应该为这 1 MB 的 PCIe 共享区域单独添加一个 no-map 的 reserved-memory 节点,使其可以通过 /dev/mem 访问?
 
为什么同一份固件在 CCS/JTAG 下可以正常计算,但在 Linux remoteproc 启动场景下,DSP 看不到 A72 已经写入 shared DDR 的 ready flag?
这是否与 C71x MMU/cache 属性、shared DDR 的 reserved-memory 配置、remoteproc 启动方式,或者 A72/C71x cache coherency 有关?
  • 您好

    已经收到了您的案例,调查需要些时间,感谢您的耐心等待

  • 您好

    对于 dma-heap-carveout 类型的保留区域,用户态程序通过什么方式访问是正确的?是否需要通过 /dev/dma_heap/ 接口?或者我是否应该为这 1 MB 的 PCIe 共享区域单独添加一个 no-map 的 reserved-memory 节点,使其可以通过 /dev/mem 访问?

    对于 DMA 堆的划分,您需要使用 ioctl 调用 DMA 缓冲区驱动程序来分配该区域的内存,该驱动程序将返回一个可供用户空间应用程序使用的虚拟地址。有关其实现方式的更多详细信息,您可以查看 $(psdkra)/app_utils/utils/mem/src/app_mem_linux_dma_heap.c 中的 appMemAlloc() 函数。 

    如果你想通过 /dev/mem 将其映射为 IO 内存,那么你必须添加一个单独的 no-map 区域

    为什么同一份固件在 CCS/JTAG 下可以正常计算,但在 Linux remoteproc 启动场景下,DSP 看不到 A72 已经写入 shared DDR 的 ready flag?

    我建议在与 Linux 一起使用时,对 c7x 固件进行正常启动。

    这是否与 C71x MMU/cache 属性、shared DDR 的 reserved-memory 配置、remoteproc 启动方式,或者 A72/C71x cache coherency 有关?

    这是第一次使用 CCS 加载固件,还是固件已经通过正常启动加载,这是第二次使用 CCS 加载?

    请尝试在 c7x 中读取内存之前执行 cache invalidate 操作,以确定是否是缓存问题。请确认 a72 是否已写入就绪标志,如果没有,则可能是 remoteproc 启动问题。

    为什么要通过CSS加载它?