Skip to main content
Visitor II
August 12, 2021
Question

getchar not working

  • August 12, 2021
  • 4 replies
  • 2123 views

I have a STM32L4R5 STM32CubeIde project using FreeRTOS.

I have implemented _read(), _write() etc. to use UART for I/O.

printf() is working fine.

I can read characters from stdin using read(0, &mychar, 1) but getchar() does not work.

I've traced through getchar() execution and found that it is only calling _read() the first time it is called when it is doing a bunch of initialization.

On subsequent calls __sresill_r() is not calling _read().

I tried making stdin unbufferd by calling setvbuf(stdin, NULL, _IONBF, 0) before getchar(). Didn't change anything.

Any suggestions on how to fix this?

If not can I get the library source and project that builds it.

Randy

    This topic has been closed for replies.

    4 replies

    Super User
    August 15, 2021

    STMCubeIde uses newlib https://sourceware.org/git/newlib-cygwin.git. You may look at the implementation (newlib/libc), but I'm not aware of official patch+build instructions. How did you implement _read, what is the return value?

    hth

    KnarfB

    RHerm.3Author
    Visitor II
    August 16, 2021

    Is ST using the latest newlib, 4.1.0? Have they done anything to port it to their processors?.

    The uart driver called by _read() is pulling characters from a ring buffer. The ST HAL RX callback that places characters into the ring buffer.

    If I use read(x,*char, 1) it works fine. Only having a problem with getchar().

    Here is my _read() implementation:

    int _read(int file, char *ptr, int len)

    {

    int uartRtn;

    // check file for valid value

    if ((file < 0) || (file >= ioNumHandles))

    { // bad handle

    return BAD_FILE_ID;

    }

    // read from the uart

    uartRtn = uartRead(ioHandleArray[file].hUart, (BYTE*) ptr, len);

    if (file == 0)

    {

    STDINreads++;

    }

    return uartRtn;

    }

    And here is my uartRead implementation:

    int uartRead(UART_HandleTypeDef *hUart, BYTE *buffer, int nbytes)

    {

    int numBytes = 0;

    uartDrvStruct *drv = NULL;

    // find the matching uart driver structure

    drv = uartGetDrvStruct(hUart);

    // bad handle

    if (drv == NULL)

    {

    return UART_BAD_UART;

    }

    // Driver will not be Opened unless intialized

    // Only check open state

    if (drv->opened != TRUE)

    {

    return UART_NOT_OPEN;

    }

    // disable the uart interrupt

    HAL_NVIC_DisableIRQ(drv->irq);

    // get bytes from RX ring buffer

    numBytes = rngBufGet(drv->rxRingBuf, buffer, nbytes);

    // enable interrupt

    HAL_NVIC_EnableIRQ(drv->irq);

    if (hUart == &hDEBUGSIO)

    {

    DebugUartReads++;

    }

    return numBytes;

    }

    Super User
    August 16, 2021

    Is there a summary of changes for the newlib 4.1.0 shipped with new toolchain? What we need to know?

    Super User
    August 16, 2021

    > Is ST using the latest newlib, 4.1.0?

    No. There is a version file. On my STM32CubeIDE 1.7.0 (STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_2.0.0.202105311346\tools\arm-none-eabi\include\_newlib_version.h), it says

    #define _NEWLIB_VERSION "3.3.0"

    > Have they done anything to port it to their processors?

    Wish I knew where to look for that.

    man getchar says: "return the character read as an unsigned char cast to an int or EOF on end of file or error." So, there is simply no third option returning "there is currently no character available". Think the issue is when your ring buffer is empty and you return 0 for numBytes. You could implement an additional chars_avail() function returning the momentary size of the read buffer.

    hth

    KnarfB

    RHerm.3Author
    Visitor II
    August 16, 2021

    I plan on going through the newlib source for getchar() to determine why it on;y works on the 1st call.

    Need to know if ST modified anything or provided port implementations that are called.