**注:**关于CAN
的分时复用和发送FIFO
,这里受我师父小猫爪教导,得到了一些理解,在这里作为记录,后续有新的理解再进行更新。这里建议有些经验的人观看,不然会比较辛苦!有问题辛苦指出,和大家一起学习!
CAN
的分时复用
先谈谈分时复用是什么吧:can
的分时复用实际上也就是给我们每一个发送出去的报文,加上一层offset
。这层offset
实际上也就是dbc
文件里面的那个offset
,也就是我们的延时。
那么这个延时到底有什么作用呢?这个作用就是在CAN Mailbox
邮箱数量不够的情况下,在一定程度上,减少因为邮箱数量不够,而带来的拥堵。而且CAN
的发送也是有仲裁机制的,这里仲裁机制还要走个发送优先级,因此难免会导致报文的周期不稳定。
我师傅给我举了个例子,在这里分享给大家:比如说mailbox
的数量为1,我CAN
报文的数量为8,且都按100ms
的报文周期发送。此时,我8个CANID
的报文都要进行一个发送,那么我肯定是要在这一个mailbox
里面进行发送的,但我又不能一次性给他全部发送出去,CAN
的mailbox
还没有那么伟大,雨露均沾。只能让每个报文排队,一个一个来。那么这时候问题来了,我CAN
的报文发送周期比如说是5ms
一次,那么我肯定是在每5ms
发出一帧报文,这时候分时复用offset
的作用就体现出来了!A
报文的offset
设置为5ms
、B
报文offset
设置为10ms
、C
报文offset
设置为15ms.......
(注意,这里最好按照CANID
的优先级高低!设置) 以此类推。这时候CAN
报文就会按照A、B、C....
一直到最后一个报文的顺序从这一个mailbox
邮箱里面发送出去。这样就避免了全部在第一个5ms
发生踩踏事故的情况,每一个报文都可以按照自己的周期稳定发出!
注意,这里其实offset
不建议设置成0ms
开始,因为你0ms
开始的话,我邮箱发送报文也是需要时间的,那么之后的每一帧都会出现这个微秒级别的延时,看起来就很难受,因此从5ms
开始设置就好了。
只能说,老法师不愧是老法师!!!
那么到这里你以为就完了吗?当然没有,这时候聪明的我提问了,如果说我的100ms
周期CAN
报文数量有21个肿么办呢?这时候,发送FIFO就派上用场了!
CAN
发送FIFO
这时候有人可能会说,那我可以设置offset
为105ms
啊,挤一挤不就好了!当然不行!如果这样设置的话,当我第一个100ms
周期的20个报文发送完以后,第二个100ms
的开始5ms
的邮箱里面又会同时要发送2个报文,拥挤又出现了!!! 这种方法在这就行不通了(除非这个报文周期是200ms
)!
那么这时候就只能用上我们的中断发送FIFO
了,大家一定对CanIf_TxConfirmation()
这个回调函数不陌生吧!没错,就是他能解决我们的大问题!我们可以在RAM
区域设置一个FIFO
来存储我们要发送的报文。比如我21个报文全挤在一坨要发送,这时候我就把他们全部存储在FIFO
里面,然后我发送完一帧报文之后,就通过CanIf_TxConfirmation()
这个函数去确认FIFO
这个队列,如果还有报文未发送,那么我就继续发。查到没有要发送的报文了我就停止发送!大家知道中断其实是很快的,相对于我5msTask
来说,中断就能在5ms
以内一顿往外发不知道多少帧报文了,而且只用一个邮箱!太香了!!
其实在AUTOSAR
有类似的流程图的:
缓冲区的相关篇幅在原文第43页:
总结
其实到这里大家也都清楚了,分时复用解决的实际上是一个CAN
总线拥堵的一个问题,而中断FIFO
实际上解决的是一个邮箱(mailbox)数量不够的问题。那么他们两个可以共用吗?答案是当然可以!!!
以上均为师傅教导和个人总结,欢迎大家指正,再次感谢!!!