zynq 在linux下can总线bus-off无法自恢复的问题
内核dump
[ 10.972675] at803x_config_init !
[ 10.973178] IPv6: ADDRCONF(NETDEV_UP): eth2: link is not ready
[ 11.629082] macb ff0b0000.ethernet eth0: link up (1000/Full)
[ 11.629110] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 11.980898] xilinx_axienet a0000000.ethernet eth2: Link is Down
[ 13.072256] xilinx_can ff060000.can can0: bitrate error 0.0%
[ 13.114484] xilinx_can ff070000.can can1: bitrate error 0.0%
[ 13.155897] xilinx_can a0020000.can can2: bitrate error 0.0%
[ 13.197189] xilinx_can a0030000.can can3: bitrate error 0.0%
[ 13.239037] xilinx_can a0040000.can can4: bitrate error 0.0%
[ 13.281563] xilinx_can a0050000.can can5: bitrate error 0.0%
[ 13.324999] xilinx_can a0060000.can can6: bitrate error 0.0%
[ 13.367929] xilinx_can a0070000.can can7: bitrate error 0.0%
[ 14.189016] random: crng init done
[ 14.189026] random: 7 urandom warning(s) missed due to ratelimiting
[ 5796.758579] xilinx_can a0060000.can can6: bus-off
[ 6894.946613] xilinx_can ff060000.can can0: bitrate error 0.0%
[ 6894.998665] xilinx_can ff070000.can can1: bitrate error 0.0%
[ 6895.052884] xilinx_can a0020000.can can2: bitrate error 0.0%
[ 6895.106374] xilinx_can a0030000.can can3: bitrate error 0.0%
[ 6895.156836] xilinx_can a0040000.can can4: bitrate error 0.0%
[ 6895.208594] xilinx_can a0050000.can can5: bitrate error 0.0%
[ 6895.258665] xilinx_can a0060000.can can6: bitrate error 0.0%
[ 6895.274154] IPv6: ADDRCONF(NETDEV_UP): can6: link is not ready
[ 6895.274179] IPv6: ADDRCONF(NETDEV_CHANGE): can6: link becomes ready
[ 6895.308874] xilinx_can a0070000.can can7: bitrate error 0.0%
可以看到在内核启动5796s时发现can的bus-off error从而导致这一路can出现问题后,再没有进行数据的接收了
通过查看内核的can的驱动框架
不需要看的很深,其大体的uml关系图如下
可以看到内核对于can_bus-off是由相关的处理机制的
/*
* CAN bus-off
*
* This functions should be called when the device goes bus-off to
* tell the netif layer that no more packets can be sent or received.
* If enabled, a timer is started to trigger bus-off recovery.
*/
void can_bus_off(struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
netdev_info(dev, "bus-off\n");
netif_carrier_off(dev);
//debug时发现该值为0
if (priv->restart_ms)
schedule_delayed_work(&priv->restart_work,
msecs_to_jiffies(priv->restart_ms));
}
EXPORT_SYMBOL_GPL(can_bus_off);
通过debug,发现这个时间值为0,那么只需要在probe时加上该值的赋值即可