views:

44

answers:

2

This seems like a simple question, but it is difficult to search for. I need to interface with a device over the serial port. In the event my program (or another) does not finish writing a command to the device, how do I ensure the next run of the program can successfully send a command?

Example:

  1. The foo program runs and begins writing "A_VERY_LONG_COMMAND"
  2. The user terminates the program, but the program has only written, "A_VERY"
  3. The user runs the program again, and the command is resent. Except, the device sees "A_VERYA_VERY_LONG_COMMAND," which isn't what we want.

Is there any way to make this more deterministic? Serial port programming feels very out-of-control due to issues like this.

+1  A: 

I would guess that if you call write("A_VERY_LONG_COMMAND"), and then the user hits Ctrl+C while the bytes are going out on the line, the driver layer should finish sending the full buffer. And if the user interrupts in the middle of the call, the driver layer will probably just ignore the whole thing.

Just in case, when you open a new COM port, it's always wise to clear the port.

Do you have control over the device end? It might make sense to implement a timeout to make the device ignore unfinished or otherwise corrupt packets.

mtrw
When you say clear the port, what do you mean? I'm a newbie to serial port programming. I'm used to sockets, where you start clean everytime. I agree that the chance of happening is small; but its important that this cannot happen.I have no control over the device. It appears to respond with "ERROR" or "OK" for all commands when done with output. However, its difficult to tell whether I need to reset its state or not.
Matt Green
I've only ever programmed com ports on win32, so I don't know what calls are available in Linux. But in general, you should flush the output, check if any characters are present on the input read them up if there are, and clear the error flags. The win32 ways of doing this are using `WriteFile`, `ReadFile`, and `ClearCommError`, along with a `ComStat` structure.
mtrw
+1  A: 

The required method depends on the device.

  • Serial ports have additional control signal lines as well as the serial data line; perhaps one of them will reset the device's input. I've never done serial port programming but I think ioctl() handles this.
  • There may be a single byte which will reset, e.g. some control character.
  • There might be a timing-based signal, e.g. Hayes command set modems use “pause +++ pause”.
  • It might just reset after not receiving a complete command after a fixed time.

It might be useful to know whether the device was originally intended to support interactive use (serial terminal), control by a program, or both.

Kevin Reid