本文介绍了PXA270上的RS232通讯延时高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



所提到的延迟是在PXA板通过RS232(115200波特)从外部设备接收数据包,直到发送ACK定制数据包回到外部设备。
我使用示波器测量PXA板上的延迟,Rx上的一个通道,Tx上的另一个通道。



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



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



我以为PXA板上的RTC具有非常差的分辨率,AEL不能将时序对准内部RTC分辨率。但RTC的频率为32.768 kHz。分辨率是足够的,仍然不能解释高延迟。 Btw,我认为操作系统正在使用内部PXA时钟(它也有足够的分辨率),而不是RTC的时序。



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



以下控制标志用于C ++应用程序中的RS232通信,根据:



在$ COM $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
//如果没有数据可用,强制读取调用块
int f = fcntl(mPhysicalComPort,F_GETFL,0);
f& =〜O_NONBLOCK;
fcntl(mPhysicalComPort,F_SETFL,f);
//获取端口的当前选项...
tcgetattr(mPhysicalComPort,& options);
// ...并将它们设置为所需的值
cfsetispeed(& options,baudRate);
cfsetospeed(& options,baudRate);
//无奇偶校验(8N1)
options.c_cflag& =〜PARENB;
options.c_cflag& =〜CSTOPB;
options.c_cflag& =〜CSIZE;
options.c_cflag | = CS8;
//禁用硬件流控制
options.c_cflag& =〜CRTSCTS;
// raw input
options.c_lflag = 0;
//禁用软件流控制
options.c_iflag = 0;
// raw output
options.c_oflag = 0;
//设置字节时间
options.c_cc [VMIN] = 1;
options.c_cc [VTIME] = 0;
//设置端口的新选项
tcsetattr(mPhysicalComPort,TCSAFLUSH,& options);
//刷新设置工作
tcflush(mPhysicalComPort,TCIOFLUSH);

我想我错过了一些非常简单的东西。我认为,如果应用程序的进程运行在更高的优先级,这将不能解决问题。必须有一些东西,指示RS232驱动程序以更高的优先级处理请求以最小化延迟。



有没有人有任何想法?非常感谢您的帮助。

解决方案

非常感谢您的意见。



我能够将延迟减少到〜0.4ms。在AEL手册中引用了命令。和宾果,我发现 low_latency 标记在那里,具有以下描述:

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



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



我添加了以下代码行,其效果与来自setserial的low_latency标志:

  #include< sys / ioctl.h> 
#include< linux / serial.h>
//在COM1上打开RS232
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);


I'm experiencing a long delay (1.5ms - 9.5ms) in a RS232 communication on a PXA270 RISC PC/104. I want to minimize the long delay but I'm a beginner with embedded devices and C++ so I think I'm missing something.

The mentioned delay is at the time when the PXA board receives a packet from the external device via RS232 (115200 baud) until it sends an ACK custom packet back to the external device.I measured the delay on the PXA board with an oscilloscope, one channel at the Rx and the other on the Tx.

The PXA board is running an Arcom Embedded Linux (AEL). I know, it's not a real-time OS, but I still think, that an average delay of 4.5ms is way too high for extracting the received packet, verify it's CRC16, construct an ACK packet (with CRC) and send it back the serial line.I also deliberately put the CPU under heavy load (some parallel gzip operations) but the delay time didn't increase at all.The maximum size of a received packet is 30 bytes.

A C++ application (another former co-worker wrote it) is handling the reception of the packets and their acknowledgement.One thread is sending and the other is receiving the packets.

I thought that the RTC on the PXA board has a very bad resolution and the AEL can not align the timing to the internal RTC resolution. But the RTC has a frequency of 32.768 kHz. The resolution is sufficient, still don't explain the high delay. Btw, I think the OS is using the internal PXA clock (which has also a sufficient resolution) instead of the RTC for the timing.

Therefore the problem must be in the C++ app or in a driver/OS setting of the RS232 interface.

The following control flags are used for the RS232 communication in the C++ application according to the Serial Programming Guide for POSIX Operating Systems:

// 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);

I think I'm missing something very simple. I think, that if the process of the app is running under a higher priority, this will not solve the problem. There must be something, which instructs the RS232 driver to handle the requests with a higher priority to minimize the latency.

Does anyone have any ideas? Thank you very much in advance for your help.

解决方案

Thank you very much for your comments.

I was able to reduce the delay to ~0.4ms. The command setserial(8) was referenced in the AEL manual. And bingo, I found the low_latency flag there with the following description:

I then executed setserial /dev/ttyS1 low_latency and the delay was reduced to ~0.4ms :-)

But I wanted to implement this behaviour in the C++ app, without setting this flag globally with setserial (this command is by default not included in all distros).

I've added the following code lines, which had the same effect as the low_latency flag from setserial:

#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);

这篇关于PXA270上的RS232通讯延时高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 04:50
查看更多