Home/Support/Support Forum/Flushing FIM receive buffers
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

Flushing FIM receive buffers

0 votes
Has anyone had a problem using tcflush() on the FIM serial port on the ME9210?

I had a problem where the FIM refused to receive, which I've currently resolved by disabling calls to tcflush() for the FIM
asked Nov 12, 2010 in Linux by steved2 Seasoned Professional (151 points)
recategorized Dec 5, 2013 by tuxembb

Please log in or register to answer this question.

6 Answers

0 votes
Instead of tcflush what are you doing to clear receive buffer? i will soon be using fim serial port.
answered Nov 12, 2010 by dpitts New to the Community (9 points)
0 votes
Quote:
Instead of tcflush what are you doing to clear receive buffer? i will soon be using fim serial port.
At the moment, nothing - I just reset various receive-related variables. (In my particular application its pretty unlikely that there would be anything in the receive buffer at the time I was flushing it, and the application would recover soon enough)
answered Nov 17, 2010 by steved2 Seasoned Professional (151 points)
0 votes
It appears that this might have been one symptom of a bigger problem with the FIM.
I now have my software basically running, and find that the FIM-based UART stops receiving after a random time of order 50-100 minutes. Reset requires power cycling or reboot.
The FIM isn't being worked particularly hard - fairly continuous 9600 baud half-duplex, as a 2-wire UART.

The software driving the FIM is pretty much the same as I've been using for years with a 'normal' UART in the ME; main change is use of select() when waiting for receive data.

Has anyone else seen this type of problem (or got the FIM working without such problems)?
answered Nov 24, 2010 by steved2 Seasoned Professional (151 points)
0 votes
I've used FIM as UART with func. like that, and i haven't observe problems:

//
Open UART RAW
//Open FIM module as a com port!
//
int OpenUARTRaw( const char * pszDev)
{
int hFile = open( pszDev, O_RDWR | O_NOCTTY );
struct termios options;
if( 0 > hFile )
{
return -1;
}
tcgetattr(hFile, &options);

cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
cfmakeraw( &options );

tcsetattr(hFile, TCSANOW, &options);
return hFile;
}
//
//
//
int PollRead( int hFile )
{
struct pollfd arrHFiles[1];
arrHFiles[ 0 ].fd = hFile;
arrHFiles[ 0 ].events = POLLIN;
if( 0>= poll(arrHFiles, 1, 100) )
return 0;
if( arrHFiles[ 0 ].revents & POLLIN )
return 1;
return 0;
}
//
ReadByte
//Reads a Byte from serial FIM0
//
unsigned char ReadByte( int hFile )
{
unsigned char ucIn;
if( 0 > read( hFile, &ucIn , 1 ) )
exit( 0 );
return ucIn;

}

//
ReadByte
//Write a Byte to serial FIM0
//

void WriteByte( int hFile, unsigned char ucOut )
{

if( 0 > write( hFile, &ucOut , 1 ) )
exit( 0 );
}



.......................Somewhere in main....................
hFile = OpenUARTRaw( "/dev/ttyFIM0");
if( 0 > hFile )
return 1;

.........................................................................



I.m not sure is it helpful for you but it is works fine.
Cheers
Danail
answered Nov 25, 2010 by MYXATA New to the Community (9 points)
0 votes
Given the feedback, I've done some more extensive testing, and encountered errors using the FIM UART where the 'normal' UART is rock solid.

1. No doubt that tcflush(channel, TCIFLUSH) on /com/4 wrecks receive.

2. I have a board with serial buffers on both /com/0 and /com/4 (FIM). So to eliminate potential problems with my own code, I compiled the TCP/IP to Serial example for each of the ports - literally the only difference being the last digit of the port name.
I then connected a piece of equipment which responds to polls to the serial port, and used a network app to generate the polls and display the responses, using TCP/IP. So the serial port is operating in half duplex, 9600,e,7.
a) Using /com/0 polling continued for the 60 minutes over which I tested. Throughput about 470 cps. (Second test of 30 minutes no problems)
b) Using /com/4 polling started OK, with a throughput of around 680cps. It ceased after about 7 minutes (repeated several times, and pretty consistent).
Happened after 8189 or 8190 transactions (suspiciously close to 8192?)
A breakpoint shortly after the select() (line 470 of tcpserial.c) demonstrated that select() was never picking up on data received from the network.

I tried increasing the stack size for the serial task, with no change.

3. Using my own code, I get a slightly different problem - it appears as if every so often the FIM fails to send a message. Again, errors using FIM, rock solid using /com/0.

So it looks as if the problem is somewhere in the FIM driver. Related to select(), maybe?

Any thoughts on how to track this down?
answered Dec 7, 2010 by steved2 Seasoned Professional (151 points)
0 votes
Found most of the problem - the FIM driver is subtly different to that for the regular serial ports.

I'm using 2-wire serial, and can be confident the transmit buffer is empty when I send a new message. So my code assumed that write() will always succeed. (And on the regular serial ports, this appears to have been the case).

However... the FIM uses a buffer, with capacity for 8K characters. And the code doesn't automatically wrap round during a single write() when the end of the buffer is reached. So sometimes write() wouldn't send a complete message. It correctly returned that it had only added part of the message to the send buffer, and now I handle this scenario that part is working OK. Technically correct behaviour, but perhaps counter-intuitive!

The timeouts look as if they're being caused by a related wrapround problem - if my message exactly fills the remaining space at the end of the transmit buffer (and its wrapping round after 8191 characters rather than 8192, which masks the problem somewhat) the transmit side appears to irretrievably lock up.
answered Dec 10, 2010 by steved2 Seasoned Professional (151 points)
...