Having a sketch reflash portions of itself (feasibility)

Continuing the discussion from Ardynia - a Zelda style adventure, now available:


My last post:

That’s what I’m saying, it can - via the bootloader code… and it might even be simpler if the bootloader has compiled SPM into the end of a function or a smaller piece of code you could just CALL. You setup everything in “userspace” then just call into the bootloader for the SPM , which can only run from bootloader space. Then a return (or some awesome interrupt tricks) gets you back. Once you have it working it’d 100% reliable since the timing is precise.

I wonder if reflashing the beginning of flash over and over would really have any effect on the long-term durability (in practical terms).

@Mr.Blinky So we don’t abduct the awesome RPG thread.

I’ve been wanting to play around with this kind of thing on the Gamebuino (which actually supports sketches relfashing portions of themselves officially - though I don’t think anyone is doing it) and it’d be fun on Arduboy also but not as useful with the stock units as you don’t really have anywhere to get stuff from. Though I guess you could use it for a large save file or something.

reflash any part of the sketch at runtime? if so, I might use that in a future ardynia game. currently I load a room into memory and then alter the map from there. but being able to just alter it in progmem might enable squeezing that much more out of the system. the cost being the only way to “delete a save” is to do a complete reflash of the game.

being able to treat the entire flash space as a “disk” could lead to some interesting sketches.

Well technically - but for reliability you’d likely want to set aside a “data” area that did not overlap with your program area. That way your flasher never has a chance to corrupt itself. Luckily your program (on AVR) sits low in flash, so any space “above” your program (and before the bootloader) would be usable data area.

How much do you alter the maps? For a tiny room lik you have you could just store a small list of changes to the room (x [4 bits], y [4], tile [8]) and when you query the current tile just scan that list and see if it’s been changed or not. Of course aren’t your rooms already only 40 bytes or so?

Not sure I follow. You could save/restore/delete save if you had the code to write to flash.

Yes, that would definitely be safest. but It’d be pretty fun to alter code on the fly :slight_smile:

if the player bombs a secret wall I clear that tile out, and if they trigger a switch a water tile turns into a bridge tile.

in my case it was just easiest to decompress them into memory. I need to read the tiles to render the room and for collision detection, and rather than try and have one common decompress method both could call, I just decompress into memory once per room transition. so altering them in memory was a nice bonus.

true, you’d have to keep track of every bit you’ve flashed and flash it back to its initial value. keeping track of it might get cumbersome if you’re doing a lot of changes.

Why not keep it simple and just use part of the 1 KB EEPROM (unless you need to store even more map data than that)?

The EEPROM supports 10x the erase/write cycles (100,000) compared to the flash (10,000), and can be erased/re-written at the byte level. I believe the flash requires erasing a 256 byte page at a time, making it much harder to manage things and eating up those flash cycles much more quickly.

1 Like

Ugh, not sure I follow. Either you’re storing things in RAM or you’re storing them in flash. Copying things off of flash to keep track of them in RAM just to change the flash makes no sense at all.

To “erase” the save you’d just write the whole area to “0xFF” (or the first page at least) to make it empty. No need to know what was there before.

Ie, it makes no sense to “save” flash in RAM while using flash as a slower RAM.

Yes, obviously EEPROM would be the first choice. This would be if you needed more space or wanted to store something a bit longer term. One could imagine generating a large map for example and saving it to 3kb of flash and then playing it for hours.

Yes, I think you’d need to write 256 or 512 blocks. I think you can write the data into the special SPM buffer before you erase the page though… (ie not needing a memory cache). If you did truly need a memory cache you could just steal it from the video buffer during a repaint cycle.

Sure, but that raises the question of where does the data come from to begin with? It is either part of the flash (progmem) already, or dynamically generated, or comes from some external system. I don’t think a stock Arduboy has any ability to get data from any external system.

Are there any Arduboy games that actually have/need dynamically generated maps that are that big? Why not just make the generation code be re-entrant, where you could ask it for a subset of the map based on a ‘seed’ value?

I don’t think that is how it works. You ERASE a page/block at a time. You can then WRITE to flash in as little as one byte increments as long as you don’t overwrite the same byte again (without erasing it first). You would need to read/erase/write an entire page/block to change a single byte, and you need RAM available to buffer it.

1 Like

Maybe the generation is expensive time wise?

That’s how a lot of flash chips work, yes. Typically for AVR you’re flashing the whole block (as part of reprogramming) but perhaps it does allow you to do one byte at a time… that’s even better then because it would allow progressive writes, change detection, etc.

and you need RAM available to buffer it.

Nope. The AVR chip has internal buffers that can buffer a full page. So to change a single byte you’d read all 256 and write them to the SPM buffer just change the one you wanted (in flight), then issue an erase/rewrite. It’d also be pretty easy to “stream” from a buffer to a section of flash.

Yeah, apparently I was thinking more of how other flash controllers work that I have been dealing with more recently.

Looking at the datasheet again, it looks like the ATmega32U4 has 128 byte (64 word) pages.

You have to erase an entire page at a time.

At first glance, it looks like you have to write an entire page at a time as well, but in reality you can write chunks as small as a word (2 bytes) at a time. The erase command is the only way to change a 0 to a 1, and the write command is the only way to change a 1 to a 0. So, after an erase, all data is 0xFF (i.e. 1’s). If you ‘write’ a 0xFF to a byte that already has 0xFF nothing really happens (i.e. all write command doesn’t do anything with 1’s), and you can still change it to something else at a later time. You just can’t change anything already written to a 0 back to a 1 without erasing an entire page. (https://www.avrfreaks.net/comment/245230#comment-245230)

That’s pretty neat that the AVRs have a temporary page buffer. Frees up a bit of ram (128 bytes) for read/erase/write procedures. Too bad it isn’t usable for other purposes.

Yeah, that was my first thought but so far as I know it’s INPUT only and the only way OUT is SPM to flash somewhere.

My Cathy2K and 3K bootloaders have a function built in that can be called by the sketch to reflash itself:

You could probably just call it with a function pointer without the inline ASM. Look at the Gamebuino if you want examples.