Skip to main content
Senior
August 24, 2026
Solved

Why does CubeIDE restrict the available memory to 128 for STM32L451 (160K SRAM)

  • August 24, 2026
  • 4 replies
  • 81 views

I have one question.

The L451CC has 160K of SRAM split in 128K + 64K.

According to the datasheet SRAM2 is rermapped just on top of SRAM1 giving a full block of 160K.

Wonderful, but… not so wonderful because CubeIDE ignores the SRAM2 and restrict the memory space to SRAM1.

Is there a way to use SRAM2 E.G. by writing a customized malloc like function (I did that for the L429 series and it works fine) ?

static volatile void * ccm_current_pointer;
static volatile uint32_t ccm_current_free_memory;

static void ccm_Malloc_failed(void);

// ADJUST ONLY THE RESERVED AREA SIZE
// TO CHANGE THE CCM HEAP SIZE

#define CCM_RESERVED_SIZE 0
#define CCM_AS_HEAP_SIZE 65536 - CCM_RESERVED_SIZE
#define CCM_AS_HEAP_BASE (0x10000000 + CCM_RESERVED_SIZE)

void ccm_Heap_init(void)
{
ccm_current_pointer = (void *) CCM_AS_HEAP_BASE;
ccm_current_free_memory = CCM_AS_HEAP_SIZE;
memset((void *) ccm_current_pointer, 0, ccm_current_free_memory);
}

void * ccm_Malloc(uint32_t block_size, bool force_in_sram)
{
void * _ptr;
uint32_t _block_size;

_block_size = block_size;
_ptr = NULL;

// ADJUST BLOCK SIZE TO 4 BYTES ALIGNMENT
if ((_block_size & 0x3) != 0)
{
_block_size &= 0xFFFFFFF8;
_block_size += 4;
}
if (!force_in_sram)
{
// LOCK MEMORY MANAGER
vTaskSuspendAll();
if (_block_size <= ccm_current_free_memory)
{
_ptr = (void *) ccm_current_pointer;
ccm_current_pointer += _block_size;
ccm_current_free_memory -= _block_size;
}
// RELEASE MEMORY MANAGER
xTaskResumeAll();
}
if (_ptr == NULL)
{
_ptr = pvPortMalloc(block_size);
}

if (_ptr == NULL)
ccm_Malloc_failed();

return _ptr;
}

uint32_t ccm_Get_free_memory(void)
{
return ccm_current_free_memory;
}

static void ccm_Malloc_failed(void)
{
HAL_GPIO_WritePin(FAIL_A_GPIO_Port, FAIL_A_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(FAIL_B_GPIO_Port, FAIL_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(FAIL_C_GPIO_Port, FAIL_C_Pin, GPIO_PIN_RESET);
for (;;)
{
osDelay(50);
HAL_GPIO_TogglePin(FAIL_A_GPIO_Port, FAIL_A_Pin);
HAL_GPIO_TogglePin(FAIL_B_GPIO_Port, FAIL_B_Pin);
HAL_GPIO_TogglePin(FAIL_C_GPIO_Port, FAIL_C_Pin);
osDelay(450);
HAL_GPIO_TogglePin(FAIL_A_GPIO_Port, FAIL_A_Pin);
HAL_GPIO_TogglePin(FAIL_B_GPIO_Port, FAIL_B_Pin);
HAL_GPIO_TogglePin(FAIL_C_GPIO_Port, FAIL_C_Pin);
}
}

force_in_sram parameter is required for the l’ to insure that the allocated memory is accessible to the DMA controller

May this code work with the L451?

Regards

Didier

Best answer by TDK

It’s just a default. If you don’t like the default, change the linker script to use more memory.

There are thousands of different chips. The defaults are not tuned to optimize each and every combination.

4 replies

Ozone
Principal
August 25, 2026

I don’t know the L42x/L45x MCUs, you should consult the datasheets for specific details in this regard.
But two things I noticed:

First, you posted malloc() related code, which is usually referred to as “heap”.
I rarely port POSIX compatible code, and thus most of my projects have a heap size of zero.
Do you really need a 160kB heap ?

Second, all the function names in the posted code are preceded with “ccm”.
CCM is a ST euphemism for RAM that is unaccessible to DMA.
I would be very careful in regard to merging both regions, else you might get nasty bugs.
I ran into this problem, because my toolchain priorizes CCM over normal RAM for certain derivates.

zeboss49Author
Senior
August 25, 2026

Hello,

I’m using FreeRTOS with dynamic allocations, so I do need as large a heap as possible.

Concerning CCM I’m aware that it is not accessible to DMA and the force_in_sram parameter is used to prevent allocation of memory in CCM when the block must be accessible to the DMA controller.

For the L452 there is no CCM, only SRAM1 and SRAM2 and i don’t found any restriction about DMA access to SRAM2.

So the parameter could be useless for the L452.

.

 

Ozone
Principal
August 25, 2026

As said, I don’t know specific details about the L4xx MCUs. Perhaps CCM is not a problem in your case.

> I’m using FreeRTOS with dynamic allocations, so I do need as large a heap as possible.

I would think - not.
It needs to be as large as necessary, you need stack as well.

Heap is “off limits” for the stack(s), function calls, and static & global variables, so you need  pick proper sizes for your application.
I never experienced any serious impact of FreeRTOS on heap allocation but this might depend on configuration and application specifics.
I would enable FreeRTOS’ runtime stack overflow check feature, by the way.

TDK
TDKBest answer
August 25, 2026

It’s just a default. If you don’t like the default, change the linker script to use more memory.

There are thousands of different chips. The defaults are not tuned to optimize each and every combination.

"If you feel a post has answered your question, please click ""Accept as Solution""."