В настоящее время я пытаюсь установить связь с внешним устройством через последовательный порт, и оно работает просто отлично ... если устройство подключено.Однако, поскольку нет гарантии, что это так (и у меня есть несколько последовательных портов на выбор), было бы идеально, если бы я мог использовать синхронизированное чтение VMIN = 0 / VTIME> 0 для проверки портов (и, как правило, для предотвращения моего приложения).от блокировки на неопределенный срок, если устройство отсоединено во время работы).
Вот мой код, чтобы открыть последовательный порт и установить его в неканонический режим.Но даже если я установил VTIME на 5 (что должно быть полсекунды) и VMIN на 0 (чтобы тайм-аут начинался немедленно), read () просто блокируется на неопределенный срок, если ни одно устройство не подключено.
int32_t OpenDevice(char* device)
{
if (access(device, R_OK | W_OK))
{
LOG(Log_Error, "%s() access(): %s", __func__, strerror(errno));
goto ERR_ACCESS;
}
int32_t fd = open(device, O_RDWR | O_NOCTTY);
if (fd == -1)
{
LOG(Log_Error, "%s() open(): %s", __func__, strerror(errno));
goto ERR_OPEN;
}
struct termios tios;
if (tcgetattr(fd, &tios))
{
LOG(Log_Error, "%s() tcgetattr(): %s", __func__, strerror(errno));
goto ERR_GETATTR;
}
cfmakeraw(&tios);
if (cfsetspeed(&tios, B115200))
{
LOG(Log_Error, "%s() cfsetspeed(): %s", __func__, strerror(errno));
goto ERR_SETSPEED;
}
tios.c_cflag |= CLOCAL | CREAD;
tios.c_cflag &= ~CRTSCTS;
tios.c_cc[VMIN] = 0;
tios.c_cc[VTIME] = 5;
if (tcsetattr(fd, TCSANOW, &tios))
{
LOG(Log_Error, "%s() tcsetattr(): %s", __func__, strerror(errno));
goto ERR_SETATTR;
}
struct termios tios_new;
tcgetattr(fd, &tios_new);
if (memcmp(&tios_new, &tios, sizeof(tios)))
{
LOG(Log_Error, "%s() failed to set attributes", __func__);
goto ERR_SETATTR;
}
return fd;
ERR_SETATTR:
ERR_SETSPEED:
ERR_GETATTR:
close(fd);
ERR_OPEN:
ERR_ACCESS:
return -1;
}
Я не знаю, имеет ли это значение, но мое приложение работает не на ПК, а на Cyclone V SoC (от Altera / Intel) с двухъядерным процессором Cortex-A9.Используемый драйвер - это CONFIG_SERIAL_ALTERA_UART, который создает несколько устройств / dev / ttyAL.Сама ОС является версией из git-репозитория Altera, с уже включенным набором патчей PREEMPT_RT (rel_socfpga-4.1.22-ltsi-rt_16.10.02_pr).
PS: я знаю, что могу просто использовать select () иНазовите это днем, но я бы предпочел сохранить свой код простым, вместо того, чтобы добавлять кучу накладных расходов, просто чтобы получить этот тайм-аут.
Заранее спасибо за любые советы по этой проблеме.