我遇到长延迟 - 在对某PXA270 RISC PC/104一个RS232通信(为1.5ms率为9.5ms)。我想尽量减少长时间的延迟,但我是一个嵌入式设备和C++的初学者,所以我想我错过了一些东西。高延迟RS232通讯上的PXA270
所提到的延迟是在当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。这个决议是足够的,仍然不能解释高延迟。顺便说一句,我认为操作系统使用内部PXA时钟(它也有足够的分辨率),而不是RTC的时间。
因此该问题必须在C++应用或RS232接口的驱动器/ OS的设置。
以下控制标志根据Serial Programming Guide for POSIX Operating Systems用于在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驱动程序处理具有更高优先级的请求,以最小化延迟。
有没有人有任何想法?非常感谢您的帮助。
你有这些延迟为每个字符,还是你的输入来时,有一个\输入中的n还是缓冲区已满?串行驱动程序上有一些与终端相关的东西,可以根据您的时间进行推断。 – Rudi 2011-01-12 09:42:26
延迟不会发生在每个字符上。发生时,当收到整个数据包(〜30字节)时,直到ACK数据包被发回。 – saxos 2011-01-12 10:16:31