Discussion:
RTEMS interrupt help for UART
lmatthews_leonhelp
2011-01-11 16:56:11 UTC
Permalink
Hi

I'm using the RTEMs RTOS in order to develop an application for an Aeroflex Gaisler LEON3 processor that is running on a Pender GR-CPCI-AX2000 development board.

My application needs to read data in from the serial port and then forward it over a spacewire link. I have been using the example "rtems-uart-loopback.c" found in the "C:\opt\rtems-4.10-mingw\src\samples" directory as a base.

However I seem to be losing bytes when they arrive in rapid succession at the serial port. This occurs when the baud rate is set to 115200 or 9600, I imagine that it occurs for other rates also.

If I set a long delay (about 500ms) between the transmission of each byte on the transmitter, everything seems to work ok.

I presume that the standard reception mode uses polling?

I imagine that configuring my software to use UART interrupts would be a better solution. Does anyone have any example code or a tutorial that explains how to setup UART reception via interrupts?

Thanks in advance,

Lee Matthews


-- A snippet of my code


console='b';
sprintf(buf, "/dev/console_%c", console);
printf("Trying to open console : %s\n",buf);
fd = open(buf, O_RDWR);
if ( fd < 0 ) {
printf("Failed to open %s.\nNumber of consoles available: %d\nCause open failed, ERRNO: %d = %s\n\n\n",buf,(console-'b')+1,errno,strerror(errno));
exit(0);
}

/* Get current configuration */
tcgetattr(fd, &term);

/* Set Console baud to 38400, default is 38400 */
cfsetospeed(&term, B9600);
cfsetispeed(&term, B9600);

term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Raw input mode

term.c_cflag |= (CLOCAL | CREAD);

/* Update driver's settings */
tcsetattr(fd, TCSANOW, &term); // Update immediately

fflush(NULL);

while(1)
{
bytes_read=read(fd, &buf[0], 300);

if(bytes_read>0)
{
printf("Received %d bytes. \n",bytes_read);

for(i=0;i<bytes_read;i++)
{
printf("Binary field value : "BYTETOBINARYPATTERN" \\x%02x\n", BYTETOBINARY(buf[i]),buf[i]);
}
}
}







------------------------------------
Daniel Hellstrom
2011-01-12 10:25:07 UTC
Permalink
Hello,

Please use the latest RTEMS distribution (15a or later) since it has a
fix for APBUART in interrupt mode.

/opt/rtems-4.10/src/rtems-hello.c demonstrates how the System console
and the debug output can be configure to a certain UART, and how
interrupt mode can be configured by setting "mode" to 1.

Default is polling mode.

Regards
Daniel Hellstrom
Post by lmatthews_leonhelp
Hi
I'm using the RTEMs RTOS in order to develop an application for an
Aeroflex Gaisler LEON3 processor that is running on a Pender
GR-CPCI-AX2000 development board.
My application needs to read data in from the serial port and then
forward it over a spacewire link. I have been using the example
"rtems-uart-loopback.c" found in the
"C:\opt\rtems-4.10-mingw\src\samples" directory as a base.
However I seem to be losing bytes when they arrive in rapid succession
at the serial port. This occurs when the baud rate is set to 115200 or
9600, I imagine that it occurs for other rates also.
If I set a long delay (about 500ms) between the transmission of each
byte on the transmitter, everything seems to work ok.
I presume that the standard reception mode uses polling?
I imagine that configuring my software to use UART interrupts would be
a better solution. Does anyone have any example code or a tutorial
that explains how to setup UART reception via interrupts?
Thanks in advance,
Lee Matthews
-- A snippet of my code
console='b';
sprintf(buf, "/dev/console_%c", console);
printf("Trying to open console : %s\n",buf);
fd = open(buf, O_RDWR);
if ( fd < 0 ) {
printf("Failed to open %s.\nNumber of consoles available: %d\nCause
open failed, ERRNO: %d =
%s\n\n\n",buf,(console-'b')+1,errno,strerror(errno));
exit(0);
}
/* Get current configuration */
tcgetattr(fd, &term);
/* Set Console baud to 38400, default is 38400 */
cfsetospeed(&term, B9600);
cfsetispeed(&term, B9600);
term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Raw input mode
term.c_cflag |= (CLOCAL | CREAD);
/* Update driver's settings */
tcsetattr(fd, TCSANOW, &term); // Update immediately
fflush(NULL);
while(1)
{
bytes_read=read(fd, &buf[0], 300);
if(bytes_read>0)
{
printf("Received %d bytes. \n",bytes_read);
for(i=0;i<bytes_read;i++)
{
printf("Binary field value : "BYTETOBINARYPATTERN" \\x%02x\n",
BYTETOBINARY(buf[i]),buf[i]);
}
}
}
------------------------------------

Loading...