1
\$\begingroup\$

I am working with an STM32, more specifically an STM32F401RE. I am trying to send some float value over UART by using the printf command. When I execute the code, it goes into an infinite loop during the printf call.

Here is the UART implementation

#include <stdio.h>
#include "stm32f4xx_hal.h"

UART_HandleTypeDef huart2;

void uart_init()
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    // Enable UART pins clock access
    __HAL_RCC_GPIOA_CLK_ENABLE();
    // Enable UART module clock access
    __HAL_RCC_USART2_CLK_ENABLE();
    // Configure pints to act as alternate func pins (UART)
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2; // (datasheet page 47)
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // Configure UART module
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 115200;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;

    HAL_UART_Init(&huart2);
}

int __io_putchar(int ch)
{
    HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 10);
    return ch;
}

Inside my main function I define a float value:

float x = 0;
printf("x = %.2f\n", x);

In the MCU setting of STMCubeIde I did check the option Use float with printf for newlib-nano (-u _printf_float).

\$\endgroup\$
3
  • \$\begingroup\$ Technically, it's not an infinite loop. One of the parameters you are providing to HAL_UART_Transmit is the timeout interval for the UART transaction which you have set to HAL_MAX_DELAY, which is in ms I believe, and is defined as 2^32 - 1. This is a very long time (~50 days). There is some issue with the UART peripheral. I'd take time to examine the registers to make sure everything is as you expect. First thing I'd look at is whether or not it is actually enabled. \$\endgroup\$ Dec 16, 2021 at 18:30
  • \$\begingroup\$ If I try to print some text the UART work perfectly and I see output value in the serial console. I adjusted the example with __io_putcharthat I confirm works for other types \$\endgroup\$
    – Michael
    Dec 16, 2021 at 19:12
  • \$\begingroup\$ printf needs output device assigned to huart2. It must be in the porting layer. \$\endgroup\$
    – jay
    Dec 16, 2021 at 19:45

1 Answer 1

5
\$\begingroup\$

It's an old question, but since my favorite search engine hit it:

The toolchains often use the newlib-nano C-runtime library which does not implement float conversions in printf/scanf related functions by default.

One has to enable that by adding undefined symbols to the linker flags like: -u _printf_float -u _scanf_float (shown for arm-gcc toolchain).

Some IDEs might have fancy buttons for that.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.