关于串口写超时的问题

riverking 2003-09-10 08:04:29

我在英文版win2K+sp3的系统中读写串口时遇到这样的问题:

串口进行了一段时间的正常操作后,如果这时有一个写操作在执行前没有进行写超时设置(调用API SetCommTimeouts()),则以后所有的写操作将都会等到超时才会完成。
也就是说,如果设的写超时为5秒,则写操作就要5秒后才完成,设为10秒,则过10秒后执行完成,不过最后都执行成功了,只是这样就会相当的慢。

如果再次出现写操作前不设超时,则写操作将永远无法结束,线程挂死!!


请问这是什么问题,是不是API的BUG???
(一周后结贴)
...全文
449 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
riverking 2003-09-16
  • 打赏
  • 举报
回复
该问题经多方努力,初步定为我们用的串口扩展设备驱动程序有问题。
先结贴,有进行一步情况再告诉大家。

谢谢帮助!!!
riverking 2003-09-16
  • 打赏
  • 举报
回复 1

该问题现在已彻底解决了,其原因是我们用的串口扩展设备:Moxa(摩莎)卡驱动程序有BUG,通过修改驱动程序的设置可以解决问题,在此不详述了,如哪位有类似的问题出现,可以联系我。
riverking 2003-09-12
  • 打赏
  • 举报
回复
你这样做也是对的,虽然总超时为无限的,但你有字符间超时,不会吊死。

newComTimeOuts.ReadIntervalTimeout = MAXDWORD;


另外,我的系统是运行了18天后出问题的,我正在测试,可能18天后有回出问题。
Behard 2003-09-12
  • 打赏
  • 举报
回复
我看了一下 我都是没有设置的:
// Get the timeout values for the port and set our timeout values.
COMMTIMEOUTS newComTimeOuts;

GetCommTimeouts(comHandle, &comTimeOuts);

newComTimeOuts.ReadIntervalTimeout = MAXDWORD;
newComTimeOuts.ReadTotalTimeoutConstant = 0;
newComTimeOuts.ReadTotalTimeoutMultiplier = 0;
newComTimeOuts.WriteTotalTimeoutMultiplier = 0;
newComTimeOuts.WriteTotalTimeoutConstant = 0;

SetCommTimeouts(comHandle, &newComTimeOuts);

// Now lets try to set the port to our default values.
if (!SetCommState(comHandle, &comDCB))
comLastError = GetLastError();
从来没有发现会出错
riverking 2003-09-11
  • 打赏
  • 举报
回复


也就是说,写串口时,你设多少秒的写超时,函数就几秒完成写操作。
一般情况下,如果我们设5秒超时,可能非常顺利,1秒不到就完成了写操作。
riverking 2003-09-11
  • 打赏
  • 举报
回复
可以肯定的是,数据写成功了!
riverking 2003-09-11
  • 打赏
  • 举报
回复
每次写之前设一下超时,因为写超可能需要改变一下。
有代码分析一下:

int __fastcall TCommBase::WriteDataToComm(byte *InBuff,DWORD dwSize,int TimeOut)
{
struct time t;
AnsiString TimeString;
ErrorCode = 0;
AnsiString RealString = "";
//设定写超时
if(SetWriteTimeOut(TimeOut)<0)
{
ErrorCode=ERROR_SET_COM_TIMEOUT;
goto Error;
}

if(!WriteFile(hCom,InBuff,dwSize,&dwWrite,olReadWrite))
{
if(GetLastError()!=ERROR_IO_PENDING)
{
ErrorCode=ERROR_ASYN_WRITE;
ClearCommError(hCom,NULL,NULL);
goto Error;
}
}

if(GetOverlappedResult(hCom,olReadWrite,&dwWrite,true)==0)
{
ErrorCode=ERROR_ASYN_WRITE;
goto Error;
}
else
ResetEvent(olReadWrite);
//是否超时
if(dwWrite<dwSize)
{
ErrorCode=ERROR_WRITE_TIMEOUT;
goto Error;
}

Error:

return ErrorCode;
}
//------------------------------------------------------------------------------
bool __fastcall TCommBase::SetWriteTimeOut(int ConstantTimeOut,int MultiTimeOut)
{
COMMTIMEOUTS sCTO;
memset(&sCTO,0,sizeof(sCTO));
if(ConstantTimeOut==0) //若常量超时时长(ConstantTimeOut)为缺省(0)时,写
//超时由系统的站属性和写操作用去的时间之差决定。
{
switch(Station)
{
case 'M':
sCTO.WriteTotalTimeoutConstant = MWriteTimeOut;
break;
case 'S':
sCTO.WriteTotalTimeoutConstant = SWriteTimeOut;
break;
case 'N':
sCTO.WriteTotalTimeoutConstant = NWriteTimeOut;
break;
default:
return false; //有些特殊情况可能不会设超时,这里就会有问题
}
}
else //若常量超时时长(ConstantTimeOut)不为缺省(0)时,读超
//时的常量由常量超时时长(ConstantTimeOut)决定;读超
//时的系数由系数时长(MultiTimeOut)决定.
{
sCTO.WriteTotalTimeoutMultiplier=MultiTimeOut;
sCTO.WriteTotalTimeoutConstant =ConstantTimeOut;
}

return(SetCommTimeouts(hCom,&sCTO));
}
//------------------------------------------------------------------------------
dragonhux 2003-09-11
  • 打赏
  • 举报
回复
1、开大写缓冲区
2、只设置一次写超时的时间

估计出现这个问题是因为设置CommTimeOuts.WriteTotalTimeoutConstant
时所耗用的时间!
Behard 2003-09-11
  • 打赏
  • 举报
回复
我看了不是很理解楼主的意思!

-----------------------------------
现在混水园了!
Behard 2003-09-11
  • 打赏
  • 举报
回复
因为写 COM 口有可能是失败的
所以可能会等到超时才出来 你看一看究竟写完了没有?
Behard 2003-09-11
  • 打赏
  • 举报
回复
本来就是你说的一样呀!

但是你是怎么样设置和读写的?
riverking 2003-09-10
  • 打赏
  • 举报
回复

先谢谢大家!

每次写操作作都重设写超时是以前的代码留下来的,改一改也是可以的。
我主要是想知道为什么会出现“所有的写操作将都会等到超时才会完成”
情况,因为我认为这没有道理,想找一下它的根源。
土著巫师 2003-09-10
  • 打赏
  • 举报
回复
1、楼上说的对,只要一次设置就可以了,而且超时值和你的工作时速度相适应,不应太长。

2、
COMMTIMEOUTS CommTimeOuts;
bool Result ;

CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 2*CBR_9600/FBaudRate ;
CommTimeOuts.WriteTotalTimeoutConstant = 0 ;
Result = SetCommTimeouts(FHandle, &CommTimeOuts) ;
if (!Result)
RaiseCommError(“Error”, GetLastError()); //这个不是SDK里的函数。
kingcaiyao 2003-09-10
  • 打赏
  • 举报
回复
你串口的DCB应该是一个全局的变量,何必每次进行写操作都要进行超时设置呢?这点你须要在你的程序中改进。“否则写线程将永远无法结束“这并非是API的BUG,而是你的程序处理不当造成

thp 2003-09-10
  • 打赏
  • 举报
回复
riverking 2003-09-10
  • 打赏
  • 举报
回复
还有没有谁有过这样的经历,谢谢了!
riverking 2003-09-10
  • 打赏
  • 举报
回复
另外在一些情况下,读写超时是不同的,
所以在使用串口通讯时,也可能会需要修改超时。

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧