# 脚本编写说明
一、 入口函数
脚本加载后,会执行__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: 信号值。

414

被折叠的 条评论
为什么被折叠?



