Усеченные данные (если больше 512 байт) при использовании boost :: asio :: async_read_until из последовательного порта - PullRequest
0 голосов
/ 22 апреля 2020

Я использую функцию boost :: asio :: async_read_until для чтения с последовательного порта в Windows 10. Разделителем является шаблон Regex. Он работает, как и ожидалось, если полученные данные не превышают 512 байт.

Если полученные данные превышают 512 байт, они просто усекаются, и функция readComplete больше не будет вызываться. Однако, если я отправлю больше данных, достаточно 1 байта, отсутствующие данные будут получены вместе с новыми данными.

Я использовал ту же реализацию для tcp / сокета, и она работает безупречно. Есть ли какие-либо ограничения в собственном последовательном интерфейсе в Windows, вызывающие такое поведение?

РЕДАКТИРОВАТЬ 1: Я заметил, что если скорость передачи данных снижается с 115200 до 28800, никакие данные отсутствуют.

// from .h-file: boost::asio::streambuf streamBuf_;

void RS232Instrument::readAsyncChars()
{
   boost::asio::async_read_until(
      serial_,
      streamBuf_,
      boost::regex(regexStr_.substr(6, regexStr_.length() - 7)),
      boost::bind(
         &RS232Instrument::readComplete,
         this,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred));
}

void RS232Instrument::readComplete(const boost::system::error_code& error, size_t bytes_transferred)
{   
   if(error)
   {
     // Error handling
   }
   else
   {
      std::string rawStr(
         boost::asio::buffers_begin(streamBuf_.data()),
         boost::asio::buffers_begin(streamBuf_.data()) + bytes_transferred);

      // Log the data in rawStr....

      // Remove data from beginning until all data sent to log
      streamBuf_.consume(bytes_transferred);

      if(abort_ == false)
      {
         readAsyncChars();
      }
   }
}

1 Ответ

0 голосов
/ 24 апреля 2020

Поскольку я выяснил, что это вызвало эту проблему, я сам отвечу на этот вопрос.

Я упустил некоторый код выше для ясности, код, который я не осознавал, на самом деле был проблемой. Пример оставленного кода:

LOG_DEBUG ("Rs232Data Received");

Я использую функцию boost: log, и я добавил больше "раковин" в структуру журнала. Приемник, используемый в этом случае, регистрирует вектор в ram и выводит на консоль при запуске из пользовательского ввода.

Оказывается, каркас журнала потребляет около 1 мс, прежде чем вызывается функция «потребление» в приемнике. , Этого достаточно, чтобы вызвать потерю данных из последовательного порта при использовании async_read_until.

Извлеченные уроки: не вызывайте трудоемких задач в функции-обработчике в async_read_until

...