我的环境是RK3568的板卡和龙芯2k1000的板卡,均采用原生芯片的can接口,没有采用SPI扩展CAN,我是用的是linux嵌入式系统和中标麒麟系统。系统版本均在linux3.0以上,我遇到的CAN问题是:CAN频繁的掉线,掉帧很严重,负载率越大,掉帧越严重。我想请问一下,我使用的是linux 的socket can,采用select去监听can的套接字,有消息触发我就去read,同时我有需要发送数据的时候就去write发送。我是B线程再使用read,C线程在write,他们会不会打架呢?因为can是半双工的。请问是否要做收发互斥。还有一个问题就是 我每个节点机器都跑如上所说同样的程序,会不会打架呢?再CAN网上有10台机器均再读写。CAN网负载率在20%左右,请问这个关于can的通信如何设计。希望能解惑,麻烦了。byte_j@163.com
----------补充
我是编写上位机程序的,采用Qt框架,我使用的也是linux socket can 来对两个物理can口进行监听收发,但是目前频繁的出现掉帧情况,我们的协议设计采用的是扩展帧通信,并且设备节点也设计的有不同的帧ID。我的这个程序再整个CAN网节点上会跑4台。收发会不会打架?引起掉帧呢?麻烦能给出通信代码 供参考,谢谢
socket CAN 通信机制
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
1条回答 默认 最新
- 「已注销」 2023-10-09 11:15关注
首先,让我们解决您提出的两个主要问题。
- 线程间的收发互斥:在您的描述中,您有一个读线程(B线程)和一个写线程(C线程)。由于CAN是半双工的,这意味着在任何给定的时间点,一个节点只能在一个方向上发送或接收数据。因此,您需要确保在任何时候只有一个线程在操作CAN接口。这可以通过使用互斥锁(mutexes)或其他同步原语来实现,以确保在任何时候只有一个线程在读写CAN接口。
- 多节点间的通信协调:在一个有10个节点的CAN网络上,你需要确保每个节点都有一个唯一的帧ID,并且每个节点都知道其他节点的帧ID。当一个节点要发送一条消息时,它需要检查该消息的目标节点和帧ID是否与正在接收的消息的节点和帧ID相匹配。如果匹配,则该消息应被接收并处理。如果不匹配,则该消息应被忽略。
对于您提到的掉帧问题,这可能是由于多种原因引起的,例如网络负载过大、信号干扰、硬件故障等。如果网络中每个节点的负载都较高(20%以上),那么可能会出现一些性能问题,因为每个节点都需要处理大量的数据。您可能需要查看您的协议设计,看看是否有可能优化数据传输的频率或数据量,以减少网络负载。
至于代码方面,由于涉及的内容较多且与硬件平台密切相关,这里无法提供具体的代码。但可以为您提供一些通用的思路和步骤:
- 初始化CAN接口:包括设置CAN接口的波特率、数据位、停止位、校验位等基本参数,以及向CAN接口发送和接收滤波器配置消息等。
- 创建和初始化互斥锁:用于保护CAN接口的读写操作,确保在任何时候只有一个线程在操作CAN接口。
- 创建和初始化帧ID列表:存储所有节点的帧ID,以便于在接收消息时进行匹配和过滤。
- 编写发送和接收消息的函数:使用上述互斥锁来保护CAN接口的读写操作,确保收发不会冲突。同时,在发送消息时,检查目标节点和帧ID是否与正在接收的消息的节点和帧ID相匹配。
- 编写处理接收消息的函数:当接收到消息时,根据帧ID列表中的信息进行处理。
- 编写监控网络负载的函数:定期检查网络负载,如果负载过高(超过20%),则考虑优化协议设计或减少数据传输的频率或数据量。
请注意,上述步骤仅是一个简单的示例,并且需要根据您的具体需求进行适当的修改和调整。同时,由于您的硬件平台是RK3568和龙芯2K1000,您可能需要参考这些平台的开发文档和示例代码来更好地理解如何在这些平台上使用Linux的Socket CAN接口。
解决 无用评论 打赏 举报