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.
Thank you Thomas After fixing the linking as you suggested i got it to work. Now i only need to do some clean up in my makefile. /Dennis
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!?
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.