CAN开发指导FAQ

FAQ001: CAN驱动相关问题

问:CAN的实时性怎么保证?

答:Linux socket CAN数据的发送接收过程如图:

Gener4001

  • 数据发送时,如果其他模块中断很频繁,可能导致无法及时发送数据;

  • 数据接收时,中断不能及时由GIC分发给CPU处理、软中断无法被及时调度到,都会影响实时性。Linux无法保证较高的实时性。


问:CAN的软中断用的哪种类型?中断线程化之后,还有没有软中断?

答:CAN数据发到上层协议用的NAPI机制,NAPI实质上就是软中断。(关于NAPI更详细的原理可以在网上找,资料较多)

napi_schedule的实现如下:

napi_schedule
        __napi_schedule
                ____napi_schedule
                        __raise_softirq_irqoff(NET_RX_SOFTIRQ);

最终通过__raise_softirq_irqoff(NET_RX_SOFTIRQ)调度软中断的执行;

NAPI的这个软中断使用的是NET_RX_SOFTIRQ,优先级低于tasklet。

  • 软中断是每个CPU上有一个线程:softirqd,线程的调度策略是SCHED_NORMAL,softirqd做的事情是检查软中断标志是否被设置,如果设置了,执行相应的额action;

  • 中断线程化之后,中断变成线程,优先级默认是50,调度策略为SCHED_FIFO;

因此,中断线程化之后,还有软中断。


问:中断线程化后,调整当前线程的优先级,能够保证can数据收发的实时性吗?但是上层协议层的延迟还是没办法保证是吧?

答:实际中CAN的数据很多,如果优先级调高,可能会影响其他比较重要的应用。因此现在没有调整CAN的优先级。数据包送给上层协议栈,走的是Linux的软中断,这个延时也没办法保证的。


问:CAN里面的mtu能具体展开讲一下吗?

答:MTU一般指最大传输单元。

对于CANFD,MTU是72,对于CAN,MTU是16;

对于Linux socket CAN,MTU代表什么,可以直接看内核代码:include/uapi/linux/can.h

struct canfd_frame {
        canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
        __u8    len;     /* frame payload length in byte */
        __u8    flags;   /* additional flags for CAN FD */
        __u8    __res0;  /* reserved / padding */
        __u8    __res1;  /* reserved / padding */
        __u8    data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
};
struct can_frame {
        canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
        __u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
        __u8    __pad;   /* padding */
        __u8    __res0;  /* reserved / padding */
        __u8    __res1;  /* reserved / padding */
        __u8    data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};

typedef __u32 canid_t;

#define CAN_MAX_DLEN 8

#define CANFD_MAX_DLEN 64

问:CPU不及时读取CAN数据导致溢出,这个是否有打印信息?

答:

数据的溢出可能在两个地方:

  1. 硬件上mailbox全部填充满,导致无mailbox可以用,导致溢出。

maibox这边的溢出可以通过ifconfig查询:

溢出的话,这两个参数会增加:

offload->dev->stats.rx_over_errors:对应ifconfig中的frame

offload->dev->stats.rx_errors:对应ifconfig中的errors

Gener4002

  1. 队列队列长度超过最大长度导致溢出。

中断服务函数将skb插入offload->skb_queue队列的时候会判断长度是否超出offload->skb_queue的最大长度,如果超出了,就会有debug的打印信息。


问:CAN支持多少mailbox?

答:

CAN的mailbox空间总共2048字节,对于CAN标准帧,数据部分8字节,CAN帧头部8字节,一共16字节。所以对于CAN标准帧一共2048/16 = 128个。

对于CANFD:支持的携带的数据大小:8、16、32、64字节,CAN帧头部还是8字节,RAM空间分为4个Block

每个Block支持的mailbox数量:512除以mailbox大小,例如CANFD携带16字节数据,mailbox大小为16+8 = 24,512 / 24 = 21.33333取整数部分等于21,21个mailbox其实只使用了21*24 = 504,剩下的不够存一个mailbox了。

Gener4003


问:CAN ID过滤CAN帧在软件还是硬件实现?

答:

CAN ID的过滤在软件实现,硬件也支持ID过滤,但是没有使用。

CAN ID过滤可以看下图的数据接收过程:

Gener4004


FAQ002: 基础知识相关

问:CAN的速率好像还没有spi和i2c高,既然速率这么低,为啥汽车里面还要用CAN作为数据传输的主要通路呢

答:这个问题的回答从几个方面:为什么要发明CAN总线、SPI/I2C和CAN的对比;

为什么要发明CAN总线:

20世纪80年代初期,由于消费者对于汽车功能的要求越来越多,而这些功能的实现大多是基于电子操作的,这就使得电子装置之间的通讯越来越复杂,同时意味着需要更多的连接信号线。提出can总线的最初动机就是为了解决现代汽车中庞大的电子控制装置之间的通讯,减少不断增加的信号线。于是,他们设计了一个单一的网络总线,所有的外围器件可以被挂接在该总线上。

总线类型

速率

物理层传输方式

传输距离

几根线(对布线复杂度有影响)

节点之间关系

一个网络可以有多少设备

CAN

CAN帧速率1M,CANFD帧数据段最高8M

两根线进行差分传输

Gener4005

CAN的通信距离见上图

两根线:CAN_H、CAN_L

无主从关系

理论上一条CAN总线上可以连接110个节点设备

SPI

SPI是一种事实标准,由Motorola开发,并没有一个官方标准。已知的有的器件SPI已达到50Mbps。具体到产品中SPI的速率主要看主从器件SPI控制器的性能限制。

两根线传输数据,每根线负责一个传输方向。

Motorola白皮书没有明确规定SPI的传输距离。但是根据经验,考虑干扰和高速带来的不可靠性,最好保持在50CM内。

四根线:MISO、MOSI、SCLK、CS/SS

一主多从

如果总线的驱动功率足够大,最多可以连接255个设备,但是实际工作中这个功率没有那么大,一般只能连接5个以内的设备。

I2C

标准模式: 100 kbps

快速模式:400 kbps

高速模式:3.4 Mbps

收发共用一根数据线

一般传输距离30cm以下。

2根:一根数据线,一根时钟线

一主多从

127个设备

CAN的几个优势:

  • 差分信号传输,抗干扰性强;

  • 没有主从关系,并且只需要两根线,解决现代汽车中庞大的电子控制装置之间的通讯,减少不断增加的信号线;

  • CAN总线方式连接的控制单元中有一个发生故障,其它控制单元仍可发送各自的数据,互不影响

  • 通信距离较长。

I2C/SPI一般用于电路板内的通信,CAN用于汽车组件之间的通信。


FAQ003: CAN使用相关问题

问:CAN的采样点设置为多少比较好?

答:

J5只需要和总线上的其他设备保持一致即可。

一般采用如下配置:

75% when 波特率 > 800K

80% when 波特率 > 500K

87.5% when 波特率 <= 500K