cancel
Showing results for 
Search instead for 
Did you mean: 

stm32h747 GETCHAR_PROTOTYPE strangeness

ACapo.1
Senior

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

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

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);

 

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

4 REPLIES 4
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".
TDK
Guru

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);

 

If you feel a post has answered your question, please click "Accept as Solution".

Hi @TDK 

Thanks so much, that was driving me mad!

 

Pleas, share with us where this:  

setvbuf(stdin, NULL, _IONBF, 0);

 is documented.  I would like to know before I get bit by some other "Gotch-yah" like this one.

Thanks.

Clyde