将串行消息发送到设备,直到它联机

时间:2017-12-04 23:12:19

标签: linux python-3.x serial-port pyserial

我正在尝试通过串行接口更新控制器的固件。要做到这一点,我必须向控制器发送一个重启消息(没有问题),然后发送另一条消息(字符'w')它启动的MOMENT,以便它可以在写模式下启动。使用minicom实用程序可以通过在设备重新启动时连续按w来轻松完成。

我希望使用python代码来实现此功能,但我无法弄清楚如何在设备启动之前发送消息而不会抛出异常(因为设备未连接)。

这是我尝试过的,但它不起作用(使用pyserial):

def send_w(serial_port, baud_rate):
    msgw = "w_"
    ans = ""
    ser = serial.Serial(port=serial_port, baudrate=baud_rate,timeout = 10)
    ser.write(msgw)
    ans = ser.read(24)
    ser.close()
    print(ans)
    return ans

def set_firmware_version(serial_port, baud_rate):
    s = ""
    try:
        with serial.Serial(serial_port,baud_rate,timeout=1) as ser:
            msgr = "%reset "+sk+"_"
            ser.write(msgr)
            ser.close()
            print("reset")
    except (IOError) as e:
        print("Error in: set_firmware_version")
        print(e)
        return s
    time.sleep(1)
    send_w(serial_port, baud_rate)

set_firmware_version(sp,br)

这会出现以下错误:

serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

我也尝试在短暂超时的循环中发送消息,但是遇到了同样的问题。有没有办法连续发送消息,如果找不到设备则忽略异常?

非常感谢任何帮助。

完整追溯:

Traceback (most recent call last):
  File "mc_config.py", line 69, in <module>
    set_firmware_version(sp,br)
  File "mc_config.py", line 64, in set_firmware_version
    send_w(serial_port, baud_rate)
  File "mc_config.py", line 46, in send_w
    ans = ser.read(24)
  File "/home/avidbots/.local/lib/python2.7/site-packages/serial/serialposix.py", line 501, in read
    'device reports readiness to read but returned no data '
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

(我使用的是ubuntu 16.04和python 3)

1 个答案:

答案 0 :(得分:1)

如果将异常代码放入try然后使用except serial.serialutil.SerialException {...}块捕获异常,该怎么办?

显然,有一个重要的时间窗口提交w(否则“按w”方法通常不会起作用。)那么,您的要求是仅重试绝对代码的一部分发送w所必需的,以便您足够快地发送它以“捕获”系统处于启动状态。由于回溯显示send_w中出现异常,因此您可以在try末尾添加except / while块和set_firmware_version循环。 {1}}。

而不仅仅是这个:

send_w(serial_port, baud_rate)

这样的事情可能会解决问题:

while True:
  try:
    send_w(serial_port, baud_rate)
    break
  except serial.serialutil.SerialException:
    pass # retry

您可能需要更改导入以公开该异常,fyi。您可能需要考虑是否捕获了太多可能的异常 - 异常也可能代表其他不应重试的错误。您可能还需要在那里添加一个小的休眠时间 - 这实际上是一个繁忙的等待循环(https://en.wikipedia.org/wiki/Busy_waiting)。