Skip to main content
Knowledgebase
Home
Renesas Electronics America - Knowledgebase

Why do I get a system crash when using printf() with a GUIX and Dave 2D implementation?

Latest Updated:10/11/2016

Question:

Does the current release of SSP 1.0.0 crash when printf uses a floating point argument with GUIX and Dave 2D also used together? What can I do about this?

Answer:

If sprintf() is used with a floating point argument, in a GUIX project, it can crash GUIX. This is caused by the fact that the Dave2D heap gets allocated in the middle of the normal heap:

.heap 0x2005e340 0x8400 load address 0x000b5140
0x2005e340 __HeapBase = .
0x2005e340 __end__ = .
0x2005e340 end = __end__
*(.heap*)
.heap_d1 0x2005e340 0x8000 ./synergy/ssp/src/framework/sf_tes_2d_drw/sf_tes_2d_drw_memory.o
.heap 0x20066340 0x400 ./synergy/ssp/src/bsp/cmsis/Device/RENESAS/S7G2/Source/startup_S7G2.o
0x20066740 __HeapLimit = .

and as sprintf() with floating point arguments uses quite alot of memory from the heap, the Dave2D heap area gets altered by sprintf(), leading to the system crash.

So, an alteration of the linker map is required, to locate the dave2D heap outside the normal heap :-

.heap (NOLOAD):
{
KEEP(*(.heap_d1)) <<<<<<<<< Addition to move the Dave2D heap
__HeapBase = .;
__end__ = .;
end = __end__;
KEEP(*(.heap*))
__HeapLimit = .;
} > RAM

This then leads to the memory allocation for the heap :

.heap 0x2005e340 0x8400 load address 0x000b5140
*(.heap_d1)
.heap_d1 0x2005e340 0x8000 ./synergy/ssp/src/framework/sf_tes_2d_drw/sf_tes_2d_drw_memory.o
0x20066340 __HeapBase = .
0x20066340 __end__ = .
0x20066340 end = __end__
*(.heap*)
.heap 0x20066340 0x400 ./synergy/ssp/src/bsp/cmsis/Device/RENESAS/S7G2/Source/startup_S7G2.o
0x20066740 __HeapLimit = .

Also, for SSP 1.0 there is a bug with the malloc code in the GCC newlib, meaning malloc will be allocated memory all the way to the current stack pointer, rather than the limit of the stack (this is fixed in SSP 1.1.0), so an external version of _sbrk() is required (this is taken from SSP 1.1.0) :-

caddr_t _sbrk(int incr)
{
extern char _Heap_Begin __asm ("__HeapBase"); ///< Defined by the linker.
extern char _Heap_Limit __asm ("__HeapLimit"); ///< Defined by the linker.

static char* current_heap_end = 0;
char* current_block_address;

if (current_heap_end == 0)
{
current_heap_end = &_Heap_Begin;
}

current_block_address = current_heap_end;

/** Need to align heap to word boundary, else will get */
/** hard faults on Cortex-M0. So we assume that heap starts on */
/** word boundary, hence make sure we always add a multiple of */
/** 4 to it. */
incr = (incr + 3) & (~3); ///< align value to 4
if (current_heap_end + incr > &_Heap_Limit)
{
/** Heap has overflowed */
errno = ENOMEM;
return (caddr_t) - 1;
}

current_heap_end += incr;
return (caddr_t) current_block_address;
}

With these changes, sprintf() with floating point arguments doesn't crash GUIX.