I’ve had a idea
I think there’s a way to do this but it would require extra effort to organise and maintain the bootloader.
The bootloader would be divided into two sections, which I’ll call the core and support sections. The core section would reside in the flash area actually reserved for the bootloader, which would be reduced from a 4K to a 2K size. The support section would then be placed immediately before the bootloader area.
You would put as much code as possible in the 2K core section, including any code containing the SPM instruction (which can only be executed from the bootloader area). Additional code required beyond 2K would be written as subroutines and located in the support section. So, from a hardware point of view there would be a 2K bootloader but it would be calling subroutines, as necessary, in the application area just below it. You could software protect writes to the support area, as you’ve currently done.
A new board type would be created that allowed sketch code to go up to the start of the bootloader support area (or maybe the closest 1K or 512 byte boundary so as to leave a bit of headroom for future bootloader size increases). This board type could specify either locking the bootloader area or leaving it unlocked, as desired.
The additional enhancements that have been, or will be, made to control the display and RGB LED, and read the buttons, means that the bootloader has to initialise this hardware. If the bootloader made sure that, before jumping to the application, all the hardware was initialised identically to the way it’s currently being done in the Arduboy2 library’s bootPins(), bootSPI() and bootOLED() functions, then this code could be removed from the Arduboy2 library. The Arduboy2 library could do this using conditional compile tests, based on the new board type. This would make even more space available for the actual application.
I get the idea of splitting the bootloader up in a core and support section (this makes it possible to put api calls in the vector table using RJMPs). But I don’t get why you want to take space away from the application area. (<0x7000) to gain more space after the bootloader (0x7800-0x7FFF)
The support section would still be mandatory and should also be protected otherwise the bootloader can still be bricked.
The ‘core’ caterina bootloader is 2718 bytes atm. Arduboy code 354 bytes. I could move some of the non essential command stuff up but that doesn’t get me close to 2K for a core (that would be a Cathy 2K challenge for later)
On Another thought,
Sounds good. I’m not sure I do all initializing that Arduboy2 does. But the buttons LEDs and OLED are initialized and the display routine could be used as well. I’ll do a check later to see if I can add complete initialisation. I’m currently at exactly 3K.
Hmm now that you mention freeing code for more Application space. I’m thinking about that 3K USB code. I’m wondering how small a bare minimum ‘enter bootloader through USB’ would be…
Oh man! I think I’m not getting to work on SD card support for a while …
Back to the bootloader. I’ve updated the zip file with a new version of the bootloader and streaming demo. This new version support the set LED AVR910 command to control the RGB breathing, RxTx transfer status and turn OLED display, RGB LEDs and Rx,Tx LEDs on and off. I’ve also changed the OLED display code to use page/column mode. So it works with other OLED displays too.
Let’s talk in terms of words instead of bytes, to match the datasheet. The bootloader area can be set to 4 sizes: 256, 512, 1024 or 2048 words.
Currently the bootloader is set to the maximum size of 2048 words (4096 bytes), which means it starts at address 0x3800 and ends at address 0x3FFF. The application area is thus 0x0000 to 0x37FF.
My proposal is to set the fuses for a 1024 word bootloader area size, from 0x3C00 to 0x3FFF. The application area is then increased: 0x0000 to 0x3BFF (an extra 1K words or 2K bytes).
However, you can’t squeeze the bootloader down to fit in 1K words. So what you do is put as much of it into the 1K word bootloader area as possible and move the rest into subroutines at the top of the application area from 0x3BFF downwards. If you need 1536 words total (3K bytes), then this support (maybe extended is a better term?) section would be 512 words from 0x3A00 to 0x3BFF. The application area that could be used by sketches would be 0x0000 to 0x39FF (a gain of 1K bytes over the current amount).
This table shows the current and proposed program flash memory maps (in words):
TaDa! Your proposal has been successfully implemented!. We have 1K more flash for Applications
Moved stuf around,done some more optimizing to keep a subroutine from crossing the 2K boundary and moved the hardware initialisation for Arduboy upfront so when it enters application right away (power on) hardware is initialized too.
@Mr.Blinky … for those of us who aren’t quite following this detaield discussion, do you think you can summarise what your new bootloader does (apart from save memory ! Woo hoo) and any limitations it might have?
Not fully yet. The display code supports OLED displays with SSD1306, SSD1309 and SH1106. The latter only has a 2 pixel shift which can be fixed by changing a single byte in the display initialization code. (will make a seperate build for it)
I’ll still need to add support for the official devkit and alternate pin configurations for Arduboy clones using Arduino Micro and Pro Micro. These version will have different build of the bootloader.
Talking about devkits. Here’s mine where I develop this bootloader on. A Breadboard Arduino shield hooked to an Arduino Leonardo. I can keep the ICSP programmer hooked up all the time and exchange OLED displays for tests then when I’m satisfied with a testbuild. I burn it to my Ardunoy for more testing.
Okay tweaked the bootloader a bit more. more stable reset for the OLED display, the hardware also gets initialized pretty much the same as in bootPins bootSPI bootOLED and added build support for the official DevKit. The batch make spits out 7 different bootloaders (Arduboy,DevKit and 5 clone variants) Unfortunately I don’t have an original DevKit to test it on.
Anyone with an official DevKit who wan’t to be a guinea pig?
I’ve updated my Arduboy variant package with the bootloader and extra 1K board support.
You can select the Arduboy +1K board that gives you the extra 1K of application space.
You can also burn the new bootloader using the Arduino IDE it also burns the right fuse settings.
Besides Arduboy and clone variants. I’ve also include +1K versions for Leonardo, Micro and Esplora.
In the below image I’ve Burned the Arduboy +1K, ProMicro SH1106 Version using the Arduino IDE on a test ProMicro.
I’m pleased with the end result.
Ohoh old idea is back. Before I had the idea of adding an 64Mbit SPI flash chip (for 256 in 1 games) to an Arduboy (clone) but dropped it because it would require a loader app to download the contents through USB and flash it through a loader app which I find too awkward (and wearsinternal flash faster).
Now I realize I could add support to the bootloader to program the flash chip and add a little loader menu too without using up too much code. But I’m not sure if I should persue this idea or start looking at SD Card support (and definetly loose that 1K freed space) any thoughts?
If it’s for the masses adding additional writes to flash is a no no and the space can be used better for single games not to mention the amount of users unable or unwilling to modify their hardware.
If it’s a personal project then whatever floats your boat but then you might as well be giving clones a thrashing to preserve your Arduboy but once you’ve moved away from actual hardware you might as well go for something completely different like @MLXXXp did with his Arduboy Zero.
I lack the technical knowledge but I’m assuming that SPI Flash would be more practical to implement than cram and cut SD into the existing shell and possibly remove some headaches and bloat dealing with bulky file systems, but would it be possible to redirect the 32u4 to read the spi flash instead of internal flash? removing the need to constantly rewrite internal flash.
If so I would be looking to:
1 Use the 32u4 to give me access to the spi flash from PC over USB and also handle the required redirects when in use.
2 write a PC app that’s capable of building a multi game with menu from existing code if possible and transfer the raw data to the newly installed flash.
From what I have read on other posts most methods suggest using an external storage method to flash the internal flash thus doubling the amount of writes and if any of that above were possible your internal flash would only require an initial flash then everything else would be run on the fly from the external.
Apologies bit of a ramble I’m typing aloud rather than thinking first and posted it…
Exactly, I don’t want to waste a flash cycle for burning a loader. That’s why I added the streaming feature in the bootloader already so a dock doesn’t need to flash a loader.
I’m doing it for my personal enjoyment. But I’m keeping the community in mind because that makes it it much more fun.
It will be tricky to add Arduboy but the case doesn’t need to be modified when using an flash chip in a WSON package. But it will be easy for clones to add.
I like to stick with the atmega32u4. When moving on to a more powerful chip new arduboy sketches won’t work on older Arduboys and you’re basically moving on to a new handheld. I also think there still a lot of potential in the current Arduboy.
unfortunately not. There is no support external memory.
The idea is to extent the read/write block commands in bootloader mode as I did for the OLED display support. The contents of the atmega32u4 isn’t changed in the process.
Yes the idea is to manage the content on a PC/Pi. Each game would get a title screen or one is created by the tool (gamename) and games could be grouped for easier selecting. In the bootloader menu would just step through these screens and when you make your choice it burns the game.
That is correct. However if you want to preserve the contents of the EEPROM after chip erase then you should use 0xD2. I’m going to use that as default in my board package update.
I’m using the feature quite a lot while experimentiong with the USB core and library optimalisations. and it’s a delight to have it.
I’m also so used to the flashing RGB LED in bootloader mode now that at one time I though my Arduboy froze up when the RGB LED didn’t flash before realizing I had just flashed the oldbootloader back for testing