problem with sprint/printf with freeRTOS on stm32f7

2.6k views Asked by At

Since two days I am trying to make printf\sprintf working in my project... MCU: STM32F722RETx

I tried to use newLib, heap3, heap4, etc, etc. nothing works. HardFault_Handler is run evry time. Now I am trying to use simple implementation from this link and still the same problem. I suppose my device has some problem with double numbers, becouse program run HardFault_Handler from this line if (value != value) in _ftoa function.( what is strange because this stm32 support FPU) Do you guys have any idea? (Now I am using heap_4.c) My compiller options:

target_compile_options(${PROJ_NAME} PUBLIC
$<$<COMPILE_LANGUAGE:CXX>:
    -std=c++14
>
-mcpu=cortex-m7
-mthumb
-mfpu=fpv5-d16
-mfloat-abi=hard
-Wall
-ffunction-sections
-fdata-sections
-O1 -g
-DLV_CONF_INCLUDE_SIMPLE
 )

Linker options:

target_link_options(${PROJ_NAME} PUBLIC
${LINKER_OPTION} ${LINKER_SCRIPT}
-mcpu=cortex-m7
-mthumb
-mfloat-abi=hard
-mfpu=fpv5-sp-d16
-specs=nosys.specs
-specs=nano.specs
# -Wl,--wrap,malloc
# -Wl,--wrap,_malloc_r
-u_printf_float
-u_sprintf_float
 )

Linker script:

/* Highest address of the user mode stack */
_estack = 0x20040000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
   RAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 256K
  FLASH (rx)    : ORIGIN = 0x08000000, LENGTH = 512K
}

UPDATE: I don't think so it is stack problem, I have set configCHECK_FOR_STACK_OVERFLOW to 2, but hook function is never called. I found strange think: This soulution works:

float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f", 23.5f);

but this solution not:

float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f",d);

No idea why passing variable by copy, generate a HardFault_Handler...

3

There are 3 answers

2
Spectrem On

You can implement a hard fault handler that at least will provide you with the SP location to where the issue is occurring. This should provide more insight.

https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

It should let you know if your issue is due to a floating point error within the MCU or if it is due to a branching error possibly caused by some linking problem

0
Tạ Lục Gia Hoàng On

I also had error with printf when using FreeRTOS for my SiFive HiFive Rev B.

To solve it, I rewrite _fstat and _write functions to change output function of printf

/*
 * Retarget functions for printf()
 */
#include <errno.h>
#include <sys/stat.h>

int _fstat (int file, struct stat * st) {
    errno = -ENOSYS;
    return -1;
}

int _write (int file, char * ptr, int len) {
    extern int uart_putc(int c);
    int i;

    /* Turn character to capital letter and output to UART port */
    for (i = 0; i < len; i++) uart_putc((int)*ptr++);
    return 0;
}

And create another uart_putc function for UART0 of SiFive HiFive Rev B hardware:

void uart_putc(int c)
{
#define uart0_txdata    (*(volatile uint32_t*)(0x10013000)) // uart0 txdata register
#define UART_TXFULL             (1 << 31)  // uart0 txdata flag
    while ((uart0_txdata & UART_TXFULL) != 0) { }
    uart0_txdata = c;
}
0
Евгений Глуховский On

The newlib C-runtime library (used in many embedded tool chains) internally uses it's own malloc-family routines. newlib maintains some internal buffers and requires some support for thread-safety: http://www.nadler.com/embedded/newlibAndFreeRTOS.html

hard fault can caused by unaligned Memory Access: https://www.keil.com/support/docs/3777.htm