有没有办法用Twisted Python连接到RFC2217网络串口?
Pyserial似乎通过serial.serial_for_url("rfc2217://...")
function支持它。并且它们表明twisted使用pyserial来管理串行连接,但是twisted.internet.serialport.SerialPort
似乎期望一个端口名称或数字,这表明它只是将它传递给serial.Serial
构造函数。
我可以使用socat在外部创建一个PTY并将dev名称传递给twisted,这样可以正常工作,但我想知道我是否可以通过直接使用pyserial支持来绕过这一步。
socat PTY,link=/dev/myport TCP:192.168.1.222:9001
编辑:pyserial faq建议对实例化串行对象进行此修改:
try:
s = serial.serial_for_url(...)
except AttributeError:
s = serial.Serial(...)
不确定这是否有帮助......
答案 0 :(得分:2)
我得出的结论是,使用Pyserial的RFC2217支持Twisted Python并非易事。除了being currently experimental之外,Pyserial的RFC2217实现使用线程来管理套接字连接,他们声称这是基于选择的应用程序的问题:
当前实现启动一个不断读取(内部)套接字的线程。该线程由open()/ close()上的rfc2217.Serial端口对象自动管理。但是,对于喜欢使用select而不是线程的用户应用程序来说,这可能是一个问题。
将t.i.serialport.SerialPort子类化并覆盖_serialFactory方法(创建用于访问串口的pyserial对象)非常简单。
class SerialPort(serialport.SerialPort):
def _serialFactory(self, dev, *args, **kwargs):
" pyserial recommends the following for supporting serial urls "
try:
return serial.serial_for_url(dev)
except AttributeError:
return serial.Serial(dev, *args, **kwargs)
但是,生成的对象缺少文件描述符,因此fileno()
方法(由t.i._posixserialport
内部使用)会引发异常。
--- <exception caught here> ---
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py", line 1204, in mainLoop
self.doIteration(t)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 105, in doSelect
[], timeout)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/_posixserialport.py", line 48, in fileno
return self._serial.fd
exceptions.AttributeError: 'Serial' object has no attribute 'fd'
当前的解决方法是使用问题中描述的socat
,或者对于我正在使用的网络串行服务器(Brainboxes ES-842),您可以在“原始TCP”模式下配置它而不是“ Telnet / RFC2217“模式,只需通过TCP连接使用现有协议(只要您不依赖于流量控制或其他串行控制线,并且可以使用预定义的固定波特率)。