Serial Flush

Discussion to talk about software related topics only.
Post Reply
k1mgy
Posts: 24
Joined: Thu Oct 14, 2010 8:25 am

Serial Flush

Post 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?
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: Serial Flush

Post 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.
User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Serial Flush

Post 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.
k1mgy
Posts: 24
Joined: Thu Oct 14, 2010 8:25 am

Re: Serial Flush

Post 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.
rnixon
Posts: 833
Joined: Thu Apr 24, 2008 3:59 pm

Re: Serial Flush

Post 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.
User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Serial Flush

Post 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
k1mgy
Posts: 24
Joined: Thu Oct 14, 2010 8:25 am

Re: Serial Flush

Post 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.
Post Reply