Get program size (flash used) RUNTIME - possible?

Hi all,

I know that I can see free SRAM with the [u]MemoryFree[/u] library, but is there a way to determine the amount of PROGMEM (flash) memory used?

Yes the IDE tells me how large the code is, but I want to be able to determine it runtime. Is this possible?

I tried re-flashing the bootloader (which erases the whole chip except for the last 512 bytes), then used pgm_read_byte(address) running backwards to find the first non 0xFF byte (which works), but it seems like a clumsy way to do it (and the start point differs between 16K, 32K, 256K, etc... boards).

Is there a good way to do this?

Thanks!

-- Roger

but I want to be able to determine it runtime.

Why? You can't do anything different if there is one free byte vs. 250,000 free bytes.

PaulS:

but I want to be able to determine it runtime.

Why? You can't do anything different if there is one free byte vs. 250,000 free bytes.

Yes he can. Leftover flash can be used as storage in a program...

Yes the IDE tells me how large the code is, but I want to be able to determine it runtime.

Why? It does not (cannot) change between compiling and running.

Like AWOL said, this is not a very useful piece of information, however someone on the forum came up with this:

extern int _etext;
extern int _edata;
static inline unsigned SketchSize() { return (unsigned)(&_etext) + ((unsigned)(&_edata) - 256); }

Krupski:
I tried re-flashing the bootloader (which erases the whole chip except for the last 512 bytes), then used pgm_read_byte(address) running backwards to find the first non 0xFF byte (which works), but it seems like a clumsy way to do it (and the start point differs between 16K, 32K, 256K, etc... boards).

Is there a good way to do this?

I looked at a couple of disassemblies and the last thing symbol always seems to be a thing called "__stop_program".

It's two bytes long and is probably the "fini0" section mentioned here: Memory Sections

So...try this:

extern char *__stop_program;
char *programEnd = __stop_program+2;

(nb. I don't know if "__stop_program" is guaranteed to be the last thing but it looks reasonable...)

Yes he can. He can use it as storage in his program...

Really? You want to explain how read-only memory can be used for storage?

PaulS:

Yes he can. He can use it as storage in his program...

Really? You want to explain how read-only memory can be used for storage?

Flash isn't read-only.

How do you think a bootloader puts a program in flash memory when it sees data arriving on the serial port?

1 Like

How do you think a bootloader puts a program in flash memory

By residing in the read-only boot segment of program memory.
Software elsewhere in memory cannot write to program memory, so if you want to use unused program memory to store data, you're going to have to write your own bootloader that handles those writes for you.

AWOL:
Software elsewhere in memory cannot write to program memory

It can if you set the fuses appropriately...see section 26.5 of the datasheet.

1 Like

It can if you set the fuses appropriately...see section 26.5 of the datasheet.

In which case, the whole of memory is boot segment, the only place the SPR instruction can execute.
Using unused program memory at runtime is not really sensible:

  1. limited erase/write cycles.
  2. per-page only updates.

I think what this section of the datasheet shows you can

26.5 Boot Loader Lock Bits
If no Boot Loader capability is needed, the entire Flash is available for application code. The
Boot Loader has two separate sets of Boot Lock bits which can be set independently. This gives
the user a unique flexibility to select different levels of protection.
The user can select:
• To protect the entire Flash from a software update by the MCU.
• To protect only the Boot Loader Flash section from a software update by the MCU.
• To protect only the Application Flash section from a software update by the MCU.
• Allow software update in the entire Flash.
See Table 26-2 and Table 26-3 for further details. The Boot Lock bits can be set in software and
in Serial or Parallel Programming mode, but they can be cleared by a Chip Erase command
only. The general Write Lock (Lock Bit mode 2) does not control the programming of the Flash
memory by SPM instruction. Similarly, the general Read/Write Lock (Lock Bit mode 1) does not
control reading nor writing by LPM/SPM, if it is attempted.

I can't see why any one would want to change the flash at run time, as it only has a life of a few 1000's of writes.

Mark

AWOL:

It can if you set the fuses appropriately...see section 26.5 of the datasheet.

In which case, the whole of memory is boot segment, the only place the SPR instruction can execute.

"SPM"?

AWOL:
Using unused program memory at runtime is not really sensible:

  1. limited erase/write cycles.
  2. per-page only updates.

The OP didn't say what he was doing but I'm sure there's applications where (1) and (2) aren't a problem and the EEPROM is too small.

holmes4:
I can't see why any one would want to change the flash at run time, as it only has a life of a few 1000's of writes.

Mark

10,000 updates is quite a lot if it's a list of permitted access codes which only changes a couple of times a week (for example).

10,000 updates is quite a lot if it's a list of permitted access codes which only changes a couple of times a week (for example).

Good point!

Mark

pYro_65:
Like AWOL said, this is not a very useful piece of information, however someone on the forum came up with this:

extern int _etext;

extern int _edata;
static inline unsigned SketchSize() { return (unsigned)(&_etext) + ((unsigned)(&_edata) - 256); }

Thank you for the reply! (and karma++; to you).

To the others: I want this piece of information because the program I am writing is for a research project (I'm not a student - I'm support staff). The professor wants one of the menu screens to display hardware stats like supply voltage from the wall wart, free SRAM, free FLASH and free EEPROM (as well as a few other things).

Don't ask me why... I don't know. I'm just doing what I'm told! :slight_smile:

Anyway, I could have just hardcoded some numbers into the program and forgot about it, but I want to to it right... so that's why I asked!

(and yes I COULD actually use the flash memory runtime to store things like program settings (which I currently store in EEPROM) if, for example, the settings changed a LOT and I didn't want to wear out the EEPROM).

But, alas it's only for display purposes.

Thanks again all! Always get fast and great help here!

-- Roger

pYro_65:
Like AWOL said, this is not a very useful piece of information, however someone on the forum came up with this:

UPDATE: Corrected library is a few posts below.

-- Roger

Additional questions......

I just discovered that the stock MemoryFree function (to show free SRAM) does not work properly on a MEGA 2560 board (unless the board has over 32K of SRAM!)...

The "new" PROGMEM size function works perfectly, but the original FreeMemory() function does not.

Is it supposed to work with the MEGA 2560?

I get this with my MEGA 2560, using your example:

Free RAM (variables) memory: 7348 bytes
Free FLASH (PROGMEM) memory: -6957 bytes

:astonished:

guix:
I get this with my MEGA 2560, using your example:

Free RAM (variables) memory: 7348 bytes

Free FLASH (PROGMEM) memory: -6957 bytes



:astonished:

Sorry... my example had a mistake. The PROGMEM in a MEGA 2560 is larger than an unsigned INT so the format string should be %ld, not %d.

I didn't have a MEGA 2560 board to test it (I just bought one tonight!).

I'll correct the demo and post it.

-- Roger