栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

检测特定can消息的自动化实现:

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

检测特定can消息的自动化实现:

can协议简介:

控制器局域网总线(CAN,Controller Area Network)是一种用于实时应用的串行通讯协议总线,它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。CAN协议用于汽车中各种不同元件之间的通信,以此取代昂贵而笨重的配电线束。该协议的健壮性使其用途延伸到其他自动化和工业应用。CAN协议的特性包括完整性的串行数据通讯、提供实时支持、传输速率高达1Mb/s、同时具有11位的寻址以及检错能力。
控制器局域网CAN( Controller Area Network)属于现场总线的范畴,是一种有效支持分布式控制系统的串行通信网络。是由德国博世公司在20世纪80年代专门为汽车行业开发的一种串行通信总线。由于其高性能、高可靠性以及独特的设计而越来越受到人们的重视,被广泛应用于诸多领域。而且能够检测出产生的任何错误。当信号传输距离达到10km时,CAN仍可提供高达50kbit/s的数据传输速率。由于CAN总线具有很高的实时性能和应用范围,从位速率最高可达1Mbps的高速网络到低成本多线路的50Kbps网络都可以任意搭配。因此,CAN己经在汽车业、航空业、工业控制、安全防护等领域中得到了广泛应用。
具体的can协议的讲解是一个庞大的工程,不是本节培训的侧重点。

can的仲裁机制简单理解:

仲裁这个字眼,一般都是出现在法律领域里,它的意思是双方争执不决时,由第三者居中调解,作出裁决。其实,在我们的生活里,也是随处可见仲裁这个字眼的身影,例如题目中CAN总线的仲裁设计。
CAN总线是一种工业现场总线,说白了就是工业控制系统,汽车的操作都靠这个东西。以往的其他控制总线都是一主多从或者是一对一通讯,工作效率那是相当的低。针对这些情况,CAN总线被开发出来了,它是一种多主通讯的总线,采用广播式的通讯设计,即总线上的每一个节点都可以独立发出信息,节点之间没有绝对的从属关系。这么设计,工作效率肯定是上去了,但也出现了一个问题,那就是当总线上有两个或者更多个节点同时发数据,那让谁的数据先行通过呢?举个例子来说,一台车子,它的上面有许许多多个节点设备,包括发动机,刹车,雨刷器等等,你觉得它们当中谁的重要性更高一些呢?很明显,绝大多数情况下,刹车的重要性肯定是高于雨刷器的。好的,我们继续想象,在一个雨天里,你正在开汽车出行。这时候,你在经过十字路口时,有一辆车突然出现在前面不远的地方,你是觉得刹车重要呢还是用雨刷器重要呢?很明显,这时候你希望刹车发挥作用。一条刹车的CAN数据,一条雨刷运动的CAN数据,都在CAN总线上生成了,总线的仲裁机制开始发挥作用,它会根据两条CAN数据的帧ID进行判断仲裁,即谁的帧ID数值较小,谁的总线通过优先度就更高。显然,刹车的帧ID是小于雨刷的。其实,如果你专门研究一下的你就会发现,但凡和汽车动力装置有关的CAN数据,它们的帧ID都比较小,信息通过优先度都是最高的。要不然,车子都撞飞了,还谈什么别的呢?

can的特点:

无源,仲裁,信息帧类型[数据帧,远程帧,错误帧,超载帧

命令行实现: 使用candump接收:
candump can0
candump can0 |grep 101
candump can0 
#更多高级用法请自己探索。
使用cansend发送:
cansend can0 666#0500ffffffff0000
#更多高级用法请自己探索。
Python实现:

参考资料:https://python-can.readthedocs.io/en/master/

使用python-can接收:
#!/usr/bin/python3

import os

import can

can.rc['interface'] = 'socketcan_native'
can.rc['channel'] = 'can0'
can.rc['bitrate'] = 500000


def recv():
    bus = can.interface.Bus();
    msg = bus.recv(100);
    ''' 接收信息 '''
    try:
        bus.send(msg)
        print(msg)
        print(msg.data[0])  # 接收回来的第一个字节的数据
        print(msg.arbitration_id)  # 接收回来的ID
        return msg
    except can.CanError:
        print("Message NOT sent")


if __name__ == "__main__":
    recv()
使用python-can发送:
#!/usr/bin/env python
# coding: utf-8

"""
This example shows how sending a single message works.
"""

from __future__ import print_function

import time
import can

def send_one():

    # this uses the default configuration (for example from the config file)
    # see https://python-can.readthedocs.io/en/stable/configuration.html
    bus = can.interface.Bus(bustype='socketcan', channel='can0',bitrate=500000)
    
    msg = can.Message(arbitration_id=0x666,
                      data=[0, 25, 0, 1, 3, 1, 4, 1],
                      is_extended_id=False)
    
    while True:
        time.sleep(1)
        try:
            bus.send(msg)
            print("Message sent on {}".format(bus.channel_info))
        except can.CanError:
            print("Message NOT sent")

if __name__ == '__main__':
    send_one()
使用python库脚本来进行can操作:
# 用python命令抓can的报文
python -m can.logger -c can0 -b 500000 -i socketcan
# 保存到文件
python -m can.logger -c can0 -b 500000 -i socketcan -f myLog.Logger

# 实时显示,实时刷新。
python -m can.viewer -c can0 -b 500000 -i socketcan
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/729305.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号