High-mem USB boot loader

jcw
Wed Oct 28, 2015 12:43 pm
I’d like to look into creating a USB boot loader using DFU which sits in high memory. Several notes:

* the same code will run with and without boot loader installed
* no need to relocate the boot vector, could work even on Cortex M0 (if they have USB support, evidently)
* it’s going to use up 8 KB flash, as before, but from the high end of flash memory
* re-flashing must take care to not erase that high memory, and keep the reset jump vector intact

The basic trick is to change the uploaded code in-flight, before flashing it, so that the reset jump vector continues to point to the boot loader, and to stash the original value somewhere else (perhaps an unused interrupt vector entry), for the boot loader to jump to once the upload finishes, or when no new code is being uploaded.

I’ve written boot loaders before, including one using this trick. I’ve never worked with USB though.

The main benefit would be that this avoids having to build different firmware images for different boot mechanisms. We can continue to use serial, ST-Link, or BMP (disabling this boot loader), with the same application firmware image. Then again, if this USB loader is robust and usable on all O/S platforms, I expect it to be convenient for day-to-day use.

* has anyone tried this approach?
* is “STM32duino-bootloader” a solid starting point to tackle this?
* any tips?

I’m having a lot of trouble with USB on Mac OSX, would love to get this going, but I’m also a bit worried about all the issues and tinkering with the Maple USB boot loader over the past few years. Still trying to figure out whether this has even the slimmest chance of succeeding…


jcw
Wed Oct 28, 2015 12:50 pm
To get around the current explosion of pin choices for USB enabling, I propose to place these values in the firmware image in such a way that they can be patched and changed in the binary (next to a unique identifying string, for example). Then a single firmware binary can be created for each supported memory density variant (and memory size, since the boot loader’s base address differs).

For my immediate needs, I’ll want to focus on just the medium-density F103’s.


jcw
Wed Oct 28, 2015 1:17 pm
Hm, this thread is probably better off in the “Bootloaders and Cores” section (man, there are so many sections!).

RogerClark
Wed Oct 28, 2015 8:16 pm
I will need to log in on my PC as Admin and move it this thread if you want.

Im not totally sure what you mean about the bootloader running in RAM

you would still need something in the bottom of flash to get the code to jump to the ram address.

How do you get it into ram in the first place (copy from flash ?)

Note on the vector table stuff. AFIK youd need to update a lot of stuff in the vector table, albeit probably just add a fixed number, but its not just the stack add, there are loads of vectors in the table.


jcw
Wed Oct 28, 2015 8:29 pm
Sorry, I didn’t mean the USB bootloader in RAM, but located in the top of flash memory.
The low reset vector entry always points to that high location (i.e. @56K or @120K, in 64/128K parts, respectively).

The boot loader can then load the application code at address 0, modifying the reset vector to itself before actually flashing it, so that it still retains control on each reset.

Given the already-high number of build combinations, this avoids the need for with-vs-without-boot-loader builds. It also means I can save firmware images which will work either way.

I’m only modifying the reset vector entry. The rest still points to the app. The boot loader has its own copy of the interrupt vector, which is used while it is running, then the vector base is reset to 0 before passing control to the application code.


Rick Kimball
Wed Oct 28, 2015 8:41 pm
jcw wrote:I didn’t mean the USB bootloader in RAM, but located in the top of flash memory.
The low reset vector entry always points to that high location (i.e. @56K or @120K, in 64/128K parts, respectively).

jcw
Wed Oct 28, 2015 8:53 pm
Agreed on the “real debugger” – in fact, I’m quite happy with using the command line and gdb myself.

But this is for Arduino’ish folks. Then, a boot loader means you plug in a USB cable, and off you go: power up, upload, printf-debug, and other app-level serial-over-USB comms. One app (the IDE), one cable, one board.


RogerClark
Wed Oct 28, 2015 8:54 pm
Sorry.

So…

You plan to put the bootloader in the top of flash and also write the 2 vectors at the base of flash with the PC jump vector and the SP vector.

So you would stuff need stuff in the bottom of flash ?

BTW.Re: Whether the current bootloader is the best place to start…

The current bootloader is someone of an evolution from the original Maple bootloader, and has been modified a number of times.

From what I’ve read, the DFU handling is not ideal, (though it seems to work for us).

So you may be better of looking at other STM32 DFU bootloaders.

If you are planning on supporting multiple processor families, ie other than just the F103, you should start with the STM32Cube MX, which is ST’s core code generator.

Originally the Cube didn’t support the F103 but ST enhanced it about 6 months ago.

The one caveat, is that the linker files generated by the CUBE have a problematic source code license. We think this is an oversight by ST, as all the rest of the code has and open source friendly license, but not the linker files.
(Note, they may have fixed this now, as I”m not update my CUBE for a month or two)

BTW. The Cube uses the new HAL Standard Peripheral Lib, rather than the original SPL. As the HAL SPL is fairly new, you’d need to port the SPL calls to the HAL versions, if you used older existing bootloader code with the HAL SPL.

I recall searching for “STM DFU Bootloader” and finding some other examples. But I can’t recall where they were of if they were any good :-( (Sorry….)


jcw
Wed Oct 28, 2015 9:19 pm
So you would stuff need stuff in the bottom of flash ?
Correct, this needs a minimal boot vector in low mem and the boot loader in high mem to start the ball rolling. In another project, I simply loaded the boot loader image twice – in low as well as high mem. After that, low mem will be re-flashed from the boot loader.

I’ll probably look into the current boot loader – don’t want to sink too much energy and time into this. Thanks for the STM32Cube MX hint, though – looks interesting (yet more to read and digest). There’s also ChibiOS, which has a pretty wide coverage of STM µCs, including a USB serial driver which worked out of the box for me. The driver code is in a separate HAL section, and can apparently now be used without having to use the ChibiOS RTOS itself.

Ok, thanks. First of all, I’ll see if I can get the current boot loader working on any of my boards here (on Mac).
So far, it has eluded me…


RogerClark
Wed Oct 28, 2015 10:04 pm
Ok, thanks. First of all, I’ll see if I can get the current boot loader working on any of my boards here (on Mac).
So far, it has eluded me…

The current bootloader is easy to rebuild

Just put the Arduino’s ARM compiler in your path, cd into the STM32F1 folder and run make <board type>

e.g. make maple-mini

However in your case the best think to do is to modify the config for maple_mini (look in config.h) and change the reset pin (and possibly which direction it toggles – as I can’t remember which way it is on the maple mini)

then

make clean
make maple-mini

then flash the maple mini bin file from the binaries folder


jcw
Wed Oct 28, 2015 10:27 pm
Woohoo – thank you!

Picking the Maple Mini (and using the IDE’s gcc i.s.o. my default 4.9.3 setup) made all the difference.
It uploads! Still some snag after that (LED stuck on, investigating now), but hey, a big step forward!


jcw
Thu Oct 29, 2015 9:57 am
Here’s a thought regarding all Maple-like boards with active D+ pull-up control circuitry: how about making all of them behave like the generic ones, i.e. using the PA12 trick, and then in some central startup code or even the user setup(), we permanently set the controlling pin to enable that pull-up all the time?

RogerClark
Thu Oct 29, 2015 10:47 am
I guess that should be possible

I’d have to give it a try on one of my Maple mini’s


Leave a Reply

Your email address will not be published. Required fields are marked *