FreeRTOS/Eclipse/gcc/malloc() Linker Script

rousea wrote on Monday, February 15, 2010:

I am developing a project for an STM32 processor, using FreeRTOS, Eclipse and gcc.  I use the stm32_flash.ld linker file supplied with FreeRTOS examples, and I have been able to debug code without any major problems.  However, I have now added routines that use library functions, in particular gmtime() to handle real-time, so I have added the time.h header file.

When I first compiled the project I got an error message '“syscalls_r.c undefined reference to ‘end’”.  I eventually tracked this down to a problem with the linker script.  I modified my makefile to instead invoke stm32rom.ld, supplied by ST in their examples for the STM32 processor.  This didn’t give any errors, but the resulting code couldn’t be downloaded to the target for debugging.

I then looked at the differences between the two linker scripts.  I am struggling to understand all the nuances of them, but I found a line at the end of the latter “PROVIDE(end = .);” to set a variable ‘end’ equal to the current location pointer.  I copied this to the end of the STM32_flash.ld file and it then compiled without error.  I could then download the code to my target and run it.  However, when execution reached the line " TimeArray = *gmtime(&TimeCnt);" it crashes with a Hard Fault.

Can anyone suggest a fix for this?

I have tried stepping through the disassembly code and it appears that gmtime() calls malloc() which creates a number of local variables of type struct_malloc_chunk*.  This structure comprises int previous_size, int size,   struct_malloc_chunk* fd and  struct_malloc_chunk* bk.  As far as I can see this creates an infinite number of  struct_malloc_chunk*'s!

My analysis may be wrong, but whatever the cause of the fault I can’t progress with my development until I can overcome the problem.

davedoors wrote on Tuesday, February 16, 2010:

Library functions that call malloc are nasty. Can you implement the function yourself? Where is it getting the time from?

Does the linker script define a heap segment? The one supplied with FreeRTOS probably does not because the demos normally use a large array as the heap (heap_2.c). You could try switching to use heap_3.c which uses the standard library malloc but you would also have to define a heap in the linker script. Another solution might be to change the library to call pvPortMalloc() in place of malloc and vPortFree in place of free.

If it is mallocing and freeing blocks each time it is called I think re-implementing it would be the best thing to do.

rousea wrote on Tuesday, February 16, 2010:

Thanks for the suggestion.  I have now written my own routines to simulate gmtime() and ctime() and it has resolved the problem.  It has also given me the freedom to modify the format of the structures and strings to make it easier for me to process the data.

As further detail, I am using the RTC in the STM32 to generate a 32-bit count of seconds.  I have written a routine GetTimeArrayFromCnt() that translates this count to int TimeArray, which is my equivalent of the structure tm used by gmtime().  I found this more useful, since I can access it using an index where, for example, DAY_OF_WEEK = 0, MONTH = 1.

I have written another routine GetTimeStringFromArray() which converts TimeArray to an ASCII string, similar to ctime(), but I have modified the string to the format in which I want to display the time/date.

Finally I have written a routine GetTimeCntFromArray() which I can call after modifying TimeArray through a keypad and LCD display, so the user can set the RTC to the current time.

Once again, thanks for your suggestion