有时我只需要从串行设备读取数据,因此我跳过了minicom
orscreen
和 just的复杂性cat
。但是,只有当我stty <baud>
在尝试打开文件之前首先设置终端的波特率时,这才有效。
该数据可能已经(或可以)在内核中缓冲,在这种情况下,是使用UART 转 USB 桥接器。对于给定标准,USB 传输速率是固定的,因此设置波特率只能影响数据的解释。鉴于我对 USB 数据包中的数据可能是什么样子缺乏了解,我不确定如何以某种固定的读取速率(波特率)可视化 USB 数据包数据的“解释”。
$ stty 115200
$ cat /dev/ttyACM0
这里究竟发生了什么?我理解这个设置在硬件中的含义,但是它在用户空间软件?
答案1
看起来你可能对这一切是如何运作的有点困惑。
首先,/dev/ttyACM0
它不代表 USB 链路,甚至不代表您所连接的任何串行适配器的 USB 端点,它代表适配器内部处理串行通信的 UART。您从中读取的数据将不包括任何 USB 标头或帧,就像您从中读取的数据/dev/ttyS0
将不包括任何 PCI Express 标头或帧一样。设置这些波特率会影响它所代表的硬件,而不是它所连接的总线,因此这不会对 USB 连接产生任何影响。
其次,波特率是一种硬件设置,而不是软件设置。当您调用stty
在串行端口上设置它时,即告诉内核告诉硬件更改它尝试接收数据的波特率。这尤其意味着在此更改之前接收到的任何数据要么是伪造的(因为硬件未正确解释它,有时如果波特率彼此接近或精确谐波,就会出现这种情况),要么完全丢失(因为硬件不接受它,在现代硬件上更可能出现这种情况)。
如果您计划从串行线路读取数据,则需要在另一端传输任何数据之前正确设置波特率。这也意味着改变波特率不会改变内核解释数据的方式。如果数据已经在内核中缓冲,那么它不会仅仅因为您更改波特率而改变(尽管在更改波特率后排出内核缓冲区是一个很好的做法,以便您知道任何未来的数据都是好的)。
因此,澄清一下,在不使用特殊软件的情况下从 USB 转串行适配器获取数据的正确方法是:
- 设置系统启动时的波特率。对于 USB 转串口适配器,这可能应该是一个 udev 规则,以便在设备插入时它也会被设置。
- 使用
cat
(或者od
如果您需要字节值而不是文本)来读取数据。这将返回 USB 到串行适配器接收到的确切数据(假设适配器不进行特殊处理)。