EmbeddedRelated.com
Forums

serial port flush?

Started by Thomas January 29, 2005
Hi there,

I've written a programme, to communicates with a microcontroller, but
sometimes there is no reaction when I send the initial byte. I'm working
under Suse Linux 9.2 prof. and as I know from a windows programme this
problem shouldn't be caused by the microcontroller. As it always works with
this programme under windows.

So could it be, that when there is a failure at the microcontroller, so that
the byte isn't received (i.e. it isn't in bootstrap mode), that after this
the serial port might be blocked by the previous byte? Or somthing like
that. I know, that this byte cannot really "block" the serial port, but
there must be something that blocks the transfer.

So is there a way to "flush" the serial port before starting a transfer? Or
is it something else that causes my problems.

Hier is my procedure that initializes the serial port:

int openport(char* device)
{
        int fd;
        struct termios options;

        //Stream oeffnen
        fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
        
        //ueberpruefen
        if (fd == -1)
                return -1;

        //Alles auf Null setzen
        bzero(&options, sizeof(options));

        //aktuelle Einstellungen holen
        tcgetattr(fd, &options);
        
        //moeglicherweise vorhandene ungewuenschte Einstellungen zuruecksezten
        options.c_cflag &= ~PARENB;     //kein Parity-Bit
        options.c_cflag &= ~CSTOPB;     //ein Stopbit
        options.c_cflag &= ~CSIZE;      //Datenmaske zuruecksetzen
        
        //weitere Controllflags setzen
        options.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
        options.c_iflag = IGNPAR;       
        options.c_oflag &= ~OPOST;
        options.c_lflag = 0;
        options.c_cc[VMIN]  = 1;
        options.c_cc[VTIME]  = 0;

        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &options);

        return (fd);
}


So could anybody please help me?

Thanks in advance

Thomas


Thomas wrote:

> Hi there, > > I've written a programme, to communicates with a microcontroller, but > sometimes there is no reaction when I send the initial byte. I'm working > under Suse Linux 9.2 prof. and as I know from a windows programme this > problem shouldn't be caused by the microcontroller. As it always works > with this programme under windows. > > So could it be, that when there is a failure at the microcontroller, so > that the byte isn't received (i.e. it isn't in bootstrap mode), that after > this the serial port might be blocked by the previous byte? Or somthing > like that. I know, that this byte cannot really "block" the serial port, > but there must be something that blocks the transfer. > > So is there a way to "flush" the serial port before starting a transfer? > Or is it something else that causes my problems. > > Hier is my procedure that initializes the serial port: > > int openport(char* device) > { > int fd; > struct termios options; > > //Stream oeffnen > fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); > > //ueberpruefen > if (fd == -1) > return -1; > > //Alles auf Null setzen > bzero(&options, sizeof(options)); > > //aktuelle Einstellungen holen > tcgetattr(fd, &options); > > //moeglicherweise vorhandene ungewuenschte Einstellungen > zuruecksezten > options.c_cflag &= ~PARENB; //kein Parity-Bit > options.c_cflag &= ~CSTOPB; //ein Stopbit > options.c_cflag &= ~CSIZE; //Datenmaske zuruecksetzen > > //weitere Controllflags setzen > options.c_cflag = B19200 | CS8 | CLOCAL | CREAD; > options.c_iflag = IGNPAR; > options.c_oflag &= ~OPOST; > options.c_lflag = 0; > options.c_cc[VMIN] = 1; > options.c_cc[VTIME] = 0; > > tcflush(fd, TCIFLUSH); > tcsetattr(fd, TCSANOW, &options); > > return (fd); > } > > > So could anybody please help me? > > Thanks in advance > > Thomas
For me it looks like it should work, but I'm not an expert of setting termios structures. In one of our applications, we are using system(3) and the stty(1) program to set the serial line characteristics. If you can call system() it's much more easier to do (and to experiment with it). Besides this, I like to suggest some things: - Use an Scope to watch the serial interface if one single Byte is transmitted immediately. - store the current terminal settings, in case you have to restore - Don't use C++ comments in a C-program - and don't use bzero(3) it's deprecated -- use memset(3) in new programs. Regards Heinz -- | Heinz-J�rgen Oertel port GmbH http://www.port.de
Heinz-J�rgen Oertel wrote:

>>... > > For me it looks like it should work, but I'm not an expert of setting > termios structures. In one of our applications, we are using system(3) and > the stty(1) program to set the serial line characteristics. If you can > call system() it's much more easier to do (and to experiment with it). > > Besides this, I like to suggest some things: > - Use an Scope to watch the serial interface > if one single Byte is transmitted immediately. > - store the current terminal settings, in case you have to restore > - Don't use C++ comments in a C-program > - and don't use bzero(3) it's deprecated -- use memset(3) in new programs. > > > Regards > Heinz > > > -- > | Heinz-J�rgen Oertel port GmbH http://www.port.de
Thanks for your fast answer. What do you mean by "use an Scope"? What is that? I'm using interceptty for watching the serial port while communicating, but for single bytes it does not work. Here's the configuration of my serial port read with stty while my program was running: stty -F /dev/ttyS0 -a speed 19200 baud; rows 0; columns 0; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts -ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke Maybe that could help somebody finding the mistake... Thomas
On Sun, 30 Jan 2005 12:49:29 +0100, Thomas <thomas@tho-bai.de> wrote:


>Thanks for your fast answer. What do you mean by "use an Scope"? What is >that?
Google for oscilloscope :-). In practice, for serial line protocol debugging, the oscilloscope is only usable for detecting ACK/NAC characters. Paul
FWIW, anyone that debugs serial comms should check out an inexpensive 
(US$230) tool, the USBEE.  Way better than a scope because the tool can 
decode the bit patterns from I2C, SPI and regular old UART serial data.  It 
also is a generator so that you can transmit data into your UART. 
http://www.usbee.com/sx.html

I have used it for I2C and RS-485 UART data debugging and it has saved much 
time because I can't ever remember what order the bits come out.


Not affiliated with the company that sells the USBEE,

John G.


"Paul Keinanen" <keinanen@sci.fi> wrote in message 
news:70npv0933gaei6ra504dol8phi67hishv8@4ax.com...
> On Sun, 30 Jan 2005 12:49:29 +0100, Thomas <thomas@tho-bai.de> wrote: > > >>Thanks for your fast answer. What do you mean by "use an Scope"? What is >>that? > > Google for oscilloscope :-). > > In practice, for serial line protocol debugging, the oscilloscope is > only usable for detecting ACK/NAC characters. > > Paul >
Thomas wrote:
> Hi there, > > I've written a programme, to communicates with a microcontroller, but > sometimes there is no reaction when I send the initial byte. I'm working > under Suse Linux 9.2 prof. and as I know from a windows programme this > problem shouldn't be caused by the microcontroller. As it always works with > this programme under windows. > > So could it be, that when there is a failure at the microcontroller, so that > the byte isn't received (i.e. it isn't in bootstrap mode), that after this > the serial port might be blocked by the previous byte? Or somthing like > that. I know, that this byte cannot really "block" the serial port, but > there must be something that blocks the transfer. > > So is there a way to "flush" the serial port before starting a transfer? Or > is it something else that causes my problems. > > Hier is my procedure that initializes the serial port: > > int openport(char* device) > { > int fd; > struct termios options; > > //Stream oeffnen > fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
This could be a problem. Try omitting the O_NDELAY flag. Also, you might consider adding the O_SYNC flag (read about it first).
> //ueberpruefen > if (fd == -1)
This would be better as "if (fd < 0)" -- there is no guarantee that the number returned for an error is -1.
> //Alles auf Null setzen > bzero(&options, sizeof(options)); > > //aktuelle Einstellungen holen > tcgetattr(fd, &options); > > //moeglicherweise vorhandene ungewuenschte Einstellungen zuruecksezten > options.c_cflag &= ~PARENB; //kein Parity-Bit > options.c_cflag &= ~CSTOPB; //ein Stopbit > options.c_cflag &= ~CSIZE; //Datenmaske zuruecksetzen
// oder mit alles zusammen options.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
> //weitere Controllflags setzen > options.c_cflag = B19200 | CS8 | CLOCAL | CREAD; > options.c_iflag = IGNPAR;
options.c_iflag |= IGNPAR;
> options.c_oflag &= ~OPOST; > options.c_lflag = 0;
// these are the flags that I've used successfully options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
> options.c_cc[VMIN] = 1; > options.c_cc[VTIME] = 0; > > tcflush(fd, TCIFLUSH); > tcsetattr(fd, TCSANOW, &options);
// replace the two lines above with this to flush both input and output tcsetattr(fd, TCSAFLUSH, &options);
> return (fd); > } > > > So could anybody please help me?
I'm not sure -- while I've made some suggestions above, there's not really anything obviously wrong that would cause the symptoms you describe. I would suspect that it might be a problem on the micro end. One way you can check this is to run two computers back to back with a crossover cable (or the same one if you have multiple serial ports). In one terminal, run this program and run a serial term program in the other. Check for framing errors. Ed
Paul Keinanen wrote:

> On Sun, 30 Jan 2005 12:49:29 +0100, Thomas <thomas@tho-bai.de> wrote: > > >>Thanks for your fast answer. What do you mean by "use an Scope"? What is >>that? > > Google for oscilloscope :-). > > In practice, for serial line protocol debugging, the oscilloscope is > only usable for detecting ACK/NAC characters. > > Paul
I only suggested it to see if something is leaving the tty device, not necessarily to look what is inside. Heinz -- | Heinz-J&#4294967295;rgen Oertel port GmbH http://www.port.de