Почему чтение из последовательного порта с использованием `poll ()` иногда возвращает `0x00` вместо фактического байта?Linux

Ответить Пред. темаСлед. тема
Anonymous
 Почему чтение из последовательного порта с использованием `poll ()` иногда возвращает `0x00` вместо фактического байта?

Сообщение Anonymous »

Я работаю над приложением Linux, которое связано с модемом HART над последовательным портом , в частности, с использованием модема FTDI USB-to-Serial . Приложение использует boost.asio для асинхронной последовательной связи. Например, когда устройство отправляет {0x0a, 0x0b, 0x0c} , приложение получает {0x0a, 0x0b, 0x00} .
Для изучения я создал упрощенную тестовую программу (не используя Boost.asio), что MIMICS поведение с низкими системами системы Live-Level System. Вот минимальный воспроизводимый пример < /strong>, который повторяет проблему.

Код: Выделить всё

int fd = open(comPort.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);

while (true) {
uint8_t byte;
ssize_t n = read(fd, &byte, 1);

if (n > 0) {
SPDLOG_INFO("Read byte: 0x{:02X}", byte);
} else if (n == -1 && errno != EAGAIN) {
SPDLOG_ERROR("Read error: {}", strerror(errno));
break;
} else {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}

close(fd);
< /code>
Эта версия работает надежно-все байты принимаются правильно, включая контрольную сумму. < /p>

 ❌ Проблемная версия (с использованием poll () < /code>): < /h3>
 0) {
SPDLOG_INFO("Read byte: 0x{:02X}", byte);
} else if (n == -1 && errno != EAGAIN) {
SPDLOG_ERROR("Read error: {}", strerror(errno));
break;
} else {
pollfd pfd{};
pfd.fd = fd;
pfd.events = POLLIN;

int ret = poll(&pfd, 1, -1);
if (ret == -1) {
SPDLOG_ERROR("poll() error: {}", strerror(errno));
break;
}

// No delay here
}
}

close(fd);
Эта версия работает Большинство времени, но очень время отредка последний байт сообщения принимается как 0x00 . Обычно это происходит на контрольной сумме byte < /strong>, что приводит к ошибкам проверки сообщений.

Код: Выделить всё

// Inside the poll() block
std::this_thread::sleep_for(std::chrono::microseconds(1));
Добавление даже 1-Microsecond Dolempt [/b] после опроса () постоянно предотвращает проблему. Все байты, включая контрольную сумму, принимаются правильно. byte? />
Должен ли я всегда добавлять короткую задержку после опроса () < /code>? Или есть более надежный подход - особенно при использовании boost.asio?>

Подробнее здесь: https://stackoverflow.com/questions/795 ... 0x00-inste
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»