解决RK3568的CAN驱动导致CPU负载率100%问题

该文章已生成可运行项目,

结论:NAPI机制不适用于此芯片

1.现象:

控制器上电后,电机驱动器平均以0.2ms帧间隔持续发送CAN报文,绑定该CAN硬件中断的核心CPU负载率飙至100%

2.debug思路:

2.1 查看CAN硬件中断绑定在哪个CPU核心

cat /proc/interrupts

2.2 使用trace工具抓取内核事件

分析trace后发现:CAN的软中断嵌套、softirq_raise调用频繁;ksoftirqd/1一直运行,代表一直被唤醒处理软中断;CAN使用了NAPI机制。

NAPI机制适用于大量小包的网络设备,包括CAN。但是事实证明,有些CPU不适用于NAPI。

3. 优化思路

3.1 将CAN0中断同时绑定到多个CPU核心,分摊核心的资源消耗

echo 0-2 > /proc/irq/52/smp_affinity_list

但是未奏效,CAN0中断仍然只跑在一个核心里

3.2 排查NAPI机制问题

NAPI机制通过接收到硬件中断后,屏蔽CPU响应硬件中断,然后用轮询的方式读取FIFO,减少CPU响应硬件中断次数,所以该FIFO内的数据帧不应该过少。

由于NAPI是接收中断中调用,且其能够减少CPU响应硬件中断次数,所以对其掩码CPU响应中断的地方打log。包括:rx_init_cnt计数值、napi_schedule()调用次数。

结果:驱动调用napi_schedule()的次数与USB-CAN卡发送的CAN帧数一致,且rx_init_cnt一直为0,接收缓存区一直只有1帧CAN报文;于是认为该NAPI机制起到了反效果,所以导致了NAPI机制不仅没有减少CPU响应硬件中断次数,反而增加了NAPI的资源调度,导致ksoftirqd/1一直执行,将CPU负载率抬到了100%。

4.修改NAPI机制驱动

取消NAPI机制,改为普通中断响应

    //	if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
    //		napi_enable(&rcan->napi);
......
    //	if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
    //		napi_disable(&rcan->napi);
......
    // netif_napi_add(ndev, &rcan->napi, rockchip_canfd_rx_poll, 6);
.....
    //	if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
    //		netif_napi_del(&rcan->napi);
......
#if 0
static int rockchip_canfd_rx_poll(struct napi_struct *napi, int quota){
.....
}
static void rockchip_canfd_tx_retry(struct net_device *ndev, u32 isr) {
......
}
#endif
.......
    if ((isr & RX_FINISH_INT) || (isr & RX_FIFO_OV_INT) ||
        (isr & RX_FIFO_FULL_INT)) {
        if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2) {
            // rockchip_canfd_write(rcan, CAN_INT_MASK, 0x1);
            work_done = 0;
            quota =
                (rockchip_canfd_read(rcan, CAN_RXFC) & rcan->rx_fifo_mask) >>
                rcan->rx_fifo_shift;
            if (quota) {
                while (work_done < quota) work_done += rockchip_canfd_rx(ndev);
            }
        } else {
            work_done = 0;
            quota =
                (rockchip_canfd_read(rcan, CAN_RXFC) & rcan->rx_fifo_mask) >>
                rcan->rx_fifo_shift;
            if (quota) {
                while (work_done < quota) work_done += rockchip_canfd_rx(ndev);
            }
        }
    }

本文章已经生成可运行项目
内容概要:本文围绕RK3588芯片的CAN总线调试,系统讲解了基于Linux内核SocketCAN子系统的配置流程与错误帧分析方法。文章首先介绍RK3588芯片与CAN总线在工业自动化和汽车电子中的重要性,随后详细阐述SocketCAN的环境搭建、设备树与内核配置、接口参数设置及功能验证全过程,并深入解析CAN总线错误帧的结构、类型及其产生原因。结合实战案例,展示了如何利用candump、cansend、CAN分析仪和示波器等工具进行错误排查,特别指出RK3588原生CAN控制器在处理扩展帧和CRC校验时存在的硬件缺陷,并提出采用SPI转CAN控制器(如MCP2518FD)作为可靠替代方案。最后通过实际项目案例总结调试经验,强调软硬件协同优化的重要性。; 适合人群:具备嵌入式Linux开发基础,熟悉CAN通信协议,从事工业控制、汽车电子或物联网相关工作的1-3年经验研发人员; 使用场景及目标:①掌握RK3588平台下SocketCAN的完整配置与调试流程;②学会使用标准工具验证CAN通信功能并分析错误帧;③应对RK3588原生CAN控制器缺陷,设计高可靠CAN通信方案; 阅读建议:此资源以实战为导向,建议读者结合开发板动手实践,重点理解设备树配置、内核编译、命令行工具使用及错误排查逻辑,同时关注硬件设计与电气特性对通信稳定性的影响,全面提升CAN总线系统级调试能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脆莓不想当 Linux 小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值