AnsweredAssumed Answered

KSDK 1.1.0 getchar() does not return EOF

Question asked by Scott Whitney on Apr 9, 2015
Latest reply on Jun 9, 2015 by Scott Whitney

Hi folks, I have started using KSDK 1.1.0 with the TWR-K60D100M.  I can build and run the "hello world" demo without problem, but it seems that getchar() exhibits non-standard behavior.  Instead of returning EOF if no character is available, it blocks.

 

I'm using the IAR 7.40.2 ARM tools for Cortex-M.  I'm not using MQX or any other RTOS.  The application I will be developing is a "bare metal" super-loop.

 

I think the offending area in the KSDK code is in the implementation of _read(), in fsl_debug_console.c.  Here it is:

 

#pragma weak __read

size_t __read(int handle, unsigned char * buffer, size_t size)

{

    /* This function only reads from "standard in", for all other file*/

    /* handles it returns failure.*/

    if (handle != _LLIO_STDIN)

    {

        return _LLIO_ERROR;

    }

 

    /* Do nothing if the debug uart is not initialized.*/

    if (s_debugConsole.type == kDebugConsoleNone)

    {

        return _LLIO_ERROR;

    }

 

    /* Receive data.*/

    s_debugConsole.ops.rx_union.Receive(s_debugConsole.baseAddr, buffer, size);

 

    return size;

}

 

The Receive() function above in turn calls UART_HAL_ReceiveDataPolling(), from fsl_uart_hal.c.  Here's the code:

 

uart_status_t UART_HAL_ReceiveDataPolling(uint32_t baseAddr,

                                          uint8_t *rxBuff,

                                          uint32_t rxSize)

{

    uart_status_t retVal = kStatus_UART_Success;

 

    while (rxSize--)

    {

        while (!UART_HAL_IsRxDataRegFull(baseAddr))

        {}

 

        UART_HAL_Getchar(baseAddr, rxBuff++);

       

        /* Clear the Overrun flag since it will block receiving */

        if (BR_UART_S1_OR(baseAddr))

        {

            HW_UART_S1_RD(baseAddr);

            HW_UART_D_RD(baseAddr);

            retVal = kStatus_UART_RxOverRun;

        }

    }

 

    return retVal;

}

 

The loop while (!UART_HAL_ISRxDataRegFull(baseAddr)) guarantees that this function won't return until a character is actually received.  According to all the C references I have read, it _should_ return an EOF is there isn't a character available.  That way the code could poll for a character, and if it gets EOF, just skip to the next step in my super-loop.

 

In pseudocode, something like this:

 

while (1)

{

     int c;

 

     while ((c = getchar()) != EOF)

     {

          // Add the character to an input buffer

          // See if it's the end of the line

          // If so, parse the line and decide what command to execute

     }

 

     RunTask1();     // Functions that perform some kind of ongoing action, like reading ADC values, scanning GPIO lines, etc.

     RunTask2();

     // etc.

}

 

Have any of you run into this situation?  How did you keep getchar() from blocking?  I could rewrite the _read() function to do what I need, but I'm a little surprised at the default behavior of the fsl_debug_console.

 

As a next step, I would like to run the UART transmit and receive in interrupt-driven mode to avoid polling altogether, perhaps only checking to see if an entire input line has been received.  Do any of you have examples of how to set up a UART in interrupt mode with buffers for transmit and receive?  And down the line, there will be two UARTs, one that accepts commands from a PC and one to dump out debug information (and maybe accept some simple debug commands).

 

Many thanks for your help!

Outcomes