周立功ZXDOC脚本编写

 

# 脚本编写说明

一、 入口函数

 脚本加载后,会执行__zxdoc_main__()函数。

    def __zxdoc_main__():
        pass

二、 出口函数

    如果脚本定义了__zxdoc_on_exit__()函数,则脚本停止时会执行它。

    def __zxdoc_on_exit__():
        pass

# 模块接口

一、主模块(ZXDoc)

    想要使用ZXDoc提供的各个接口,必须导入主模块"ZXDoc"。

    import ZXDoc
    或
    from ZXDoc import *

二、应用程序模块(app)

    应用程序模块用于与ZXDoc主程序交互,目前仅开放日志输出接口。

三、测量模块(measurement)

    测量模块用于管理测量的启动/停止,也可以通过on_status_changed()函数监听测量状态的变更。

四、通道模块(channel)

    通道模块用于通道的管理、数据传输等。通过通道模块可以发送CAN、LIN报文。通过add_data_sink()函数可监听通道数据。

五、诊断模块(diagnostics)

    诊断模块用于处理UDS请求。支持DoCAN、DoLIN、DoIP。

六、设备模块(device)

    设备模块用于获取设备信息。

七、信号模块(signals)

    通过信号模块可以设置信号值、监听信号值等。

八、标定模块(calibration)

    标定模块用于对ZXDoc的标定控制。

九、 仿真模块(simulation)

    控制总线仿真启停、配置参数、设置信号值。

from typing import List, Dict, Tuple

from enum import IntEnum, unique

基本定义

# 日志等级
LOG_LVL_DEBUG = 0
LOG_LVL_INFO = 1
LOG_LVL_WARNING = 2
LOG_LVL_ERROR = 3

# 总线类型
BUS_TYPE_ANY = 0
BUS_TYPE_CAN = 1
BUS_TYPE_LIN = 2
BUS_TYPE_ETHERNET = 3

# CAN帧类型
CAN_FRAME_TYPE_CAN = 0
CAN_FRAME_TYPE_CANFD = 1
CAN_FRAME_TYPE_CANFD_BRS = 2

# CAN传输协议
CAN_TP_ISO15765_2_2004 = 0
CAN_TP_ISO15765_2_2016 = 1

# DoIP的传输协议
DOIP_TP_ISO_13400_2_2010 = 0x01
DOIP_TP_ISO_13400_2_2012 = 0x02
DOIP_TP_ISO_13400_2_2019 = 0x03
DOIP_TP_ISO_13400_2_2019_AMD1 = 0x04


# DoIP路由激活类型
ZDOIP_ACTIVATION_DEFAULT = 0x00
ZDOIP_ACTIVATION_WWH_OBD = 0x01
ZDOIP_ACTIVATION_CENTRAL_SECURITY = 0xE0

# UDS响应状态
UDS_RSP_STATUS_OK = 0
UDS_RSP_STATUS_CANCELED = 1
UDS_RSP_STATUS_SUPPRESS_RESPONSE = 2
UDS_RSP_STATUS_FAILED = 3

# UDS响应类型
UDS_RSP_TYPE_NEGATIVE = 0
UDS_RSP_TYPE_POSITIVE = 1
UDS_RSP_TYPE_UNKNOWN = 0xFF

# 测量状态
MEASUREMENT_STATUS_STOPED = 0
MEASUREMENT_STATUS_STARTED = 1

@unique
class ZMeasEvent(IntEnum):
    POLLING = 1  # 轮询获取
    DAQ_EVENT = 2  # ECU按指定DAQ事件上送
    DAQ_CYCLIC = 3  # ECU按DAQ事件的整数倍周期上送, 周期小于1ms的事件不支持Cyclic模式
    ON_INPUT = 4  # 依赖输入信号,自己不轮询
    INVALID = -1

基本结构体定义

class ZCANFDData:CAN/CANFD 数据
    成员:
        can_id:     CAN帧ID
        is_canfd:   0:CAN帧, 1:CANFD帧
        is_extend:  0:标准帧, 1:扩展帧
        is_remote:  CAN帧有效 0:数据帧, 1:远程帧
        is_brs:     是否加速帧
        direction:  传输方向,报文监听时有效 0:接收, 1:发送
        data:       报文内容,类型可以为 bytes、bytearray、List[int]
        DLC:        DLC

    __slots__ = (
        "can_id",
        "is_canfd",
        "is_extend",
        "is_remote",
        "is_brs",
        "direction",
        "data",
        "DLC",
    )

class ZLINData:LIN 数据
    成员:
        PID:        PID
        timestamp:  时间戳
        direction:  传输方向,报文监听时有效 0:接收, 1:发送
        checksum:
        data:       报文内容,类型可以为 bytes、bytearray、List[int]

    __slots__ = ("PID", "timestamp", "direction", "checksum", "data")


class ZRawData:合并接收数据数据结构,支持CAN/CANFD/LIN等不同类型数据
    成员:
        number:                 数据编号
        absolute_timestamp:     绝对时间戳,单位微秒(us)
        relative_timestamp:     相对时间戳,单位微秒(us)
        channel:                通道号
        data:                   数据:ZCANFDData、ZLINData

    __slots__ = (
        "number",
        "absolute_timestamp",
        "relative_timestamp",
        "channel",
        "data",
    )

class ZUdsRequest:UDS请求数据
    成员:
        src_addr:           源地址(物理地址或功能地址)
        dst_addr:           目标地址(响应地址)
        sid:                服务ID
        data:               数据 List
        suppress_response:  是否抑制响应 True/False
        is_extend:          是否使用扩展帧 True/False

    __slots__ = (
        "src_addr",
        "dst_addr",
        "sid",
        "data",
        "suppress_response",
        "is_extend",
    )

class ZUdsResponse:UDS响应数据
    成员:
        status:             响应状态
            取值如下:
                UDS_RSP_STATUS_OK = 0
                UDS_RSP_STATUS_CANCELED = 1
                UDS_RSP_STATUS_SUPPRESS_RESPONSE = 2
                UDS_RSP_STATUS_FAILED = 3

        responseType:       响应类型
            取值如下:
                UDS_RSP_TYPE_NEGATIVE = 0
                UDS_RSP_TYPE_POSITIVE = 1
                UDS_RSP_TYPE_UNKNOWN = 0xFF
        sid:                服务ID
        data:               响应数据 List
        NRC:                消极响应错误码
        errorCode:          其它错误码。

    可通过 diagnostics.get_uds_error_msg() 方法取得错误信息。

    __slots__ = ("status", "responseType", "sid", "data", "NRC", "errorCode")

class ZUdsCANCfg:DoCAN 的接口配置
    frameType: int = CAN_FRAME_TYPE_CAN  # CAN帧类型
    protocolVersion: int = CAN_TP_ISO15765_2_2004  # 协议类型
    fillByte: int = 0  # 填充字节
    isFillByte: bool = True  # 是否填充字节
    p2Timeout: int = 2000  # P2超时(ms)
    p2xTimeout: int = 5000  # P2*超时(ms)
    isReplaceEcuSTmin: bool = (
        False  # 是否忽略ECU返回流控的STmin,强制使用本程序设置的 remoteSTmin
    )
    remoteSTmin: int = 0  # 远程STmin
    fcTimeout: int = 1000  # 流控响应超时(ms)

class ZUdsLINCfg:DoLIN 的接口配置
    fillByte: int = 0  # 填充字节
    isFillByte: bool = True  # 是否填充字节
    p2Timeout: int = 2000  # P2超时(ms)
    p2xTimeout: int = 5000  # P2*超时(ms)
    isReplaceEcuSTmin: bool = (
        False  # 是否忽略ECU返回流控的STmin,强制使用本程序设置的 remoteSTmin
    )
    remoteSTmin: int = 0  # 远程STmin

class ZUdsDoIPCfg:DoLIN 的接口配置
    vehicleIp: str  # DoIP实体的IP地址
    localIp: str = "0.0.0.0"  # 本地IP地址
    localPort: int = 0  # 本地端口
    srcLogicalAddr: int  # 源逻辑地址
    protocolVersion: int = DOIP_TP_ISO_13400_2_2019  # 协议版本
    routingActivationType: int = ZDOIP_ACTIVATION_DEFAULT  # 路由激活类型
    oemSpecificData: Union[List[int], bytes, bytearray] = field(
        default_factory=bytes
    )  # OEM特定数据(4 bytes)
    aliveCheckCycle: int = 0  # 主动保活的周期,单位为毫秒,0表示不主动保活
    isResponseAliveCheck: bool = False  # 是否响应存活检查
    p2Timeout: int = 1000  # P2超时时间(ms)
    p2xTimeout: int = 2000  # P2*超时时间(ms)
    waitForACK: bool = True  # 每次请求是否等待ACK
    ackTimeout: int = 500  # 等待ACK的超时时间(ms)

class ZSignalValue:用于存储一个信号的值
    成员:
        sourceId:       信号源ID
            指示信号的来源,可通过signals.find_device_source()方法获取。
        signalId:       信号ID,即信号名称。
        timestamp:      时间戳
        frameNumber:    帧序号
        rawValue:       原始值
        phyValue:       物理值
            值(物理值/原始值)的类型可能为:数值、字符串、多维数组。
        rowIndex:       行索引
            当 phyValue 为数组的其中一个元素值时有效。 rowIndex 小于0时表示无效。
        colIndex:       列索引
            当 phyValue 为数组的其中一个元素值时有效。 colIndex 小于0时表示无效。

    __slots__ = (
        "sourceId",
        "signalId",
        "timestamp",
        "frameNumber",
        "rawValue",
        "phyValue",
        "rowIndex",
        "colIndex",
    )

    def set(self):设置信号值,等同于signals.set_signal_value(self)

@unique
class ZDBType(IntEnum):
    UNKNOWN = 0x00
    DBC = 0x01
    ODX = 0x02
    A2L = 0x04
    LDF = 0x08
    SysVar = 0x10
    FuncVar = 0x20
    ALL = 0xFFFF

@dataclass
class ZDatabase:
    type: ZDBType = ZDBType.UNKNOWN
    id: str = ""
    name: str = ""
    filePath: str = ""

@unique
class ZDeviceType(IntEnum):
    CCP = 0  # CCP协议的ECU
    XCP = 1  # XCP协议的ECU
    Diagnostic = 2  # 诊断
    CANFD = 3  # CAN或CANFD总线监测
    LIN = 4  # LIN总线监测
    UNKNOWN = 0xFF

@dataclass
class ZDeviceInfo:设备信息
    成员:
        id:             设备ID
        type:           设备类型
        name:           设备名称
        busType:        设备的总线类型
        logicalChannel: 逻辑通道号
        isEnabled:      设备是否启用
        databaseId:     数据库ID
        databaseName:   数据库名称
        configuration:  设备配置信息

    id: str = ""
    type: ZDeviceType = ZDeviceType.UNKNOWN
    name: str = ""
    busType: int = -1
    logicalChannel: int = -1
    isEnabled: bool = False
    databaseId: str = ""
    databaseName: str = ""
    configuration: Dict = field(default_factory=dict)

@unique
class ZUserVariableType(IntEnum):自定义变量类型
    Int = 0
    Uint = 1
    Float = 2
    Double = 3
    String = 4

@dataclass
class ZUserVariable:自定义变量
    name: str
    value_type: ZUserVariableType
    group: str = field(default="")
    unit: str = field(default="")
    init_value: str = field(default="")
    min_value: str = field(default="")
    max_value: str = field(default="")
    comment: str = field(default="")

@dataclass
class ZSignalIdentifier:
    sourceId: str
    signalId: str

@unique
class ZSimSendType(IntEnum):仿真数据发送类型
    Cycle = 0  # 循环发送
    OnChange = 1  # 当值变更时发送
    OnWrite = 2  # 当值被写入时发送,即使写入的是相同的值

class CRCCalculator:CRC计算器
    def calculate(self, input_data: bytes, prev_result: Optional[int] = None) -> int:计算CRC
            input_data 输入数据
            prev_result 之前的计算结果,可选

常用头文件

import app
import channel
import measurement
import diagnostics
import device
import calibration
import simulation
import E2E

常用APP接口

def write_log(level: int, msg: str):日志输出
level: 日志等级
            LOG_LVL_DEBUG = 0
            LOG_LVL_INFO = 1
            LOG_LVL_WARNING = 2
            LOG_LVL_ERROR = 3
        msg: 日志内容

def add_user_variable(var:ZUserVariable):添加自定义变量
var: ZUserVariable 类型,指定变量的配置信息。
    设置自定义变量的值:
        val = ZSignalValue()
        val.sourceId = 'UserVar::UserDefined' # 信号源ID固定为"UserVar::UserDefined"
        val.signalId = 'variable_name'
        val.phyValue = 8
        signals.set_signal_value(val)

def remove_user_variable(name:str, group:str):删除自定义变量
name: 变量名称
group: 变量所属的分组名称

常用标定接口

from ZXDoc import *
def connect() -> bool:为所有标定设备建立连接
def disconnect():断开连接
def start_data_acquisition() -> bool:开始获取数据
def stop_data_acquisition():停止获取数据
def add_meas_signal(deviceId: str, signalId: str, measEvent: ZMeasEvent, eventChannel: int = 0,
  pollingPeriod: int = 1000, daqCyclic: int = 1000) -> bool:添加测量信号
  参数:
      deviceId: 设备ID。通过device.get_devices()获取到的设备的ID。
      signalId: 信号ID,即信号名称。
      measEvent: 测量事件。
      eventChannel: DAQ事件通道索引。当 measEvent 为 ZMeasEvent.DAQ_EVENT 时有效。
      pollingPeriod: 获取周期。当 measEvent 为 ZMeasEvent.POLLING 时有效。
      daqCyclic:  上送周期。当 measEvent 为 ZMeasEvent.DAQ_CYCLIC 时有效。
      * 如果 measEvent 为无效值,则默认为 ZMeasEvent.DAQ_EVENT,并使用第一个有效的事件通道索引,
          如果没有合适的DAT事件,则使用 ZMeasEvent.POLLING ,周期为1000ms。

def remove_meas_signal(deviceId: str, signalId: str): 移除测量信号

常用通道接口

def start_can_simulation():启动CAN总线仿真

def stop_can_simulation():停止CAN总线仿真

def get_channels(busType: int) -> List[Dict]:获取所有通道信息。
    返回内容如下:
    [
        {
            'busType': 0,               # 总线类型 BUS_TYPE_CAN、BUS_TYPE_LIN
            'logicalIndex': 1,          # 通道索引
            'physicalIndex': 4849664,   # 物理索引
            'enabled': 1,               # 通道是否已启用
            'activated': 1              # 通道是否已激活
        },
        ...
    ]   

def transmit(busType: int, channelIndex: int, datas: List) -> int:报文发送
        busType: 总线类型 BUS_TYPE_CAN、BUS_TYPE_LIN
        channelIndex: 通道索引
        datas: 需要发送的数据列表,类型需要根据busType填充
            * busType 为 BUS_TYPE_CAN 时,datas 为 List[ZCANFDData]
            * busType 为 BUS_TYPE_LIN 时,datas 为 List[ZLINData]
    返回值:
        返回发送的数据个数。

def add_data_sink(callback_func): 设置数据收发回调

callback_func: 回调函数,def callback_func(dataSet: List[ZRawData]):

常用设备接口

def get_devices() -> List[ZDeviceInfo]: 获取所有设备信息

def config_device(deviceId: str, configuration: Dict):配置设备

def create_device(name: str, deviceType: ZDeviceType, busType: int, logicalChannel: int):创建新设备

def delete_device(deviceId: str):删除设备

常用诊断接口

def create_uds_interface(busType, channelIndex, config) -> int:创建一个新的UDS接口对象

busType: 总线类型。

取值可以为 BUS_TYPE_CAN/BUS_TYPE_LIN/BUS_TYPE_ETHERNET, 分别对应DoCAN/DoLIN/DoIP
channelIndex: 通道号。 仅对BUS_TYPE_CAN/BUS_TYPE_LIN有效。
    config: 接口配置。
      config的类型可以为以下三种:
        ZUdsCANCfg:   CAN配置
        ZUdsLINCfg:   LIN配置
        ZUdsDoIPCfg:  DoIP配置
  返回值:
    如果成功,返回接口的句柄,失败返回-1。 

def free_uds_interface(handle: int):释放UDS接口对象

handle: 由create_uds_interface()创建的UDS接口句柄。

def uds_request(handle: int, requestData: ZUdsRequest) -> ZUdsResponse:发送UDS请求
    handle: 由create_uds_interface()创建的UDS接口句柄。
    requestData: ZUdsRequest对象。
  返回值:
    如果成功,返回 ZUdsResponse 对象,否则返回 None。

def get_uds_error_msg(handle: int, response: ZUdsResponse):不同的UDS接口可能有不同的错误信息,通过该接口可获取。
    handle: 由create_uds_interface()创建的UDS接口句柄。
    response: 由uds_request()返回的响应。

def cancel_uds_request(handle: int):取消当前的UDS请求

handle: 由create_uds_interface()创建的UDS接口句柄。

常用E2E接口

def get_crc8_calculator() -> CRCCalculator:获取CRC-8(多项式0x07,初始值0x00,最终异或值0x00,不反转输入,不反转输出)

def get_crc8sae_calculator() -> CRCCalculator: 获取CRC-8-SAE(多项式0x1D,初始值0xFF,最终异或值0xFF,不反转输入,不反转输出)

def get_crc8h2f_calculator() -> CRCCalculator:获取CRC-8-H2F(多项式0x2F,初始值0xFF,最终异或值0xFF,不反转输入,不反转输出)def get_crc16_calculator() -> CRCCalculator:获取CRC-16(多项式0x8005,初始值0x0000,最终异或值0x0000,反转输入,反转输出)

def get_crc16ccitt_calculator() -> CRCCalculator:获取CRC-16-CCITT(多项式0x1021,初始值0x0000,最终异或值0x0000,反转输入,反转输出)

def get_crc16ccittfalse_calculator() -> CRCCalculator: 获取CRC-16-CCITT-FALSE(多项式0x1021,初始值0xFFFF,最终异或值0x0000,不反转输入,不反转输出)

def get_crc32_calculator() -> CRCCalculator:获取CRC-32(多项式0x04C11DB7,初始值0xFFFFFFFF,最终异或值0xFFFFFFFF,反转输入,反转输出)

def get_crc32p4_calculator() -> CRCCalculator:获取CRC-32-P4(多项式0xF4ACFB13,初始值0xFFFFFFFF,最终异或值0xFFFFFFFF,反转输入,反转输出)

def get_crc64ecma_calculator() -> CRCCalculator:获取CRC-64(多项式0x42F0E1EBA9EA3693,初始值0xFFFFFFFFFFFFFFFF,最终异或值0xFFFFFFFFFFFFFFFF,反转输入,反转输出)

def get_custom_crc_calculator(width: int, polynomial: int, initial_value: int, xor_value: int, reflect_input: bool, reflect_output: bool) -> CRCCalculator:获取自定义CRC
  参数:
    width为位宽,可选值为8、16、32和64
    polynomial为多项式
    initial_value为初始值
    xor_value为最终异或值
    reflect_input为反转输入
    reflect_output为反转输出

常用测量接口

def start() -> bool:启动测量

def stop():停止测量

def is_started() -> bool: 测量是否已启动

def on_status_changed(callback_func):测量状态变更回调

回调函数定义如下:def callback_func(status):
    参数 status:
      MEASUREMENT_STATUS_STARTED: 测量启动
      MEASUREMENT_STATUS_STOPED: 测量停止

常用信号接口

def subscribe_signals(signals: List[ZSignalIdentifier]) -> bool:订阅信号
  示例:
    signals.subscribe_signals([
        ZSignalIdentifier('Channel::CAN1', 'ABSdata.CarSpeed'),
        ZSignalIdentifier('Channel::CAN2', 'EngineData.EngSpeed')
    ])

def unsubscribe_signals(signals: List[ZSignalIdentifier]) -> bool:取消订阅信号
    signals.unsubscribe_signals([
        ZSignalIdentifier('Channel::CAN1', 'ABSdata.CarSpeed'),
        ZSignalIdentifier('Channel::CAN2', 'EngineData.EngSpeed')
    ])

def set_signals_observer(callback_func):设置信号接收回调
  回调函数定义如下:
    def callback_func(signalValues : List[ZSignalValue]):
  备注:需要订阅了信号,才能收到信号回调。参考subscribe_signals函数。

def find_device_source(deviceId: str, databaseId: str) -> str:
  通过设备ID和数据库ID查找信号源ID。
  返回值:
    成功返回对应的 sourceId,失败返回空字符串""。

def get_signal_value(sourceId: str, signalId: str) -> ZSignalValue:读取信号的值
  返回值:
    如果信号存在且有值,返回其当前值,否则返回None。

def get_signal_init_value(sourceId: str, signalId: str) -> ZSignalValue:读取信号的初始值
  返回值:如果信号存在,返回其初始值,否则返回None。

def set_signal_value(signalValue : ZSignalValue) -> bool:设置指定信号的值

  一、 单值信号设置

    val = ZSignalValue()
    val.sourceId = 'SignalSource'
    val.signalId = 'SignalId'
    val.rowIndex = -1
    val.colIndex = -1
    val.phyValue = 8  # 值类型可以是 int float str
    signals.set_signal_value(val)

二、多维/数组信号设置

    val = ZSignalValue()
    val.sourceId = 'SignalSource'
    val.signalId = 'SignalId'
    val.rowIndex = -1
    val.colIndex = -1
    val.phyValue = [
      [1, 2, 3],
      [4, 5, 6],
      [7, None, 8]
    ]
    signals.set_signal_value(val)

三、按索引设置数组信号

    val = ZSignalValue()
    val.sourceId = 'SignalSource'
    val.signalId = 'SignalId'
    val.rowIndex = 1  # 数组的行索引
    val.colIndex = 2  # 数组的列索引
    val.phyValue = 8
    signals.set_signal_value(val)

常用仿真接口

def start_can_simulation() -> bool:启动CAN仿真
  备注:必须先启动测量,才能成功启动仿真。

def stop_can_simulation() -> bool:停止CAN仿真

def active_can_send(channelIndex: int, databaseId: str, node: str, message: str, isActive: bool) -> bool:激活CAN消息的发送
    channelIndex: 通道号。
    databaseId: 该通道关联的DBC数据库ID。
    node: DBC消息节点名称。
    message: DBC消息名称。
    isActive: 是否激活。
      True为激活,False为去激活。

def set_can_send_type(channelIndex, databaseId: str, node: str, msg: str, type: ZSimSendType) -> bool:设置CAN消息的发送类型
    channelIndex: 通道号。
    databaseId: 该通道关联的DBC数据库ID。
    node: DBC消息节点名称。
    message: DBC消息名称。
    type: 发送类型。
      发送类型可取以下值:
        ZSimSendType.Cycle:     循环发送
        ZSimSendType.OnChange:  当信号值变化时发送
        ZSimSendType.OnWrite:   当信号值写入时发送(即使写入相同的值)

def set_can_send_cycle_time(channelIndex, databaseId: str, node: str, message: str, cycleTime: int) -> bool:设置CAN消息的发送周期
    channelIndex: 通道号。
    databaseId: 该通道关联的DBC数据库ID。
    node: DBC消息节点名称。
    message: DBC消息名称。
    cycleTime: 周期(ms)。

def set_can_send_repetitions(channelIndex: int, databaseId: str, node: str, message: str, repetitions: int) -> bool:设置CAN消息的重复发送次数
    channelIndex: 通道号。
    databaseId: 该通道关联的DBC数据库ID。
    node: DBC消息节点名称。
    message: DBC消息名称。
    repetitions: 周期(ms)。
      repetitions 小于0时,表示无穷次。

def set_can_signal_value(channelIndex: int, databaseId: str, node: str, message: str, signal: str, value: float) -> bool:设置CAN消息的重复发送次数
    channelIndex: 通道号。
    databaseId: 该通道关联的DBC数据库ID。
    node: DBC消息节点名称。
    message: DBC消息名称。
    signal: DBC信号名称。
    value: 信号值。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃鱼的羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值