I'm writing an IO class to upload/download files to a controller over RS-232 serial. Unfortunately, I cannot send a whole file all at once, I have to break it into packets and send it a little bit at a time. Here's the basic approach...
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 );
}
I know that using Sleep() is not a good design practice, but if I remove the Sleep() statement or even shorten the amount time the loop sleeps, then the controller throws errors about it's buffer being full, and the transfer fails. Is there a better way to do this?
Before you say it, no I cannot send a message to the controller to determine if it's ready for the next packet. It does not have that functionality.
Edit: I forgot to mention that the interval at which I'm having to sleep is somewhat "blind." The protocol specification provided by the manufacturer does not detail any length of time needed between packets. So I had to determine that value by trial and error. I'm afraid that it may not work on every PC and more so that it may not work on every controller.
This development is being done for Windows XP/Vista/7.
Edit #2: Also, the amount of data per packet is actually a trial and error guess as well. The protocol specification allows for packets of 65,535 bytes (including the header). But if you send more than 129 bytes at a time, you start seeing issues where sometimes it works and sometimes it doesn't. There also seems to be a relationship between the time you have to sleep and the amount of bytes you can send. If I drop the packet size down to 20 bytes per packet, I can drop the sleep time down to 400 milliseconds. I believe the reason for these issues stem from the time it takes to the controller to move data from its buffer to the file.
Alternative: use wait() and notify() Now we have to refactor our test as well. After we start the counter we need to block the thread running the test until the counting is over. Remember, the counting happens in a different thread.
Thread. sleep is bad! It blocks the current thread and renders it unusable for further work.
Answer: Sleep () function suspends the execution of the program for a specified period of time. This time period is specified as an argument to the sleep () function. Q #2) What is the header file for sleep in C++? Answer: The header for sleep is “unistd. h” for LINUX/UNIX Operating system and “Windows.
Sleep method. Calling the Thread. Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread. Once that interval elapses, the sleeping thread resumes execution.
What you are doing is called blind-cycle synchronization. It is not necessarily bad design. If your device does not have the functionality to indicate that it is ready for more data or not, this is the only way to do it.
It is common for devices to specify a maximum data rate, or minimum amount of time between bytes.
I think the idea of this being bad practice comes from cases where you blindly pick a delay value (performance will suffer if it is larger than it needs to be), if you have better synchronization methods available, or if you are using delays to cover up timing problems (say, in a multithreaded application).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With