taotoolkit 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- taotoolkit/__init__.py +81 -0
- taotoolkit/asrVrf.py +322 -0
- taotoolkit/tao_camDvt.py +1186 -0
- taotoolkit/tao_cmdTool.py +626 -0
- taotoolkit/tao_common.py +435 -0
- taotoolkit/tao_device.py +1011 -0
- taotoolkit/tao_flash.py +823 -0
- taotoolkit/tao_tuning.py +1344 -0
- taotoolkit/tao_vrfTool.py +690 -0
- taotoolkit-1.0.0.dist-info/METADATA +50 -0
- taotoolkit-1.0.0.dist-info/RECORD +13 -0
- taotoolkit-1.0.0.dist-info/WHEEL +5 -0
- taotoolkit-1.0.0.dist-info/top_level.txt +1 -0
taotoolkit/tao_common.py
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
from functools import wraps
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Callable, Dict, List, Optional, Any
|
|
9
|
+
from colorama import Back, Fore, Style, init
|
|
10
|
+
|
|
11
|
+
init(autoreset=True)
|
|
12
|
+
|
|
13
|
+
_DEBUG_MODE = False
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def debugCtrl(debug: int) -> None:
|
|
17
|
+
global _DEBUG_MODE
|
|
18
|
+
_DEBUG_MODE = debug == 1
|
|
19
|
+
|
|
20
|
+
level_colors = {
|
|
21
|
+
"DEBUG": Fore.WHITE,
|
|
22
|
+
"INFO": Fore.GREEN,
|
|
23
|
+
"HIGH": Fore.MAGENTA,
|
|
24
|
+
"WARN": Fore.YELLOW,
|
|
25
|
+
"ERROR": Fore.RED,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def logDecorator(level="INFO", callStack=1):
|
|
29
|
+
def decorator(func):
|
|
30
|
+
@wraps(func)
|
|
31
|
+
def wrapper(*args, **kwargs):
|
|
32
|
+
try:
|
|
33
|
+
frame = sys._getframe(callStack)
|
|
34
|
+
fileName = os.path.basename(frame.f_code.co_filename)
|
|
35
|
+
funcName = frame.f_code.co_name
|
|
36
|
+
lineNum = frame.f_lineno
|
|
37
|
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
|
38
|
+
|
|
39
|
+
result = func(*args, **kwargs)
|
|
40
|
+
if level == "DEBUG" and _DEBUG_MODE != 1:
|
|
41
|
+
return result
|
|
42
|
+
color = level_colors.get(level, Fore.WHITE)
|
|
43
|
+
message = f"{timestamp} {color}{Back.RESET}{Style.NORMAL}{level.ljust(5)} [{fileName}:{lineNum} {funcName}] "
|
|
44
|
+
args_str = " ".join(map(str, args))
|
|
45
|
+
kwargs_str = " ".join(f"{k}={v}" for k, v in kwargs.items())
|
|
46
|
+
all_args = f"{args_str} {kwargs_str}".strip()
|
|
47
|
+
|
|
48
|
+
print(f"{message}: {all_args}")
|
|
49
|
+
return result
|
|
50
|
+
except Exception as e:
|
|
51
|
+
print(f"Error in logDecorator: {e}")
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
return wrapper
|
|
55
|
+
|
|
56
|
+
return decorator
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@logDecorator(level="DEBUG")
|
|
60
|
+
def logd(*args):
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@logDecorator(level="INFO")
|
|
65
|
+
def logi(*args):
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@logDecorator(level="HIGH")
|
|
70
|
+
def logh(*args):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@logDecorator(level="WARN")
|
|
75
|
+
def logw(*args):
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@logDecorator(level="ERROR")
|
|
80
|
+
def loge(*args):
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _create_log_call_func(level, default_callStack=2):
|
|
85
|
+
"""Factory function to create log functions with customizable callStack."""
|
|
86
|
+
def log_func(*args, callStack=None):
|
|
87
|
+
if callStack is None:
|
|
88
|
+
callStack = default_callStack
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
frame = sys._getframe(callStack)
|
|
92
|
+
fileName = os.path.basename(frame.f_code.co_filename)
|
|
93
|
+
funcName = frame.f_code.co_name
|
|
94
|
+
lineNum = frame.f_lineno
|
|
95
|
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
|
96
|
+
|
|
97
|
+
if level == "DEBUG" and _DEBUG_MODE != 1:
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
color = level_colors.get(level, Fore.WHITE)
|
|
101
|
+
message = f"{timestamp} {color}{Back.RESET}{Style.NORMAL}{level.ljust(5)} [{fileName}:{lineNum} {funcName}] "
|
|
102
|
+
args_str = " ".join(map(str, args))
|
|
103
|
+
|
|
104
|
+
print(f"{message}: {args_str}")
|
|
105
|
+
return None
|
|
106
|
+
except Exception as e:
|
|
107
|
+
print(f"Error in log call: {e}")
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
return log_func
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
logCallDebug = _create_log_call_func("DEBUG", default_callStack=2)
|
|
114
|
+
logCallInfo = _create_log_call_func("INFO", default_callStack=2)
|
|
115
|
+
logCallWarn = _create_log_call_func("WARN", default_callStack=2)
|
|
116
|
+
logCallHigh = _create_log_call_func("HIGH", default_callStack=2)
|
|
117
|
+
logCallErr = _create_log_call_func("ERROR", default_callStack=2)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def exit() -> None:
|
|
121
|
+
sys.exit(1)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def eExit(msg: str) -> None:
|
|
125
|
+
loge(msg)
|
|
126
|
+
sys.exit(1)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def iExit(msg: str) -> None:
|
|
130
|
+
logi(msg)
|
|
131
|
+
sys.exit(0)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def sleep(seconds: float) -> None:
|
|
135
|
+
time.sleep(seconds)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
sysVersion = sys.platform
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def createFolder(path: str) -> None:
|
|
142
|
+
os.makedirs(path, exist_ok=True)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def fileExist(path: str) -> bool:
|
|
146
|
+
return os.path.exists(path)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def findFilesBySuffixKeyword(path: str, suffix: str, keyword: str) -> List[str]:
|
|
150
|
+
result = []
|
|
151
|
+
for root, _dirs, files in os.walk(path):
|
|
152
|
+
for f in files:
|
|
153
|
+
if f.endswith(suffix) and keyword in f:
|
|
154
|
+
result.append(os.path.join(root, f))
|
|
155
|
+
return result
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def findFilesWithSuffix(path: str, suffix: str) -> List[str]:
|
|
159
|
+
result = []
|
|
160
|
+
for root, _dirs, files in os.walk(path):
|
|
161
|
+
for f in files:
|
|
162
|
+
if f.endswith(suffix):
|
|
163
|
+
result.append(os.path.join(root, f))
|
|
164
|
+
return result
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def get_file_index(prefix: str, suffix: str, filename: str) -> int:
|
|
168
|
+
pattern = re.compile(rf"{prefix}(\d+){suffix}")
|
|
169
|
+
res = pattern.findall(filename)
|
|
170
|
+
if len(res) != 1:
|
|
171
|
+
raise Exception("Cannot get file index!")
|
|
172
|
+
return int(res[0])
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def is_number(s: str) -> bool:
|
|
176
|
+
try:
|
|
177
|
+
float(s)
|
|
178
|
+
return True
|
|
179
|
+
except ValueError:
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def run_as_admin() -> bool:
|
|
184
|
+
try:
|
|
185
|
+
import ctypes
|
|
186
|
+
|
|
187
|
+
return ctypes.windll.shell32.IsUserAnAdmin()
|
|
188
|
+
except Exception:
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def removeAnyContainStr(string: str, subStringList: list, matchCase=True) -> List[str]:
|
|
193
|
+
if matchCase:
|
|
194
|
+
return [s for s in subStringList if string not in s]
|
|
195
|
+
return [s for s in subStringList if string.lower() not in s.lower()]
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def renameFile(old_path: str, new_path: str) -> None:
|
|
199
|
+
os.rename(old_path, new_path)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class ErrCode:
|
|
203
|
+
SUCCESS = 0
|
|
204
|
+
ERROR = -1
|
|
205
|
+
FILE_NOT_FOUND = -2
|
|
206
|
+
FILE_ILLEGAL = -3
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def fileExceptionNotFound(path: str) -> Exception:
|
|
210
|
+
return FileNotFoundError(f"File not found: {path}")
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def fileExceptionillegal(path: str) -> Exception:
|
|
214
|
+
return ValueError(f"Illegal file: {path}")
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def normalize_args(args: List[str]) -> List[str]:
|
|
218
|
+
if not args:
|
|
219
|
+
return []
|
|
220
|
+
first = args[0]
|
|
221
|
+
if first.endswith(".py") or first.endswith(".exe") or first in {"tao", "python", "python3"}:
|
|
222
|
+
return args[1:]
|
|
223
|
+
if os.path.basename(first) in {"tao", "tao.exe"}:
|
|
224
|
+
return args[1:]
|
|
225
|
+
return list(args)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def register_command(*names: str, registry: Optional[Dict[str, Callable]] = None) -> Callable:
|
|
229
|
+
def decorator(func: Callable) -> Callable:
|
|
230
|
+
if registry is not None:
|
|
231
|
+
for name in names:
|
|
232
|
+
registry[name] = func
|
|
233
|
+
return func
|
|
234
|
+
|
|
235
|
+
return decorator
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def inputSerial(start: int, end: int) -> int:
|
|
239
|
+
while True:
|
|
240
|
+
try:
|
|
241
|
+
idx = int(input(f"请输入序号 ({start}-{end}): "))
|
|
242
|
+
if start <= idx <= end:
|
|
243
|
+
return idx
|
|
244
|
+
loge(f"输入超出范围,请输入 {start}-{end} 之间的数字")
|
|
245
|
+
except ValueError:
|
|
246
|
+
loge("请输入有效的数字")
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def refreshWait(_keyword: str, timeout: int, interval: float, func: Callable, *args) -> bool:
|
|
250
|
+
start = time.time()
|
|
251
|
+
while time.time() - start < timeout:
|
|
252
|
+
if func(*args):
|
|
253
|
+
return True
|
|
254
|
+
sleep(interval)
|
|
255
|
+
return False
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def checkMsg(msg: str, *keywords: str) -> None:
|
|
259
|
+
if msg:
|
|
260
|
+
for kw in keywords:
|
|
261
|
+
if kw in msg.lower():
|
|
262
|
+
eExit(msg)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def parseArgs(argsList: List[str], prog: str, description: str = "") -> Any:
|
|
266
|
+
import argparse
|
|
267
|
+
|
|
268
|
+
parser = argparse.ArgumentParser(prog=prog, description=description)
|
|
269
|
+
return parser.parse_args(argsList)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def parseDeviceInfo(info: str) -> Dict[str, str]:
|
|
273
|
+
result = {}
|
|
274
|
+
lines = info.strip().split("\n")
|
|
275
|
+
for line in lines:
|
|
276
|
+
if "device" in line:
|
|
277
|
+
parts = line.split()
|
|
278
|
+
if len(parts) >= 2:
|
|
279
|
+
result["serial"] = parts[0]
|
|
280
|
+
result["model"] = parts[1]
|
|
281
|
+
return result
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def pCmd(
|
|
285
|
+
cmd: str,
|
|
286
|
+
sleep_s=1.0,
|
|
287
|
+
showCmd=False,
|
|
288
|
+
shell=False,
|
|
289
|
+
splitCmd=True,
|
|
290
|
+
encoding="utf-8",
|
|
291
|
+
waitDone=True,
|
|
292
|
+
timeOut=3,
|
|
293
|
+
showRet=False,
|
|
294
|
+
checkErr=False,
|
|
295
|
+
ignoreTimeOut=False,
|
|
296
|
+
logLevel="debug",
|
|
297
|
+
):
|
|
298
|
+
if showCmd:
|
|
299
|
+
if logLevel == "warn":
|
|
300
|
+
logCallWarn(cmd)
|
|
301
|
+
elif logLevel == "error":
|
|
302
|
+
logCallErr(cmd)
|
|
303
|
+
elif logLevel == "info":
|
|
304
|
+
logCallInfo(cmd)
|
|
305
|
+
else:
|
|
306
|
+
logCallDebug(cmd)
|
|
307
|
+
try:
|
|
308
|
+
if splitCmd:
|
|
309
|
+
proc = subprocess.Popen(
|
|
310
|
+
cmd.split(" "),
|
|
311
|
+
stdin=subprocess.PIPE,
|
|
312
|
+
stdout=subprocess.PIPE,
|
|
313
|
+
stderr=subprocess.PIPE,
|
|
314
|
+
encoding=encoding,
|
|
315
|
+
shell=shell,
|
|
316
|
+
# env=os.environ.copy(),
|
|
317
|
+
)
|
|
318
|
+
else:
|
|
319
|
+
proc = subprocess.Popen(
|
|
320
|
+
cmd,
|
|
321
|
+
stdin=subprocess.PIPE,
|
|
322
|
+
stdout=subprocess.PIPE,
|
|
323
|
+
stderr=subprocess.PIPE,
|
|
324
|
+
encoding=encoding,
|
|
325
|
+
shell=shell,
|
|
326
|
+
# env=os.environ.copy(),
|
|
327
|
+
)
|
|
328
|
+
except subprocess.TimeoutExpired:
|
|
329
|
+
return "", f"Command '{cmd}' timed out after {timeOut} seconds"
|
|
330
|
+
except subprocess.CalledProcessError as e:
|
|
331
|
+
return "", f"Command '{cmd}' failed with error: {e.stderr}"
|
|
332
|
+
out = ""
|
|
333
|
+
error = ""
|
|
334
|
+
if waitDone:
|
|
335
|
+
try:
|
|
336
|
+
out, error = proc.communicate(timeout=timeOut)
|
|
337
|
+
except subprocess.TimeoutExpired:
|
|
338
|
+
logCallErr(f"{cmd} timeout", "error")
|
|
339
|
+
if not ignoreTimeOut:
|
|
340
|
+
exit()
|
|
341
|
+
else:
|
|
342
|
+
return "None", "None"
|
|
343
|
+
|
|
344
|
+
sleep(sleep_s)
|
|
345
|
+
if checkErr:
|
|
346
|
+
checkMsg(error, "error")
|
|
347
|
+
checkMsg(out, "failed")
|
|
348
|
+
checkMsg(out, "error")
|
|
349
|
+
if showRet:
|
|
350
|
+
if out != "":
|
|
351
|
+
logCallInfo(re.sub(r"\n$", "", out))
|
|
352
|
+
if error != "" and ("error" in error or "failed" in error):
|
|
353
|
+
logCallErr(error)
|
|
354
|
+
elif error != "":
|
|
355
|
+
logCallInfo(error)
|
|
356
|
+
return out, error
|
|
357
|
+
else:
|
|
358
|
+
return "None", "None"
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def rCmd(
|
|
362
|
+
cmd: str,
|
|
363
|
+
sleep_s=1.0,
|
|
364
|
+
showCmd=False,
|
|
365
|
+
shell=False,
|
|
366
|
+
splitCmd=True,
|
|
367
|
+
encoding="utf-8",
|
|
368
|
+
timeOut=3,
|
|
369
|
+
showRet=False,
|
|
370
|
+
checkErr=False,
|
|
371
|
+
logLevel="debug",
|
|
372
|
+
):
|
|
373
|
+
if showCmd:
|
|
374
|
+
if logLevel == "warn":
|
|
375
|
+
logCallWarn(cmd,callStack=3)
|
|
376
|
+
elif logLevel == "error":
|
|
377
|
+
logCallErr(cmd,callStack=3)
|
|
378
|
+
elif logLevel == "info":
|
|
379
|
+
logCallInfo(cmd,callStack=3)
|
|
380
|
+
else:
|
|
381
|
+
logCallDebug(cmd,callStack=3)
|
|
382
|
+
try:
|
|
383
|
+
if splitCmd:
|
|
384
|
+
result = subprocess.run(
|
|
385
|
+
cmd.split(" "),
|
|
386
|
+
capture_output=True,
|
|
387
|
+
text=True,
|
|
388
|
+
encoding=encoding,
|
|
389
|
+
shell=shell,
|
|
390
|
+
check=True,
|
|
391
|
+
timeout=timeOut,
|
|
392
|
+
)
|
|
393
|
+
else:
|
|
394
|
+
result = subprocess.run(
|
|
395
|
+
cmd,
|
|
396
|
+
capture_output=True,
|
|
397
|
+
text=True,
|
|
398
|
+
encoding=encoding,
|
|
399
|
+
shell=shell,
|
|
400
|
+
check=True,
|
|
401
|
+
timeout=timeOut,
|
|
402
|
+
)
|
|
403
|
+
except subprocess.TimeoutExpired:
|
|
404
|
+
return "", f"Command '{cmd}' timed out after {timeOut} seconds"
|
|
405
|
+
except subprocess.CalledProcessError as e:
|
|
406
|
+
return "", f"Command '{cmd}' failed with error: {e.stderr}"
|
|
407
|
+
|
|
408
|
+
sleep(sleep_s)
|
|
409
|
+
if checkErr:
|
|
410
|
+
checkMsg(result.stderr, "error")
|
|
411
|
+
checkMsg(result.stderr, "failed")
|
|
412
|
+
checkMsg(result.stdout, "error")
|
|
413
|
+
if showRet:
|
|
414
|
+
if len(result.stdout) != 0:
|
|
415
|
+
logCallInfo(result.stdout.strip())
|
|
416
|
+
if len(result.stderr) != 0:
|
|
417
|
+
if "error" in result.stderr or "failed" in result.stderr:
|
|
418
|
+
logCallErr(result.stderr.strip())
|
|
419
|
+
else:
|
|
420
|
+
logCallInfo(result.stderr.strip())
|
|
421
|
+
return result.stdout, result.stderr
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def oCmd(cmd: str, sleep_s=1.0, showCmd=False, logLevel="debug"):
|
|
425
|
+
if showCmd:
|
|
426
|
+
if logLevel == "warn":
|
|
427
|
+
logCallWarn(cmd, callStack=3)
|
|
428
|
+
elif logLevel == "error":
|
|
429
|
+
logCallErr(cmd, callStack=3)
|
|
430
|
+
elif logLevel == "info":
|
|
431
|
+
logCallInfo(cmd, callStack=3)
|
|
432
|
+
else:
|
|
433
|
+
logCallDebug(cmd, callStack=3)
|
|
434
|
+
os.system(cmd)
|
|
435
|
+
sleep(sleep_s)
|