PC 上位机(UDE)与下位机(CANoe)数据交互工具设计文档
一、需求说明
1. 功能目标
实现上位机 PC UDE 与下位机 PC CANoe 的数据通信。
背景问题:
测试用例的 CANoe ETH 相关 CAPL 自动化脚本中会用到 UDE,但 CAPL 无法直接与 UDE 交互。
因此,需要通过 Python 工具 作为中间层,实现两者之间的数据桥梁。
2. 功能开发内容
实现以下 UDE API 功能 的 Python 封装:
- 变量读写(
ReadVariable
/WriteVariable
) - 程序控制(
BreakProgram
,StartProgram
,Reset
) - 连接控制(
ConnectTarget
,DisconnectTarget
,TryConnectAgain
) - 状态查询(
State
,VarValueCTime
)
Python 程序可启动并自动加载 UDE 工作空间,实现自动化交互。
二、背景与优势
1. 文档目的
角色 | 目的 |
---|---|
开发人员 | 参考开发实现逻辑 |
测试人员 | 指导使用操作流程 |
其他人员 | 了解软件整体功能与通信机制 |
三、开发环境
1. 使用 IDE
- PyCharm
- CANoe
- UDE + UKey
- VS Code
2. 编程语言与库
- Python
- py_canoe
- win32com
- 熟悉 CAPL 脚本
四、软件使用说明
1. CANoe 与 UDE 交互前置准备
1.1 使用到的 UDE API
ReadVariable, WriteVariable, BreakProgram, StartProgram,
State, Reset, VarValueCTime, TryConnectAgain,
ConnectTarget, DisconnectTarget
1.2 前期准备流程
启动顺序:
- 打开正确的 CANoe 工程(包含该工具的 Feature 工程)
- 启动 CANoe
- 启动 Python 程序
- 执行测试用例(Python 程序会自动创建系统变量)
Python 初始化示例
python
import win32com.client
app = win32com.client.Dispatch('CANoe.Application')
sys = app.System
namespaces = sys.Namespaces
五、系统变量定义
1. CAPL 读取 Python 返回的系统变量
python
namespaces.Add("CAPLReadSysVar")
CAPLRead_ns = namespaces("CAPLReadSysVar")
var = CAPLRead_ns.Variables
var.AddWriteable("ReadRVInt", 0)
var.AddWriteable("ReadRVFloat", 0.0)
var.AddWriteable("BreakProgramRV", 0)
var.AddWriteable("WriteRV", 0)
var.AddWriteable("DisConnRV", 0)
var.AddWriteable("ConnRV", 0)
var.AddWriteable("ResetRV", 0)
var.AddWriteable("StartProgramRV", 0)
var.AddWriteable("StateRV", 0)
2. CAPL 写入系统变量传入 Python 程序
读变量接口
python
namespaces.Add("ReadVariable")
readvar_ns = namespaces("ReadVariable")
readvar_ns.Variables.AddWriteable("Action", "False")
readvar_ns.Variables.AddWriteable("VarName", "")
写变量接口
python
namespaces.Add("WriteVariable")
writevar_ns = namespaces("WriteVariable")
writevar_ns.Variables.AddWriteable("Action", "False")
writevar_ns.Variables.AddWriteable("VarName", "")
writevar_ns.Variables.AddWriteable("ValueInt", 0)
断点、启动、状态、复位、时间戳、重连等接口
(以下为统一示例)
python
namespaces.Add("BreakProgram")
namespaces("BreakProgram").Variables.AddWriteable("Action", "False")
namespaces.Add("StartProgram")
namespaces("StartProgram").Variables.AddWriteable("Action", "False")
namespaces.Add("State")
namespaces("State").Variables.AddWriteable("Action", "False")
namespaces.Add("Reset")
namespaces("Reset").Variables.AddWriteable("Action", "False")
namespaces.Add("VarValueCTime")
ctime_ns = namespaces("VarValueCTime")
ctime_ns.Variables.AddWriteable("Action", "False")
ctime_ns.Variables.AddWriteable("VarName", "")
ctime_ns.Variables.AddWriteable("Time", "")
ctime_ns.Variables.AddWriteable("Input", "")
namespaces.Add("TryConnectAgain")
namespaces("TryConnectAgain").Variables.AddWriteable("Action", "False")
namespaces.Add("ConnectTarget")
namespaces("ConnectTarget").Variables.AddWriteable("Action", "False")
namespaces.Add("DisconnectTarget")
namespaces("DisconnectTarget").Variables.AddWriteable("Action", "False")
六、交互流程
CANoe ↔ Python ↔ UDE 数据交互流程
CAPL → 系统变量(Action=True) → Python检测并调用对应UDE API
→ 获取UDE返回数据 → 写入CAPLReadSysVar系统变量
→ CAPL通过sysGetVariable读取结果
七、CAPL 系统变量函数
1. sysSetVariableString
用于写值
c
long sysSetVariableString(char namespace[], char variable[], char value[]);
示例:
c
sysSetVariableString(sysvar::ReadVariable::Action,"True");
sysSetVariableString(sysvar::ReadVariable::VarName,checkchar1);
2. sysGetVariableString
用于读值
c
long sysGetVariableString(SysVarName, char buffer[], long bufferSize);
示例:
c
char demo[100];
sysGetVariableString(sysvar::CAPLReadSysVar::StrValue, demo, elcount(demo));
write("demo is %s", demo);
触发条件区别:
触发方式 | 描述 |
---|---|
on sysvar |
值变化时触发 |
on sysvar_update |
有更新记录即触发(即使值未变化) |
八、CAPL 实例代码
1. 自动连接 UDE
c
void connectUDE()
{
sysSetVariableString("DisconnectTarget","Action","True");
testWaitForTimeout(50);
sysSetVariableString("ConnectTarget","Action","True");
testWaitForTimeout(50);
sysSetVariableString("StartProgram","Action","True");
testWaitForTimeout(50);
}
2. 检查 UDE 连接状态
c
void check_UDEconnect()
{
int flag, i;
if (udeflag == 1)
{
connectUDE();
}
flag = read_10mstask_state();
if (flag == 1) return;
for (i=0; i<10; i++)
{
if (udeflag == 1)
connectUDE();
else {
PowerCtrlUbd(0,1,2);
PowerCtrlUbd(1,1,2);
}
testWaitForTimeout(10);
flag = read_10mstask_state();
if (flag == 1)
{
return;
}
if (i == 9)
{
testStepFail("check","UDE can not Connect");
return;
}
}
}
3. 读取 UDE 变量值
3.1 从 UDE 获取变量值
c
int getudevalueint(char buffer[])
{
int value;
sysSetVariableString("ReadVariable","Action","True");
testWaitForTimeout(5);
sysSetVariableString("ReadVariable","VarName",buffer);
testWaitForTimeout(5);
value = sysGetVariableInt("CAPLReadSysVar","ReadRVInt");
testWaitForTimeout(5);
return value;
}
3.2 读取任务状态
c
export long read_10mstask_state()
{
int A, i;
char buffer[100];
readcoretask(buffer);
task[0] = getudevalueint(buffer);
write("aaaa=%d", task[0]);
for (i=0; i<100; i++)
{
A = task[0];
testWaitForTimeout(10);
task[0] = getudevalueint(buffer);
if (task[0] != A)
{
testStepPass("check","UDE Connect after %d ms",(i+1)*1);
return 1;
}
}
return 0;
}
九、总结
- CAPL 脚本与 UDE 无法直接通信,通过 Python 中间件 实现实时交互;
- 通过 系统变量机制 实现 CAPL ↔ Python 双向数据传递;
- Python 调用 UDE API 进行变量读写与调试控制;
- 实现 高实时性、可扩展、自动化的测试通信机制。
十、python的CANoe-UDE交互工具源码
要查看源码可以下载链接:下载地址 CANoe_UDETool_v1.0。
1. CANoe_UDE_Data_Exchange_Tools.py
源码:
python
# -*- coding:utf-8 -*-
# author:ext.zonghuo.liu
import sys
import os
import time
import gc
import signal
import win32com.client
from common import *
import threading
import multiprocessing
import pythoncom
def Open_andConnected_Loadelf_Start(WspFile):
print("create new UDELauncher object")
ProgId = "UDELauncher"
Launcher = win32com.client.Dispatch(ProgId)
print(" Launcher: " + Launcher.Version)
bCreateWorkspace = False
print("start new UDE instance")
# Ude = Launcher.StartAndCreateWorkspace("UDEVisualPlatform.exe", WspFile, CfgFile, 1)
Ude = Launcher.StartAndOpenWorkspace("UDEVisualPlatform.exe", WspFile, "--silent-reload")
# Ude = Launcher.StartAndOpenWorkspace("UDEVisualPlatform.exe", WspFile, "--dont-reload")
print(" UDE version: " + Ude.VersionInfo)
print("access workspace")
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
print("wait for target connected")
if not Workspace.WaitForTargetConnected(10000): # 10s timeout
print("ERROR: target not connected !")
exit()
print("access first core debugger")
Debugger = Workspace.CoreDebugger(0)
# MultiCoreLoader = Workspace.MultiCoreLoader
# if MultiCoreLoader is None:
# print("Failed to access MultiCoreLoader!")
# return None
# else:
# Index1 = MultiCoreLoader.AddFile(ElfFile)
# MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core0", False)
# MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core0", True)
# MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core1", True)
# MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core1", True)
# MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core2", False)
# MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core2", True)
# MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core3", False)
# MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core3", True)
# MultiCoreLoader.DoDownload(0)
# print('load elf Core1 of bin success')
Debugger.Go()
# Open_andConnected_Loadelf_Start(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\zeekr.wsx",r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.elf")
def Creat_andConnected_Loadelf_setupkeeprunning_Start(WspFile, CfgFile, ElfFile):
print("create new UDELauncher object")
ProgId = "UDELauncher"
Launcher = win32com.client.Dispatch(ProgId)
print(" Launcher: " + Launcher.Version)
print("start new UDE instance")
Ude = Launcher.StartAndCreateWorkspace("UDEVisualPlatform.exe", WspFile, CfgFile, 1)
print(" UDE version: " + Ude.VersionInfo)
print("access workspace")
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
print("wait for target connected")
if not Workspace.WaitForTargetConnected(10000): # 10s timeout
print("ERROR: target not connected !")
exit()
# print("Wait for target connected")
# while 0 == UDEDebugger.Connected:
# UDEWorkspace.Sleep(100)
print("access first core debugger")
TargIntf = Debugger.TargIntf
Setup = TargIntf.Setup
Setup.SetItem("ConnOption", "KeepRunning")
# Setup.SetItem("PortType", "CommDev")
# Setup.SetItem("CommDevSel", "DeviceNumber=624126,PortType=USB,Type=UAD2")
MultiCoreLoader = Workspace.MultiCoreLoader
if MultiCoreLoader is None:
print("Failed to access MultiCoreLoader!")
return None
else:
Index1 = MultiCoreLoader.AddFile(ElfFile)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core0", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core0", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core1", True)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core1", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core2", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core2", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core3", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core3", True)
MultiCoreLoader.DoDownload(0)
print('load elf Core1 of bin success')
Debugger.Go()
CreatState = State()
return CreatState
# Creat_andConnected_Loadelf_setupkeeprunning_Start(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\wsx\zeekr_api1.wsx",r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\renesas_rh850_u2a16_debug_lpd4.cfg",r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.elf")
def Creat_andConnected_Loadelf_Start(WspFile, CfgFile, ElfFile):
print("create new UDELauncher object")
ProgId = "UDELauncher"
Launcher = win32com.client.Dispatch(ProgId)
print(" Launcher: " + Launcher.Version)
print("start new UDE instance")
Ude = Launcher.StartAndCreateWorkspace("UDEVisualPlatform.exe", WspFile, CfgFile, 1)
print(" UDE version: " + Ude.VersionInfo)
print("access workspace")
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
print("wait for target connected")
if not Workspace.WaitForTargetConnected(10000): # 10s timeout
print("ERROR: target not connected !")
exit()
# print("Wait for target connected")
# while 0 == UDEDebugger.Connected:
# UDEWorkspace.Sleep(100)
print("access first core debugger")
MultiCoreLoader = Workspace.MultiCoreLoader
if MultiCoreLoader is None:
print("Failed to access MultiCoreLoader!")
return None
else:
Index1 = MultiCoreLoader.AddFile(ElfFile)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core0", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core0", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core1", True)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core1", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core2", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core2", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core3", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core3", True)
MultiCoreLoader.DoDownload(0)
print('load elf Core1 of bin success')
Debugger.Go()
# Creat_andConnected_Loadelf_Start(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\wsx\zeekr_api1.wsx",r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\renesas_rh850_u2a16_debug_lpd4.cfg",r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.elf")
def Creat_andConnected(WspFile, CfgFile):
print("create new UDELauncher object")
ProgId = "UDELauncher"
Launcher = win32com.client.Dispatch(ProgId)
print(" Launcher: " + Launcher.Version)
print("start new UDE instance")
Ude = Launcher.StartAndCreateWorkspace("UDEVisualPlatform.exe", WspFile, CfgFile, 1)
print(" UDE version: " + Ude.VersionInfo)
print("access workspace")
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
print("wait for target connected")
if not Workspace.WaitForTargetConnected(10000): # 10s timeout
print("ERROR: target not connected !")
exit()
# print("Wait for target connected")
# while 0 == UDEDebugger.Connected:
# UDEWorkspace.Sleep(100)
print("access first core debugger")
Debugger = Workspace.CoreDebugger(0)
# Creat_andConnected(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\zeekr_api1.wsx",r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\renesas_rh850_u2a16_debug_lpd4.cfg")
def Load_Elf(ElfFile):
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
MultiCoreLoader = Workspace.MultiCoreLoader
if MultiCoreLoader is None:
print("Failed to access MultiCoreLoader!")
return None
else:
Index1 = MultiCoreLoader.AddFile(ElfFile)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core0", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core0", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core1", True)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core1", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core2", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core2", True)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core3", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core3", True)
Workspace.UserProfile.SetConfigParam('NoSrcFileDlg', 'System', 'ON')
MultiCoreLoader.DoDownload(0)
print('load elf Core1 of bin success')
# Load_Elf(r'C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.elf')
def Load_Hex(HexFile):
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
MultiCoreLoader = Workspace.MultiCoreLoader
if MultiCoreLoader is None:
print("Failed to access MultiCoreLoader!")
return None
else:
Index1 = MultiCoreLoader.AddFile(HexFile)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core0", True)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core0", False)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core1", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core1", False)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core2", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core2", False)
MultiCoreLoader.SetLoadBin(Index1, "Controller0.Core3", False)
MultiCoreLoader.SetLoadSym(Index1, "Controller0.Core3", False)
MultiCoreLoader.DoDownload(0)
print('load elf Core0 of bin success')
# Load_Hex(r'C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.hex')
def RemoveAllFiles():
'删除已加载的hex,elf文件'
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
MultiCoreLoader = Workspace.MultiCoreLoader
if MultiCoreLoader is None:
print("Failed to access MultiCoreLoader!")
return None
else:
MultiCoreLoader.RemoveAllFiles()
print('Remove Success')
# RemoveAllFiles()
def Init(cfgpath):
'''
Parameters
[in] Val (BSTR) Path of the target configuration file to be used. This may be•an absolute path to the cfg file
•a cfg file name within default 'Targets' folder
•a cfg file name within current directory
:return:
'''
import win32com.client
State = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
Debugger.Init(cfgpath)
State = Debugger.State
print('Start Success = ', State)
return State
# Init()
def SaveWorkspace():
'''
Parameters
[in] Val (BSTR) Path of the target configuration file to be used. This may be•an absolute path to the cfg file
•a cfg file name within default 'Targets' folder
•a cfg file name within current directory
:return:
'''
import win32com.client
State = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
Debugger.SaveWorkspace()
State = Debugger.State
print('Start Success = ', State)
return State
# SaveWorkspace()
def SaveWorkspaceAs(NewFilePath):
'''
Parameters
[in] Val (BSTR) Path of the target configuration file to be used. This may be•an absolute path to the cfg file
•a cfg file name within default 'Targets' folder
•a cfg file name within current directory
:return:
'''
import win32com.client
State = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
Debugger.SaveWorkspaceAs(NewFilePath)
State = Debugger.State
print('Start Success = ', State)
return State
# SaveWorkspaceAs(NewFilePath)
def Close():
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Ude.CloseWorkspace()
print("finished")
# Close()
def Cleanup():
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
RunningInstanceManager.Cleanup()
print("finished")
# Cleanup()
def StopInstance():
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
print("release objects and close UDE instance")
RunningInstanceManager.StopInstance(Ude)
print("finished")
# StopInstance()
def ReadVariable(VariableName):
print(VariableName)
VariableValue = 0
# ProgId = "UDERunningInstanceManager"
# RunningInstanceManager = win32com.client.Dispatch(ProgId)
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
# Ude = RunningInstanceManager.GetInstance(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
# print(" Workspace: " + Workspace.ProjectTitle)
if 0 == RunningInstanceManager.InstanceCount:
# print("ERROR: no running UDE instances found !")
# exit()
pass
else:
if not Workspace.CheckTargetConnected():
# print("ERROR: target not connected !")
VariableValue = Debugger.ReadVariable(VariableName)
# print('Read ', VariableName, '=', VariableValue)
# exit()
else:
try:
VariableValue = Debugger.ReadVariable(VariableName)
# print('Read ',VariableName,'=', VariableValue)
except:
pass
# print('read fail')
return VariableValue
# ReadVariable('OsShell_Cntr10msTask_OsCore1')
# ReadVariable('OsShell_Cntr10msTask_OsCore1')
# ReadVariable('CanNm_PnClusterResetTimer.raw[0][0]')
# ReadVariable('CanNm_NmState.str.ZCL_CANFD2_ZCL_3c2fd207')
# ReadVariable('?(CanNm_PnClusterResetTimer.str.CanNmPnFilterMaskByte_001[0])')
def WriteVariable(VariableName, NewValue):
ReadWriteValue = ''
# WriteValue = ''
WriteStatus = 0
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
# print(" Workspace: " + Workspace.ProjectTitle)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
else:
if not Workspace.CheckTargetConnected():
if not Workspace.WaitForTargetConnected(10): # 10s timeout
print("ERROR: target not connected !")
# exit()
else:
Debugger.WriteVariable(VariableName, NewValue)
# WriteValue = NewValue
# print('Write ',VariableName,'=',NewValue)
ReadWriteValue = Debugger.ReadVariable(VariableName)
# print('ReadWriteValue=', ReadWriteValue)
if str(ReadWriteValue) == str(NewValue):
WriteStatus = 1
print('Write ', VariableName, '=', NewValue)
return WriteStatus
# WriteVariable('?(CanNm_PnClusterResetTimer.str.CanNmPnFilterMaskByte_001[0])',0)
# WriteVariable('?(CanNm_NmState.str.ZCL_CANFD11_ZCL_301797c7)',1)
# WriteVariable('Tlib_AccrPedlNotCmplPsdChks_ZCLCANFD7_C',1)
def BreakProgram():
'''
Get the execution state of the core, which is controlled this debugger instance.
NoteThis property is deprecated. For new automation projects use function IUDEDebuggerInterface.GetState() instead.Parameters
[out] pState (BOOL*) Pointer to BOOL variable, that holds the state flag.•FALSE - the core execution is halted,
•TRUE - the core execution is not halted ( means executing or inactive). Due to its definition - BOOL is defined from basic type integer. The following integer return values provide more details about the execution state of the core:
•0 - the core execution is halted,
•1 - the core is running to execute code,
•2 - the core is inactive after reset.
:return:
'''
BreakStatus = 0
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
# print(" Workspace: " + Workspace.ProjectTitle)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
else:
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
# exit()
else:
Debugger.Break()
if not Debugger.WaitForHalt(3000): # 3s timeout
print("ERROR: not halted at breakpoint !")
# exit()
else:
State = Debugger.State
# print('Break Success = ',State)
if State == 0:
BreakStatus = 1
print('Break Success = ', State)
return BreakStatus
# BreakProgram()
def StartProgram():
StartStatus = 0
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
else:
Debugger.Go()
State = Debugger.State
if State == 1:
StartStatus = 1
# print('StartProgram')
return StartStatus
# StartProgram()
def State():
'''
•0 - the core execution is halted,
•1 - the core is running to execute code,
•2 - the core is inactive after reset. inactive
:return:
'''
import win32com.client
core0_State = ''
core1_State = ''
core2_State = ''
core3_State = ''
State = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger1 = Workspace.CoreDebugger(0)
Debugger2 = Workspace.CoreDebugger(1)
Debugger3 = Workspace.CoreDebugger(2)
Debugger4 = Workspace.CoreDebugger(3)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
else:
core0_State = Debugger1.State
core1_State = Debugger2.State
core2_State = Debugger3.State
core3_State = Debugger4.State
# if (core0_State == 1) and (core1_State == 1) and (core2_State == 1) and (core3_State == 1):
# State = 1
# #return State
# elif (core0_State == 2) or (core1_State == 2) or (core2_State == 2) or (core3_State == 2):
# State = 2
# else:
# State = 0
# print('core0_State = ', core0_State)
# print('core1_State = ', core1_State)
# print('core2_State = ', core2_State)
# print('core3_State = ', core3_State)
State = str(core0_State) + str(core1_State) + str(core2_State) + str(core3_State)
print('State=', State)
del ProgId
del RunningInstanceManager
# del Workspace
del Ude
del Workspace
del Debugger1
del Debugger2
del Debugger3
del Debugger4
del core0_State
del core1_State
del core2_State
del core3_State
return State
# return core0_State
# State()
def LoadAndFlash(elfpath, Options):
'''
Loads the target program from given file path into target and execute FLASH programming if necessary.
Parameters
[in] Path (BSTR)
[in] Options (VARIANT) Options 'VerifyOnly' and 'ProgramAndVerify'
[out] pVal (VARIANT_BOOL*) Pointer to return function result VARIANT_TRUE ... succeeded VARIANT_FALSE ... failed
:return:
'''
State = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
State = Debugger.GetState()
if 1 == State:
print(" Core is running")
elif 2 == State:
print(" Core is inactive")
else:
print(" Core is halted")
# 1st: check if elf file was already loaded
if not Debugger.LoadAndFlash(elfpath, Options):
# 2nd: load and FLASH-program elf file
if not Debugger.LoadAndFlash(elfpath):
print("ERROR: failed to load elf file !")
exit()
print("start target application")
Debugger.Go()
if not Workspace.WaitForAllCoresRunning(10000, False): # 1s timeout
print("ERROR: target not running !")
exit()
else:
print("wait a second")
Workspace.Sleep(1000)
State = Debugger.State
print('Start Success = ', State)
return State
# LoadAndFlash(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.elf",'ProgramAndVerify')
# LoadAndFlash(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.elf",'VerifyOnly')
def LoadHexDataFile(hexpath, Options):
'''
Loads the target data from given hex file path into target. Optionally execute FLASH programming if necessary.
Parameters
[in] Path (BSTR) String variable that holds the data file path string.
[in] ProgFlash (VARIANT_BOOL) VARIANT_TRUE ... execute FLASH programming is necessary
[in] Options (VARIANT) Options 'VerifyOnly' and 'ProgramAndVerify'
[out] pVal (VARIANT_BOOL*) Pointer to return function result VARIANT_TRUE ... succeeded VARIANT_FALSE ... failed
:return:
'''
State = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
else:
State = Debugger.GetState()
if 1 == State:
print(" Core is running")
elif 2 == State:
print(" Core is inactive")
else:
print(" Core is halted")
# 1st: check if elf file was already loaded
if not Debugger.LoadHexDataFile(hexpath, True, Options):
print('load and FLASH-program hex file')
print("start target application")
Debugger.Go()
if not Workspace.WaitForAllCoresRunning(10000, False): # 1s timeout
print("ERROR: target not running !")
exit()
else:
print("wait a second")
Workspace.Sleep(1000)
State = Debugger.State
print('Start Success = ', State)
return State
# LoadHexDataFile(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.hex",'ProgramAndVerify')
# LoadHexDataFile(r"C:\Users\ext.xiangxiang.guo\Desktop\UDE\PVER.hex",'VerifyOnly')
def Reset():
# print('Reset')
ResetStatus = 0
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
else: # 需取消注释
Debugger.ResetTarget()
State = Debugger.State
# print('Reset Success = ', State)
# print('Reset Success')
if State == 0:
ResetStatus = 1
print('Reset Success = ', State)
# print('Reset= ok')
return ResetStatus
# Reset()
def Restart():
'Restart 后需要重新上下电'
State = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
else:
Debugger.ReloadProgram()
State = Debugger.State
print('Restart Success = ', State)
return State
# Restart()
def ConnectTarget():
import win32com.client
ConnectStatus = 'false'
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Workspace.ConnectTarget(3000)
Debugger1 = Workspace.CoreDebugger(0)
Debugger2 = Workspace.CoreDebugger(1)
Debugger3 = Workspace.CoreDebugger(2)
Debugger4 = Workspace.CoreDebugger(3)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
else:
core0_State = Debugger1.State
core1_State = Debugger2.State
core2_State = Debugger3.State
core3_State = Debugger4.State
if (core0_State == 1) and (core1_State == 1) and (core2_State == 1) and (core3_State == 1):
State = 1
elif (core0_State == 0) and (core1_State == 2) or (core2_State == 2) or (core3_State == 2):
State = 2
elif (core0_State == 0) and (core1_State == 0) and (core2_State == 0) and (core3_State == 0):
State = 0
else:
State = 3
state = core0_State & core1_State & core2_State & core3_State
# print('State = ', State)
# print('core0_State = ', core0_State)
# print('core1_State = ', core1_State)
# print('core2_State = ', core2_State)
# print('core3_State = ', core3_State)
return State
# ConnectTarget()
def DisconnectTarget():
# DisconnectStatus = 'false'
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Workspace.DisconnectTarget(3000)
Debugger1 = Workspace.CoreDebugger(0)
Debugger2 = Workspace.CoreDebugger(1)
Debugger3 = Workspace.CoreDebugger(2)
Debugger4 = Workspace.CoreDebugger(3)
core0_State = Debugger1.State
core1_State = Debugger2.State
core2_State = Debugger3.State
core3_State = Debugger4.State
if (core0_State == 0) and (core1_State == 0) and (core2_State == 0) and (core3_State == 0): # 3s timeout
State = 0
else:
State = 1
# exit()
# Debugger = Workspace.CoreDebugger(0)
# State = Debugger.State
if State == 0:
DisconnectStatus = 1
# print('DisconnectStatus = ', State)
else:
DisconnectStatus = 0
# print('DisconnectStatus = ',State)
# print('Connect Target')
return DisconnectStatus
# DisconnectTarget()
def SetupKeeprunning():
ProgId = "UDERunningInstanceManager"
# RunningInstanceManager = win32com.client.Dispatch(ProgId)
# # Ude = RunningInstanceManager.GetInstance(0)
# # Workspace = Ude.Workspace
# # Debugger = Workspace.CoreDebugger(0)
# print(434)
# # TargIntf = Debugger.TargIntf
# # Setup = TargIntf.Setup
# # Setup.SetItem("ConnOption", "KeepRunning")
# SetupKeeprunning()
def SetupCommDev(DeviceNumber, UAD):
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
Debugger = Workspace.CoreDebugger(0)
TargIntf = Debugger.TargIntf
Setup = TargIntf.Setup
# Setup.SetItem("ConnOption", "KeepRunning")
Setup.SetItem("PortType", "CommDev")
Setup.SetItem("CommDevSel", "DeviceNumber=" + DeviceNumber, "PortType=USB", "Type=" + UAD)
# SetupCommDev('624126','UAD')
def SetBreakPoint_andWrite(Breakpoint, VariableName, NewValue): # 未验证
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
exit()
else:
print("set a breakpoint and wait for halt")
Debugger.Breakpoints.Add(Breakpoint)
Debugger.WriteVariable(VariableName, NewValue) # trigger halt at breakpoint
if not Debugger.WaitForHalt(3000): # 3s timeout
print("ERROR: not halted at breakpoint !")
exit()
# SetBreakPoint_andWrite("MulticoreDemo.c 363","g_SharedData.Seconds",59)
def BreakPointAdd(Function): # 未验证
'''
•a function
Debugger.Breakpoints.Add("main")
•a hex address
Debugger.Breakpoints.Add ("0xA00002CE")
•a source file line
Debugger.Breakpoints.Add ("hellopcp.c 175")
:param Function:
:return:
'''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
exit()
else:
print("set a breakpoint and wait for halt")
Debugger.Breakpoints.Add(Function)
if not Debugger.WaitForHalt(3000): # 3s timeout
print("ERROR: not halted at breakpoint !")
exit()
# Workspace.RemoveAllBreakpoints()
# BreakPointAdd('0xA00002CE')
def BreakPointAddAndGetResult(Function): # 未验证
'''
Add a new breakpoint to the the collection based on a textual description or value and tell the caller the result of the action by an integer code.
Parameters
[in] vDescriptionOrValue (VARIANT) Breakpoint descriptor
Textual description of breakpoint description:
•<function_name>
•<function_name> + L<line_offset>
•<function_name> + L<line_offset> + 0x<hexadecimal_address_offset>
•<function_name> + 0x<hexadecimal_address_offset>
•<source_file_name> <line>
•<source_file_name> .<line>
•0x<hexadecimal_address>
For inline functions and static functions:
•<source_file_name> <function_name>
•<source_file_name> <function_name> + L<line_offset>
•<source_file_name> <function_name> + L<line_offset> + 0x<hexadecimal_address_offset>
•<source_file_name> <function_name> + 0x<hexadecimal_address_offset>
Possible delimiters for <source_file_name> are: '...' and "...".
For inline functions the description <function_name> sets breakpoints to all instances. This possibly results to an error code because not enough hardware breakpoints are available. Description <source_file_name> <function_name> selects instances of an inline function from one source file only or selects a static function if the function name is used more than one time.
Parameters
[out] pnResultCode (long *) Pointer to location of long variable, which receives the result code Result code Description•>0 "%d breakpoints successfully added"
•0 "Breakpoint description '%s' cannot resolved"
•-2 "Not enough breakpoints available to add '%s'"
'''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
exit()
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
exit()
else:
print("set a breakpoint and wait for halt")
Debugger.Breakpoints.AddAndGetResult(Function)
if not Debugger.WaitForHalt(3000): # 3s timeout
print("ERROR: not halted at breakpoint !")
exit()
# BreakPointAddAndGetResult('main')
def DoEventsUntil(VariableName): # 未验证
'1.等待响应时间为2分钟'
holdtime = 0
changetime = 0
value3 = 0
value2 = 0
time1 = 0
time2 = 0
time3 = 0
time4 = 0
time5 = 0
t = time.perf_counter() # 读取前的时间
value = ReadVariable(VariableName)
while 1:
value1 = ReadVariable(VariableName)
if value != value1:
time1 = time.perf_counter() # 识别变量第一次变化得时间
value2 = value1
break
if time.perf_counter() - t > 120:
print(time.perf_counter() - t)
break
while 1:
value3 = ReadVariable(VariableName)
if value2 != value3:
time2 = time.perf_counter() # 识别变量第二次变化得时间
value4 = value3
break
if time.perf_counter() - t > 120:
print(time.perf_counter() - t)
break
while 1:
value4 = ReadVariable(VariableName)
if value3 != value4:
time3 = time.perf_counter() # 识别变量第三次变化得时间
if time.perf_counter() - t > 120:
print(time.perf_counter() - t)
break
while 1:
value5 = ReadVariable(VariableName)
if value4 != value5:
time4 = time.perf_counter() # 识别变量第四次变化得时间
if time.perf_counter() - t > 120:
print(time.perf_counter() - t)
break
changetime = time4 - time3
print(270, changetime)
return changetime
# DoEventsUntil('OsShell_Cntr10msTask_OsCore1')
def ReadArrayVariable(Addr, Array, Options): # 未验证
VariableValue = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
# print(" Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
# exit()
# print("wait for target connected")
# if not Workspace.WaitForTargetConnected(100): # 10s timeout
# print("ERROR: target not connected !")
# exit()
else:
VariableValue = Debugger.ReadArray(Addr, Array, Options)
print('VariableValue=', VariableValue)
return VariableValue
def ReadMemory8(Adr):
VariableValue = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print("Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
# exit()
else:
VariableValue = Debugger.ReadMemory8(Adr)
print('VariableValue=', VariableValue)
return VariableValue
# ReadMemory8('0xFE0586C6')
def ReadMemory16(Adr):
VariableValue = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print("Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
# exit()
else:
VariableValue = Debugger.ReadMemory16(Adr)
print('VariableValue=', VariableValue)
return VariableValue
# ReadMemory16('0xFE0586C6')
def ReadMemory32(Adr):
VariableValue = ''
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
print("Workspace: " + Workspace.ProjectTitle)
Debugger = Workspace.CoreDebugger(0)
if 0 == RunningInstanceManager.InstanceCount:
print("ERROR: no running UDE instances found !")
# exit()
if not Workspace.CheckTargetConnected():
print("ERROR: target not connected !")
# exit()
else:
VariableValue = Debugger.ReadMemory32(Adr)
print('VariableValue=', VariableValue)
return VariableValue
# ReadMemory32('0x00096E34')
def UDE_TaskKill():
'1.关闭UDE和其小程序'
# ReturnInfo = os.popen('tasklist | findstr "UDEVisualPlatform.exe"').read()
ReturnInfo = os.popen('tasklist | findstr "ude.exe"').read()
print(ReturnInfo)
if "ude.exe" in ReturnInfo:
os.system('taskkill /F /IM ude.exe')
# ReturnInfo = os.popen('tasklist | findstr "AccessRunningUde.exe"').read()
# print(ReturnInfo)
# if "AccessRunningUde.exe" in ReturnInfo:
# os.system('taskkill /F /IM AccessRunningUde.exe')
print('关闭UDE软件')
return 0
# UDE_TaskKill()
def AccessRunningUde_TaskKill():
'1.关闭UDE和其小程序'
# ReturnInfo = os.popen('tasklist | findstr "UDEVisualPlatform.exe"').read()
# print(ReturnInfo)
# if "UDEVisualPlatform.exe" in ReturnInfo:
# os.system('taskkill /F /IM UDEVisualPlatform.exe')
ReturnInfo = os.popen('tasklist | findstr "AccessRunningUde.exe"').read()
# print(ReturnInfo)
if "AccessRunningUde.exe" in ReturnInfo:
os.system('taskkill /F /IM AccessRunningUde.exe')
print('关闭AccessRunningUde.exe')
return 0
# UDE_TaskKill()
def VarValueCTime(VariableName, VarValueArray, RunningTime):
Ctime0 = {}
# eventlet.monkey_patch()
# with eventlet.Timeout(1, False):
RunningTime = int(RunningTime)
# VarValueArray = eval(VarValueArray)#eval
# print(type(VarValueArray))
time00 = time.time()
while True:
# VarValue0= ReadVariable(VariableName)
VarValue0 = str(ReadVariable(VariableName))
# print(type(VarValue0))
if VarValue0 in VarValueArray:
VarValueArray.remove(VarValue0)
time0 = time.time()
while True:
VarValue = str(ReadVariable(VariableName))
time1 = time.time()
if VarValue0 != VarValue:
RTime = time1 - time0
Ctime0.update({VarValue0: RTime})
# print(VarValue0, RTime)
break
else:
RTime1 = time1 - time0
if RTime1 > RunningTime:
# print("超时")
break
# time.sleep(0.2)
time2 = time.time()
RTime2 = time2 - time00
if RTime2 > RunningTime:
break
# time.sleep(0.2)
print(VariableName, Ctime0)
return Ctime0
def TryConnectAgain233():
TryConnectStatus = 0
while TryConnectStatus == 0:
try:
start_time = time.time()
ude_state = DisconnectTarget()
if ude_state == 1:
log_and_print('UDE is Disconnected successfully!!!')
Result = ConnectTarget()
if Result != 0:
log_and_print("Connected successfully")
Startstatus = StartProgram()
if Startstatus == 1:
end_time = time.time()
TryConnectStatus = int((end_time - start_time) * 100)
log_and_print(f'UDE is Running,try connected 耗时: {TryConnectStatus}')
return TryConnectStatus
else:
log_and_print("Failed to start program!!!")
else:
log_and_print("Failed to connect!!!")
else:
log_and_print("Failed to disconnect!!!")
except IOError:
print('请保持UDE连接')
def TryConnectAgain():
TryConnectStatus = 0
ProgId = "UDERunningInstanceManager"
RunningInstanceManager = win32com.client.Dispatch(ProgId)
Ude = RunningInstanceManager.GetInstance(0)
Workspace = Ude.Workspace
# print("Workspace: " + Workspace.ProjectTitle)
# Debugger = Workspace.CoreDebugger(0)
while TryConnectStatus == 0:
try:
if not Workspace.CheckTargetConnected():
log_and_print("target not connected !")
start_c_time = time.time()
Result = ConnectTarget()
if Result != 0:
log_and_print("Connected successfully")
Startstatus = StartProgram()
if Startstatus == 1:
end_c_time = time.time()
TryConnectStatus = int((end_c_time - start_c_time) * 100)
log_and_print(f'UDE is Running,try connected 耗时: {TryConnectStatus}')
else:
log_and_print("Failed to start program!!!")
else:
log_and_print("Failed to connect!!!")
else:
start_p_time = time.time()
Startstatus = StartProgram()
if Startstatus == 1:
end_p_time = time.time()
TryConnectStatus = int((end_p_time - start_p_time) * 100)
log_and_print(f'UDE is Connected!!,启动程序耗时: {TryConnectStatus}')
else:
start_time = time.time()
ude_state = DisconnectTarget()
if ude_state == 1:
log_and_print('UDE is Disconnected successfully!!!')
Result = ConnectTarget()
if Result != 0:
log_and_print("Connected successfully")
Startstatus = StartProgram()
if Startstatus == 1:
end_time = time.time()
TryConnectStatus = int((end_time - start_time) * 100)
log_and_print(f'UDE is Running,try connected 耗时: {TryConnectStatus}')
else:
log_and_print("Failed to start program!!!")
else:
log_and_print("Failed to connect!!!")
else:
log_and_print("Failed to disconnect!!!")
return TryConnectStatus
except IOError:
print('请保持UDE连接')
# print('Connect Target')
# print('Connect Target')
def TryConnectAgain1():
ConnectStatus = 'false'
try:
UDE_State = State()
if UDE_State == 1:
ConnectStatus = 'true'
print('UDE is Running')
else:
print('try reseting')
Result = ConnectTarget()
if Result == 'true':
ConnectStatus = 'true'
print('UDE is Running')
else:
Reset()
Result = StartProgram()
if Result == 'true':
ConnectStatus = 'true'
print('UDE is Running')
except IOError:
print('请保持UDE连接')
# print('Connect Target')
return ConnectStatus
def close_program():
log_and_print("Program is closing")
log.colse()
os._exit(0)
# sys.exit(0)
# VarValueCTime('CanNm_NmState.raw[2]',[5,4,3,2,1],1)
signal.signal(signal.SIGINT, close_program)
signal.signal(signal.SIGTERM, close_program)
if __name__ == "__main__":
delete_variables_namespaces()
defined_canoe16_sp6_sys_vars()
while True:
try:
if get_system_variable_value('ReadVariable::Action') == "True":
log_and_print(
"*************************************************<<ReadVariable>>*******************************************\n")
set_system_variable_value('ReadVariable::Action', "False")
start_time = time.time()
read_var_name = get_system_variable_value('ReadVariable::VarName')
Value = ReadVariable(read_var_name)
# get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::ReadRVInt", Value)
if isinstance(Value, int):
modify_status = set_system_variable_value("CAPLReadSysVar::ReadRVInt", Value)
# set_system_variable_value("CAPLReadSysVar::ReadRVInt", Value)
elif isinstance(Value, float):
modify_status = set_system_variable_value("CAPLReadSysVar::ReadRVFloat", Value)
else:
log_and_print("其他类型不传入")
if modify_status:
log_and_print(f"读取UDE返回值成功:{Value}")
# get_sys_var = get_system_variable_value("CAPLReadSysVar::ReadRVInt")
# log_and_print(f"修改CANoe系统变量成功:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('WriteVariable::Action') == "True":
log_and_print(
"*************************************************<<WriteVariable>>*******************************************\n")
set_system_variable_value('WriteVariable::Action', "False")
start_time = time.time()
write_var_name = get_system_variable_value('WriteVariable::VarName')
write_var_value = get_system_variable_value('WriteVariable::Value')
write_var_value_int = int(write_var_value)
Result = WriteVariable(write_var_name, write_var_value_int)
# ude_value = str(Result)
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::WriteRV", Result)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('BreakProgram::Action') == "True":
log_and_print(
"*************************************************<<BreakProgram>>*******************************************\n")
set_system_variable_value('BreakProgram::Action', "False")
start_time = time.time()
Result = BreakProgram()
# ude_value = str(Result)
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::BreakProgramRV", Result)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('StartProgram::Action') == "True":
log_and_print(
"*************************************************<<StartProgram>>*******************************************\n")
set_system_variable_value('StartProgram::Action', "False")
start_time = time.time()
Result = StartProgram()
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::StartProgramRV", Result)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('State::Action') == "True":
log_and_print(
"*************************************************<<State>>*******************************************\n")
set_system_variable_value('State::Action', "False")
start_time = time.time()
Value = State()
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::StateRV", Value)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('Reset::Action') == "True":
log_and_print(
"*************************************************<<Reset>>*******************************************\n")
set_system_variable_value('Reset::Action', "False")
start_time = time.time()
Result = Reset()
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::ResetRV", Result)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('VarValueCTime::Action') == "True":
log_and_print(
"*************************************************<<VarValueCTime>>*******************************************\n")
set_system_variable_value('VarValueCTime::Action', "False")
start_time = time.time()
VariableName = get_system_variable_value('VarValueCTime::VarName')
CTime = get_system_variable_value('VarValueCTime::Time')
Valueinput = get_system_variable_value('VarValueCTime::Input')
Valueout = VarValueCTime(VariableName, Valueinput, CTime)
ude_value = str(Valueout)
get_sys_var = return_value_to_canoe_sys_var(ude_value)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('TryConnectAgain::Action') == "True":
log_and_print(
"*************************************************<<TryConnectAgain>>*******************************************\n")
set_system_variable_value('TryConnectAgain::Action', "False")
start_time = time.time()
Result = TryConnectAgain()
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::TryConnRV", Result)
log_and_print(f"修改CANoe系统变量成功,重连耗时:{get_sys_var}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('ConnectTarget::Action') == "True":
log_and_print(
"*************************************************<<ConnectTarget>>*******************************************\n")
set_system_variable_value('ConnectTarget::Action', "False")
start_time = time.time()
UDE_State = ConnectTarget()
conn_time = time.time()
if UDE_State == 1:
Result = 1
else:
Result = 0
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::ConnRV", Result)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var},连接耗时:{(conn_time - start_time) * 1000}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
if get_system_variable_value('DisconnectTarget::Action') == "True":
log_and_print(
"*************************************************<<DisconnectTarget>>*******************************************\n")
set_system_variable_value('DisconnectTarget::Action', "False")
start_time = time.time()
ude_state = DisconnectTarget()
disconn_time = time.time()
get_sys_var = return_value_to_canoe_sys_var("CAPLReadSysVar::DisConnRV", ude_state)
log_and_print(f"修改CANoe系统变量成功:{get_sys_var}, 断连耗时:{(disconn_time - start_time) * 1000}")
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
log_and_print(f"Code execution completed,time-consuming: {execution_time_ms:.2f} ms")
except Exception as e:
log_and_print(f"Error :{e}")
# close_program()
2. common.py
CANoe API的封装库,基于py_canoe修改的。
python
# -*- coding:utf-8 -*-
# author:ext.zonghuo.liu
import win32com.client
import pythoncom
from typing import Union
from logger import CustomLogger
log = CustomLogger()
def log_and_print(message, level='info'):
if level == 'info':
log.info(message)
elif level == 'error':
log.error(message)
elif level == 'warning':
log.warning(message)
elif level == 'debug':
log.debug(message)
elif level == 'critical':
log.critical(message)
# print(message)
def get_canoe_status():
try:
pythoncom.CoInitialize()
com_obj = win32com.client.Dispatch('CANoe.Application')
status = com_obj.Measurement.Running
except Exception as e:
log_and_print(f"Error setting CANoe Status: {str(e)}", level='error')
finally:
pythoncom.CoUninitialize()
return status
def get_system_variable_value(sys_var_name: str) -> Union[int, float, str, tuple, None]:
r"""get_system_variable_value Returns a system variable value.
Args:
sys_var_name (str): The name of the system variable. Ex- "sys_var_demo::speed"
Returns:
System Variable value.
"""
pythoncom.CoInitialize()
namespace = '::'.join(sys_var_name.split('::')[:-1])
variable_name = sys_var_name.split('::')[-1]
return_value = None
try:
com_obj = win32com.client.Dispatch('CANoe.Application')
sys = com_obj.System
namespaces = sys.Namespaces
namespace_com_object = namespaces(namespace)
variable_com_object = namespace_com_object.Variables(variable_name)
return_value = variable_com_object.Value
# self.log.info(f'system variable({sys_var_name}) value <- {return_value}.')
except Exception as e:
log_and_print(f'failed to get system variable({sys_var_name}) value. {e}', level='error')
finally:
pythoncom.CoUninitialize()
return return_value
def set_system_variable_value(sys_var_name: str, value: Union[int, float, str]) -> None:
r"""set_system_variable_value sets a value to system variable.
Args:
sys_var_name (str): The name of the system variable. Ex- "sys_var_demo::speed".
value (Union[int, float, str]): variable value. supported CAPL system variable data types integer, double, string and data.
"""
namespace = '::'.join(sys_var_name.split('::')[:-1])
variable_name = sys_var_name.split('::')[-1]
modify_value = False
try:
pythoncom.CoInitialize()
com_obj = win32com.client.Dispatch('CANoe.Application')
sys = com_obj.System
namespaces = sys.Namespaces
namespace_com_object = namespaces(namespace)
variable_com_object = namespace_com_object.Variables(variable_name)
if isinstance(variable_com_object.Value, int):
variable_com_object.Value = int(value)
modify_value = True
elif isinstance(variable_com_object.Value, float):
variable_com_object.Value = float(value)
modify_value = True
else:
variable_com_object.Value = value
modify_value = True
log_and_print(f'system variable({sys_var_name}) value set to -> {value}.')
except Exception as e:
log_and_print(f'failed to set system variable({sys_var_name}) value. {e}', level='error')
finally:
pythoncom.CoUninitialize()
return modify_value
def get_canoe_version_info():
r"""The Version class represents the version of the CANoe application.
Returns:
"full_name" - The complete CANoe version.
"name" - The CANoe version.
"build" - The build number of the CANoe application.
"major" - The major version number of the CANoe application.
"minor" - The minor version number of the CANoe application.
"patch" - The patch number of the CANoe application.
"""
try:
pythoncom.CoInitialize()
com_obj = win32com.client.Dispatch('CANoe.Application')
ver_obj = com_obj.Version
version_info = {'full_name': ver_obj.FullName,
'name': ver_obj.Name,
'build': ver_obj.Build,
'major': ver_obj.major,
'minor': ver_obj.minor,
'patch': ver_obj.Patch}
log_and_print('> CANoe Application.Version <'.center(100, '='))
for k, v in version_info.items():
log_and_print(f'{k:<10}: {v}')
log_and_print(''.center(100, '='))
except Exception as e:
log_and_print(f"Error setting up CANoe Versions: {str(e)}", level='error')
finally:
pythoncom.CoUninitialize()
return version_info
class Namespace:
def __init__(self, namespace_com_obj):
self.com_obj = win32com.client.Dispatch(namespace_com_obj)
self.__com_obj_dir = dir(self.com_obj)
@property
def name(self) -> str:
"""Returns the name of the Namespace.
Returns:
str: The name of the namespace.
"""
return self.com_obj.Name
# @property
# def namespaces(self):
# """Returns the Namespaces object.
# """
# return Namespaces(self.com_obj.Namespaces) if 'Namespaces' in self.__com_obj_dir else None
#
# @property
# def variables(self):
# """Returns the Variables object.
# """
# return Variables(self.com_obj.Variables) if 'Variables' in self.__com_obj_dir else None
def fetch_namespaces():
try:
pythoncom.CoInitialize()
com_obj = win32com.client.Dispatch('CANoe.Application')
sys = com_obj.System
namespaces = sys.Namespaces
counts = namespaces.Count
# namespaces_data = dict()
namespaces_list = list()
if counts > 0:
for index in range(1, counts + 1):
namespace_com_obj = namespaces.Item(index)
namespace = Namespace(namespace_com_obj)
#namespaces_data[namespace.name] = namespace
namespaces_list.append(namespace.name)
except Exception as e:
log_and_print(f"Error setting up CANoe system variables: {str(e)}", level='error')
finally:
pythoncom.CoUninitialize()
return namespaces_list
def defined_canoe16_sp6_sys_vars():
try:
pythoncom.CoInitialize()
get_canoe_version_info()
get_all_namespace_name = fetch_namespaces()
com_obj = win32com.client.Dispatch('CANoe.Application')
sys = com_obj.System
namespaces = sys.Namespaces
variables_to_add = [
("CAPLReadSysVar", [
("ReadRVInt", 0),
("ReadRVFloat", 0.0),
("BreakProgramRV", 0),
("WriteRV", 0),
("DisConnRV", 0),
("TryConnRV", 0),
("ConnRV", 0),
("ResetRV", 0),
("StartProgramRV", 0),
("StateRV", 0)
]),
("ReadVariable", [("Action", "False"), ("VarName", "")]),
("WriteVariable", [("Action", "False"), ("VarName", ""), ("ValueInt", 0)]),
("BreakProgram", [("Action", "False")]),
("StartProgram", [("Action", "False")]),
("State", [("Action", "False")]),
("Reset", [("Action", "False")]),
("VarValueCTime", [
("Action", "False"),
("VarName", ""),
("Time", ""),
("Input", "")
]),
("TryConnectAgain", [("Action", "False")]),
("ConnectTarget", [("Action", "False")]),
("DisconnectTarget", [("Action", "False")])
]
for ns_name, vars_list in variables_to_add:
if ns_name not in get_all_namespace_name:
namespaces.Add(ns_name)
log_and_print(f'system NameSpace[{ns_name}] Added successfully.')
ns = namespaces(ns_name)
for var_name, default_value in vars_list:
try:
ns.Variables.AddWriteable(var_name, default_value)
log_and_print(f'system variable({var_name}) added successfully.')
except Exception as e:
log_and_print(f"Error adding variable '{var_name}' in namespace '{ns_name}': {str(e)}")
else:
log_and_print(f'Namespaces <<{ns_name}>> already exists, Skipping creation.')
except Exception as e:
log_and_print(f"Error setting up CANoe system variables: {str(e)}", level='error')
finally:
pythoncom.CoUninitialize()
def return_value_to_canoe_sys_var(Variable, value):
run_status = get_canoe_status()
get_sys_var = None
run_status = 1
if run_status:
modify_status = set_system_variable_value(Variable, value)
log_and_print(modify_status)
if modify_status:
log_and_print("modify values Successed")
get_sys_var = get_system_variable_value(Variable)
else:
log_and_print("modify values Failed")
else:
log_and_print("CANoe工程未启动!请检查!!!!")
return get_sys_var
# app.delete_system_variable_namespace('UdeExchangeData4::ReturnValues')
def delete_sys_var_ssssnasssmespace1(sys_var_name: str):
r"""delete_system_variable Create a system variable with an initial value
Args:
sys_var_name (str): The name of the system variable. Ex- "sys_var_demo::speed"
Returns:
object: none.
"""
namespace_name = '::'.join(sys_var_name.split('::')[:-1])
variable_name = sys_var_name.split('::')[-1]
try:
com_obj = win32com.client.Dispatch('CANoe.Application')
sys = com_obj.System
namespaces = sys.Namespaces
# print(namespaces)
# namespace_com_object = namespaces(namespace_name)
# variable_com_object = namespace_com_object.Variables(variable_name)
# namespace_com_object.Variables.Remove(variable_name)
namespaces.Remove(namespace_name)
log_and_print(f'system variable({sys_var_name}) deleted successfully.')
except Exception as e:
log_and_print(f'failed to deleted system variable({sys_var_name}). {e}', level='error')
def delete_sys_var_namespace(namespace_name, variables):
try:
pythoncom.CoInitialize()
com_obj = win32com.client.Dispatch('CANoe.Application')
sys = com_obj.System
namespaces = sys.Namespaces
# if namespace_name in namespaces:
namespace_com_object = namespaces(namespace_name)
for variable_name in variables:
# if variable_name in namespace_com_object.Variables:
namespace_com_object.Variables.Remove(variable_name)
log_and_print(f'Variable <<{variable_name}>> in namespace [{namespace_name}] deleted successfully.')
namespaces.Remove(namespace_name)
log_and_print(f'Namespace {namespace_name} deleted successfully.')
# else:
# log_and_print(f'Namespace {namespace_name} does not exist.')
except Exception as e:
log_and_print(f'Failed to delete namespace ({namespace_name}) or its variables. {e}', level='error')
finally:
pythoncom.CoUninitialize()
def delete_variables_namespaces():
variables_to_add = [
("CAPLReadSysVar", [
"ReadRVInt",
"ReadRVFloat",
"BreakProgramRV",
"WriteRV",
"DisConnRV",
"ConnRV",
"TryConnRV",
"ResetRV",
"StartProgramRV",
"StateRV"
]),
("ReadVariable", ["Action", "VarName"]),
("WriteVariable", ["Action", "VarName", "ValueInt"]),
("BreakProgram", ["Action"]),
("StartProgram", ["Action"]),
("State", ["Action"]),
("Reset", ["Action"]),
("VarValueCTime", [
"Action",
"VarName",
"Time",
"Input"
]),
("TryConnectAgain", ["Action"]),
("ConnectTarget", ["Action"]),
("DisconnectTarget", ["Action"])
]
for namespace, vars_list in variables_to_add:
delete_sys_var_namespace(namespace, vars_list)
if __name__ == "__main__":
file_path = r"E:\UDE_Develop\CANOE_UDE 2\UDE_API\UDE_Variable.ini"
file_path1 = r"E:\UDE_Develop\CANOE_UDE 2\UDE_API\UDE_Variable2.ini"
# monitor_ini_file_and_section(file_path)
# d = fetch_namespaces()
# print(d)
# defined_canoe16_sp6_sys_vars()
# delete_sys_var_ssssnamespace("VarValueCTime::VarName")
sd = return_value_to_canoe_sys_var("TryConnectAgain::Action", "True")
print(sd, type(sd))
# app.set_system_variable_value('ReadVariable::Action', "True")
# value = "3453"
# return_value_to_canoe_sys_var(value)
# remove_duplicate_keys(file_path)
# read_canoe_sys_var()
3. logger.py
打印log的库封装
python
import logging
import os
from datetime import datetime
from logging.handlers import TimedRotatingFileHandler
class CustomLogger:
def __init__(self, log_dir='logs', log_level=logging.INFO):
self.log_dir = log_dir
self.log_level = log_level
self.logger = logging.getLogger('CustomLogger')
self.logger.setLevel(self.log_level)
self._setup_log_directory()
self._configure_logger()
def _setup_log_directory(self):
if not os.path.exists(self.log_dir):
os.makedirs(self.log_dir)
def _get_log_file_path(self):
current_date = datetime.now().strftime('%Y-%m-%d')
log_file_name = f'{current_date}.log'
return os.path.join(self.log_dir, log_file_name)
def _configure_logger(self):
log_file_path = self._get_log_file_path()
handler = logging.FileHandler(log_file_path)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
self.logger.addHandler(handler)
stream_handler = logging.StreamHandler()
stream_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
stream_handler.setFormatter(stream_formatter)
self.logger.addHandler(stream_handler)
def info(self, message):
self.logger.info(message)
self._flush_log()
def error(self, message):
self.logger.error(message)
self._flush_log()
def warning(self, message):
self.logger.warning(message)
self._flush_log()
def debug(self, message):
self.logger.debug(message)
self._flush_log()
def critical(self, message):
self.logger.critical(message)
self._flush_log()
def _flush_log(self):
for handler in self.logger.handlers:
handler.flush()
def colse(self):
handlers = self.logger.handlers[:]
for handler in handlers:
handler.close()
self.logger.removeHandler(handler)
# 使用示例
if __name__ == "__main__":
log = CustomLogger()
log.info("This is an info message.")
log.error("This is an error message.")
log.warning("This is a warning message.")
log.debug("This is a debug message.")
log.critical("This is a critical message.")
这些是我工作在做以太网的时候需要CAPL脚本来调用UDE做一些操作,所以我就开发了一个CANoe UDE交互工具出来,感谢各位大佬,关注和点评,有啥疑问随时评论区见,希望能给大家带来一点帮助。