2019-05-29 10:54 AM
Hi,
I'm having trouble, because I got when I defined a second array which I need for processing a image with the STM32F429ZI Microcontroller a message that I have a RAM overflow.
When I now define a smaller array, like uint8_t image[240][320] my whole application is not running on the Microcontroller. But when I comment the initialization n of the image array out, everything is working fine.
How can I see how much memory I have used and how could I rearrange other memory on the Microcontroller?
Thank you
2019-05-29 02:14 PM
>>But somehow my code is not working correctly
Something no doubt you'll need to debug yourself.
>>When I use "uint8_t image[240][320]" (locally in the main function) I don't get an error.
Yes, the array will be half the size, and allocated from the stack. You probably aren't doing a stack-check, so good chance it will blow out globals/statics below the stack/heap
0x20030000 - 0x20024e70 = 0xB190 (45456 bytes), probably not going to accommodate 76800 (320x240)
2019-05-29 02:23 PM
CCM RAM in the 'F40x/42x is connected directly to the mcu and is unavailable for other bus masters, i.e. DMA, including the OTG_HS and ETH DMA.
As such, it's the prime memory to put stack and the processor-only variables into.
JW
(PS, Both OTG_USB modules have their own FIFO RAM - as does CAN - which do not count towards the total 256kB of RAM).
2019-05-29 02:24 PM
CCM RAM can be used but it is not contiguous with other RAM; it is located at 0x1000 0000 - 0x1000 FFFF.
This region would have to be described in your linker control file, then variables / arrays could be placed there (must be less than 64K bytes in size though).
Is your image data constant? If so, you could locate it in flash memory very easily (declare array as const).
2019-05-29 02:31 PM
I personally would put the stack into the CCM at 0x10000000 64KB, but in the GNU/GCC case that would actually require you to understand and fix the memory allocator in _sbrk
Clearly you won't be able to put a 76800 byte array into 64KB either, but you should perhaps evaluate your use of auto/local variables.
Rough math
uint16_t image[74880] takes 149760 bytes
149760 - 45456 bytes left
104304 over available
Does your STM32F429 implementation include SDRAM?
2019-05-29 02:33 PM
Oops - yeah, I mis-added the RAM sizes. There is indeed 192K bytes of RAM starting at 0x20000000 through 0x2002ffff, and the other 64K is the CCM down at 0x10000000 as @Community member said.
2019-05-29 03:24 PM
> I personally would put the stack into the CCM at 0x10000000 64KB, but in the GNU/GCC case that would actually require you to understand and fix the memory allocator in _sbrk
For heap, not stack.
Putting stack to CCM is a trivial exercise in startup code. That most gnu-based tools mess with some linker-based symbol is just that, a mess.
OTOH it won't help with the RAM overflow, stack (unless multitasking aka RTOS) usually does not contain more than a few hundred bytes - oh, and unless there's an attempt to locate huge memories on stack through local declarations. Moving most of mcu-only data into CCM (which requires to retarget bbs/COMMON and data into CCM, two lines in the linker script; but the manually and individually locate large and other-masters-handled data into the "conventional RAM") could help, but not in this case, where 100kB+ is missing.
Our OP clearly omitted some basic back-of-the-envelope calculation before starting a project. I see this more and more often: it appears that these days the newcomers are simply not aware of the orders of magnitude larger information content (=> memory requirement) of pictures (and as an extension, video), and of course the requirements to move these data around not to mention processing them. Caused probably by the ubiquity of huge colorful displays and cheap giga/terabyte memories. This is one of those things which ought to be taught at the higher grades of elementary school these days, instead of formal grammar.
JW
2019-05-29 03:42 PM
Thank you Bob and Clive for your time!
To your questions Bob:
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
2019-05-29 03:46 PM
Thank you Bob and Clive for your response!
To your questions Bob,
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
2019-05-29 04:55 PM
>>For heap, not stack.
it was more of a commentary on the craptacular _sbrk implementations that uses the SP has a high water mark for the heap, and the expectation that both reside in the 0x20000000 memory space, when the stack is down below 0x10010000 it assumes you're 20,000 leagues under the sea and dies.
/*
sbrk
Increase program data space.
Malloc and related functions depend on this
*/
caddr_t _sbrk(int incr) {
extern char _ebss; // Defined by the linker
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &_ebss;
}
prev_heap_end = heap_end;
char * stack = (char*) __get_MSP();
if (heap_end + incr > stack)
{
_write (STDERR_FILENO, "Heap and stack collision\n", 25);
errno = ENOMEM;
return (caddr_t) -1;
//abort ();
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
2019-05-30 12:00 AM
Uh.
I stand firmly on the *control* side of micro*control*ler, which almost completely excludes the notion of dynamic allocation of memory, let alone through any third party library, however glorified it is.
In other words, I didn't know this... ;) Thanks.
Jan