我正在编写一个IO类,通过RS-232串行将文件上载/下载到控制器。不幸的是,我无法一次发送整个文件,我不得不将它分解成数据包并一次发送一次。这里的基本方法...睡眠()是一个糟糕的设计,但似乎是我唯一的选择
ifstream file ("path/to/file.ext", ios::in | ios::binary);
while(!file.eof())
{
//... zero buffer, and add packet header (8 bytes)
size_t nResult = file.read(&buffer[8], 129);
Serial.Write(buffer, nResult+8);
//... see if controller wrote anything to the serial port and process it's command
Sleep(600);
}
我知道,使用睡眠()是不是一个好的设计,但如果我删除了睡眠()语句甚至缩短时间量的循环休眠,则控制器抛出关于缓冲区已满的错误,并且传输失败。 有没有更好的方法来做到这一点?
在你说出来之前,我不能发送消息给控制器,以确定它是否准备好接受下一个数据包。它没有这个功能。
编辑: 我忘了提,我不得不睡在哪个区间是有点“盲目”。制造商提供的协议规范没有详细说明数据包之间所需的任何时间长度。所以我必须通过反复试验来确定这个价值。我担心它可能无法在每台PC上运行,因此它可能无法在每个控制器上运行。
该开发工作正在为Windows XP/Vista/7完成。
编辑#2: 此外,每个数据包的数据量实际上也是一个试错法猜测。协议规范允许包含65,535字节的数据包(包括头部)。但是,如果您一次发送超过129个字节,您会发现问题有时会起作用,有时不起作用。睡眠时间和可以发送的字节数量之间似乎也有关系。如果我将数据包大小降低到每个数据包20个字节,我可以将睡眠时间降低到400毫秒。我相信造成这些问题的原因是控制器将数据从缓冲区移动到文件的时间。
你总是从控制器得到答案吗? – dwo
如果您的硬件需求包括一次发送如此多的字节,然后等待那么多毫秒,那么实现它的方式并不明显。 – Gabe
是的,我甚至会认为使用睡眠不是一个想法的坏处。我想你可以写一个奇特的函数,包括,但考虑到你的条件,Sleep()听起来很合理。 –
ScarletAmaranth