Отметка времени поступающих последовательных данных под WinXP 32 с использованием Boost ASIO и Boost posix time? - PullRequest
0 голосов
/ 19 марта 2012

Я пытаюсь считывать данные и метки времени с устройства с последовательным интерфейсом под WinXP 32. Я использую boost :: asio для моего последовательного получения, но столкнулся с некоторыми ограничениями.Если я попытаюсь прочитать и пометить меткой времени каждое 2-байтовое измерение диапазона, сказав asynch_read_some использовать 2-байтовый буфер, я получу огромную задержку при измерениях диапазона.

Чтобы обойти это, мой план заключался в использовании большого(5 kb) буферов, отметка времени, время, когда я получаю каждый буфер и выгружаю буфер, отметку времени и некоторые другие вещи (размер, заголовок, нижний колонтитул и т. Д.) В файл.Мне нужны эти временные метки, так как я должен синхронизировать данные датчика с данными с другого устройства на одном ПК.Процесс регистрации для этого устройства также применяет временные метки почти таким же образом, и я собираюсь подключить все это в автономном режиме после того, как я взял свои журналы.

Эта функция вызывается непосредственно из моего boost :: asioпоследовательный обратный вызов RX, как только данные получены, и передан указатель на буфер и количество полученных байтов.

void AR2500CallbackFunction(char * RXBuff, unsigned int bytesRcvd)
{
  boost::posix_time::ptime nowPTime( boost::posix_time::microsec_clock::local_time() );
  uint64_t pktTimestamp( nowPTime.time_of_day().total_microseconds() );

  // Log Packet Header - PacketStartSentinel                                                    
  m_logFileStream.write((char *)PacketStartSentinel, sizeof(PacketStartSentinel));
  // Log Packet ID - m_packetCounter
  m_logFileStream.write((char *)&m_packetCounter, sizeof(m_packetCounter));
  // Add number of bytes recieved - bytesRcvd
  m_logFileStream.write((char *)&bytesRcvd, sizeof(bytesRcvd));
  // Log Data - RXBuff
  m_logFileStream.write(RXBuff, bytesRcvd);
  // Add Timestamp - pktTimestamp
  m_logFileStream.write((char *)&pktTimestamp, sizeof(pktTimestamp));
  // Add End Sentinel - PacketEndSentinel
  m_logFileStream.write((char *)PacketEndSentinel, sizeof(PacketEndSentinel));
  m_packetCounter++;
}

Поскольку мои данные поступают в виде постоянного потока через последовательный порт, я затемсделать то, что кажется разумным предположением.Я предполагаю, что отметка времени, которую я записываю с каждым пакетом, является повторяемой (но не обязательно точной, будет некоторая приблизительно постоянная задержка, прежде чем обратный вызов будет фактически выполнен), измерения времени, в которое я получил последнюю выборку в пакете.На этапе постобработки я беру метку времени из предыдущего пакета, метку времени текущего пакета и линейно интерполирую, чтобы оценить метку времени каждой из выборок в текущем пакете.

Что япосле постобработки обнаружилось, что даже для чрезвычайно низких скоростей передачи данных, когда для каждого обратного вызова есть только 1 или 2 показания диапазона, я получаю крайне нестабильную временную метку.Некоторые пакеты помечаются как имеющие одинаковое время, некоторые последовательные пакеты помечаются как имеющие невероятно большие промежутки.Когда я устанавливаю частоту дискретизации датчика равной 10 Гц, я по-прежнему получаю некоторые различия в метках времени между выборками по 125 миллисекунд, а некоторые - до 80 миллисекунд.Если я увеличу частоту дискретизации (датчик может возвращать показания 2-байтового диапазона на частоте до 30 кГц по каналу RS232 со скоростью 921600 бод), я обнаружу, что нестабильность становится еще хуже.Используя осциллограф на последовательных линиях, я знаю, что датчик фактически выплевывает данные с заданной скоростью, поэтому недостаток должен быть где-то на стороне программного обеспечения.

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

1 Ответ

0 голосов
/ 19 марта 2012

Отметка времени данных, внешних по отношению к ПК, или использование ОС реального времени.Настольные ОС, которые действительно хорошо работают с Office и Firefox, совершенно бесперспективны при сборе данных в режиме реального времени.Драйверы оптимизированы, чтобы сигнализировать о получении огромных буферов данных, чтобы максимизировать пропускную способность сложных веб-страниц и потокового мультимедиа.Немедленная сигнализация получения пары байтов (или даже 5 КБ) немного ниже их - драйверы не могут быть обеспокоены и имеют тенденцию лежать без дела целую вечность, если поступает больше данных, тогда они могут сигнализировать все этосразу: ((*

Все мои встроенные контроллеры, которые возвращают данные, для которых требуется отметка времени, возвращают отметку в данных и не полагаются на какую-либо мегалитическую операционную систему настольного компьютера для пробуждения потока в любом приглашении

Тем не менее, вы можете настроить драйвер COMMTIMEUTS последовательного драйвера для более быстрого возврата данных. Другой вопрос - поможет ли это, потому что у вас есть другие устройства, которые могут подвергаться таким же проблемам.

Кроме того, что такое m_logFileStream? Это еще одна асинхронная запись или запись в очередь на диск, помещенная в очередь? Если нет, то это должно быть.

Если вы хотите попробовать применить временные метки к данным на ПК втак, как вы, кажется, хотите, тогда в идеале все ваши данные должны проходить через один и тот же поток, который добавляет временные метки и ведет журналирование.Журналы iple и их последующая фильтрация для сортировки по меткам времени просто добавят еще больше дрожания.Это то, что делают разработчики Unix, потому что их компьютеры могут выполнять только скрипты bash:))

...