当前位置: 首页 > 面试题库 >

PXA270上的RS232通信中的高延迟

姜育
2023-03-14
问题内容

我在PXA270 RISC PC / 104上的RS232通信中遇到了很长的延迟(1.5ms-9.5ms)。我想尽量减少长时间的延迟,但是我是嵌入式设备和C
++的初学者,所以我认为我缺少一些东西。

提到的延迟是在PXA板通过RS232(115200波特)从外部设备接收到数据包之前,直到它向外部设备发送ACK自定义数据包为止。我用示波器在PXA板上测量了延迟,一个通道在Rx上,另一个在Tx上。

PXA板正在运行Arcom嵌入式Linux(AEL)。我知道,这不是一个实时操作系统,但我仍然认为,这4.5ms的平均延迟方式
太高
用于提取接收的数据包,验证它的CRC16,构建一个ACK包(带CRC)并将其发回的串行线。我还故意将CPU置于沉重的负载下(某些并行的gzip操作),但延迟时间根本没有增加。接收到的数据包的最大大小为30个字节。

一个C ++应用程序(另一个前同事写的)正在处理数据包的接收及其确认。一个线程正在发送,另一个线程正在接收数据包。

我以为PXA板上的RTC分辨率很差,AEL无法将时序与内部RTC分辨率对齐。但是RTC的频率为32.768
kHz。分辨率足够,仍然不解释高延迟。顺便说一句,我认为操作系统正在使用内部PXA时钟(也具有足够的分辨率)而不是RTC进行计时。

因此,问题必须出在C ++应用程序中或RS232接口的驱动程序/操作系统设置中。

根据POSIX操作系统串行编程指南,以下控制标志用于C
++应用程序中的RS232通信:

// Open RS232 on COM1
mPhysicalComPort = open(aPort, O_RDWR | O_NOCTTY | O_NDELAY);
// Force read call to block if no data available
int f = fcntl(mPhysicalComPort, F_GETFL, 0);
f &= ~O_NONBLOCK;
fcntl(mPhysicalComPort, F_SETFL, f);
// Get the current options for the port...
tcgetattr(mPhysicalComPort, &options);
// ... and set them to the desired values
cfsetispeed(&options, baudRate);
cfsetospeed(&options, baudRate);
// no parity (8N1)
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// disable hardware flow control
options.c_cflag &= ~CRTSCTS;
// raw input
options.c_lflag = 0;
// disable software flow control
options.c_iflag = 0;
// raw output
options.c_oflag = 0;
// Set byte times
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 0;
// Set the new options for the port
tcsetattr(mPhysicalComPort, TCSAFLUSH, &options);
// Flush to put settings to work
tcflush(mPhysicalComPort, TCIOFLUSH);

我想我缺少了一些简单的东西。我认为,如果应用程序的进程以更高的优先级运行,则无法解决问题。必须有一些东西指示RS232驱动程序以更高的优先级处理请求,以最大程度地减少延迟。

有人有什么想法吗?预先非常感谢您的帮助。


问题答案:

非常感谢您的评论。

我能够将延迟减少到〜0.4ms。AEL手册中引用了命令setserial(8)。宾果游戏,我在low_latency那里找到带有以下描述的标志:

以提高CPU利用率为代价,最大程度地减少串行设备的接收延迟。(通常,在将字符移交给行障碍之前,平均等待时间为5-10毫秒,以最大程度地减少开销。)默认情况下,此功能处于关闭状态,但是某些实时应用程序可能会发现此功能有用。

然后我执行setserial /dev/ttyS1 low_latency了,延迟减少到了〜0.4ms :-)

但是我想在C ++应用程序中实现此行为,而不用setserial全局设置此标志(默认情况下,并非所有发行版中都包含此命令)。

添加了以下代码行,其效果与setserial中的low_latency标志相同:

#include <sys/ioctl.h> 
#include <linux/serial.h>
// Open RS232 on COM1
mPhysicalComPort = open(aPort, O_RDWR | O_NOCTTY | O_NDELAY);
struct serial_struct serial;
ioctl(mPhysicalComPort, TIOCGSERIAL, &serial); 
serial.flags |= ASYNC_LOW_LATENCY; // (0x2000)
ioctl(mPhysicalComPort, TIOCSSERIAL, &serial);


 类似资料:
  • 问题内容: 我正在Linux上的串行端口上实现协议。该协议基于请求应答方案,因此吞吐量受将数据包发送到设备并获得应答所花费的时间限制。这些设备主要基于Arm,并且运行Linux> = 3.0。我无法将往返时间缩短到10ms以下(115200波特,8个数据位,无奇偶校验,每条消息7个字节)。 哪些IO接口将为我带来最低的延迟:选择,轮询,epoll或使用ioctl手动轮询?阻塞或非阻塞IO是否会影响

  • 我在一个公认的缓慢配置中设置了Kafka——但我不期待我看到的数字。 我将集群设置为<code>LogAppendTime</code>,因此我正在测量事件写入Kafka(由代理决定)与服务接收到事件之间的时间。代理和应用程序都位于“同一位置”,因此服务器之间的ping时间很短,时钟应该同步或接近。 我看到延迟在 到 600ms 之间,很多是 ......巨大的差异让我觉得我的设置出了问题。它因消

  • 我在一个由三台机器组成的集群上使用cassandra 2.1.12,每台机器都有32 GB的RAM和4个内核(在Amazon AWS上) 我使用的是cassandra的所有默认配置。 我用它来进行我的网站事件分析(时间序列数据),每天的数据约为1 GB,复制因子为3。 我的数据在每台机器上已经增长到85 GB左右,现在它的读取延迟约为 我的行很少更新,所以,我没有使用Levelorder Comp

  • 大家好,已经有人问过类似的问题,但我想我们有点不同的问题: 我们使用Cassandra 2.2.6一个节点安装(并将升级到最新的)。现在我们有可怕的查询时间,有时会写超时。 为了进行比较,有一个不同的表包含大约10万条记录,其构造与上述非常相似 区别在于第一个包含大量地图和UDT。在dev center中进行简单测试选择*from。。。限制999;(省略任何Lucene索引等)最后一个显示183m

  • 我不熟悉ApacheStorm和kafka,作为POC的一部分,我正在尝试使用kafka和ApacheStorm处理消息流。我使用的是暴风Kafka的来源https://github.com/apache/storm/tree/master/external/storm-kafka,我能够创建一个示例程序,该程序使用KafkaSpout读取来自kafka主题的消息,并将其输出到另一个kafka主题

  • 我已经建立了一个具有3个节点的Cassandra。在客户端,我使用的是Datasatx java驱动程序,我的查询如下 正如我们在上面的查询中看到的,我希望最大的“cluster_column”小于10。我有宽行。所以当数据在行间增长时,读取延迟会增加。 我只使用密钥缓存和级别压缩策略。MemTable大小保持为2048 MB。 我可以调整什么参数来降低服务器级别的读取延迟。 请回复 提前感谢