Windows XP встроенная - проблемы RS485 - PullRequest
1 голос
/ 19 июня 2009

У нас есть система под управлением XP, с COM2 в качестве аппаратного порта RS485.

В моем коде я устанавливаю DCB с помощью RTS_CONTROL_TOGGLE . Я бы предположил, что будет делать то, что он говорит ... отключить RTS в режиме ядра, как только прерывание записи пусто. Это должно быть практически мгновенно.

Вместо этого мы видим из области видимости, что ПК управляет шиной где-то на 1-8 миллисекунд дольше, чем конец сообщения. Устройство, с которым мы разговариваем, отвечает примерно за 1-5 миллисекунд. Итак ... коррупции в изобилии. Нет, нет способа изменить время реакции цели.

Теперь мы подключились к порту RS232 и подключили прицел к линиям TX и RTS, и мы видим то же самое. Линия RTS остается высокой 1-8 миллисекунд после отправки сообщения.

Мы также пытались отключить FIFO или установить глубину FIFO на 1 без эффекта.

Есть идеи? Я собираюсь попробовать вручную управлять линией RTS из пользовательского режима с приоритетом REALTIME во время цикла «SendFile, clear RTS». Я не очень надеюсь, что это сработает. Это не должно быть сделано в пользовательском режиме.

Ответы [ 2 ]

4 голосов
/ 19 июня 2009

RTS_CONTROL_TOGGLE не работает (имеет переменную задержку в 1-15 миллисекунд перед выключением после передачи) на нашей встроенной платформе XP. Возможно, я мог бы уменьшить это, если бы я изменил квант времени до 1 мс, используя timeBeginPeriod (1) и т. Д., Но я сомневаюсь, что это будет надежно или достаточно важно. (Иногда устройство реагирует на 1 миллисекунду)

Окончательное решение действительно ужасно, но оно работает на этом оборудовании. Я бы не использовал его ни на чем, где железо не зафиксировано в камне.

В основном:

1) установите для FIFO на странице диспетчера устройств последовательного порта значение off или 1 символ глубиной

2) отправьте ваше сообщение + 2 дополнительных байта , используя этот код:

int WriteFile485(HANDLE hPort, void* pvBuffer, DWORD iLength, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped)
{
  int iOldClass = GetPriorityClass(GetCurrentProcess());
  int iOldPriority = GetThreadPriority(GetCurrentThread());
  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

  EscapeCommFunction(hPort, SETRTS);

  BOOL bRet = WriteFile(hPort, pvBuffer, iLength, pdwWritten, lpOverlapped);

  EscapeCommFunction(hPort, CLRRTS);

  SetPriorityClass(GetCurrentProcess(), iOldClass);
  SetThreadPriority(GetCurrentThread(), iOldPriority);

  return bRet;
}

WriteFile () возвращается, когда последний или два байта были записаны в последовательный порт. Они еще не вышли из порта, поэтому необходимо отправить 2 дополнительных байта. Один или оба из них будут разбиты, когда вы делаете CLRRTS.

Как я уже сказал ... это ужасно.

1 голос
/ 19 июня 2009

Есть идеи?

Вы можете обнаружить, что в DDK есть исходный код драйвера последовательного порта, который позволит вам увидеть, как предполагается реализовать эту опцию: то есть, на уровне прерывания, на уровне DPC или хуже.

Другие возможности включают переписывание драйвера; использование стороннего драйвера RS485, если вы можете его найти; или использование стороннего оборудования RS485 с его собственным драйвером (например, по крайней мере, в прошлом третьи стороны использовали для создания «интеллектуальных плат последовательных портов» с 32 портами, глубокими буферами и собственным микропроцессором; решено кем-то).

8 миллисекунд действительно удручающе долго; Я знаю, что XP не является ОСРВ, но я ожидаю, что она (обычно) будет лучше, чем эта. Еще одна вещь, на которую стоит обратить внимание, это наличие других высокоприоритетных потоков, которые могут создавать помехи. Если вы повышаете приоритеты некоторых потоков в своем собственном приложении, возможно, вместо этого вам следует уменьшить приоритеты других потоков.

Я собираюсь вручную управлять линией RTS из пользовательского режима с приоритетом REALTIME во время цикла «SendFile, clear RTS».

Не позволяйте этому потоку выйти из-под контроля: IME такой поток может, если он глючит, вытеснять любой другой поток пользовательского режима навсегда.

...