hello :
env : all case test on xilinx zynqmp ultra96 board with 4 A53 (smp)
bsp : xilinx zynqmp ultra96
version: rtems 5.1

I see,RTEMS have three console driver to use, but all driver are does not work properly in same case. Description and analysis are as follows

1.CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
This driver do not work very well on SMP. If i create 4 task , all task use printf to output message, all message are out-of-order. 
Maybe the function "_Console_simple_Write" shoule be locke when output message( Maybe this will affect concurrency ) . My test code like follows
==========================
 #include "consolesimple.h"
 
+RTEMS_INTERRUPT_LOCK_DEFINE( static, rtems_zynq_uart_bsp_lock, "rtems_zynq_uart_bsp_lock" );
 static ssize_t _Console_simple_Write(
   rtems_libio_t *iop,
   const void    *buffer,
@@ -48,9 +49,12 @@ static ssize_t _Console_simple_Write(
   buf = buffer;
   n = (ssize_t) count;
 
+  rtems_interrupt_lock_context lock_context;
+  rtems_interrupt_lock_acquire(&rtems_zynq_uart_bsp_lock, &lock_context);
   for ( i = 0; i < n; ++i ) {
     rtems_putc( buf[ i ] );
   }
+  rtems_interrupt_lock_release(&rtems_zynq_uart_bsp_lock, &lock_context);
 
   return n;
 }

==========================

2.CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
When I use this driver On smp , the RTEMS will crash.
My test case like this : create 4 task , all task use printf to output message,After some time, the system will crash.


3.CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
This driver has a bug. If this BUG is triggered, the shell will work abnormally, such that top command (and other commands) will not display any information, all printf will return -1,because the console is EOF . And let the system run for a while after this BUG appears, it may crash 
analysis are as follows:
I find _Console_simple_task_Write will return 0 when _Console_simple_task_Instance.buf if full.code follows

==========================
static ssize_t _Console_simple_task_Write(
  rtems_libio_t *iop,    
  const void    *buffer, 
  size_t         count   
)                        
{
  ...............
    rtems_interrupt_lock_release( &cons->buf_lock, &lock_context );   
                                                                      
    if ( junk == 0 ) {                                                
      break;                                                                                                           
    }                                                                 
  }                                                                   
                                                                      
  rtems_event_system_send( cons->task, RTEMS_EVENT_SYSTEM_SERVER );   
                                                                      
                                                                                              
  return (ssize_t) ( count - todo );       //      can not return 0                      
}
==========================

if junk is 0 , return will be 0, but you can see NEWLIBC code , when _Console_simple_task_Write return 0 , then fd will become EOF (see trace _puts_r ---> __sfvwrite_r --->_fflush_r ---->__sflush_r ). so maybe there can not return 0.  
I find when junk == 0 , use "break" , maybe Perhaps to resolve scheduling deadlocks (the _Console_simple_task_Task's priority is too low,when other high priority output , _Console_simple_task_Task and and high priority task will deadlock).but i think this function can not return 0 .  maybe i will drop some message . and  always return then len of the mesage. 
the task priority should config by USER . so user can configure priority correctly.
My test code follow , the priority of _Console_simple_task_Task use 128 (some as my other task , and all other us time slice). I testd and work well. 

==========================

static Console_simple_task_Control _Console_simple_task_Instance;
 
+
+size_t lcx_head;
+size_t lcx_tail;
+
 static size_t _Console_simple_task_Capacity(
   const Console_simple_task_Control *cons
 )
@@ -97,6 +102,10 @@ static ssize_t _Console_simple_task_Write(
 
     junk = _Console_simple_task_Capacity( cons );
 
     if ( junk > todo ) {
       junk = todo;
     }
@@ -116,15 +125,23 @@ static ssize_t _Console_simple_task_Write(
 
     cons->head = head;
 
     rtems_interrupt_lock_release( &cons->buf_lock, &lock_context );
 
     if ( junk == 0 ) {
-      break;
+      //break;
+      continue;
     }
   }
 
   rtems_event_system_send( cons->task, RTEMS_EVENT_SYSTEM_SERVER );
 
   return (ssize_t) ( count - todo );
 }


@@ -235,7 +256,8 @@ void _Console_simple_task_Initialize( void )
 
   rtems_task_create(
     rtems_build_name('C', 'O', 'N', 'S'),
-    RTEMS_MAXIMUM_PRIORITY - 1,
+    //RTEMS_MAXIMUM_PRIORITY - 1,
+    128,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_ATTRIBUTES,
     RTEMS_DEFAULT_MODES,


==========================
_______________________________________________
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users

Reply via email to