我用RDK s100和MCU的五路CAN控制27个标准CAN协议1M波特率的电机,控制代码根据/app/Can/can_multi_ch/main.cpp改编而来,目前是单路发送线程和五路接收线程,发送线程的控制频率是200hz,编译成可执行程序后运行代码电机可以运行,但是在mcu端进行debug时cat log出来发现RollcntErr的数量和RecvAllNum数量只相差1,我不知道这个RollcntErr报错对机器人控制影响有多大,怎么才能避免这么多报错呢?同时dmesg日志中针对我的可执行程序有以下报错求大佬分析:[ 114.794855] ipc-shm-hal: data_callback()[851]: [0][2] irq/14-29f00000(69) put_data_tofifo failed
[ 114.796300] ipc-shm-hal: data_callback()[851]: [0][2] irq/14-29f00000(69) put_data_tofifo failed
[ 114.797946] ipc-shm-hal: data_callback()[851]: [0][3] irq/14-29f00000(69) put_data_tofifo failed
[ 114.798929] ipc-shm-hal: data_callback()[851]: [0][3] irq/14-29f00000(69) put_data_tofifo failed
[ 114.799660] ipc-shm-hal: data_callback()[851]: [0][3] irq/14-29f00000(69) put_data_tofifo failed
[ 114.806256] ipc-shm-hal: data_callback()[851]: [0][2] irq/14-29f00000(69) put_data_tofifo failed
[ 114.850026] ipc-shm-hal: data_callback()[851]: [0][7] irq/14-29f00000(69) put_data_tofifo failed
[ 114.850169] ipc-shm-hal: data_callback()[851]: [0][7] irq/14-29f00000(69) put_data_tofifo failed
[ 115.007860] ipc-shm-hal: data_callback()[851]: [0][7] irq/14-29f00000(69) put_data_tofifo failed
[ 115.008001] ipc-shm-hal: data_callback()[851]: [0][7] irq/14-29f00000(69) put_data_tofifo failed
[ 118.287001] ipc-shm-hal: hal_channel_manage_init()[650]: [0][6] maita_can_test(5910) channel register success.
[ 118.287514] ipc-shm-hal: hal_channel_manage_init()[650]: [0][7] maita_can_test(5910) channel register success.
[ 118.287873] ipc-shm-hal: hal_channel_manage_init()[650]: [0][2] maita_can_test(5910) channel register success.
[ 118.288277] ipc-shm-hal: hal_channel_manage_init()[650]: [0][3] maita_can_test(5910) channel register success.
[ 118.288634] ipc-shm-hal: hal_channel_manage_init()[650]: [0][4] maita_can_test(5910) channel register success.
[ 211.318492] ipc-shm-hal: hal_channel_manage_free()[705]: [0][4] maita_can_test(5910) channel un-register success.
[ 211.318590] ipc-shm-hal: hal_channel_manage_free()[705]: [0][2] maita_can_test(5910) channel un-register success.
[ 211.318656] ipc-shm-hal: hal_channel_manage_free()[705]: [0][3] maita_can_test(5910) channel un-register success.
[ 211.318749] ipc-shm-hal: hal_channel_manage_free()[705]: [0][7] maita_can_test(5910) channel un-register success.
[ 211.318794] ipc-shm-hal: hal_channel_manage_free()[705]: [0][6] maita_can_test(5910) channel un-register success.
你好,RollcntErr这个输出可以忽略,是代码的bug,put_data_tofifo failed这个还在排查中,有进展的话会第一时间同步的
好的好的,非常感谢您
你好,put_data_tofifo failed这个报错应该是acore侧ipc接收数据的fifo满了,想问一下出现这个错误的时候有返回-14的错误吗,如果可以的话可以发下源码,设备接线图以及完整的输出log吗,如果不方便发在评论区的话可以发到我的邮箱:jiawen01.zheng@d-robotics.cc
您好,我已经把您需要的资料发送到您的邮箱了,麻烦您查收哈,感谢您
你好,目前初步排查下来问题应该是接收不够及时,导致IPC中的fifo满了。从而报put_data_tofifo的错误,可以优化一下代码中相关的逻辑
好的谢谢您,我优化一下代码后再试试
可以把recv的进程优先级调高,尽可能的快速收报看看
好的好的感谢!!!
@a热阔落 帖主你好。请问你测下来使用5个can带27个电机,软件开销时间大概是多少?另外,你说的“控制代码根据/app/Can/can_multi_ch/main.cpp改编而来”,那你的控制代码时在MCU的SDK编译的吗?我记得/app/Can/can_multi_ch/main.cpp是Acore这边编译。
你好 @eric_qiang,这个问题问到了 RDK S100 多路 CAN 控制的核心痛点。结合社区已有案例和官方回复,给你直接结论:
核心结论
- 架构确认:
/app/Can/can_multi_ch/main.cpp确实是 Acore 侧 的示例代码(通过 IPC 调用 MCU 资源),不是 MCU 原生代码。 - 性能瓶颈:你提到的 Acore 侧 IPC 通讯 ~300us 的延迟是正常现象(上下文切换 + 数据拷贝),对于 5 路 CAN 控制 27+ 个电机的高频场景(如 200Hz+),这种架构确实存在瓶颈。
- 最佳实践:官方完全支持并推荐 MCU 侧原生开发(FreeRTOS 环境)。即:MCU1 直接操作 CAN 硬件收发,Acore 仅通过共享内存/精简 IPC 与 MCU 进行周期性数据交互(如 1ms 周期)。
针对你问题的具体回答
-
软件开销时间:
- Acore 侧方案(当前帖主方案):受限于 IPC,单帧通讯开销约 300us+,多路并发时 CPU 负载较高,200Hz 控制 27 个电机已接近极限(参考帖主遇到的
put_data_tofifo failed报错,本质是接收处理不及时导致 FIFO 溢出)。 - MCU 侧方案(推荐):MCU 直接操作硬件,CAN 收发延迟可控制在 50us 以内。Acore 与 MCU 的数据交互(共享内存)开销极低,整体控制周期轻松稳定在 1ms (1kHz) 甚至更高。
- Acore 侧方案(当前帖主方案):受限于 IPC,单帧通讯开销约 300us+,多路并发时 CPU 负载较高,200Hz 控制 27 个电机已接近极限(参考帖主遇到的
-
编译环境区分:
- Acore 侧:使用 Ubuntu 交叉编译工具链(aarch64),编译生成 Linux 可执行文件,运行在 Acore Linux 系统下。
- MCU 侧:使用 FreeRTOS SDK 工具链,编译生成 MCU 固件(.bin/.elf),烧录至 MCU1 运行。
优化建议与排查路径
如果你目前仍在使用 Acore 侧方案(如帖主),遇到 put_data_tofifo failed 和大量 RollcntErr,可尝试以下临时优化(但治标不治本):
- 提高接收优先级:
将 CAN 接收线程的优先级调至最高(如SCHED_FIFO99),减少被调度延迟。# 示例:设置进程优先级 chrt -f 99 ./your_can_app - 优化接收逻辑:
检查接收循环是否阻塞过久,尽量使用非阻塞 IO 或增大接收缓冲区。 - 降低发送频率:
如果 200Hz 导致 FIFO 溢出,尝试降至 100Hz 测试稳定性。
长期解决方案(强烈推荐):
迁移至 MCU 侧开发。
- 参考教程:【S100-MCU-UseGuide】-1- 环境准备与开发流程
- 参考案例:社区已有用户成功在 MCU 侧实现 5 路 CAN 控制 27 个电机,稳定运行。
- 优势:彻底消除 IPC 瓶颈,释放 Acore 算力用于感知/决策,系统实时性大幅提升。
总结
- 帖主代码:运行在 Acore 侧,通过 IPC 控制 MCU CAN,存在性能瓶颈。
- 你的场景(31 关节):必须采用 MCU 侧原生开发 才能满足实时性要求。
- 下一步:建议直接搭建 MCU 开发环境,基于 FreeRTOS SDK 中的 CAN 示例进行开发,避免在 Acore 侧 IPC 方案上过度优化。
如果有 MCU 环境搭建或代码移植的具体问题,欢迎继续交流。
