cancel
Showing results for 
Search instead for 
Did you mean: 

Cube 32 MX IDE leaves out FreeRTOS options, and kills code in files to fix the problem.

Harvey White
Senior III

I'm putting the FreeRTOS heap in extended memory in an F469I-Disco board.

Got the memory working properly (needs to be there for the LTDC display to work).

FreeRTOS needs the configAPPLICATION_ALLOCATED_HEAP option to be set to 1. CubeMXIDE setup options (in version 1.8.0) do not give that option anywhere and default to a 0 for this parameter.

Setting the variable in FreeRTOS.h works, but lasts until a change is made and code regenerated from the IOC file.

In addition, the heap4c file needs to be modified to allow FreeRTOS (@line 58) to search a named block of extended memory.

This gets wiped out when regenerating code as well.

An easy fix would be to have the last section (static heap) be conditional only on the variable == 0.

Then the user could add their own code in a user section with a preprocessor directive.

An alternative to that would be to add a user code section with the existing structure when user heap is needed.

Code needed to be added (apologies for lack of formatting, not available when asking a question) is:

#if( configAPPLICATION_ALLOCATED_HEAP == 1 )

/* The application writer has already defined the array used for the RTOS

heap - probably so it can be placed in a special segment or address. */

// extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".freertos_data")));

#else

static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

#endif /* configAPPLICATION_ALLOCATED_HEAP */

So two fixes needed, one in the IDE code options for user heap, the second for changes to heap4c (likely needed for other implementations).

No, hadn't considered using heap 5C because I don't want the heap split, just gracefully relocated.

1 ACCEPTED SOLUTION

Accepted Solutions
Harvey White
Senior III

FreeRTOS forum has come up with a solution to the heap4c problem:

In short, on that topic, I was looking for a complex solution where there was a simple one.

1) leave heap4c alone

2) the definition of the ucHeap is external.

3) in FreeRTOSconfig.h, add to the user code section (whole section shown)

/* USER CODE BEGIN 0 */
  extern void configureTimerForRunTimeStats(void);
  extern unsigned long getRunTimeCounterValue(void);
 // ALLOW FreeRTOS TO USE EXTENDED MEMORY
#define configAPPLICATION_ALLOCATED_HEAP     1
/* USER CODE END 0 */

You'll need the first two lines for timer, etc, if you use that feature

4) Then in main.c, add this in the PV section:

uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".freertos_data")));

Note that you're telling the linker that the ucHeap variable is to be placed in the .freertos_data section, which requires that the linker file be modified. You need to change only one, apparently, so I changed the ....FLASH.ld by adding:

MEMORY
{
  CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 320K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 2048K
  LTDC1    	(rw)    : ORIGIN = 0xc0000000,   LENGTH = 1500K				/* SDRAM, 1.5 MB, graphics page 0 */
  LTDC2    	(rw)    : ORIGIN = 0xc0180000,   LENGTH = 1500K				/* SDRAM, 1.5 MB, graphics page 1 */
  RTOS     	(rw)    : ORIGIN = 0xc02f8000,   LENGTH = 320K				/* SDRAM, 320 K RTOS extended heap */
  XXHEAP	(rw)   	: ORIGIN = 0xc0349000,   LENGTH = 2048K				/* SDRAM, 1.0 MB graphics screen tree as heap */
  SDRAM		(rw)   	: ORIGIN = 0xc0549000,   LENGTH = 10000K			/* SDRAM, 11 MB, remaining graphics memory */
  
}
 

In particular, you want the RTOS section, note how it fits with the other memory sections. This memory map allows two LTDC screens, an XXHEAP (mine) and a general SDRAM section in the linker.

Then the RTOS section needs to be specified (you've already said where it is, but now what):

Add the following after the user heap stack section:

/* FREERTOS STACK */
.freertos_data (NOLOAD) :
  {
    . = ALIGN(4);
    _freertos_data_begin = .;
    *(.freertos_data)
    *(.freertos_data*)
    . = ALIGN(4);
    _freertos_data_end = .;
  } >RTOS
 

That ought to do it. The map ought to show the sections, and depending on your FreeRTOS setting, will show occupation. Don't worry about the percentage of occupation, the region allocated by FreeRTOS only grows when you change FreeRTOS settings.

DESIGN NOTE: the linker script only accepts /* */ as comments, it does not accept // style comments, which cause a syntax error.

View solution in original post

5 REPLIES 5
Sara BEN HADJ YAHYA
ST Employee

Hello @Harvey White​ ,

Thanks for your feedback,

Could you please share your ioc file ?

Thanks,

Sara.

Harvey White
Senior III

IOC file is identical to the one submitted on the multiple definitions bug.

Please look at the options in the IOC editor view and note that there is not an option for allowing the user heap to be placed anywhere.

Since the changes are added manually, refreshing the appropriate generated files destroys the needed changes because the code is not structured to allow needed changes to be put in the user code areas, even IF there were an option to generate the user heap.

Sara BEN HADJ YAHYA
ST Employee

Hello @Harvey White​ ,

Sorry for the late reply,

The heap_4.c file is not generated by CubeMX, it is managed by FreeRTOS, please check the latest version 10.4.6 available on Github, if the issue is not yet fixed you can report it there.

About the configAPPLICATION_ALLOCATED_HEAP option, I've raised an internal Ticket to investigate more the issue. I'll keep you posted with the updates.

Internal ticket number: 122817 (This is an internal tracking number and is not accessible or usable by customers).

I hope this helps !

If your issue is solved, please close this post by clicking the "Select as Best" button. This will help other members of the community find this response more quickly ��

Sara.

Harvey White
Senior III

I've opened a topic on the FreeRTOS forum, so we'll see how they handle it.

Fortunately, the configAPPLICATION_ALLOCATED_HEAP option would be an easy fix, just add another option to the list of options.

If you know where heap4c is hidden in the file structures, I can fix it there and the code will regenerate properly until I upgrade to a new FreeRTOS version. Doesn't solve all the problems, but it eliminates at least one.

As is, on the F469I, I have the linker defining the standard regions for the processor, then in external memory, I have two LTDC regions, an XXHEAP (that I use for my own extended memory manager), a FreeRTOS area, and then left over memory is just there.

A trifle complicated, but it works.

Harvey White
Senior III

FreeRTOS forum has come up with a solution to the heap4c problem:

In short, on that topic, I was looking for a complex solution where there was a simple one.

1) leave heap4c alone

2) the definition of the ucHeap is external.

3) in FreeRTOSconfig.h, add to the user code section (whole section shown)

/* USER CODE BEGIN 0 */
  extern void configureTimerForRunTimeStats(void);
  extern unsigned long getRunTimeCounterValue(void);
 // ALLOW FreeRTOS TO USE EXTENDED MEMORY
#define configAPPLICATION_ALLOCATED_HEAP     1
/* USER CODE END 0 */

You'll need the first two lines for timer, etc, if you use that feature

4) Then in main.c, add this in the PV section:

uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".freertos_data")));

Note that you're telling the linker that the ucHeap variable is to be placed in the .freertos_data section, which requires that the linker file be modified. You need to change only one, apparently, so I changed the ....FLASH.ld by adding:

MEMORY
{
  CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 320K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 2048K
  LTDC1    	(rw)    : ORIGIN = 0xc0000000,   LENGTH = 1500K				/* SDRAM, 1.5 MB, graphics page 0 */
  LTDC2    	(rw)    : ORIGIN = 0xc0180000,   LENGTH = 1500K				/* SDRAM, 1.5 MB, graphics page 1 */
  RTOS     	(rw)    : ORIGIN = 0xc02f8000,   LENGTH = 320K				/* SDRAM, 320 K RTOS extended heap */
  XXHEAP	(rw)   	: ORIGIN = 0xc0349000,   LENGTH = 2048K				/* SDRAM, 1.0 MB graphics screen tree as heap */
  SDRAM		(rw)   	: ORIGIN = 0xc0549000,   LENGTH = 10000K			/* SDRAM, 11 MB, remaining graphics memory */
  
}
 

In particular, you want the RTOS section, note how it fits with the other memory sections. This memory map allows two LTDC screens, an XXHEAP (mine) and a general SDRAM section in the linker.

Then the RTOS section needs to be specified (you've already said where it is, but now what):

Add the following after the user heap stack section:

/* FREERTOS STACK */
.freertos_data (NOLOAD) :
  {
    . = ALIGN(4);
    _freertos_data_begin = .;
    *(.freertos_data)
    *(.freertos_data*)
    . = ALIGN(4);
    _freertos_data_end = .;
  } >RTOS
 

That ought to do it. The map ought to show the sections, and depending on your FreeRTOS setting, will show occupation. Don't worry about the percentage of occupation, the region allocated by FreeRTOS only grows when you change FreeRTOS settings.

DESIGN NOTE: the linker script only accepts /* */ as comments, it does not accept // style comments, which cause a syntax error.