pySerial 问题:嵌入式控制器停止回显命令
pySerial problem: embedded controller stops echoing commands
我正在尝试在 Ubuntu 主机上使用 pySerial 运行 来自动测试嵌入式控制器。我可以在终端 window(例如 PuTTY)中输入命令并全天从 EC 获得响应。然而,当我尝试使用 pySerial 程序做同样的事情时,EC 在一段时间后停止回显命令,就在回显命令的中间。从那时起,EC 将停止响应该程序,包括不发送中断命令的结果。
如果我终止程序并尝试再次使用终端连接到 EC,EC 没有响应。如果发生导致 EC 将输出写入终端的外部事件,则该信息会正确显示。问题一直存在,直到我重新启动 EC - 这也会删除问题发生时 EC 上发生的所有日志。 (日志只能通过串口访问...)
似乎 pySerial 正在做的事情导致 EC 的输入处理停止。我试着输入 Ctrl-Q (XON),希望有一些不明显的软件流控制在进行,但这并没有什么不同。我已经尝试在程序中发送交替命令,在发送命令之间发送空行,在发送命令之间插入延迟 - 但每次在处理一些命令后它都会死掉。
这是我目前使用的脚本:
import serial
from datetime import datetime
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
print('Starting up')
# send an empty command to ensure a prompt is displayed
ser.write(b'\r\n')
commandToSend = 'battery current'
failed = 0
running = True
while running:
while running:
# read from the EC until a timeout occurs with no data available
try:
# wait for the EC prompt
rcvData = ser.read_until(b' ec> ')
now = datetime.now().time()
print('{}\tRead from device: "{}"'.format(now, rcvData))
decoded = rcvData.decode('ascii')
if len(decoded) == 0:
# timeout, nothing read from EC, send next command
failed += 1
break
# normalize line terminations then split the data into lines
lines = decoded.replace('\r\r\n','\r\n').split('\r\n')
for line in lines:
print('{}{}'.format(' '*34, line))
break
except KeyboardInterrupt:
print('\nKeyboard interrupt, aborting')
running = False
break
except Exception as e:
print(e) # this branch never executes, from my observation
pass
now = datetime.now().time()
if failed > 1:
print('{}\tCommunication with the EC has failed'.format(now))
break
if running:
# send the command when there's no data to read
print('{}\tWriting: "{}\r\n"'.format(now, commandToSend))
ser.write('{}\r\n'.format(commandToSend).encode())
ser.flush()
上述脚本 运行 的典型结果是这样的:
$ ./ec-uart-test.py
Starting up
20:19:10.620998 Read from device: "b'\r\n ec> '"
ec>
20:19:11.622234 Read from device: "b''"
20:19:11.622345 Writing: "battery current\r\n"
20:19:11.627921 Read from device: "b'\r\n ec> '"
ec>
20:19:11.628690 Read from device: "b'battery current\r\n0ma\r\r\n ec> '"
battery current
0ma
ec>
20:19:11.628777 Writing: "battery current\r\n"
20:19:11.635899 Read from device: "b'\r\n ec> '"
ec>
20:19:12.637335 Read from device: "b'battery cu'"
battery cu
20:19:12.637439 Writing: "battery current\r\n"
20:19:13.644800 Read from device: "b''"
20:19:14.646080 Read from device: "b''"
20:19:14.646172 Communication with the EC has failed
除了破解 EC 并在其上安装硬件分析器之外,还有什么我应该尝试让此代码正常工作的方法吗?
看来测试过程实际上是错误的:按照我同事的一个例子,我在终端中输入“电池电流”命令,得到响应,然后使用向上箭头键重新运行 命令 - 似乎整天都在工作。
但是,这不是同一个测试:向上箭头(从 EC 的历史记录中检索最后一个命令)后跟 not 与重复键入命令并发送相同它。
当我尽可能快地将命令重复粘贴到终端 window 时,EC 失败的方式与使用 pySerial 发送命令的方式完全相同:失败是 EC 内部的,而不是什么不同的 pySerial 在通信线路上进行。
我正在尝试在 Ubuntu 主机上使用 pySerial 运行 来自动测试嵌入式控制器。我可以在终端 window(例如 PuTTY)中输入命令并全天从 EC 获得响应。然而,当我尝试使用 pySerial 程序做同样的事情时,EC 在一段时间后停止回显命令,就在回显命令的中间。从那时起,EC 将停止响应该程序,包括不发送中断命令的结果。
如果我终止程序并尝试再次使用终端连接到 EC,EC 没有响应。如果发生导致 EC 将输出写入终端的外部事件,则该信息会正确显示。问题一直存在,直到我重新启动 EC - 这也会删除问题发生时 EC 上发生的所有日志。 (日志只能通过串口访问...)
似乎 pySerial 正在做的事情导致 EC 的输入处理停止。我试着输入 Ctrl-Q (XON),希望有一些不明显的软件流控制在进行,但这并没有什么不同。我已经尝试在程序中发送交替命令,在发送命令之间发送空行,在发送命令之间插入延迟 - 但每次在处理一些命令后它都会死掉。
这是我目前使用的脚本:
import serial
from datetime import datetime
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
print('Starting up')
# send an empty command to ensure a prompt is displayed
ser.write(b'\r\n')
commandToSend = 'battery current'
failed = 0
running = True
while running:
while running:
# read from the EC until a timeout occurs with no data available
try:
# wait for the EC prompt
rcvData = ser.read_until(b' ec> ')
now = datetime.now().time()
print('{}\tRead from device: "{}"'.format(now, rcvData))
decoded = rcvData.decode('ascii')
if len(decoded) == 0:
# timeout, nothing read from EC, send next command
failed += 1
break
# normalize line terminations then split the data into lines
lines = decoded.replace('\r\r\n','\r\n').split('\r\n')
for line in lines:
print('{}{}'.format(' '*34, line))
break
except KeyboardInterrupt:
print('\nKeyboard interrupt, aborting')
running = False
break
except Exception as e:
print(e) # this branch never executes, from my observation
pass
now = datetime.now().time()
if failed > 1:
print('{}\tCommunication with the EC has failed'.format(now))
break
if running:
# send the command when there's no data to read
print('{}\tWriting: "{}\r\n"'.format(now, commandToSend))
ser.write('{}\r\n'.format(commandToSend).encode())
ser.flush()
上述脚本 运行 的典型结果是这样的:
$ ./ec-uart-test.py
Starting up
20:19:10.620998 Read from device: "b'\r\n ec> '"
ec>
20:19:11.622234 Read from device: "b''"
20:19:11.622345 Writing: "battery current\r\n"
20:19:11.627921 Read from device: "b'\r\n ec> '"
ec>
20:19:11.628690 Read from device: "b'battery current\r\n0ma\r\r\n ec> '"
battery current
0ma
ec>
20:19:11.628777 Writing: "battery current\r\n"
20:19:11.635899 Read from device: "b'\r\n ec> '"
ec>
20:19:12.637335 Read from device: "b'battery cu'"
battery cu
20:19:12.637439 Writing: "battery current\r\n"
20:19:13.644800 Read from device: "b''"
20:19:14.646080 Read from device: "b''"
20:19:14.646172 Communication with the EC has failed
除了破解 EC 并在其上安装硬件分析器之外,还有什么我应该尝试让此代码正常工作的方法吗?
看来测试过程实际上是错误的:按照我同事的一个例子,我在终端中输入“电池电流”命令,得到响应,然后使用向上箭头键重新运行 命令 - 似乎整天都在工作。
但是,这不是同一个测试:向上箭头(从 EC 的历史记录中检索最后一个命令)后跟 not 与重复键入命令并发送相同它。
当我尽可能快地将命令重复粘贴到终端 window 时,EC 失败的方式与使用 pySerial 发送命令的方式完全相同:失败是 EC 内部的,而不是什么不同的 pySerial 在通信线路上进行。