Page 3 of 3

Re: F4 - Update boards.txt

Posted: Tue Aug 08, 2017 3:56 am
by victor_pv
I believe that since we normally dont use "new" the heap doesn't grow much, but my understanding on what is the heap used for is limited.
The stack grows down, but 64KB is plenty for both.
On my tests I moved the BSS area, PINMAP and the USB buffers at different times.

I just submitted a PR to Steve's fork with the changes to relocate Heap, Stack and PinMap to CCMRAM, and add a new flag __CCMRAM__ so any variable can be moved to it.
https://github.com/stevstrong/Arduino_STM32/pull/5

I think the changes are mostly self explanatory, so it's easy to modify to leave any of those out of CCMRAM, but provides an example covering those uses

BSS can be relocated successfully from my tests, but the any variable declared with default attributes (not forced to normal RAM), would cause a crash if used for DMA, since the DMA controllers can't access CCMRAM.

I think the best use cause is manually adding __CCMRAM__ to the declaration of any variable that the user knows will not be used for DMA, and at the same time needs frequent access, since CCMRAM can be faster than normal RAM due to only being accessed by the CPU.
PINMAP is just a good example due to being large and not used as pointer for DMA.

Re: F4 - Update boards.txt

Posted: Tue Aug 08, 2017 11:21 am
by stevestrong
I thought PIN_MAP is in flash and will be kept there.
I personally don't see any gain by placing it to CCMram, except saving some CPU cycles which is for F4 not so critical as it anyway runs with 168MHz...

Re: F4 - Update boards.txt

Posted: Tue Aug 08, 2017 1:45 pm
by victor_pv
stevestrong wrote:
Tue Aug 08, 2017 11:21 am
I thought PIN_MAP is in flash and will be kept there.
I personally don't see any gain by placing it to CCMram, except saving some CPU cycles which is for F4 not so critical as it anyway runs with 168MHz...
In the version of the core where I used CCMRAM PIN_MAP was still in RAM, that's why I tested moving it to CCMRAM. Agreed that flash is a better place for it. But it gives an example of what's needed for moving something to CCM.
With the same attribute I moved the USB buffers, and pretty much anything that will not be used during DMA and we want a high performance can be moved there.

Re: F4 - Update boards.txt

Posted: Tue Aug 08, 2017 3:44 pm
by stevestrong
Yea, maybe you should update your local copy of the repo, there were lately some major improvements committed.

This is just for the record: heap and stack, in general

Re: F4 - Update boards.txt

Posted: Tue Aug 08, 2017 4:27 pm
by victor_pv
Steve I just commented in the PR.
The /* that was missing is corrected now, but the __ccm_end__ label, perhaps we should change it to something else. it was used the right way, but the meaning is not what you thought, it is to indicate the end of the variables allocated to CCMRAM, so the heap can start after the last variable allocated there.

I have a good understanding on how the stack work, but as far as when is the heap used, I have seem to conflicting information on how it's used in embedded systems, other than when using malloc and new. I'll read thru your link to see if it adds some clarity.

Re: F4 - Update boards.txt

Posted: Tue Aug 08, 2017 4:48 pm
by stevestrong
It seems that I misunderstood the functionality due to the used naming.
Here is what I think I understood:

CCM starts at 0x10000000. This should be called __ccmram_start__.
CCM ends 64kB after __ccmram_start__. This should be called __ccmram_end__. This is the value the stack pointer should be initialized to, right? In this case the __msp_init calculation makes not too much sense for me, and should be fixed to __ccmram_end__.

Going back to CCM start, some variables are allocated, let's say till 0x10001234. This is then the start of the heap, right? If so then it should be called __ccmram__heap_start__. Then the heap can go up to __ccmram_end__?

Stack: starts at __ccmram_end__ and is groing down theoretically till __ccmram__heap_start__, right?

I know, the head and stack may overlap under these conditions, but 64kB is a lot of space for heap and stack together.

Re: F4 - Update boards.txt

Posted: Tue Aug 08, 2017 7:08 pm
by victor_pv
stevestrong wrote:
Tue Aug 08, 2017 4:48 pm
It seems that I misunderstood the functionality due to the used naming.
Here is what I think I understood:

CCM starts at 0x10000000. This should be called __ccmram_start__.
CCM ends 64kB after __ccmram_start__. This should be called __ccmram_end__. This is the value the stack pointer should be initialized to, right? In this case the __msp_init calculation makes not too much sense for me, and should be fixed to __ccmram_end__.

Going back to CCM start, some variables are allocated, let's say till 0x10001234. This is then the start of the heap, right? If so then it should be called __ccmram__heap_start__. Then the heap can go up to __ccmram_end__?

Stack: starts at __ccmram_end__ and is groing down theoretically till __ccmram__heap_start__, right?

I know, the head and stack may overlap under these conditions, but 64kB is a lot of space for heap and stack together.
That's the way it works.
Now, __ccmram_end__ still needs to be calculated, as the way we declare the memory blocks in jtag.ld (and the rest of them) is by START and LENGTH so the linker needs to calculate the end address. No big deal, that's part of all the linker scripts we use for the different boards. I'll keep that one called msp_init since that same name is used in the other linker scripts for all the other boards, so trying to keep as much as possible common.

What I will do is change the name of __ccmram_end__ to __ccmram_heap_start__

If we dont get stack overflows with a mini with 20KB, 64KB should definitely not cause any issue. Everyone should anyway avoid using malloc and new as much as possible, so the heap should normally not grow up. But I remember somewhere reading some embedded compilers place some local large variables in heap instead of stack, and that's what has me a bit confused on how likely is the heap to go up,

I was reading more on it, and one way to find out if a collision between heap and stack caused a crash is to first fill the memory in between with a pattern, then if the system crashes, the memory can be read to find out if the pattern is gone.
FreeRTOS uses a similar system (method 2):
http://www.freertos.org/Stacks-and-stac ... cking.html

I used it once when I wasn't sure if a tasks was causing an overflow, found out it was not.

EDIT:
To be consistent with how the ld script labels were so far, I am making the following changes:
1.- .ccmram section renamed to .ccmdata. That section is to hold data (variables) allocated to CCMRam.
2.- The label for the start of the section is renamed to __ccmdata_start__ to be consistent with the normal data section label (__data_start__).
3.- The end of the section is labelled __ccmdata_end__ to be consistent with the normal ram section (__data_end__)
4.- The heap start is at __ccmdata_end__, so clearly indicating it starts where data ends.