Skip to main content
Graduate
December 9, 2023
Solved

stm32h747 GETCHAR_PROTOTYPE strangeness

  • December 9, 2023
  • 2 replies
  • 2092 views

Hi Guys,

This is driving me mad!

So this works perfectly echoing characters via uart8:

 

 

int ch = 'A';
while (1)
{
 HAL_UART_Transmit(&huart8, (uint8_t *)&ch, 1, 0xFFFF);
 HAL_UART_Receive(&huart8, (uint8_t *)&ch, 1, 0xFFFF);
}

 

 

Now if I have getchar and put char implementations:

 

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(void)

PUTCHAR_PROTOTYPE
{
 HAL_UART_Transmit(&huart8, (uint8_t *)&ch, 1, 0xFFFF);
 return ch;
}

GETCHAR_PROTOTYPE
{
	uint8_t ch;
	__HAL_UART_CLEAR_OREFLAG(&huart8);
	HAL_UART_Receive(&huart8, &ch, 1, 0xFFFF);
 return ch;
}

 

 

The following does not work, we do not get anything received and get stuck in UART_WaitOnFlagUntilTimeout() called from HAL_UART_Receive() from __io_getchar():

 

 while (1)
{
 HAL_UART_Transmit(&huart8, (uint8_t *)&ch, 1, 0xFFFF);
 ch = getchar();
}

 

 

However if I directly call __io_getchar() everything works perfectly, UART data is received:

 

while (1)
{
 HAL_UART_Transmit(&huart8, (uint8_t *)&ch, 1, 0xFFFF);
 ch = __io_getchar();
}

 

 

Has anyone any idea why __io_getchar() called directly is working and when called indirectly it isn't, no UART data?

 

Cheers


Andy

    This topic has been closed for replies.
    Best answer by TDK

    With this code:

    TDK_0-1702132385527.png

    We get this after one getchar() call:

    TDK_1-1702132421276.png

    You can set the input to unbuffered to get only a single call.

    setvbuf(stdin, NULL, _IONBF, 0);

     

    2 replies

    Super User
    December 9, 2023

    Input is buffered, so when you request a char, it reads a large number of inputs (in this case, 1024), before giving you the one you requested.

    TDKAnswer
    Super User
    December 9, 2023

    With this code:

    TDK_0-1702132385527.png

    We get this after one getchar() call:

    TDK_1-1702132421276.png

    You can set the input to unbuffered to get only a single call.

    setvbuf(stdin, NULL, _IONBF, 0);

     

    ACapo.1Author
    Graduate
    December 9, 2023

    Hi @TDK 

    Thanks so much, that was driving me mad!