Я испытываю длительную задержку (1,5 мс - 9,5 мс) в RS232-связи на ПК-104 PXA270 RISC. Я хочу свести к минимуму длительную задержку, но я новичок со встроенными устройствами и C++, поэтому я думаю, что я что-то упустил.Высокая задержка связи RS232 на PXA270
Указанная задержка заключается в том, что плата PXA получает пакет от внешнего устройства через RS232 (115200 бод), пока он не отправит собственный пакет ACK обратно на внешнее устройство. Я измерил задержку на плате PXA с помощью осциллографа, один канал на Rx, а другой на Tx.
Плата PXA работает Arcom Embedded Linux (AEL). Я знаю, что это не операционная система в реальном времени, но я все же думаю, что средняя задержка в 4,5 мс - это слишком высокая для извлечения полученного пакета, проверки его CRC16, создания ACK-пакета (с CRC) и отправки его назад к серийной линии. Я также намеренно поставил CPU под большую нагрузку (некоторые параллельные операции gzip), но время задержки не увеличилось вообще. Максимальный размер полученного пакета - 30 байт.
Приложение C++ (другое бывшее соавтора написало его) обрабатывает прием пакетов и их подтверждение. Один поток отправляется, а другой принимает пакеты.
Я думал, что RTC на плате PXA имеет очень плохое разрешение, и AEL не может согласовать синхронизацию с внутренним разрешением RTC. Но частота RTC составляет 32,768 кГц. Разрешение достаточно, но не объясняет высокую задержку. Кстати, я думаю, что ОС использует внутренние часы PXA (который также имеет достаточное разрешение) вместо RTC для синхронизации.
Поэтому проблема должна быть в приложении C++ или в настройке драйвера/ОС интерфейса RS232.
следующие флаги управления используются для связи RS232 в приложении C++ в соответствии с 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);
Я думаю, что я что-то очень простое отсутствует. Я думаю, что если процесс приложения работает под более высоким приоритетом, это не решит проблему. Должно быть что-то, что инструктирует драйвер RS232 обрабатывать запросы с более высоким приоритетом, чтобы свести к минимуму задержку.
У кого-нибудь есть идеи? Заранее благодарю вас за помощь.
Есть ли у вас эти задержки для каждого полукокса, или же ваш вход приходят, когда есть \ n на входе или буфер заполнен? В дополнение к серийному драйверу есть некоторые связанные с терминалом материалы, которые могут вывести ваше время. – Rudi
Задержка не возникает для каждого символа. Это происходит, когда весь пакет (~ 30 байт) принимается, пока пакет ACK не будет отправлен обратно. – saxos
1.Пожалуйста, покажите нам код, где вы ждете и читаете из порта. 2.Показать нам вывод 'uptime' (возможно, ваша система перегружена?) 3. У вашего Linux есть Fast Context Switch Extension (lwn.net/images/conf/rtlws11/papers/proc/p01.pdf)? PXA270 может иметь задержку переключения контекста ~ 0,5 мс без него. – atzz