Heap allocation on a microcontrollerPC shares memory with external microcontrollerHow to add memory to an ARM Cortex MicrocontrollerMicrocontroller on-chip flash consumption - size matters?How to know the memory occupied by the various memory segments in a microcontrollerInterfacing USB with a microcontrollerHow much RAM do I have for dynamic memory allocation in my Nios IIInductor near the microcontrollerSTM32 Mass Storage with 8K allocation unit sizeWhat is address allocation of memory register?Handling Large Variable Data with a Microcontroller
Would it be a copyright violation if I made a character’s full name refer to a song?
Is there a maximum distance from a planet that a moon can orbit?
Inverse-quotes-quine
Vanishing of certain coefficients coming from Coxeter groups
Archery in modern conflicts
Long term BTC investing
Is it illegal to withhold someone's passport and green card in California?
How would modern naval warfare have to have developed differently for battleships to still be relevant in the 21st century?
Are all instances of trolls turning to stone ultimately references back to Tolkien?
What's currently blocking the construction of the wall between Mexico and the US?
What reason would an alien civilization have for building a Dyson Sphere (or Swarm) if cheap Nuclear fusion is available?
Employer wants to use my work email account after I quit
STM Microcontroller burns every time
Interaction between Leyline of Anticipation and Teferi, Time Raveler
Trainee keeps missing deadlines for independent learning
How to make clear to people I don't want to answer their "Where are you from?" question?
Fill NAs in R with zero if the next valid data point is more than 2 intervals away
Why cruise at 7000' in an A319?
Can Ogre clerics use Purify Food and Drink on humanoid characters?
Can ADFS connect to other SSO services?
Why is the voltage measurement of this circuit different when the switch is on?
Cascading Repair Costs following Blown Head Gasket on a 2004 Subaru Outback
Is my Rep in Stack-Exchange Form?
How to get cool night-vision without lame drawbacks?
Heap allocation on a microcontroller
PC shares memory with external microcontrollerHow to add memory to an ARM Cortex MicrocontrollerMicrocontroller on-chip flash consumption - size matters?How to know the memory occupied by the various memory segments in a microcontrollerInterfacing USB with a microcontrollerHow much RAM do I have for dynamic memory allocation in my Nios IIInductor near the microcontrollerSTM32 Mass Storage with 8K allocation unit sizeWhat is address allocation of memory register?Handling Large Variable Data with a Microcontroller
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
I'm working on STM32F303VC. How does the heap allocation work?
When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)
There are two options:
In the 'startup_stm32f30x.s' file I see that:
Heap_Size EQU 0x00000200 // Which is only 1K!
[See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]
But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).
So I checked this in the debugger:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes
int main(void)
_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;
This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:
uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes
int main(void)
_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;
It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).
So, what is the meaning of the A line code? And the meaning of the size I enter in B?
stm32 memory
$endgroup$
|
show 1 more comment
$begingroup$
I'm working on STM32F303VC. How does the heap allocation work?
When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)
There are two options:
In the 'startup_stm32f30x.s' file I see that:
Heap_Size EQU 0x00000200 // Which is only 1K!
[See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]
But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).
So I checked this in the debugger:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes
int main(void)
_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;
This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:
uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes
int main(void)
_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;
It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).
So, what is the meaning of the A line code? And the meaning of the size I enter in B?
stm32 memory
$endgroup$
$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31
$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50
$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22
$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58
$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46
|
show 1 more comment
$begingroup$
I'm working on STM32F303VC. How does the heap allocation work?
When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)
There are two options:
In the 'startup_stm32f30x.s' file I see that:
Heap_Size EQU 0x00000200 // Which is only 1K!
[See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]
But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).
So I checked this in the debugger:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes
int main(void)
_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;
This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:
uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes
int main(void)
_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;
It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).
So, what is the meaning of the A line code? And the meaning of the size I enter in B?
stm32 memory
$endgroup$
I'm working on STM32F303VC. How does the heap allocation work?
When I declare the arrays outside main() it allocates them on the heap - SRAM - 0x2000000 and forth in this MCU. But what determines the size of the heap? (And hence its overflow.)
There are two options:
In the 'startup_stm32f30x.s' file I see that:
Heap_Size EQU 0x00000200 // Which is only 1K!
[See here: [http://www.keil.com/support/man/docs/armlib/armlib_chr1358938939461.htm. Anyway, I just used the default file from STM's library]
But on the target configurations options, the R/W memory area is declared to be a size of 0x8000 (which is 32K).
So I checked this in the debugger:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30 kilobytes
int main(void)
_xValH[4999] = 0x4;
_xValL[4999] = 0x5;
_xVal[4999] = 0x6;
This didn't throw an exception - which means that it is the second option of the above. But furthermore, even if I go above the 32K - say:
uint16_t _xValH[6000];
uint16_t _xValL[6000];
uint16_t _xVal[6000];
//3*6000*2 bytes each = 36 kilobytes
int main(void)
_xValH[5999] = 0x4;
_xValL[5999] = 0x5;
_xVal[5999] = 0x6;
It's still working! The only time it throws me to exception is when I surpass the 40K - which is the limit of the SRAM (0x20009FFF).
So, what is the meaning of the A line code? And the meaning of the size I enter in B?
stm32 memory
stm32 memory
edited Jun 7 at 10:52
Peter Mortensen
1,5893 gold badges14 silver badges22 bronze badges
1,5893 gold badges14 silver badges22 bronze badges
asked Jun 6 at 10:24
EladElad
234 bronze badges
234 bronze badges
$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31
$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50
$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22
$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58
$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46
|
show 1 more comment
$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31
$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50
$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22
$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58
$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46
$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31
$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31
$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50
$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50
$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22
$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22
$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58
$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58
$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46
$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46
|
show 1 more comment
5 Answers
5
active
oldest
votes
$begingroup$
You misunderstand what the heap is.
The heap is the area where malloc
gives you blocks of RAM dynamically at run-time.
Your globally scoped, statically allocated variables & arrays are not 'on the heap'.
If you're not using malloc
or any of its variants in your program, you can quite safely set the heap size to 0.
$endgroup$
$begingroup$
Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
$endgroup$
– Elad
Jun 7 at 12:17
add a comment |
$begingroup$
Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.
Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.
Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.
While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.
$endgroup$
add a comment |
$begingroup$
Consider:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30Kbytes
int main(void) {
These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.
$endgroup$
add a comment |
$begingroup$
The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc()
family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc()
all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc()
but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.
In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc()
. For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc()
provides no such flexibility, user-written allocation functions can.
$endgroup$
$begingroup$
"The Standard" can refer to a very large number of documents. Please say which standard you are referring.
$endgroup$
– Stig Hemmer
Jun 7 at 7:38
$begingroup$
The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
$endgroup$
– supercat
Jun 7 at 15:18
add a comment |
$begingroup$
I hope this should clear things up. It examples the different method of memory allocation in standard C.
#include <stdint.h>
#include <stdlib.h>
#include <stm32f30x.h>
uint32_t static_allocation;
int main(void)
uint32_t stack_allocation;
static uint32_t private_static_allocation;
uint32_t *heap_allocation;
heap_allocation = malloc(4);
static_allocation = 0x11111111;
stack_allocation = 0x22222222;
private_static_allocation = 0x33333333;
*heap_allocation = 0x44444444;
while(1)
// Stop simulation here
__BKPT(0);
// remove not referenced warnings
(void)static_allocation;
(void)stack_allocation;
(void)private_static_allocation;
(void)heap_allocation;
free(heap_allocation);
A quick glimpse at symbol table the ARM Linker generously created shows:
private_static_allocation 0x20000004 Data 4 main.o(.data)
static_allocation 0x20000000 Data 4 main.o(.data)
Which means the linker knows, at compile time, where these variables will live.
Including the following objects in memory map:
0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o
And to check it really works like this, simulation debugger shows:
Notice stack_allocation
isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0
the compiler optimizes stack variables.
Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.
But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.
Both heap and stack overflow are not warned about during compilation since they are runtime errors.
Relevant documentations: __use_no_heap.
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("schematics", function ()
StackExchange.schematics.init();
);
, "cicuitlab");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "135"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f442239%2fheap-allocation-on-a-microcontroller%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
You misunderstand what the heap is.
The heap is the area where malloc
gives you blocks of RAM dynamically at run-time.
Your globally scoped, statically allocated variables & arrays are not 'on the heap'.
If you're not using malloc
or any of its variants in your program, you can quite safely set the heap size to 0.
$endgroup$
$begingroup$
Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
$endgroup$
– Elad
Jun 7 at 12:17
add a comment |
$begingroup$
You misunderstand what the heap is.
The heap is the area where malloc
gives you blocks of RAM dynamically at run-time.
Your globally scoped, statically allocated variables & arrays are not 'on the heap'.
If you're not using malloc
or any of its variants in your program, you can quite safely set the heap size to 0.
$endgroup$
$begingroup$
Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
$endgroup$
– Elad
Jun 7 at 12:17
add a comment |
$begingroup$
You misunderstand what the heap is.
The heap is the area where malloc
gives you blocks of RAM dynamically at run-time.
Your globally scoped, statically allocated variables & arrays are not 'on the heap'.
If you're not using malloc
or any of its variants in your program, you can quite safely set the heap size to 0.
$endgroup$
You misunderstand what the heap is.
The heap is the area where malloc
gives you blocks of RAM dynamically at run-time.
Your globally scoped, statically allocated variables & arrays are not 'on the heap'.
If you're not using malloc
or any of its variants in your program, you can quite safely set the heap size to 0.
answered Jun 6 at 12:42
brhansbrhans
10.1k2 gold badges24 silver badges32 bronze badges
10.1k2 gold badges24 silver badges32 bronze badges
$begingroup$
Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
$endgroup$
– Elad
Jun 7 at 12:17
add a comment |
$begingroup$
Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
$endgroup$
– Elad
Jun 7 at 12:17
$begingroup$
Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
$endgroup$
– Elad
Jun 7 at 12:17
$begingroup$
Ok, so this explains that it has nothing to do with the heap. Still, what is the meaning of the r/w memory size declared in the target configurations?
$endgroup$
– Elad
Jun 7 at 12:17
add a comment |
$begingroup$
Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.
Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.
Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.
While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.
$endgroup$
add a comment |
$begingroup$
Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.
Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.
Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.
While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.
$endgroup$
add a comment |
$begingroup$
Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.
Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.
Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.
While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.
$endgroup$
Those are global variables. Which generally are not allocated on either stack or heap. Exactly where they are is a longer discussion.
Your heap space is for 'globally accessible' variables created during run time. Which is different to global variables, which are allocated before your main() function is entered. Heap space variables can be allocated, de-allocated, reallocated and resized. A global variable you're generally stuck with for the entire program execution.
Your stack space is for local variables. Anything put on it by a function will be removed when the function returns.
While some implementations may put some global variables at the base of the stack, it certainly isn't a rule.
answered Jun 6 at 13:13
heketehekete
6941 silver badge10 bronze badges
6941 silver badge10 bronze badges
add a comment |
add a comment |
$begingroup$
Consider:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30Kbytes
int main(void) {
These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.
$endgroup$
add a comment |
$begingroup$
Consider:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30Kbytes
int main(void) {
These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.
$endgroup$
add a comment |
$begingroup$
Consider:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30Kbytes
int main(void) {
These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.
$endgroup$
Consider:
uint16_t _xValH[5000];
uint16_t _xValL[5000];
uint16_t _xVal[5000];
//3*5000*2 bytes each = 30Kbytes
int main(void) {
These are global variable declarations. These declarations reserve permanent static space in RAM. The heap is for dynamic allocations in memory.
edited Jun 7 at 10:07
Peter Mortensen
1,5893 gold badges14 silver badges22 bronze badges
1,5893 gold badges14 silver badges22 bronze badges
answered Jun 6 at 23:41
Josko MarsicJosko Marsic
112 bronze badges
112 bronze badges
add a comment |
add a comment |
$begingroup$
The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc()
family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc()
all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc()
but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.
In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc()
. For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc()
provides no such flexibility, user-written allocation functions can.
$endgroup$
$begingroup$
"The Standard" can refer to a very large number of documents. Please say which standard you are referring.
$endgroup$
– Stig Hemmer
Jun 7 at 7:38
$begingroup$
The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
$endgroup$
– supercat
Jun 7 at 15:18
add a comment |
$begingroup$
The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc()
family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc()
all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc()
but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.
In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc()
. For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc()
provides no such flexibility, user-written allocation functions can.
$endgroup$
$begingroup$
"The Standard" can refer to a very large number of documents. Please say which standard you are referring.
$endgroup$
– Stig Hemmer
Jun 7 at 7:38
$begingroup$
The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
$endgroup$
– supercat
Jun 7 at 15:18
add a comment |
$begingroup$
The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc()
family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc()
all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc()
but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.
In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc()
. For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc()
provides no such flexibility, user-written allocation functions can.
$endgroup$
The Standard does not require freestanding implementations to provide any sort of heap. In some cases, they will pre-allocate a certain amount of space for use by the malloc()
family of functions, with such space being essentially wasted if no such functions are ever used. In other cases, the compiler will reserve a certain amount of RAM for the stack and then make available to malloc()
all storage that isn't and won't be used for any other purpose. In still other cases, an implementation won't provide malloc()
but will provide the starting and ending address of a range of storage that the implementation has been told the hardware has, but which the implementation itself has no use for; a user application may then subdivide this range of addresses via whatever means it sees fit.
In many cases, the latter approach is the best, because user-written allocation functions can offer finer control over allocations and fallback logic than malloc()
. For example, it may be useful to determine, before performing a bunch of allocations, whether all can be guaranteed to succeed (eliminating the need to gracefully recover from an allocation failure in the middle of a task). While malloc()
provides no such flexibility, user-written allocation functions can.
answered Jun 6 at 19:27
supercatsupercat
38.7k1 gold badge65 silver badges114 bronze badges
38.7k1 gold badge65 silver badges114 bronze badges
$begingroup$
"The Standard" can refer to a very large number of documents. Please say which standard you are referring.
$endgroup$
– Stig Hemmer
Jun 7 at 7:38
$begingroup$
The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
$endgroup$
– supercat
Jun 7 at 15:18
add a comment |
$begingroup$
"The Standard" can refer to a very large number of documents. Please say which standard you are referring.
$endgroup$
– Stig Hemmer
Jun 7 at 7:38
$begingroup$
The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
$endgroup$
– supercat
Jun 7 at 15:18
$begingroup$
"The Standard" can refer to a very large number of documents. Please say which standard you are referring.
$endgroup$
– Stig Hemmer
Jun 7 at 7:38
$begingroup$
"The Standard" can refer to a very large number of documents. Please say which standard you are referring.
$endgroup$
– Stig Hemmer
Jun 7 at 7:38
$begingroup$
The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
$endgroup$
– supercat
Jun 7 at 15:18
$begingroup$
The C89, C90, C99, C11, and C17 standards documents, along with their published final drafts, are all consistent on this issue.
$endgroup$
– supercat
Jun 7 at 15:18
add a comment |
$begingroup$
I hope this should clear things up. It examples the different method of memory allocation in standard C.
#include <stdint.h>
#include <stdlib.h>
#include <stm32f30x.h>
uint32_t static_allocation;
int main(void)
uint32_t stack_allocation;
static uint32_t private_static_allocation;
uint32_t *heap_allocation;
heap_allocation = malloc(4);
static_allocation = 0x11111111;
stack_allocation = 0x22222222;
private_static_allocation = 0x33333333;
*heap_allocation = 0x44444444;
while(1)
// Stop simulation here
__BKPT(0);
// remove not referenced warnings
(void)static_allocation;
(void)stack_allocation;
(void)private_static_allocation;
(void)heap_allocation;
free(heap_allocation);
A quick glimpse at symbol table the ARM Linker generously created shows:
private_static_allocation 0x20000004 Data 4 main.o(.data)
static_allocation 0x20000000 Data 4 main.o(.data)
Which means the linker knows, at compile time, where these variables will live.
Including the following objects in memory map:
0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o
And to check it really works like this, simulation debugger shows:
Notice stack_allocation
isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0
the compiler optimizes stack variables.
Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.
But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.
Both heap and stack overflow are not warned about during compilation since they are runtime errors.
Relevant documentations: __use_no_heap.
$endgroup$
add a comment |
$begingroup$
I hope this should clear things up. It examples the different method of memory allocation in standard C.
#include <stdint.h>
#include <stdlib.h>
#include <stm32f30x.h>
uint32_t static_allocation;
int main(void)
uint32_t stack_allocation;
static uint32_t private_static_allocation;
uint32_t *heap_allocation;
heap_allocation = malloc(4);
static_allocation = 0x11111111;
stack_allocation = 0x22222222;
private_static_allocation = 0x33333333;
*heap_allocation = 0x44444444;
while(1)
// Stop simulation here
__BKPT(0);
// remove not referenced warnings
(void)static_allocation;
(void)stack_allocation;
(void)private_static_allocation;
(void)heap_allocation;
free(heap_allocation);
A quick glimpse at symbol table the ARM Linker generously created shows:
private_static_allocation 0x20000004 Data 4 main.o(.data)
static_allocation 0x20000000 Data 4 main.o(.data)
Which means the linker knows, at compile time, where these variables will live.
Including the following objects in memory map:
0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o
And to check it really works like this, simulation debugger shows:
Notice stack_allocation
isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0
the compiler optimizes stack variables.
Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.
But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.
Both heap and stack overflow are not warned about during compilation since they are runtime errors.
Relevant documentations: __use_no_heap.
$endgroup$
add a comment |
$begingroup$
I hope this should clear things up. It examples the different method of memory allocation in standard C.
#include <stdint.h>
#include <stdlib.h>
#include <stm32f30x.h>
uint32_t static_allocation;
int main(void)
uint32_t stack_allocation;
static uint32_t private_static_allocation;
uint32_t *heap_allocation;
heap_allocation = malloc(4);
static_allocation = 0x11111111;
stack_allocation = 0x22222222;
private_static_allocation = 0x33333333;
*heap_allocation = 0x44444444;
while(1)
// Stop simulation here
__BKPT(0);
// remove not referenced warnings
(void)static_allocation;
(void)stack_allocation;
(void)private_static_allocation;
(void)heap_allocation;
free(heap_allocation);
A quick glimpse at symbol table the ARM Linker generously created shows:
private_static_allocation 0x20000004 Data 4 main.o(.data)
static_allocation 0x20000000 Data 4 main.o(.data)
Which means the linker knows, at compile time, where these variables will live.
Including the following objects in memory map:
0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o
And to check it really works like this, simulation debugger shows:
Notice stack_allocation
isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0
the compiler optimizes stack variables.
Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.
But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.
Both heap and stack overflow are not warned about during compilation since they are runtime errors.
Relevant documentations: __use_no_heap.
$endgroup$
I hope this should clear things up. It examples the different method of memory allocation in standard C.
#include <stdint.h>
#include <stdlib.h>
#include <stm32f30x.h>
uint32_t static_allocation;
int main(void)
uint32_t stack_allocation;
static uint32_t private_static_allocation;
uint32_t *heap_allocation;
heap_allocation = malloc(4);
static_allocation = 0x11111111;
stack_allocation = 0x22222222;
private_static_allocation = 0x33333333;
*heap_allocation = 0x44444444;
while(1)
// Stop simulation here
__BKPT(0);
// remove not referenced warnings
(void)static_allocation;
(void)stack_allocation;
(void)private_static_allocation;
(void)heap_allocation;
free(heap_allocation);
A quick glimpse at symbol table the ARM Linker generously created shows:
private_static_allocation 0x20000004 Data 4 main.o(.data)
static_allocation 0x20000000 Data 4 main.o(.data)
Which means the linker knows, at compile time, where these variables will live.
Including the following objects in memory map:
0x20000010 0x00000200 Zero RW 2 HEAP startup_stm32f30x.o
0x20000210 0x00000400 Zero RW 1 STACK startup_stm32f30x.o
And to check it really works like this, simulation debugger shows:
Notice stack_allocation
isn't on the actual stack yet, but in a register. This is due to the small amount of variables in this example. Even with -O0
the compiler optimizes stack variables.
Also notice the place of 0x11.., 0x22.. with 0x44.. being inside the heap object.
But no other objects are in here. This means that you can safely reduce heap to 0 if you do not use malloc. Some library functions do implicitly.
Both heap and stack overflow are not warned about during compilation since they are runtime errors.
Relevant documentations: __use_no_heap.
edited Jun 7 at 12:16
answered Jun 7 at 12:10
Jeroen3Jeroen3
12.4k19 silver badges50 bronze badges
12.4k19 silver badges50 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Electrical Engineering Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f442239%2fheap-allocation-on-a-microcontroller%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
If you're looking for a runtime exception, keep in mind that not all microcontrollers have them. For example, they will cheerfully do the math to index past the end of a static array (or before the beginning if your math can include negative numbers), access whatever happens to be there, and go on their merry way. Pointers are similarly followed blindly. No memory protection at all, so everything becomes global. | The only exception you might have of any kind could be a hardware interrupt, for which you've presumably written an interrupt service routine, a.k.a. "exception handler" of sorts.
$endgroup$
– AaronD
Jun 7 at 3:31
$begingroup$
In a context like this (powers of two, hexadecimal numbers), it is better to use 1024 for a kilobyte, not 1000.
$endgroup$
– Peter Mortensen
Jun 7 at 8:50
$begingroup$
@AaronD the fact is I do accept exception when supressing the SRAM limit, as I said.
$endgroup$
– Elad
Jun 7 at 12:22
$begingroup$
@Elad On THAT micro, you do, but you don't always have them in the first place. So don't just blindly rely on it. If you start using lower-end hardware, it'll just blindly go after whatever address comes out of the program. If that address is not implemented, it may wrap around (mod RAM_size) and use that address instead, or the write will do nothing and a read will return 0, -1, maybe the address depending on the hardware implementation, or random garbage. In all cases, the program will carry on as if nothing was wrong. What a way to create weird bugs! (peripherals are in that space too...)
$endgroup$
– AaronD
Jun 7 at 17:58
$begingroup$
@AaronD ok, that is an important note. anyway, can you tell me, if so, what is the meaning of the r/w memory area in the 'target configurations' tool on keil? I can see now on keil's site that "The default check box before each entry enables the area globally for the application" - If on practice I can still allocate area on all SRAM, so it doesn't have any meaning de facto. (?)
$endgroup$
– Elad
Jun 10 at 7:46