2021-11-19 08:10 AM
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
but 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.
I 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"
I 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.
Solved! Go to Solution.
2021-11-20 01:41 AM
*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.
2023-05-29 05:27 AM
I am facing a similar problem. How did you enable the FPU in project?
2023-05-29 06:57 AM - edited 2023-11-20 09:16 AM
in project setting...can choose hardware FPU, if possible on target cpu...
2023-06-01 04:37 AM
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?
2023-06-01 04:55 AM
> 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
2023-06-01 05:17 AM - edited 2023-11-20 09:16 AM
2023-06-01 05:20 AM
The string is long enough, that is, 50 bytes long.
2023-06-01 07:14 AM
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.
2023-06-01 08:27 AM - edited 2023-11-20 09:17 AM
2023-06-01 08:28 AM
How can i disable WWDG_IRQHandler?