manu
(Manu)
November 24, 2020, 3:03pm
1
Hi,
Greetings!
Using heap_5.c, the xPortGetFreeHeapSize() returns only the size of the last region added via vPortDefineHeapRegions(regions);
Looking at heap_5.c, it does indeed loop around all the defined regions
with
while( pxHeapRegion->xSizeInBytes > 0 )
Eventhough it does loop through all the regions, the reported/calculated size is applicable for the last defined region alone.
Initially, I am forced to think that it is a BUG, unless someone has a rationale why vPortDefineHeapRegions() considers only the very last region for the heap. In which case why does one need to define multiple regions, in the first place ?
It doesn’t really make sense to me. Can someone please explain what’s going on ?
Thanks,
Manu
rtel
(Richard Barry)
November 24, 2020, 4:21pm
2
It looks like xPortGetFreeHeapSize() just returns the xFreeBytesRemaining https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/master/portable/MemMang/heap_5.c#L325 which is decremented and incremented as bytes are allocated and freed. Are you reporting a problem with how xFreeBytesRemaining is calculated?
manu
(Manu)
November 24, 2020, 4:30pm
3
Hi Richard,
Greetings!
If you think that’s the right behaviour, then I guess a BUG exists ?
#define __ram(__addr) __attribute__((at(__addr)))
/**
* 0x38800000 - 0x38800fff ( 4096) Backup SRAM
* 0x38000000 - 0x3800ffff ( 65536) SRAM4
* 0x30040000 - 0x30047fff ( 32768) SRAM3
* 0x30020000 - 0x3003ffff ( 262144) SRAM2
* 0x30000000 - 0x3001ffff ( 131072) SRAM1
* 0x24000000 - 0x2407ffff ( 524288) AXI SRAM
* 0x20000000 - 0x2001ffff ( 131072) DTCM
* 0x1ff00000 - 0x1ff1ffff ( 131072) System Memory
* 0x08100000 - 0x081fffff (1048576) Flash memory bank 2
* 0x08000000 - 0x080fffff (1048576) Flash memory bank 1
* 0x00000000 - 0x0000ffff ( 65536) ITCM
*/
#define MEMSIZ(__start, __end) ((__end - __start) + 1)
#define SRAM_AXI (uint32_t) 0x24000000
#define SRAM_AXI_END (uint32_t) 0x2407ffff
#define SRAM_AXI_SIZ MEMSIZ(SRAM_AXI, SRAM_AXI_END)
#define SRAM_1 (uint32_t) 0x30000000
#define SRAM_1_END (uint32_t) 0x3001ffff
#define SRAM_1_SIZ MEMSIZ(SRAM_1, SRAM_1_END)
#define SRAM_2 (uint32_t) 0x30020000
#define SRAM_2_END (uint32_t) 0x3003ffff
#define SRAM_2_SIZ MEMSIZ(SRAM_2, SRAM_2_END)
#define SRAM_3 (uint32_t) 0x30040000
#define SRAM_3_END (uint32_t) 0x30047fff
#define SRAM_3_SIZ MEMSIZ(SRAM_3, SRAM_3_END)
#define SRAM_4 (uint32_t) 0x38000000
#define SRAM_4_END (uint32_t) 0x3800ffff
#define SRAM_4_SIZ MEMSIZ(SRAM_4, SRAM_4_END)
#define SRAM_RTC (uint32_t) 0x38800000
#define SRAM_RTC_END (uint32_t) 0x38800fff
#define SRAM_RTC_SIZ MEMSIZ(SRAM_RTC, SRAM_RTC_END)
static void init_heap(void)
{
// static uint8_t heap_1[SRAM_AXI_SIZ] __ram(SRAM_AXI); /* SRAM_AXI (512k) */
static uint8_t heap_2[SRAM_1_SIZ] __ram(SRAM_1); /* SRAM_1 (128k) */
static uint8_t heap_3[SRAM_2_SIZ] __ram(SRAM_2); /* SRAM_2 (256k) */
// static uint8_t heap_4[SRAM_3_SIZ] __ram(SRAM_3); /* SRAM_3 ( 32k) */
// static uint8_t heap_5[SRAM_4_SIZ] __ram(SRAM_4); /* SRAM_4 ( 64k) */
HeapRegion_t regions[] = {
// {(uint8_t *) heap_1, sizeof (heap_1)}, /* SRAM_AXI (512k) */
{(uint8_t *) heap_2, sizeof (heap_2)}, /* SRAM_1 (128k) */
{(uint8_t *) heap_3, sizeof (heap_3)}, /* SRAM_2 (256k) */
// {(uint8_t *) heap_4, sizeof (heap_4)}, /* SRAM_3 ( 32k) */
// {(uint8_t *) heap_5, sizeof (heap_5)}, /* SRAM_4 ( 64k) */
{NULL, 0} /* Terminate Array */
};
vPortDefineHeapRegions(regions);
}
int main(void)
{
MPU_Config();
SCB_EnableICache(); /* Enable I-Cache */
SCB_EnableDCache(); /* Enable D-Cache */
HAL_Init(); /* TIM6 generates IRQ @1msec, NVIC Group Priority=4 */
sysclk_config(); /* Configure the system clock to 480 MHz */
bsp_config();
init_heap();
printf(" --------------------------------\n");
printf(" -* STM32H7x Net Client *- \n");
printf(" --------------------------------\n");
printf("\n");
printf(" Available Heap: %d\n", xPortGetFreeHeapSize());
/* create task */
sys_thread_new("Bootstrap", /* Task name */
task_boot, /* Task function */
NULL, /* optional arg */
configMINIMAL_STACK_SIZE + 384, /* Stack size: 1024 bytes */
tskIDLE_PRIORITY); /* priority */
vTaskStartScheduler(); /* Start RTOS scheduler */
}
The resultant output looks thus:
--------------------------------
-* STM32H7x Net Client *-
--------------------------------
Available Heap: 262128
(420) task_boot:
(388) net_init: Configuring Network
Set Link Up ............... Link is Up
DHCP Start ............. Bound
Hostname : lwip
MAC Address : 02:00:00:00:00:00:
IPv4 Address : 192.168.1.33
IPv4 Subnet mask : 255.255.255.0
IPv4 Gateway : 192.168.1.1
MTU : 1500
Rx Task:
Rx bound to 43791 ..
Can you please confirm ?
Thanks,
Manu
rtel
(Richard Barry)
November 24, 2020, 5:31pm
4
The WinSim demo in the main FreeRTOS download uses heap_5. It uses these definitions https://github.com/FreeRTOS/FreeRTOS/blob/master/FreeRTOS/Demo/WIN32-MSVC/main.c#L81 to initialise the heap https://github.com/FreeRTOS/FreeRTOS/blob/master/FreeRTOS/Demo/WIN32-MSVC/main.c#L359 after which the free heap size is reported as 45713 bytes. The three definitions total 45680 bytes, so considering some heap is used up with block links, 45713 sounds about right.
manu:
Can you please confirm ?
You can confirm this yourself. Simply step through the vPortDefineHeapRegions() functions to see how it accumulates the total heap space as each region is added. If you find a bug there please post a link to the offending line.
manu
(Manu)
November 24, 2020, 6:30pm
5
The BUG appeared to be in my comments: SRAM_2 is 128k and not 256k
0x3003ffff - 0x30020000 = 1ffff = 128k
Cross checked with heap_5.c
Looks thus:
init_heap: SRAM1 Size: 0x20000, SRAM2 Size: 0x20000
Region: 0x30000000, Size: 0x20000
Region: 0x30020000, Size: 0x20000
--------------------------------
-* STM32H7x Net Client *-
--------------------------------
Available Heap: 262128
That was a false trail. Sorry about the noise!
Thanks,
Manu