Im trying to use snprintf but with the following arguments
char buf[100];
char *wld = "WORLD";
char buffer [100];
int n = 10;
snprintf(buffer, sizeof(buffer), "%i", n);
and it doesnt work.
I end up with hardfault on the stm32 that im using.
If i use the below statement it works fine
snprintf(buf, sizeof(buf), "hello %s", wld);
Im quite new to programing so what could i have missed
/Dennis
Dennis Eriksson wrote:
> Im trying to use snprintf but with the following arguments> char buf[100];> char *wld = "WORLD";> char buffer [100];> int n = 10;> snprintf(buffer, sizeof(buffer), "%i", n);> and it doesnt work.> I end up with hardfault on the stm32 that im using.
Maybe a problem with the heap-handling (sbrk implementation,
heap-start-adress used by sbrk). Please create a minimal example with
all source-codes and linker-script to reproduce this, pack them into a
zip-archive and attach it to a message.
You may use this example, insert your snprintf code and try again:
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/#cm3_cpp1> If i use the below statement it works fine> snprintf(buf, sizeof(buf), "hello %s", wld);
This may work since the compiler already replaces it by somthing like
strcpy(buf,"hello WORLD") and there is no call to the libc's snprintf
during runtime.
Hi Martin
First of all thank you for taking your time to help me. Attached you
will find my project (stripped to the bare bone).
I tryed you project and i got it built, but i get in to problems when
trying to get it in to my stm32. I will try some more on.
So please have a look on my files. (propobly its in the .ld file)
/Dennis
Dennis Eriksson wrote:
> Attached you will find my project (stripped to the bare bone).
Not at all! "Bare bone" would be:
- one Makefile
- one Linkerscript
- Startup-Code in one file (either .c or .S)
- one C source file.
> I tryed you project and i got it built, but i get in to problems when> trying to get it in to my stm32. I will try some more on.>> So please have a look on my files. (propobly its in the .ld file)
I just had a quick look into your files:
(1) don't use arm-*-ld for linking use the frontend (arm-*-gcc)
(2) pass the -mcpu -mthumb option too when using gcc for linking.
With this there is no need or hard-code pathes into the makefile or even
copy files from the toolchains library-path into the project. Fix this
first to make sure that the correct libc is linked.
(3) There is no need to add an output-section for the heap into the
linker-script as long as you keep the stack-placement as is (starting
from top of RAM). There should be no need to modify the linker-script.
(4) using _end, __end or _ebss for heap-start (in sbrk) should do, they
all should have the same value. No need to add an additional variable
...HEAP_START...
Martin Thomas wrote:
> Maybe a problem with the heap-handling (sbrk implementation,> heap-start-adress used by sbrk).
I don't see where the heap would be used in the posted code.
>> If i use the below statement it works fine>> snprintf(buf, sizeof(buf), "hello %s", wld);>> This may work since the compiler already replaces it by somthing like> strcpy(buf,"hello WORLD") and there is no call to the libc's snprintf> during runtime.
The compiler cannot do that! That would require the compiler to
understand the semantics of the library, and that does not happen - even
for functions in the standard library.
The code creates large arrays on the stack, and the formatted I/O
functions themselves require a significant amount of stack (4 kbytes
would not be unusual). My guess would be that there is insufficient
stack allocation. The linker script sets __Stack_Size to 1024 and
_Minimum_Stack_Size to 0x100, I suggest that these are too small to
support the formatted I/O functions.
Clifford Slocombe wrote:
> Martin Thomas wrote:>> Maybe a problem with the heap-handling (sbrk implementation,>> heap-start-adress used by sbrk).>> I don't see where the heap would be used in the posted code.
Implicitly by snprintf? When using newlib's printf different syscalls
are "requested" by the linker. Among them sbrk with is used for dynamic
memory allocation.
>>> If i use the below statement it works fine>>> snprintf(buf, sizeof(buf), "hello %s", wld);>>>> This may work since the compiler already replaces it by somthing like>> strcpy(buf,"hello WORLD") and there is no call to the libc's snprintf>> during runtime.>> The compiler cannot do that! That would require the compiler to> understand the semantics of the library, and that does not happen - even> for functions in the standard library.
As far is I understand the gcc builtins are made to "understand the
sematics" of some standard-library-functions.
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins
At least I have seen that a printf with all constant parameters has been
replaced by puts. During "single-stepping" there has been no call to the
libc's printf, puts has been called directly. So far I did not care too
much about this so this is just a remark, please correct me if I'm
wrong.
> The code creates large arrays on the stack, and the formatted I/O> functions themselves require a significant amount of stack (4 kbytes> would not be unusual). My guess would be that there is insufficient> stack allocation. The linker script sets __Stack_Size to 1024 and> _Minimum_Stack_Size to 0x100, I suggest that these are too small to> support the formatted I/O functions.
In this special case - a ld-script and startup-code based on the
templates that come with the STM32 library - the value does not set the
real stack size but is just used to create a "dummy" output-section so
the linker will thow an error message is there is not enough space left.
As far as I have seen the start of stack (stack-pointer value at 0x0) is
set to the top of RAM so there should(?!) be enough free RAM for an
application with just a few init-functions and a single call to
snprintf.
Martin Thomas wrote:
> Clifford Slocombe wrote:>> Martin Thomas wrote:>> I don't see where the heap would be used in the posted code.> Implicitly by snprintf?
I'd be very disturbed is snprintf() required dynamic memory allocation
or that a non-standard function would be optimised away.
On all else I bow to your more extensive knowledge.
Clifford Slocombe wrote:
> I'd be very disturbed is snprintf() required dynamic memory allocation
This is actually quite common in certain C libraries. Some
optimized-for-µC libs provide limited stack-only variants of standard
functions. Exotic functionality is often omitted. Popular candidates in
printf-type functions are format specifiers for floats.
> or that a non-standard function would be optimised away.http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Other-Builtins.html#Other-Builtins
Besides, why would snprintf() be non-standard (ISO C99, B.18)?
Regards
Marcus
http://www.doulos.com/arm/
Marcus Harnisch wrote:
> Clifford Slocombe wrote:>> I'd be very disturbed is snprintf() required dynamic memory allocation>> This is actually quite common in certain C libraries. Some> optimized-for-µC libs provide limited stack-only variants of standard> functions.
Is that not what we are talking about here? WinARM uses Newlib which is
exactly an "optimized-for-µC" library.
>> Besides, why would snprintf() be non-standard (ISO C99, B.18)?>
Doh!? Where have I been!?