1

我们有一个运行 XP Embedded 的系统,COM2 是一个硬件 RS485 端口。

在我的代码中,我使用RTS_CONTROL_TOGGLE设置 DCB 。我假设它会做它所说的......一旦发生写空中断,就在内核模式下关闭 RTS。这应该是即时的。

相反,我们在示波器上看到 PC 驱动总线的时间比消息结束时间长 1-8 毫秒。我们正在与之交谈的设备会在大约 1-5 毫秒内做出响应。所以... 通信腐败盛行。不,没有办法改变目标的响应时间。

我们现在已经连接到 RS232 端口并将示波器连接到 TX 和 RTS 线,我们看到了同样的情况。RTS 线在消息发送后 1-8 毫秒保持高电平。

我们还尝试关闭 FIFO,或将 FIFO 深度设置为 1,但没有任何效果。

有任何想法吗?我将尝试在“SendFile,清除 RTS”周期中以 REALTIME 优先级从用户模式手动控制 RTS 线路。我也不希望这会奏效。这不应该在用户模式下完成。

4

2 回答 2

4

RTS_CONTROL_TOGGLE在我们的嵌入式 XP 平台上不起作用(在传输后关闭它之前有 1-15 毫秒的可变延迟)。如果我使用 timeBeginPeriod(1) 等将时间量更改为 1 毫秒,我可能会降低它,但我怀疑它是否可靠或足够重要。(设备有时会在 1 毫秒内响应)

最终的解决方案真的很难看,但它适用于这个硬件。我不会在硬件没有固定在石头上的任何东西上使用它。

基本上:

1) 将串口设备管理器页面上的 FIFO 设置为关闭或 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 时,它们中的一个或两个都会被丢弃。

就像我说的......它很丑。

于 2009-06-19T17:58:28.623 回答
1

有任何想法吗?

您可能会发现 DDK 中有串行端口驱动程序的源代码,它可以让您了解该选项应该如何实现:即它是在中断级别、在 DPC 级别还是更糟。

其他可能性包括重写驱动程序;如果您能找到,请使用第 3 方 RS485 驱动程序;或使用带有自己的驱动程序的第 3 方 RS485 硬件(例如,至少在过去,第 3 方曾经制造具有 32 个端口、深度缓冲区和自己的微处理器的“智能串行端口板”;我预计 RS485 是一个一直存在的问题)由某人解决)。

8 毫秒确实看起来令人失望。我知道 XP 不是 RTOS,但我希望它(通常)做得比这更好。要查看的另一件事是是否有其他高优先级线程正在运行,可能会产生干扰。如果您一直在提高自己应用程序中某些线程的优先级,那么也许您应该降低其他线程的优先级。

我将尝试在“SendFile,清除 RTS”周期中以 REALTIME 优先级从用户模式手动控制 RTS 线路。

不要让那个线程失控:IME 一个这样的线程,如果它有问题,就可以永远抢占所有其他用户模式线程。

于 2009-06-19T15:45:54.107 回答