Termios: Non-blocking read() working? .-

Sebastian E. Garcia sg-listas at slabs.com.ar
Mon Jun 11 08:09:31 UTC 2012


I've been looking at the Termios code present in RTEMS 4.10, both 
mainstream and Gaisler's port.
So, I have some comments. Apologies if these are trivial ones; I'm just 
not acquainted with Termios' code.


1. Gaisler's UART ISR and rtems_termios_enqueue_raw_characters function 
seems OK at first glance.


2. Looking at fillBufferQueue function [termios.c:996] that loads the 
"cooked buffer" tty->cbuf from the circular queue tty->rawInBuf.theBuf 
(see line with added comment "SG" ):

static rtems_status_code
fillBufferQueue (struct rtems_termios_tty *tty)
{
   rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout;
   rtems_status_code sc;
   int               wait = 1;

   while ( wait ) {
     /*
      * Process characters read from raw queue
      */
     while ((tty->rawInBuf.Head != tty->rawInBuf.Tail) &&
                        (tty->ccount < (CBUFSIZE-1))) {
       unsigned char c;
       unsigned int newHead;

       newHead = (tty->rawInBuf.Head + 1) % tty->rawInBuf.Size;
       c = tty->rawInBuf.theBuf[newHead];
       tty->rawInBuf.Head = newHead;

<snip>

       /* continue processing new character */
       if (tty->termios.c_lflag & ICANON) {
         if (siproc (c, tty))
           wait = 0;
       } else {
         siproc (c, tty);
/* SG the following fails for the expected behavior when VMIN==0 */
         if (tty->ccount >= tty->termios.c_cc[VMIN])
           wait = 0;
       }
       timeout = tty->rawInBufSemaphoreTimeout;
     }

     /*
      * Wait for characters
      */
     if ( wait ) {
       sc = rtems_semaphore_obtain(
         tty->rawInBuf.Semaphore, tty->rawInBufSemaphoreOptions,
         timeout);
       if (sc != RTEMS_SUCCESSFUL)
         break;
     }
   }
   return RTEMS_SUCCESSFUL;
}



Without having so much experience with Termios, the behavior I expect 
when VTIME==VMIN==0, is to read at once (non-blocking):
  Min{No. of bytes requested by read(); No. of bytes in the raw buffer}
, and return ASAP.
But in this code, when VMIN==0, only one char from the raw buffer gets 
copied.
Am I wrong? Any comments will be greatly appreciated.


Best regards,
Sebastian.




On 06/08/2012 04:31 PM, Sebastian E. Garcia wrote:
> Hi there,
>
> After some tests, I'm in doubt if this feature of Termios is implemented
> in RTEMS/LEON3_BSP.
> Environment: Target LEON3/GRLIB 4113 ; RTEMS 4.10 ; RCC 1.2.0. Termios
> configured in raw mode for an APBUART.
> (I recently made a similar post to the LEON_SPARC mailing list)
>
> Have one UART receiving binary data packets. Periodically, I need
> to read the Rx SW buffer, as fast as possible. A GPIO IRQ releases a
> semaphore, signaling that a whole new (<150bytes) packet arrived.
> The behaviour I intend is the following: BSP/Termios filling the SW
> buffer using UART's Rx IRQ. And a periodic access to this SW buffer
> using a non-blocking read() function called from a given task,
> (requesting more than 150bytes).
>
> Can't achieve a non-blocking read of more than one byte at a time.
> The blocking Termios configuration variants seems to work OK with read().
> For the (desired) non-blocking operation, I've tried opening with
> O_NONBLOCK parameter, and setting Termios with VMIN=VTIME=0.
> But the output of the read() function is always 1 byte long when I set
> these non-blocking configs.
>
> I suspect there's something with the interaction between the BSP driver
> and Termios, I may be forgetting some configuration, or simply this
> feature was not implemented.
> Any pointers, known-good non-blocking configuration, or workaround will
> be greatly appreciated, before diving into RTEMS code.
>
>
> Regards,
> Sebastian.-





More information about the users mailing list