cancel
Showing results for 
Search instead for 
Did you mean: 

[SOLVED] Sprintf with floating point number crashing into hard fault on STM32L476, working fine with STM32F091

jaromir sukuba
Associate II

I'm trying to use this C code

#include <stdio.h>
 
 
char arr[50];
int var_int;
float var_float;
 
int main (void)
{
while (1)
	{
	var_int++;
	sprintf (arr,"RES 1 %d",var_int);
	var_float = var_float + 0.1;
	sprintf (arr,"RES2 %d %f",var_int,var_float);
	}
}

on STM32L476 nucleo kit, with STM32CubeIDE (Version: 1.5.0 Build: 8698_20201117_1050 (UTC)), I'm using debugger, stepping the code and observing variables in expression window, however the code always fails at second sprintf call (the one with float variable). Before trying to execute second sprintf call I can see proper output from first sprintf call, as well as float variable with proper value

0693W00000GYFKSQA5.pngbut after second sprintf call I find the MCU executing endless loop after fault. The second sprintf managed to print output up to the floating point part.

0693W00000GYFJyQAP.pngI started fresh project for this, didn't modify linker file nor any project settings, with exception of ticking "Use float with with printf from newlib-nano"

0693W00000GYFMYQA5.pngI suppose hard fault from sprintf is not desired outcome, but I can't find any obvious way to fix this.

For sake of completeness, due to size, map file is pasted here https://pastebin.com/CeyVYpEP and build output follows.

12:32:09 **** Incremental Build of configuration Debug for project test476 ****
make -j2 all 
arm-none-eabi-gcc "../Src/main.c" -mcpu=cortex-m4 -std=gnu11 -g3 -DSTM32L4 -DSTM32 -DNUCLEO_L476RG -DDEBUG -DSTM32L476RGTx -c -I../Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Src/main.d" -MT"Src/main.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Src/main.o"
arm-none-eabi-gcc -o "test476.elf" @"objects.list"   -mcpu=cortex-m4 -T"/home/jarin/STM32CubeIDE/workspace_1.5.0/test476/STM32L476RGTX_FLASH.ld" --specs=nosys.specs -Wl,-Map="test476.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -u _printf_float -Wl,--start-group -lc -lm -Wl,--end-group
Finished building target: test476.elf
 
arm-none-eabi-objdump -h -S  test476.elf  > "test476.list"
arm-none-eabi-objcopy  -O binary  test476.elf  "test476.bin"
Finished building: test476.bin
Finished building: test476.list
 
arm-none-eabi-size   test476.elf 
 
   text	   data	    bss	    dec	    hex	filename
  12520	    472	   1640	  14632	   3928	test476.elf
Finished building: default.size.stdout
 
 
12:32:10 Build Finished. 0 errors, 0 warnings. (took 830ms)

I tried the same source, with the same project setup modification (single checkbox to use float functions) on STM32F091 nucleo kit, where it works as I expect (second printf doesn't crash and prints desired output to char array).

Perhaps I'm overlooking something very obvious, but I can't see where the problem is.

Also, I'm aware of printf and similar functions not being the most fitting for small embedded systems, but this is probably not the topic here.

21 REPLIES 21

*printf() in mcu? Meh... ;-)

Even if a nanovoltmeter displaying in semilogarithmic form may be an interesting idea, I personally would still write the conversion myself. K&R's legacy in this case is IMO just too extensive/expensive, and you probably don't need 99% of the features it offers; and you also don't need/want the gotchas it may bring in (although one might argue that this is consequence of not following the basic C rules - C7.1.4#4 in this case - but who does truly and rigorously follow all of them, after all?). But yes, it's your leg and your shot. and I should just shut up.

This all of course wouldn't spare you from the hardfault, would you use floats for any other purpose. My story is, that I tried to be smart and enabled coprocessor not in startup code i.e. not in asm, but in C, in the very first line of main(). This worked OK. Much later, one day, gcc decided that - as main() is treated as a standard function (gcc may have a switch to change this and this may or may not work on Cortex-M, I did not investigate deeper) and due to code growth the usage of floats in main() exceeded the number of registers alotted as callee-saves in ABI - that it needs to save some of the the caller-saves float registers on stack in the function prologue. So that was before the very first line in main(), enabling coprocessor, was executed. And that was it.

JW

PS. Please select your post with the solution as "Best", so that thread is marked as solved.

I am facing a similar problem. How did you enable the FPU in project?

in project setting...can choose hardware FPU, if possible on target cpu...


_legacyfs_online_stmicro_images_0693W00000bl3iSQAQ.png

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

Although all settings are correct, sprintf doesn't work with floating point number only. Although it works on stm32cube, it doesn't work on bare-metal program. It loops endlessly in the Default_Handler function. I'm about to go crazy. what else can i do?

> Default_Handler function

Are you sure this is consequence of a fault? It may be e.g. also incorrectly set interrupt vector table.

At any case, don't hijack others' thread. Instead, start your own, stating your hardware, used software, expected and observed behaviour. If you feel this thread is relevant to your problem, give a link to it.

JW


_legacyfs_online_stmicro_images_0693W00000dJpNPQA0.png

The string is long enough, that is, 50 bytes long.

At any case, don't hijack others' thread. Instead, start your own, stating your hardware, used software, expected and observed behaviour. If you feel this thread is relevant to your problem, give a link to it.


_legacyfs_online_stmicro_images_0693W00000dJqH8QAK.png

FEvra.1
Associate II

How can i disable WWDG_IRQHandler?