Python对tty的读写

2024-04-29 08:55:08 发布

您现在位置:Python中文网/ 问答频道 /正文

背景:如果需要,请跳到问题部分

我正在做一个测试设备的前端。前端的目的是使编写长测试脚本更加容易。基本上只是让它们更具可读性和可写性。

设备将使用Prologix GPIB-USB控制器进行测试(请参阅Prologix.biz)。我们在http://heliosoph.mit-links.info/gpib-on-debian-linux-the-easy-way/找到了一个教程,完成了所有的步骤,并且成功了!

由于我们还没有测试设备,我们想用openpty用Python编写一个模拟器。我们有GPIB-USB控制器,只是没有连接到它的东西。我让模拟器作为GPIB-USB的完美替代品。这意味着我将遵循“Debian上的GPIB…”教程(上面)并获得我编程的模拟器返回的输出。输入和输出的方式与教程中的相同,只是读写pty设备(ie/dev/pts/2)而不是tty(ie/dev/ttyUSB0)。

现在仿真器工作了,我们想编写一个可以用来轻松编写脚本的前端。我们的目标是建立一种宏系统,当我们调用一个函数时,它会编写一堆命令。

问题:同时使用模拟器和设备时存在

我使用下面的Python函数来读、写和打开tty/pty设备,但是如果在bash中使用echo和cat,我得到的结果就不同了。

tty = os.open(tty_path, os.O_RDWR)
os.read(tty, 100)
os.write(tty, "++ver")

例如,我希望以下内容是等效的

$ cat < /dev/pty/2 &   # According to the tutorial, this must be run in parallel
$ echo "++ver" > /dev/pty/2
Prologix GPIB Version 1.2.3.4 ...

以及

tty = os.open("/dev/pyt/2", os.o_RDWR)
os.read(tty, 100) # In separate Thread to be run in parallel
os.write(tty, "++ver") # in main thread

输出是非常不同的,请解释为什么和如何修复它。

完整的代码在这里:http://pastebin.com/PWVsMjD7


Tags: theindev脚本httpos教程控制器
2条回答

实际上,您不必使用任何特殊模块来读取TTY。
选项O\u NOCTTY解决了我在使用CDCACM示例MCU应用程序时遇到的问题。
我相信它会为你工作(因为你也在Linux上工作)。

#!/usr/bin/env python3

import io, os

tty = io.TextIOWrapper(
        io.FileIO(
            os.open(
                "/dev/ttyACM1",
                os.O_NOCTTY | os.O_RDWR),
            "r+"))

for line in iter(tty.readline, None):
    print(line.strip())

我问得太早了。我希望有人能从这个自我回答中受益。

因此,这可以从模拟器和实际设备进行读写。我不太清楚原因,希望你能解释一下,但这在我所有的测试中都有效

import serial

class VISA:
    def __init__(self, tty_name):
        self.ser = serial.Serial()
        self.ser.port = tty_name
        # If it breaks try the below
        #self.serConf() # Uncomment lines here till it works

        self.ser.open()
        self.ser.flushInput()
        self.ser.flushOutput()

        self.addr = None
        self.setAddress(0)

    def cmd(self, cmd_str):
        self.ser.write(cmd_str + "\n")
        sleep(0.5)
        return self.ser.readline()

    def serConf(self):
        self.ser.baudrate = 9600
        self.ser.bytesize = serial.EIGHTBITS
        self.ser.parity = serial.PARITY_NONE
        self.ser.stopbits = serial.STOPBITS_ONE
        self.ser.timeout = 0 # Non-Block reading
        self.ser.xonxoff = False # Disable Software Flow Control
        self.ser.rtscts = False # Disable (RTS/CTS) flow Control
        self.ser.dsrdtr = False # Disable (DSR/DTR) flow Control
        self.ser.writeTimeout = 2

    def close(self):
        self.ser.close()

相关问题 更多 >