Send/Receive serial data using console driver on LEON3
Ajish Babu
babu.ajish at googlemail.com
Mon Nov 5 14:40:24 UTC 2012
Hi guys,
I am new to RTEMS and am trying to build a motor controller with LEON3
architecture.
I have set the console to use it in "raw-mode". I tried my code in both
polling-mode and interrupt-mode of the console.
In polling-mode, it works, it takes up a lot of cpu (~70% @ 90MHz) and
it looses data if it runs any slower. It is effectively useless for
running the controller.
In interrupt-mode, at first nothing worked. The console was being opened
twice by RTEMS causing an error. Then I figured out a bug in the console
driver and modified it to sort it out. It now works, but creates
segmentation fault after running for sometime, the cause of which I
can't figure out.
Am I doing it the wrong way? Is the console bug fix somehow causing the
segmentation fault? Is it a bad idea to use the console driver for this?
I need to use it to send and receive lots of data. Any help would be
appreciated !!!!!!
regards
Ajish Babu
/my code: /
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_MAXIMUM_TASKS 3
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 10
#define CONFIGURE_INIT
#define CONFIGURE_MICROSECONDS_PER_TICK 1000
#include <rtems/confdefs.h>
rtems_id tid_print, tid_read;
extern int errno;
unsigned int size, data_length;
int serialPort;
char buffer[255];
char data[255];
void assert_status(rtems_status_code status)
{
if ( status != RTEMS_SUCCESSFUL ) {
printk( "RTMES assertion failed with status of %d.\n", status );
exit( 1 );
}
}
void OpenPort()
{
size = 0;
data_length = 0;
assert_status( rtems_termios_bufsize( 1024, 512, 512 ) );
// Opens console for writing
serialPort = open("/dev/console", O_RDONLY );
if (serialPort == -1)
{
printk("Opening Console error: %s", strerror(errno));
exit( 1 );
}
struct termios config;
// gets the current configuration
tcgetattr( serialPort, &config);
// Raw mode
config.c_iflag &=
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
config.c_oflag &= ~OPOST;
config.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
config.c_cflag &= ~(CSIZE|PARENB);
config.c_cflag |= CS8;
cfsetospeed( &config, B19200 );
cfsetispeed( &config, B19200 );
// Sets the modified configuration
if(tcsetattr(serialPort, TCSANOW, &config) < 0)
{
printk("\nERROR: Set console attribites : %s\n", strerror(errno));
}
}
rtems_task ReadStream(rtems_task_argument argument)
{
int i;
OpenPort();
do
{
// Reads the data
size = read( serialPort, buffer, 255 );
if( size > 0 )
{
// Stores the data to print it in PrintData
for( i = 0; i < size; i++ )
{
data[data_length++] = buffer[i];
if( data_length >= 255 )
data_length = 0;
}
data[data_length] = '\0';
}
}
while( 1 ); //rtems_clock_get_ticks_since_boot() < 60000 );
close( serialPort );
rtems_cpu_usage_report();
assert_status( rtems_task_delete( tid_print ) );
assert_status( rtems_task_delete( RTEMS_SELF ) );
}
rtems_task PrintData(rtems_task_argument argument)
{
while(1)
{
printk("DATA: \n");
rtems_print_buffer( (unsigned char *)data, data_length );
rtems_task_wake_after( 1000 );
}
assert_status( rtems_task_delete( RTEMS_SELF ) );
}
rtems_task Init( rtems_task_argument argument )
{
assert_status(
rtems_task_create(
rtems_build_name( 'R', 'E', 'A', 'D' ),
2,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_PREEMPT,
RTEMS_NO_FLOATING_POINT,
&tid_read
)
);
assert_status(
rtems_task_create(
rtems_build_name( 'P', 'R', 'I', 'N' ),
1,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_PREEMPT,
RTEMS_NO_FLOATING_POINT,
&tid_print
)
);
assert_status( rtems_task_start( tid_print, PrintData , 0 ) );
assert_status( rtems_task_start( tid_read , ReadStream , 0 ) );
assert_status( rtems_task_delete( RTEMS_SELF ) );
}
/Modified console.c code changes//:/
...
volatile int sending;
char *buf;
* int irq_open;*
#endif
...
#if CONSOLE_USE_INTERRUPTS
apbuarts[uarts].irq = apb->irq;
* apbuarts[uarts].irq_open = 0;*
#endif
....
/* Register Interrupt handler */
* if (!uart->irq_open) {*
sc = rtems_interrupt_handler_install(uart->irq, "console",
RTEMS_INTERRUPT_SHARED, console_isr,
uart);
if (sc != RTEMS_SUCCESSFUL)
return sc;
* }**
** uart->irq_open++;*
uart->sending = 0;
....
/* uninstall ISR */
* uart->irq_open--;**
** if (!uart->irq_open) {*
rtems_interrupt_handler_remove(uart->irq, console_isr, uart);
* }*
#endif
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20121105/df63eef2/attachment.html>
More information about the users
mailing list