This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RAM/SDRAM and malloc issue

Other Parts Discussed in Thread: UNIFLASH, HALCOGEN

My project has RAM comprising both the internal RAM and 16MB SDRAM with the configuration as shown below.

I found out (test source code at the end) that:

  1. malloc(63) and memset region works
  2. malloc(64) and memset locks processor
  3. malloc(1), malloc(64), memset(64), free(64), and finally free(1) works
  4. malloc(1), malloc(4096), memset(4096), free(4096, and finally(1) works too

I tried various variations, and as long as at I do one malloc of any size and do absolutely nothing with that malloc aside from holding onto that malloc I can make any number of additional malloc/use/free operations. The problem comes in, when I have no malloc regions and I want to allocate an initial 64 bytes or larger region. That fails. If I malloc(63), free(63), and then malloc(64)/memset(64), then that will fail, because I freed the initial malloc region, so the second malloc of 64 bytes becomes the new initial malloc region.

Processor: RM48L952ZWT Hercules

Board: My own, NOT the Hercules HDK

Development Tool Chain: Halcogen, CCS (Code Composer Studio), and UniFlash

I am using the TI C/C++. All code below placed in sys_main.c

CCS Memory Map:

MEMORY
{
    VECTORS (X)  : origin=0x00000000 length=0x00000020
    FLASH0  (RX) : origin=0x00000020 length=0x0017FFE0
    FLASH1  (RX) : origin=0x00180000 length=0x00180000
    STACKS  (RW) : origin=0x08000000 length=0x00021000
    RAM     (RW) : origin=0x08021000 length=0x0001f000

/* USER CODE BEGIN (2) */
    RAM2    (RW) : origin=0x80000000 length=0x01000000
/* USER CODE END */
}

/* USER CODE BEGIN (3) */
/* Use the entire 16MB SDRAM for the heap */
--heap_size=0x01000000

#if 0
/* USER CODE END */


/*----------------------------------------------------------------------------*/
/* Section Configuration                                                      */

SECTIONS
{
    .intvecs : {} > VECTORS
    .text    : {} > FLASH0 | FLASH1
    .const   : {} > FLASH0 | FLASH1
    .cinit   : {} > FLASH0 | FLASH1
    .pinit   : {} > FLASH0 | FLASH1
    .bss     : {} > RAM
    .data    : {} > RAM
	.sysmem  : {} > RAM
	
    FEE_TEXT_SECTION : {} > FLASH0 | FLASH1
    FEE_CONST_SECTION : {} > FLASH0 | FLASH1
    FEE_DATA_SECTION : {} > RAM

/* USER CODE BEGIN (4) */
#else

SECTIONS
{
    .intvecs : {} > VECTORS
    .text    : {} > FLASH0 | FLASH1
    .const   : {} > FLASH0 | FLASH1
    .cinit   : {} > FLASH0 | FLASH1
    .pinit   : {} > FLASH0 | FLASH1
    .bss     : {} > RAM
    .data    : {} > RAM
    .sysmem  : {} > RAM2

    FEE_TEXT_SECTION : {} > FLASH0 | FLASH1
    FEE_CONST_SECTION : {} > FLASH0 | FLASH1
    FEE_DATA_SECTION : {} > RAM
#endif
/* USER CODE END */
}

Hercules RAM:

Here is test code:

boolean testMalloc()
{
	sciDisplayTextExAll("testMalloc v3e:\r\n");
	uint32 uSize2 = 62; // 62 worked
	void * lpSize2 = malloc(uSize2);
	sciDisplayTextExAll("      => after malloc uSize2\r\n");
	memset(lpSize2, 0, uSize2);
	sciDisplayTextExAll("      => after memset uSize2\r\n");
	free(lpSize2);
	sciDisplayTextExAll("      => Success 1!\r\n");


	uSize2 = 63;
	lpSize2 = malloc(uSize2);
	sciDisplayTextExAll("      => after malloc uSize2\r\n");
	memset(lpSize2, 0, uSize2);
	sciDisplayTextExAll("      => after memset uSize2\r\n");
	free(lpSize2);
	sciDisplayTextExAll("      => Success 2!\r\n");


	uint32 uSize1 = 1;
	uSize2 = 4096;
	void * lpSize1 = malloc(uSize1);
	sciDisplayTextExAll("      => after malloc uSize1\r\n");
	lpSize2 = malloc(uSize2);
	sciDisplayTextExAll("      => after malloc uSize2\r\n");
	memset(lpSize2, 0, uSize2);
	sciDisplayTextExAll("      => after memset uSize2\r\n");
	free(lpSize1);
	free(lpSize2);
	sciDisplayTextExAll("      => Success 3!\r\n");


	uSize1 = 1;
	uSize2 = 256;
	lpSize1 = malloc(uSize1);
	sciDisplayTextExAll("      => after malloc uSize1\r\n");
	lpSize2 = malloc(uSize2);
	sciDisplayTextExAll("      => after malloc uSize2\r\n");
	memset(lpSize2, 0, uSize2);
	sciDisplayTextExAll("      => after memset uSize2\r\n");
	free(lpSize1);
	free(lpSize2);
	sciDisplayTextExAll("      => Success 4!\r\n");


	uSize1 = 1;
	uSize2 = 64;
	lpSize1 = malloc(uSize1);
	sciDisplayTextExAll("      => after malloc uSize1\r\n");
	lpSize2 = malloc(uSize2);
	sciDisplayTextExAll("      => after malloc uSize2\r\n");
	memset(lpSize2, 0, uSize2);
	sciDisplayTextExAll("      => after memset uSize2\r\n");
	free(lpSize1);
	free(lpSize2);
	sciDisplayTextExAll("      => Success 5!\r\n");


	uSize2 = 64;
	lpSize2 = malloc(uSize2);
	sciDisplayTextExAll("      => after malloc uSize2\r\n");
	memset(lpSize2, 0, uSize2);
	sciDisplayTextExAll("      => after memset uSize2\r\n");
	free(lpSize2);
	sciDisplayTextExAll("      => Success 6!\r\n");

	return TRUE;
}

When I execute the above function, I see through Success 5 and through "after malloc uSize2" of Success 6, but no after and obviously no Success 6. Success 6 fails, because in my configuration one cannot allocate an initial block of memory that is 64-bytes or larger. Obviously, there is something that I did not configure properly.

What is wrong with my Halcogen/CCS map configuration, either singularly or both? Is it something else, possibly the linker?

  • Sarah, does this problem only occur when you map .sysmem to RAM2, or will it also occur if you map .sysmem to RAM?
  • Build output of trial:

    <Linking>
    "../source/sys_link.cmd", line 106: error #10099-D: program will not fit into available memory.  run placement with alignment fails for section ".sysmem" size 0x1000000 .  Available memory ranges:
       RAM          size: 0x1f000      unused: 0x1a50b      max hole: 0x1a50b   
    error #10010: errors encountered during linking; "CCMv3.out" not built

    Had the build succeeded, my application requires the malloc use the additional RAM, hence its presence, so we need to get the environment working with the SDRAM.

    I forgot to show my SDRAM settings. I do not think they make a difference, as that part I set up correctly, however...

    1. What is so magical about the 64-byte number for the very first allocation?
    2. Why is the first malloc() different than all the other malloc()? (sounds like a Passover comment)
    3. Is the first malloc() verses all other malloc() requests different, merely because possibly the first malloc() gets placed in on board RAM, while all other malloc() requests get placed in SDRAM?
    4. Is there a bug with the linker/compiler tool chain?
    5. More importantly, what other issues might there be to which I am not aware? Obviously, I can allocate 1-byte at the very start, do nothing with that allocation, and be on my merry way, but what other grief might be caused by my doing that?

    How do we successfully resolve this issue?

  • Sarah, I am trying to identify if this is a software problem, or a hardware problem. Just for this test can you reduce the size of the heap and see if your test works when .sysmem is mapped into internal memory?
  • Thank you Bob for your prompt responses.

    I commented out the --heap_size statement and set .sysmem to RAM. I also had to comment out the 4096 allocation test, as memory was not big enough for that.

    Result: Success even with the 64-byte initial allocation.

    The problem relates to use of external RAM.
  • OK, can you tell me how it fails? Does malloc() return a null pointer, or do you get a data abort, or something else? What address was returned for lpSize2 in line 62 above?
  • Malloc returns a non-NULL pointer. Execution then proceeds to the memset statement, where the processor hangs, never to return or do anything else until I physically shut power down and restart.
  • What value does it return?
  • => Malloc test, no Size1, uSize2=64
    - lpSize2=0x80000330

    Code never returned from the memset() call.

    That was a good question. :-) I should have thought of looking at the address. That address, 0x80000330, is what I saw with the debugger. That is in SDRAM and a valid address. What is interesting is that whenever I allocate memory, I always see that address. I guess that is the first allocated address and then other allocations would get something else.