2012-09-27 12:12 AM
Hello,
I am using Keil and I have started to try using C++. That seems to work okay except that i ran into some strange behaviour for which I have no explanation. Lets say that I have 4 different classes C1, C2, C3 and C4. None of these classes have a lot of data as member data (maybe 10 x u 32 for each). In the main loop I need to instanciate one of each of these classes. and for two ways which should give the same results I have two different behaviours : Situation 1, This situation works flawlessly :C1 myC1;C2 myC2;
C3 myC3;
C4 myC4;
void main(void)
{
C1.dosomething();
....
}
Situation 2 : This situation is hanging up the running.void main(void)
{
C1 *pC1 = new C1();
C2 *pC2 = new C2();
C3 *pC3 = new C3();
C4 *pC4 = new C4();
pC1->Dosomething();
} In that situation, the run will hang on the line creating C4. If I switch the order of the class creation, It will hang always on the last class creation. I have looked in the assembly and it remains stuck on teh first instruction for the new which is a mov . I suppose it might be a memory management issue, but I am not sure where to start with. last thing is that I dont do anything special in the classes contructors except initializing some members. If anyone has a clue on what could cause this behaviour, that would be appreciated :) Lionel.
2012-09-27 01:59 AM
In that situation, the run will hang on the line creating C4.
I would watch the stack/heap sizes and positions at this point C++ is notorious for it's behind-the-back memory handling and allocation. This works fine on a PC or any system with MMU and plenty of RAM, but is becoming a PITA on small systems with a few kB of RAM. To be fair, C++ was designed with PC-like systems in mind. There is a downscaled subset called EC++ for embedded design, which is supposedly more famous in japan. However, it has not received the same attention otherwhere as plain C, AFAIK. IAR had been supporting this, at least in former versions.
2012-09-27 07:14 AM
Ok, I looked in the startup*.s file and i figured that the heap size of STMF32F103 in Medium density was 0x200 (512 bytes ...) this is what comes with the CMSIS library.
Stack is 0x400 that is 1k. I have increased the heap size to 0x2000 (8k). I know that the STMF103I am using has 20k of RAM, but I have no clue on how to compute the different sizes for each memory type. Do you know if there would be any document link which would explain how to adjust the different memory sizes ? Righ now I have : Stack_Size EQU 0x00000400 Heap_Size EQU 0x00002000 (After modification). Is there anything else to take into account ? How can i know up to which heap size I can go ? Lionel.2012-09-27 07:29 AM
Is there anything else to take into account ? How can i know up to which heap size I can go ?
You'll have to make a determination of what your usage/footprint actually is. C++ being particularly good a hiding the dirty details. You'll need to become more aware. Embedded programing, with tight memory footprints, is not a good place to rely on dynamic memory allocations, with potential issues with failure, fragmentation, leakage, and garbage collection. You might need to dig deeper into the libraries to understand, and extract metrics, from the allocator. For the stack you can fill it with known patterns, and make a determination of maximum depth. There are analysis tools that can look at the call tree, vs local allocation, or you can think about it carefully.2012-09-27 08:14 AM
You'll have to make a determination of what your usage/footprint actually is. C++ being particularly good a hiding the dirty details. You'll need to become more aware.
Exactly that. As a first step, I would watch the heap/stack when single-stepping into/through the offending C++ expression. That could positively proof that you indeed ran into an out-of-memory event. OOP and bare-metal development don't fit together particularly good.