python-can + can-isotp + udsoncan 实现基础的UDS诊断功能;附代码

1:功能说明

在网上搜了一下 python-can+udsoncan 的使用说明,发现都是很笼统的介绍,没有详细的使用说明;下面根据我自己的使用经验,来给大家介绍一下;

2:源代码介绍

这里主要修改的配置是 “ bus1 = can.interface.Bus(interface=‘canalystii’, channel=0, bitrate=500000)” 这一行代码,需要根据实际使用的CAN盒进行配置;详细的代码说明都有注释

以支持的CAN盒可以从python-can官网进行查看
https://python-can.readthedocs.io/en/stable/interfaces.html

#!/usr/bin/env python
# 使用 python-can + udsoncan + can-isotp 库发送UDS请求

"""
This example shows how sending a single message works.
pip install udsoncan python-can can-isotp
"""

import can
import isotp
import udsoncan
from udsoncan.connections import PythonIsoTpConnection
from udsoncan.client import Client
from udsoncan.services import DiagnosticSessionControl
from udsoncan.services import ECUReset


def send_uds_request(client, bus1, stack):
    try:
        # 发送0x10切换会话服务, 可以自己调整参数
        response = client.change_session(DiagnosticSessionControl.Session.extendedDiagnosticSession)
        # 发送0x11复位ECU服务
        # response = client.ecu_reset(ECUReset.ResetType.softReset) 
        print(f"Message sent on {bus1.channel_info}")
        # 打印解析后的应答数据
        if response.positive:
            print(f"Positive Response:")
            print(f"  Service: {response.service.get_name()}")
            # 将字节数据转换为十六进制字符串并格式化输出
            hex_data = ''.join(f'{byte:02x}' for byte in response.data)
            formatted_data = f"0x{hex_data}"
            print(f"  Data: {formatted_data}")
        else:
            print(f"Negative Response:")
            print(f"  NRC: {response.code_name}")
    except udsoncan.exceptions.NegativeResponseException as e:
        print(f"Negative response received: {e}")
    except udsoncan.exceptions.InvalidResponseException as e:
        print(f"Invalid response received: {e}")
    except udsoncan.exceptions.TimeoutException:
        print("Request timed out")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")


if __name__ == "__main__":
    # 这里要根据实际的CAN设备进行修改
    bus1 = can.interface.Bus(interface='canalystii', channel=0, bitrate=500000)

    # 设置ISO-TP参数
    isotp_params = {
        'stmin': 32,  # 最小分隔时间
        'blocksize': 8,  # 块大小
        'wftmax': 0,  # 最大等待帧数量
        'tx_data_length': 8,  # 发送数据长度
        'tx_data_min_length': 8,  # 发送数据最小长度
        'tx_padding': 0xaa,  # 发送数据填充字节
        'rx_flowcontrol_timeout': 5000,  # 接收流控制超时时间
        'rx_consecutive_frame_timeout': 5000,  # 接收连续帧超时时间
        'max_frame_size': 4095,                 # Limit the size of receive frame.
        'can_fd': False,                        # Does not set the can_fd flag on the output CAN messages
        'bitrate_switch': False,                # Does not set the bitrate_switch flag on the output CAN messages
        'rate_limit_enable': False,             # Disable the rate limiter
        'rate_limit_max_bitrate': 1000000,      # Ignored when rate_limit_enable=False. Sets the max bitrate when rate_limit_enable=True
        'rate_limit_window_size': 0.2,          # Ignored when rate_limit_enable=False. Sets the averaging window size for bitrate calculation when rate_limit_enable=True
        'listen_mode': False,                   # Does not use the listen_mode which prevent transmission.
    }

    # 创建ISO-TP栈,使用系统自带的 isotp.CanStack 类
    tp_addr = isotp.Address(isotp.AddressingMode.Normal_29bits, txid=0x123, rxid=0x456)
    stack = isotp.CanStack(bus=bus1, address=tp_addr, params=isotp_params)

    # 创建UDS连接
    conn = PythonIsoTpConnection(stack)
    # 创建UDS客户端
    config = {
        'p2_timeout': 5,  # 设置 P2 超时时间为 5 秒
        'request_timeout': 5  # 设置请求超时时间为 5 秒
    }
    # 创建UDS客户端
    with Client(conn, config=config) as client:
        send_uds_request(client, bus1, stack)

        try:
            print("All threads have finished.")
        except KeyboardInterrupt:
            print("Interrupted by user. Shutting down...")
            bus1.shutdown()

3:代码运行及日志记录

下面是测试 诊断会话控制和ECU复位的日志,可以在服务端打印日志看python发送的数据对不对;也可以参考源代码日志自己调整发送的数据

PS D:\2_gitlab\python\udsoncan\test> python3 .\uds_test.py
Message sent on CANalyst-II: channels [0]
# 这里是解析之后的应答,可以结合代码一起看
Positive Response:
  Service: DiagnosticSessionControl
  Data: 0x0311223344
All threads have finished.
CANalystIIBus was not properly shut down
PS D:\2_gitlab\python\udsoncan\test>
PS D:\2_gitlab\python\udsoncan\test> python3 .\uds_test.py
Message sent on CANalyst-II: channels [0]
Positive Response:
  Service: ECUReset
  Data: 0x030a
All threads have finished.
CANalystIIBus was not properly shut down

你可能感兴趣的:(python,python,开发语言)