簡體   English   中英

PXA270上的RS232通信延遲很高

[英]High delay in RS232 communication on a PXA270

我在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接口的驅動程序/ OS設置中。

根據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。 命令setserial(8)在AEL手冊中引用。 和賓果游戲,我在那里找到了low_latency標志,其中包含以下描述:

以更高的CPU利用率為代價,最大限度地減少串行設備的接收延遲。 (通常在將字符切換到行discpline之前平均有5-10ms的延遲以最小化開銷。)默認情況下這是關閉的,但某些實時應用程序可能會發現這很有用。

然后我執行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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM