Я реализую класс, который общается с контроллером мотора через USB-устройство. У меня все работает, кроме способа указать, является ли параметр, выбранный по каналу связи, "свежим" или нет. Что у меня так далеко:
class MyCommClass
{
public:
bool getSpeed( double *speed );
private:
void rxThread();
struct MsgBase
{ /* .. */ };
struct Msg1 : public MsgBase
{ /* .. */ };
struct Msg2 : public MsgBase
{ /* .. */ };
/* .. */
struct MsgN : public MsgBase
{ /* .. */ };
Msg1 msg1;
Msg2 msg2;
/* .. */
MsgN msgn;
std::map< unsigned long id, MsgBase *msg > messages;
};
rxThead()
- это бесконечный цикл, выполняемый в отдельном потоке, проверяющем USB-устройство на наличие доступных сообщений. Каждое сообщение имеет уникальный идентификатор, который rxThread()
использует, чтобы вставить его в правильный msgx
объект. Что мне нужно, так это когда пользователь вызывает функцию getSpeed()
, он должен иметь возможность определить, является ли текущее значение скорости «свежим» или «устаревшим», т.е. был ли объект msgx
, который содержит значение скорости, обновлен в пределах указанного период ожидания Таким образом, каждый объект сообщения должен реализовать свое собственное время ожидания (так как они варьируются в зависимости от сообщения).
Все сообщения периодически передаются контроллером мотора, но есть также некоторые, которые передаются, как только их содержимое изменяется (но они также будут передаваться периодически, если содержимое не изменяется). Это означает, что получение сообщения с номинальной скоростью выше допустимого, но оно должно появляться как минимум один раз в течение максимального периода времени ожидания.
Устройство USB предоставляет метки времени вместе с сообщениями, поэтому у меня есть доступ к этой информации. Временная метка не отражает текущее время, это число unsigned long
с микросекундным разрешением, которое устройство обновляет каждый раз при получении сообщения. Я подозреваю, что устройство только начинает увеличивать это значение с 0
со времени, когда я вызываю его функции инициализации. Я могу придумать несколько способов реализации этого:
Каждый объект сообщения запускает поток, который бесконечно работает (WaitForSingleObject) в течение периода ожидания. По истечении времени ожидания он проверяет, была ли увеличена переменная счетчика (которая была кэширована до ожидания). Если нет, он устанавливает флаг, помечающий сообщение как устаревшее. Счетчик будет увеличиваться каждый раз, когда rxThread()
обновляет этот объект сообщения.
rxThread()
, в дополнение к заполнению сообщений, также выполняет итерацию по списку сообщений и проверяет отметку времени последнего обновления. Если отметка времени превышает время ожидания, оно помечает сообщение как устаревшее. Этот метод может иметь проблемы с объемом обработки требуется. Вероятно, это не будет проблемой на большинстве машин, но этот код должен работать на очень медленном «промышленном компьютере».
Буду очень признателен за ваши мысли и предложения о том, как это реализовать. Я открыт для идей, кроме двух, которые я упомянул. Я использую Visual Studio 2005, и кросс-платформенная переносимость не представляет большой проблемы, поскольку драйверы USB-устройств предназначены только для Windows. В настоящее время я отслеживаю около 8 сообщений, но было бы неплохо, если бы решение было достаточно легким, чтобы я мог добавить еще несколько (может быть, еще 8) без ограничений по мощности.
Заранее спасибо,
Ashish.