8-bit AVR: sketch 3,780 bytes and global variables 237 bytes
stm32duino: sketch 73,520 bytes and global variables 6,456 bytes
Heres the ReadASCIIString example compiled for the same two boards:
8-bit AVR: 3,506 bytes, global variables use 188 bytes
stm32duino: sketch 17,828 bytes and global variables use 4,224
So for an 8-bit AVR, my program is only marginally larger than ReadASCIIString, which makes sense, they do very similar things. But then on stm32 my code comes out 4 times larger than ReadASCIIString. Im not using any additional libraries, all my code does is read a serial message, read some ADC inputs and reply with the ADD values, its not very technical stuff.
I have tried chopping up the sketch and commenting out huge chunks, and I havent yet found what is causing it. I know there is a ton of extra code for the USB-serial stuff, but there must be more to it than that.
I dont really want to post the whole project (its about 300 lines), but does anyone have any ideas about where I should be looking to work this out?
I dont really want to post the whole project (its about 300 lines), but does anyone have any ideas about where I should be looking to work this out?
if you are using the bootloader, there is the Serial USB stuff (as it has to go somewhere, i.e either the bootloader of the sketch, the overall amount of space taken would be the same)
But all boards have multiple hardware serial ports, minimum of 3 hardware serial.
I suspect the libraries for some things are bigger than on AVR, I know that the double variable type is correctly supported (AVR types double back to float), and the AVR takes a load of shortcuts to reduce code size, which make it a much less standard C compiler / linker.
However, if post the code somewhere, we could take a look
I’m doing some further investigation this morning to see if I can narrow it down.
I’ve look at one of my sketches, and I saw that “cxa_demangle” from gcclibcxx is quite big. (I will try to figure out this one)
Minimal example:
void setup() {
// initialise serial
Serial.begin(115200);
//this makes a 73K sketch
//byte *buf;
//buf = new byte [64];
//this makes a 12K sketch
byte buf[64];
}
void loop()
{
Serial.println("Running...");
delayMicroseconds(1000000);
}
What you are asking the compiler to do is two completely different things.
Using “new” you are asking the compiler to create an array or objects of type byte rather than an array of bytes
I suspect the AVR compiler is simply not standards compliant and lets you do things like this, by not doing what an ANSI standard C++ compiler should do.
I have no idea why the byte object takes up so much space, probably Rick would be the person to advise on this. Perhaps its because internally the compiler is using malloc and there is a minimum allocation size.
char* pvalue = NULL; // Pointer initialized with null
pvalue = new char[20]; // Request memory for the variable
There are many things that C++ can do, but which you should avoid on embedded devices.
e.g. Use of malloc etc is generally not advised because the minimum allocation block size is often quite large in embedded terms, and also can lead to memory fragmentation.
Whether using ‘new’ was appropriate or sensible in my sketch is probably an entirely separate argument (and it was almost certainly not the best way to achieve what I was trying to).
I guess my main observation is just that it appears to work in an 8-bit arduino environment and not in the 32-bit. Im quite happy not using the function, just interested to know why it works differently on the different platforms.
I’m not sure if there is a definitive list of the differences between the AVR and ARM compilers.
Perhaps its worth posting to the Due section of the Arduino.cc forum, as that will have the same “issues” as we are using exactly the same compiler as the Due (which is why you need to install the Due from the boards manager – as the ARM compiler is no longer installed by default)
And of course the shiny new Zero board will have the same issues. I suspect people buying the Zero as a replacement for the tried and tested Uno will be in for a few surprises.
Is the Keil compiler any better. I’ve heard it is more optimised than GCC
<…>
Is the Keil compiler any better. I’ve heard it is more optimised than GCC
<…>
I have no experience with Keil and unlikely I ever will. When I want to make something small I try to make sure it isn’t using any libc stuff.
-rick
On arduino due there is the same problem. Linker generates massive binary when new and delete has been used.
Put the code at the top of the sketch.
void * operator new (size_t size) { return malloc (size); }
void * operator new (size_t size, void * ptr) { return ptr; }
void operator delete (void * ptr) { free (ptr); }
Now sketch size should by normal size.
Is the Keil compiler any better. I’ve heard it is more optimised than GCC
Thanks for the link to the free copy of Keil. I will grab a copy, just in case they change their minds about giving it away for free.
I dont need it now, but you never know in the future …..
Edit.
I downloaded the installer, but the page you get to when downloading, has text on their about limitations on demo and evaluation software.
I’m not sure if this is just because this text is always on that page, or whether this version of Keil is really just an evaluation copy.
You also need to register with MDK in order to get an activation code, i.e you can’t simply enter the code that is on the first page you get to.
So…
I’m probably not going to bother jumping through hoops to get Keil, as its unclear if I’m doing this just to get some evaluation software, rather than something I’m actually allowed to use in any practical sense.
(I know this is now the norm for big companies, even for evaluation software, to require registration and license code validation online etc etc, which is fine if you need it for work etc, but rather a pain just to evaluate something)
void setup() {
byte* a = new byte[1]; // 18330 bytes flash, 3928 bytes RAM
// byte* a = (byte*)malloc(1); // 15276 bytes flash, 2824 bytes RAM
// static byte a[1]; // 15276 bytes flash, 2824 bytes RAM
}

