Page 1 of 1

Serial Flush

Posted: Tue Mar 08, 2011 2:16 pm
by k1mgy
Board: MOD5270B
NNDK: Rel24_rc2

It's a bit frustrating not having termios, so I am trying to work around this.

I noticed that there's a termios.h file which references sys/termios.h. The reference does not exist, so including termios.h just generates an error. Not certain why it's in the tools.

I need the equivalent of tcflush(). Might be able to do without some of the other things, but this is an important function. I don't see any equivalent. Can anyone suggest how to emulate this?

Re: Serial Flush

Posted: Tue Mar 08, 2011 3:25 pm
by tod
I've never used termios and know nothing about it so I may not fully understand your question.

I would think you just want to do all your serial I/O through a SerialClass you write. In that class you will have a method that uses write() - as opposed to using writeall() - in a loop that checks for your flush flag . In the read you use ReadWithTimeout() - as opposed to read() - in a loop and also check for a flush flag. When the class flush flag gets set you just stop reading and stop writing. You can empty the class data structures that hold the partially collected or sent data if you desire.

Re: Serial Flush

Posted: Tue Mar 08, 2011 3:38 pm
by lgitlitz
I am not completely familiar with termios but I believe the flush will throw away all data in the software RX and TX buffers, correct?

If you just want to flush the RX buffer this is rather simple:
char TempBuff[256];
while( ReadWithTimeout( SerialFD, TempBuff, 256, 0 ) );

If you want to do this for both RX and TX call SerialClose on the port and then reopen it.

Just flushing the TX is a tough one. A new function in serial.cpp probably needs to be written to get this done. It would be mostly code form the serialclose function. You would need to remove any RX stuff, m_UartState|= UART_TX_EMPTY; and SetWriteAvail. The main code should all be encapsulated between USER_ENTER_CRITICAL(); and USER_EXIT_CRITICAL(); so the serial interrupt routine wont jump in.

Re: Serial Flush

Posted: Tue Mar 08, 2011 4:04 pm
by k1mgy
You can specify which buffer to flush, or both. In my case, flushing the receive buffers will do fine.

Your ReadWithTimeout() is a good suggestion. Perhaps not as efficient as pulling the bathtub plug directly on the internal buffer, but it will work.

On your suggestion I'll have a look at serial.cpp. Maybe I can hack a tcflush() there.

Thanks very much indeed.

Re: Serial Flush

Posted: Tue Mar 08, 2011 4:15 pm
by rnixon
Another way to do it without causing a block is to call dataavail(fd) first, before calling any read function. That way you know read() or any variation thereof, will return right away. This is because the read functions will block until at least one char is read. Just going from memory here, but I'm thinking of something like

void SerialRxFlush(int fd)
{
static char buf[2048];

if (dataavail(fd))
read(fd, buf, 2048);
}

Please correct me if I've made a coding error. but I think this works. A standard buffer size is 1500 bytes (per buffer), so 2048 seemed like a good number. Be sure to make the buffer static so it goes in global ram space.

Re: Serial Flush

Posted: Tue Mar 08, 2011 4:21 pm
by lgitlitz
A much more efficient "tcflush" can definitely be written at the serial driver level(serial.cpp). Just be careful that you configure any required flags for the m_UartState and also properly adjust the Set/Clr for the file descriptor. USER_ENTER_CRITICAL will protect against the interrupt or another task firing while you are flushing any of the fifos.
Another way to do it without causing a block
I used ReadWithTimeout with a timeout value of 0 to avoid any blocking. If there is no data available it immediately returns a timeout error = 0.

-Larry

Re: Serial Flush

Posted: Thu Mar 10, 2011 9:10 am
by k1mgy

Code: Select all

BOOLEAN FlushPort(void)
{
	int rv = 0;
	rv = ReadWithTimeout(fd, NULL, 1024, 10);
	if (rv<0)
		iprintf("FlushPort():Error %i\n",rv);
	return (true);
}
Note: ReadWithTimeout(fd, NULL, 1024,0); blocks.

serial.cpp:
* Waits for a specified amount of time (in ticks) for data to be available for
* reading from a specified UART. Using zero ticks specifies no time-out.


It is unfortunate that
rv = ReadWithTimeout(fd, NULL, NULL, 10);
does not error.

It would be nice if a NULL for the number of characters would read the entire buffer by default.