Is there any way within a running sketch, to determine how much flash space that sketch takes up?
In other words, when you verify or write out the sketch you get that message in the lower window "12345 bytes of 32768 bytes used" - is it possible to later on, while the sketch is running, have it figure out its own size?
I am thinking like maybe it can determine the last 'address' in use? LIke it could figure out that "last address = 0x3039" perhaps?
If that is not possible, then maybe using a custom / modified bootloader would do the trick I think? Within the bootloader, capture the final address write then write that out to a known position in EEPROM - eg. if the last byte of the sketch goes to 0x3039 then the bootloader would write that as an unsigned int to a particular spot in eeprom. Then within the sketch I could just query that location in eeprom and get the size from the bootloader?
majenko:
What do you want to know for? I can think of no reason to need to do that.
I want to know because I am curious if it can be done.
Basically like a sort of 'self-status report' from an arduino where it can report some information about its current status / condition, and as irrelevant and useless as it might be, I would like that report to include how big the sketch is.
There are various functions for reporting the amount of free memory available. One of them actually get the heap and stack pointers and computes the distance between them. Looking at how that one works may yield a clue or two.
PaulS:
There are various functions for reporting the amount of free memory available. One of them actually get the heap and stack pointers and computes the distance between them. Looking at how that one works may yield a clue or two.
Unlikely - they work on RAM, which is completely separate to PROGMEM. In a modified Harvard architecture the two types of memory don't occupy the same address space - RAM address 0x14 is not the same as PROGMEM address 0x14.
The size can be written to a file, which can be written to EEPROM.
If using a programmer like USBasp, this can be done automatically.
But with normal Arduino use, the bootloader should be changed.
There are other possibilities:
(1) The compiler has a user define option. This could be used to create a string with the size. The Arduino has to compile twice (one for the size, the second to get the size in the program.
(2) Some data is placed at the end. This is not reliable, but is should be possible to declare a string or constant integer at the end of the code. The address of that string or integer can be used to calculate the size.
(3) Perhaps an extra program section can be defined, which should be placed at the end of the code.
Start from just before the beginning of the bootloader and read backwards until you read a byte that's not 0xFF.
Of course, if there's some area that's not been erased then that may be found as the end of the sketch...
That sounds like a promising option - however I don't know that flash is erased when a sketch is uploaded via the bootloader. So if loading a large sketch, then a smaller sketch afterwards, it would probably read the result as if the larger sketch were still in place. I'm pretty sure it's always erased when using a programmer.
I've been looking through the bootloader code and all the 'fun stuff' happens in assembly which I've never used on an AVR. (I did some PIC programming with assembly but that was a decade ago). It's a fun challenge though - there must be a way to do it.
Start from just before the beginning of the bootloader and read backwards until you read a byte that's not 0xFF.
Of course, if there's some area that's not been erased then that may be found as the end of the sketch...
That sounds like a promising option - however I don't know that flash is erased when a sketch is uploaded via the bootloader. So if loading a large sketch, then a smaller sketch afterwards, it would probably read the result as if the larger sketch were still in place. I'm pretty sure it's always erased when using a programmer.
I've been looking through the bootloader code and all the 'fun stuff' happens in assembly which I've never used on an AVR. (I did some PIC programming with assembly but that was a decade ago). It's a fun challenge though - there must be a way to do it.
Cheers!
A page has to be erased before it can be written, but that's only blocks of 128 bytes (64 words). It's all down to the bootloader I guess... Time to learn AVR assembler...
teddy93093:
When you click compile or upload there should be a black box at the bottom that says Binary sketch size: ______ bytes
Read the question, teddy...
In other words, when you verify or write out the sketch you get that message in the lower window "12345 bytes of 32768 bytes used" - is it possible to later on, while the sketch is running, have it figure out its own size?
Krodal:
If it was possible, I would have added it to my ShowInfo sketch: Arduino Playground - HomePage
There are other possibilities:
(1) The compiler has a user define option. This could be used to create a string with the size. The Arduino has to compile twice (one for the size, the second to get the size in the program.
(2) Some data is placed at the end. This is not reliable, but is should be possible to declare a string or constant integer at the end of the code. The address of that string or integer can be used to calculate the size.
(3) Perhaps an extra program section can be defined, which should be placed at the end of the code.
(4) The Linker can be told to put a symbol at the end of text. The standard symbol the linker puts out is etext. So, the following may work:
You might have to subtract etext from the beginning of memory, if it isn't 0. I don't know if the IDE does anything weird and wacky, like use its own linker configuration files.
I have already uploaded a new ShowInfo with runtime calculation of sketch size.
The function "sketchSize(void)" is used with the 'i' command. http://arduino.cc/playground/Main/ShowInfo
Wow this sounds great! I'm stuck at work and can't try it out but I will as soon as I'm back home.
I had been reading one of the datasheets and was not getting anywhere - I couldn't find anything indicating a way to read from the program area, only information on writing to it.
Krodal:
This is the result of the speed test with the sketch (version July 2012) with Arduino 1.0.1. It shows clearly the problem with division on the AVR chip. Both the integer and floating point division is a lot slower than multiplying.
The 'problem' is the ATmega has no division hardware, so in order to do a division, it does a loop doing shift, compare/branch, and subtract for each bit in the integer + 1. As I read the assembly code:
8 bit division is 9 loops of 7 instructions;
16 bit division is 17 loops of 12 instructions;
32 bit division is 33 loops of 20 instructions.
Division is always slow, even if you have hardware support. However, if you are willing to put in a lot of transistors/gates to support divide, it isn't as slow as the iterative method used in embedded processors.
Division is always slow, even if you have hardware support
In the dsPICs I use it takes 1 clock cycle...
I see the quote from their tech sheet, but I have to imagine that either they throw an awful amount of chip real estate to do the divisions (possible, it may that it is advantageous in their market place), or the normal cycle is slow enough that they can do divides in a single cycle. I must admit that is the first microprocessor I've looked at that claims single cycle divide (single cycle multiply is more likely).
Division is always slow, even if you have hardware support
In the dsPICs I use it takes 1 clock cycle...
I see the quote from their tech sheet, but I have to imagine that either they throw an awful amount of chip real estate to do the divisions (possible, it may that it is advantageous in their market place), or the normal cycle is slow enough that they can do divides in a single cycle. I must admit that is the first microprocessor I've looked at that claims single cycle divide (single cycle multiply is more likely).