If the heap meta-data is corrupted, often the error is detected when when further heap operations (alloc/free) fail. Corrupting this data has non-deterministic effects on other code most often unrelated to the code that caused the error, such that it is common for failure to occur some-time after and in code unrelated to the event that caused the error. Typically such memory contains the heap-management meta-data for the block or other flocks, and the actual data for other allocations. Heap corruption - an owner of an allocated block can easily under/overrun an allocation and corrupt adjacent memory.Determinism - most heap allocators take a variable and non-deterministic length of time to allocate memory, and even freeing can be non-deterministic if it involves block consolidation.Memory leaks - your own, your colleagues on a team and third party code may not be as high a quality as you would hope you need to be certain that the entire code base is free of memory leaks (failing to deallocate/free memory appropriately).Memory constraints - many embedded systems have very small memories, you have to consider the response, safety and functionality of the system in the event an allocation request cannot be satisfied. There are a number of issues to consider, including: The use of dynamic memory (heap) allocation in embedded systems needs to be carefully considered (or even banned as would suggest, but not all embedded systems are subject to the same constraints). One notable exception is the Keil ARM-MDK toolchain, which requires you to explicitly set a heap size.Ī linker script may reserve memory regions for other purposes especially if the memory is not homogeneous - for example on-chip MCU memory will typically be faster to access than external RAM, and may itself be subdivided on different busses so for example there might be a small segment useful for DMA on a separate buss so avoiding bus contention and yielding more deterministic execution. Many default linker scripts automatically expand the heap to fill all remaining space available after static data and stack allocation. Some examples (partly toolchain specific) at: The linker script normally defines only the system stack for the main() thread and interrupt/exception handlers.Įstimating the required stack usage is not always easy, but methods for doing so exist, using either static or dynamic analysis. Typically these thread stacks are statically allocated arrays or dynamically (heap) allocated rather then defined by the linker script. For this reasons ISR should generally be short, deterministic and use few variables.įurther is you have a multi-threaded environment such as an RTOS scheduler, each thread will have a separate stack. On top of that on many architectures you have to also account for interrupt handler stack usage, which is generally less deterministic, but still has a "worst-case" of interrupt nesting and call depth. The stack usage is dynamic, but there will be some worst-case path where the combination of variables and call-depth causes a peak usage. Local, non-static variables, function arguments and call return addresses are generally stored on the stack so the required stack size depends on the call depth and the number and size of local-variables and parameters for each function in a call-tree. It is a software dependent partitioning of memory, not hardware dependent. These are not defined in the microcontroller user manual because they are not hardware defined constraints.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |