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