Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
1,188 Views

c++ class memory consumption

Hello, 

 

I am trying to code with cpp and now i started a blank project with a NIOS II/f processor, connected to 16KB onchip RAM, created with QSYS in the NIOS II IDE. 

I took the generated .sopc file and created a bsp project with it. 

Now i made a .cpp file with int main and toggled some LEDs on my Max10 FPGA Dev Kit (10m50DA), everthing OK, console tells me that 9972 Bytes are free for heap and stack. 

My next step, where the memory overflows, is where i create a class, in the same cpp and header file, where my int main() function is, with empty constructor and deconstructor and a public void function, with the toggle code. The output from the console is that .text, .rwdata and so on, would start on an address where no RAM is. 

 

Are there some docs to determine how much memory will be reserved for classes, or is the virtual key word my problem? I think vtable should be around 4Byte..? 

I am new to embedded c++, i used C for NIOS up till now and have some experience with QT5. 

The GCC cersion I am using is 4.8.3. 

The BSP settings are basically the default settings, but with small C library and reduced device drivers, cpp is enabled. 

 

Code is the following: 

 

 

/* * Main.cpp */ # include "Main.h" int main (){ Main test; do { if (IORD_ALTERA_AVALON_PIO_DATA(USER_PB_BASE)==0x2){ test.toggle_leds(); } }while (1==1); } Main::Main () { // TODO Auto-generated constructor stub } Main::~Main () { // TODO Auto-generated destructor stub } void Main::toggle_leds(void){ int counter = 0; for(counter = 0; counter <= 99999; ++counter); IOWR_ALTERA_AVALON_PIO_DATA(LEDS_BASE, 0xF); for(counter = 0; counter <= 99999; ++counter); IOWR_ALTERA_AVALON_PIO_DATA(LEDS_BASE, 0x0); }  

/* * Main.h * */ # ifndef MAIN_H_# define MAIN_H_ # include "altera_avalon_pio_regs.h"# include "system.h" class Main { public: void toggle_leds(void); Main (); virtual ~Main (); }; # endif /* MAIN_H_ */
0 Kudos
12 Replies
Highlighted
Valued Contributor III
6 Views

Hello Eggi, 

 

I do not see a problem with your code at this time. You are even not declaring any variabeles in your class, so it should be really small. 

 

If you think the virtual destructor is the culprit, in this case it is not necessary to have it virtual, so leave the word virtual out. 

It is even not necessary to program an empty desctructor or a constructor in your class anyway. 

 

Normally a lot of information can be found in the .map file that is generated by the linker during the compilation/linking process, here you can estimate code sizes. 

There is a .BSP editor in Eclispe, this editor lets you modify the sizes of segments. 

 

Best Regards, 

Johi.
0 Kudos
Highlighted
Valued Contributor III
6 Views

Hello Johi, 

 

Thank you for your answer. I am really interested in this behaviour. When i remove the destructor, the memory my program uses is nearly the same as written in C without classes. But when i add the destructor and compare the .map file with and without destructor, i see a lot of c++ classes linked (mostly libstdc++). The virtual keyword isn't the problem here. Without it the code it is still too much. 

Is there an explanation what the compiler does?  

Also, will I meet any "strange" behaviour when i remove the destructor? Say i create a function that deallocates memory.
0 Kudos
Highlighted
Valued Contributor III
6 Views

Do you do anything special in the destructor? Isn't the default compiled destructor good enough for your class? 

Do you have the same if you disable RTTI and/or exceptions? 

If it's still the original code you presented and you don't need anything more, I'd just use the default compiled destructor.
0 Kudos
Highlighted
Valued Contributor III
6 Views

Hello, 

 

I am stuck at the compiler options. Where can i set them in the NIOS SBT IDE? 

This is just to test, if I can use c++ the way I'd like to. 

I have a project, momentary written in C which contains a few functions which manage UART communication, CAN communication, writing into the internal flash of the fpga and so on and i thought about rewritting the code in c++ because i like the idea about creating classes and defining objects. 

I would probably be able to write the code without any need for a custom destructor, but just in case I want to be able to use it without the massive memory allocation which occurs at the moment.
0 Kudos
Highlighted
Valued Contributor III
6 Views

I'm not sure because I don't use Eclipse, but I think that you can add compiler options in the project settings > Nios II Application Properies, into the User flags line inside the Flags category. 

To disable rtti, use the -fnortti flag. To disable exceptions, use the -fno-exception flag. 

If your compiler uses C++11 by default (I don't remember when it became the default in GCC) it's possible it adds some additional code. I think C++11 automatically generates copy and move constructors when you define a custom destructor but I'm not sure. You can try and revert to an older standard with the -std=c++98 flag and see if it gets better.
0 Kudos
Highlighted
Valued Contributor III
6 Views

Ok, thank you for your effords. 

I tried the c++11 and 98 flags, which let me compile. 

I had a look at this: https://gcc.gnu.org/onlinedocs/gcc-2.95.2/gcc_2.html , because I use the GCC. 

I used -fno-rtti, but i haven't found a command for disabling exception. In the document was a command to enable them. Could it be, that they are default disabled? 

Still, I have rewritten a small part of my C code. Int main() creates instances of a SPI class which has a send_commands member and a CAN class which has a member which calls a static function from the SPI class and I already get memory overflow. 

I guess I either missunderstand basic c++ behaviour or c++ is just not suitable for my uses. Static methods are in the memory all the time, or am i mistaken? 

Is there any documentation how to use c++ with a NIOSII CPU, I just found the supported features of c++ for NIOSII CPUs. 

 

edit: I just saw that my BSP Settings were back to default. After enabling reduced device drivers and enabling the lightweigth device driver api, the code size was reduced by 8kBytes. It is still a bit much, but I think I can continue with these results.
0 Kudos
Highlighted
Valued Contributor III
6 Views

Sorry the command to disable exceptions is -fno-exceptions with an s. All the options in GCC that can be enabled with an -fxxx can also be disabled with an -fno-xxx. AFAIK exceptions are enabled by default when compiling C++ code and disabled when compiling C. 

Yes 8k is a lot. There doesn't seem to be a way to use a lighter standard library with C++. I think the only way to try and understand why GCC suddenly thinks it needs to link so many library functions would be to have a look at the generated assembly code. Static methods should behave the same way than global C functions.
0 Kudos
Highlighted
Valued Contributor III
6 Views

Hello, 

 

Just one more question. 

to enable the c++11 features, i added -std=c++11 in the linker flags, but when i use unscoped enums i get a warning: scoped enums only avaible with -std=c++11 or -std=gnu++11. 

I defined the enum in my headerfile: enum states : alt_u8 {....}; and there i get the warning. 

Is there an application note, where i can see what features are enabled?
0 Kudos
Highlighted
Valued Contributor III
6 Views

You should put this option in the user flags, not the linker flags. The c++ standard option is relevant at the compile stage. The linker only links already compiled code and doesn't see any high level code.

0 Kudos
Highlighted
Valued Contributor III
6 Views

Ok, here I go again. 

I have ported my C code (7kByte) to c++ code now. But.... I have the problem with the code size. 

I had a look into the map file and came to the conclusion, that from the libstc++.a file, there is a eh_personality.o object file generated which has a size of 26kBytes. 

I found the documentation on the gnu site: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2b%2b-v3/libsupc%2b%2b/eh_personality.cc , but I am bad at finding the cause of this. 

Can you help me here?  

My first guess was, that I use expensive functions, but I couldn't find a function in my code, that is noted in the eh_personality.cc file. 

I also created several instances of my classes (Class* test = new Class) and had a look at the compiler output if the memory usage goes up, but it was minimal (<1kByte). 

So the problem should be in other parts of the code? I have a few functions which aren't in a class.
0 Kudos
Highlighted
Valued Contributor III
6 Views

Eclispe - this editor lets you modify the sizes of segments.

0 Kudos
Highlighted
Valued Contributor III
6 Views

Hello, 

 

looking at the file: 2 expensive functionalities:  

 

RTTI = Runtime Type info  

 

Exception handling. 

 

I would try to disable these capabilities with gcc settings and see where you get. 

 

johi.
0 Kudos