[COMPLETED] Combining Blink & Count to the bootloader

RogerClark
Mon Jun 19, 2017 1:52 am
[Update by admin]

This proposal has now been made to the bootloader, except the sketch does not blink as this would require a different sketch binary for every bootloader / board. So instead it prints a message to Serial

Guys

A problem that we get over and over again, is people expecting to get the Serial device when they first load the bootloader
I don’t propose to add even a fake serial device to the bootloader, as composite devices are problematic on Windows.

But, combining a Blink & Count sketch to the bootloader binary, so that when new users load the bootloader, the board appears and has a com port that the IDE can see, seems like a possible solution to this.

I did consider adding some other form of demo sketch to the bootloader, but it would need to be purely text based, or just involve blinking or fading the LED.

Does anyone have any thoughts on this one.

Also… I don’t know an easy way of merging binaries or hex files. I have a tool called mergehex (from Nordic Semi) but it doesn’t seem to work for this (possibly it only works on specific address ranges)


zoomx
Mon Jun 19, 2017 6:06 am
An hex editor maybe?

RogerClark
Mon Jun 19, 2017 7:18 am
I can do it using the Jlink JFlash tool as it has a merge feature but its a pain to do it manually for all the files.

I will try again to see if I can make Nordic’s MergeHex utility work


danieleff
Mon Jun 19, 2017 7:54 am
But isn’t it just appending one to the other? I know you use Windows, but:
cat bootloader.bin > bootloader_plus_blink.bin
truncate -s8192 bootloader_plus_blink.bin
cat blink.bin >> bootloader_plus_blink.bin

stevestrong
Mon Jun 19, 2017 9:15 am
I am using HxD: https://mh-nexus.de/en/hxd/
It supports, among many interesting features, splitting or concatenating of files, too.

RogerClark
Mon Jun 19, 2017 10:35 am
[danieleff – Mon Jun 19, 2017 7:54 am] –
But isn’t it just appending one to the other? I know you use Windows, but:
cat bootloader.bin > bootloader_plus_blink.bin
truncate -s8192 bootloader_plus_blink.bin
cat blink.bin >> bootloader_plus_blink.bin

RogerClark
Mon Jun 19, 2017 10:36 am
[stevestrong – Mon Jun 19, 2017 9:15 am] –
I am using HxD: https://mh-nexus.de/en/hxd/
It supports, among many interesting features, splitting or concatenating of files, too.

Thanks

I was hoping to find something which I could run from a windows bat file


danieleff
Mon Jun 19, 2017 10:39 am
[RogerClark – Mon Jun 19, 2017 10:35 am] –

[danieleff – Mon Jun 19, 2017 7:54 am] –
But isn’t it just appending one to the other? I know you use Windows, but:
cat bootloader.bin > bootloader_plus_blink.bin
truncate -s8192 bootloader_plus_blink.bin
cat blink.bin >> bootloader_plus_blink.bin

RogerClark
Mon Jun 19, 2017 10:41 am
[danieleff – Mon Jun 19, 2017 10:39 am] –

[RogerClark – Mon Jun 19, 2017 10:35 am] –

[danieleff – Mon Jun 19, 2017 7:54 am] –
But isn’t it just appending one to the other? I know you use Windows, but:
cat bootloader.bin > bootloader_plus_blink.bin
truncate -s8192 bootloader_plus_blink.bin
cat blink.bin >> bootloader_plus_blink.bin

stevestrong
Mon Jun 19, 2017 11:42 am
For your orientation, here is a command line hex editor, with source code:
https://sourceforge.net/projects/hexciting/

zoomx
Mon Jun 19, 2017 2:10 pm
[RogerClark – Mon Jun 19, 2017 10:41 am] –
I’ll see if windows powershell has this

Edit.

No. It does not have that command.

I believe that on Cygwin it will work since it has either cat and truncate commands.


RogerClark
Mon Jun 19, 2017 10:20 pm
I have cygwin but its a big package for other people to install just to combine files

I’ve written some code to do it, But, I’ve not tested it yet.

Please feel to tell me if you see any mistakes

Note. My compiler didnt like the type unit8_t so I have declared the buffer as void *, and I’m not sure that will work.

I’ll need to find out where unit8_t is defined,

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *fpBootloader;
FILE *fpSketch;
FILE *fpOutput;
int sketchSize;
int bootloaderSize;
void *buf;
const int SKETCH_OFFSET = 0x2000;

if (argc!=3)
{
printf("mergebin bootloader.bin sketch.bin output.bin\nNote. The sketch start address is presumed to be 0x2000 from the start of the binary file\n");
return -1;
}

fpBootloader = fopen (argv[1], "r");
if (fpBootloader==NULL)
{
printf("Unable to open bootloader binary file %s\n",argv[1]);
return -2;
}
fpSketch = fopen (argv[2], "r");
if (fpSketch==NULL)
{
fclose(fpBootloader);
printf("Unable to open sketch binary file %s\n",argv[2]);
return -2;
}
fpOutput = fopen (argv[3], "w");
if (fpSketch==NULL)
{
fclose(fpBootloader);
fclose(fpSketch);
printf("Unable to open output file %s for writing \n",argv[3]);
return -2;
}

fseek(fpSketch, 0, SEEK_END); // seek to send of sketch to determine its length
sketchSize = ftell (fpSketch);
fseek(fpSketch, 0, SEEK_SET); // go back to start, so we can read from the beginning

buf=malloc(sketchSize + SKETCH_OFFSET);
if (buf==NULL)
{
fclose(fpBootloader);
fclose(fpSketch);
fclose(fpOutput);

printf("Unable to open allocate memoery\n");
return -3;
}

fseek(fpBootloader, 0, SEEK_END); // seek to send of bootloader to determine its length
bootloaderSize = ftell (fpBootloader);
fseek(fpBootloader, 0, SEEK_SET); // go back to start, so we can read from the beginning
fread(buf,bootloaderSize,1,fpBootloader);
fclose(fpBootloader);

fread(buf + SKETCH_OFFSET,sketchSize,1,fpSketch);
fclose(fpSketch);

fwrite(buf,sketchSize+SKETCH_OFFSET,1,fpOutput);

fclose(fpOutput);
return 0;
}


Rick Kimball
Mon Jun 19, 2017 11:04 pm
why not a script that just loads the bootloader at 0x8000000 and then loads the blink at 0x8000000+8192. Two steps instead of one

RogerClark
Mon Jun 19, 2017 11:06 pm
[Rick Kimball – Mon Jun 19, 2017 11:04 pm] –
why not a script that just loads the bootloader at 0x8000000 and then loads the blink at 0x8000000+8192. Two steps instead of one

Depends on how people load the file.

I a lot of people use STM’s Windows GUI tool

I just have to make this idiot proof as much as possible for all platforms


RogerClark
Mon Jun 19, 2017 11:09 pm
BTW.

If I have time I’ll make the utility general purpose

e.g. mergebin in1,offset1,in2,offset2,in3,offset3, out


RogerClark
Mon Jun 19, 2017 11:25 pm
Umm.

One thing I’d not considered is that I wanted to Blink the LED but it varies, so I can’t use the same sketch, or the sketch has to determine the LED by inspecting the bootloader.

ummm. More complications.

If there is room in the bootloader, I may just put a const string which has an ident in it, and also use that to read the pin of the LED


RogerClark
Tue Jun 20, 2017 12:10 am
There were some bugs in my first attempt. I didnt set binary read mode (doh)!

But I think its working now, and here is a combined binary (attached)

I’m not sure if the code is cross platform, (and I’d like to make it general purpose if I have time)

Note. This code is not a sketch, it needs to be compiled on windows using GCC or similar.
I used Code::Blocks

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int argc, char **argv)
{
FILE *fpBootloader;
FILE *fpSketch;
FILE *fpOutput;
int sketchSize;
int bootloaderSize;
uint8_t *buf;
const int SKETCH_OFFSET = 0x2000;

if (argc!=4)
{
printf("\nUsage. mergebin bootloader.bin sketch.bin output.bin - Incorrect number of args\n\n");
return -1;
}

fpBootloader = fopen (argv[1], "rb");
if (fpBootloader==NULL)
{
printf("Unable to open bootloader binary file %s\n",argv[1]);
return -2;
}

fseek(fpBootloader, 0, SEEK_END); // seek to send of bootloader to determine its length
bootloaderSize = ftell (fpBootloader);
fseek(fpBootloader, 0, SEEK_SET); // go back to start, so we can read from the beginning
printf("Opened bootloader file %s : size is %d\n",argv[1],bootloaderSize);

fpSketch = fopen (argv[2], "rb");
if (fpSketch==NULL)
{
fclose(fpBootloader);
printf("Unable to open sketch binary file %s\n",argv[2]);
return -2;
}

fseek(fpSketch, 0, SEEK_END); // seek to send of sketch to determine its length
sketchSize = ftell (fpSketch);
fseek(fpSketch, 0, SEEK_SET); // go back to start, so we can read from the beginning
printf("Opened sketch file %s : size is %d\n",argv[2],sketchSize);

buf=malloc(sketchSize + SKETCH_OFFSET);
if (buf==NULL)
{
fclose(fpBootloader);
fclose(fpSketch);
printf("Unable to open allocate memory\n");
return -3;
}

printf("Allocated %d bytes for buffer\n",sketchSize + SKETCH_OFFSET);

fread(buf,bootloaderSize,1,fpBootloader);
fclose(fpBootloader);

fread(buf + SKETCH_OFFSET,sketchSize,1,fpSketch);
fclose(fpSketch);

fpOutput = fopen (argv[3], "wb");
if (fpOutput==NULL)
{
fclose(fpBootloader);
fclose(fpSketch);
printf("Unable to open output file %s for writing \n",argv[3]);
return -2;
}

fwrite(buf,sketchSize+SKETCH_OFFSET,1,fpOutput);

fclose(fpOutput);
printf("Wrote combined file to %s \n",argv[3]);

return 0;
}


RogerClark
Tue Jun 20, 2017 7:11 am
I have given up on the idea of making the sketch part of the combined bootloader, blink the LED. Because I’d need separate sketches for each board.

I think I’ll just compile a blank sketch, of just one that counts, and displays a message, as that would work for all boards.


ahull
Tue Jun 20, 2017 11:29 am
Could you not specify the two pins for the button and the LED in the make script for the bootloader and the blink, making a bootloader then becomes something like.

mkbootloader BUTTON_PIN LED_PIN, which calls the routines to compile the bootloader and blink, and then merges them together into a single .bin file?

This would obviate the need to maintain a whole bunch of pre-compiled bootloaders in the first place. In fact you could take the idea one stage further and add a lookup table for common boards, so something like mkbootloader blue_pill or mkbootloader maple_mini


RogerClark
Tue Jun 20, 2017 12:00 pm
Hi Andy

I’m not sure what you mean about the Make.

I already have a Makefile which can build all the targets, albeit I don’t know enough about Makefiles so that the “Make all” makes all bootloaders

I suppose it would be possible to build the custom Blink sketch, but it would need all the LibMaple core etc, which is not currently inside the bootloader folder.

I think its easier just to have a precompiled blank.bin for all generic boards (not Maple mini etc), and then get the Makefile to do the combining.

But unfortunately I’m not very good at writing Makefiles.


ahull
Tue Jun 20, 2017 12:25 pm
I was using makebootloader in a general sense, rather than a Makefile, but I guess we could possibly use the abilities of make to do something like

make bootloader maple
or
make bootloader bluepill
or
make bootlader PB1 PC13
or
make bootloader $BUTTON $LED

EDIT:
Actually Make uses the syntax
make target FOO=bar, so the above examples might be

make bootloader BOARD=bluepill |maple |uglyboard etc

or

make bootloader BUTTON=PB1 LED=PC13

.. and so forth …

.. and have the makefile spit out what we need by building both the bootloader and the blinky with the same parameters and munging the two together.

https://stackoverflow.com/questions/282 … ne-to-make

What I initially envisaged was a script or program that when called with the correct parameters would generate a suitable boot+blink combined .bin based on the details it was passed. However getting make to do the donkey work might be a more portable solution, since a standalone script would not be OS agnostic, and Make presumably is (for the most part).


Rick Kimball
Tue Jun 20, 2017 12:29 pm
If the whole point is to make the usb serial show up, why not skip the blinky?

ahull
Tue Jun 20, 2017 12:35 pm
As I understand it, the idea is to include the blinky, so that people are less uncertain about whether the booloader worked or not.

Currently if you install just the bootloader, and fire the board on your PC, the serial port does not show up, and there is really nothing to suggest you were successful.

However if you add a suitable blinky, then when they install the bootloader for the first time, you can have the board enumerates as a serial port and the blink sketch blinks the LED, thus proving that something useful as been achieved.

This then removed a bunch of doubts and noob questions.


RogerClark
Tue Jun 20, 2017 12:37 pm
[Rick Kimball – Tue Jun 20, 2017 12:29 pm] –
If the whole point is to make the usb serial show up, why not skip the blinky?

Yes.

Thats the conclusion I came to.

I just compiled a blank sketch, to get Serial USB to appear

Then ran my utility to combine generic_boot20_pc13.bin with blank.ino.generic_stm32f103c.bin

All I need to do is add something into the makefile so that it runs the mergebin utility after compiling the bootloader bin


Rick Kimball
Tue Jun 20, 2017 1:05 pm
How about spewing the build info about the bootloader on the serial output?

Something like:

“Success! Bootloader version blah and blah is installed.”
Then maybe spew out the information about the leds used and buttons used? And a short tutorial on how to use all the features.


ahull
Tue Jun 20, 2017 1:30 pm
[Rick Kimball – Tue Jun 20, 2017 1:05 pm] –
How about spewing the build info about the bootloader on the serial output?

Something like:

“Success! Bootloader version blah and blah is installed.”
Then maybe spew out the information about the leds used and buttons used? And a short tutorial on how to use all the features.

Good move, the tutorial could simply be a link to the relevant wiki page.


stevestrong
Tue Jun 20, 2017 2:07 pm
Going back to split/merge and other stuff, I have found this GNU utilities package for windows, it may be handy for someone:
http://unxutils.sourceforge.net/

RogerClark
Tue Jun 20, 2017 10:24 pm
[Rick Kimball – Tue Jun 20, 2017 1:05 pm] –
How about spewing the build info about the bootloader on the serial output?

Something like:

“Success! Bootloader version blah and blah is installed.”
Then maybe spew out the information about the leds used and buttons used? And a short tutorial on how to use all the features.

Thats something I had considered as well.

I initially did a Blink & Count sketch, the. put in some other text.

But I agree, having a paragraph of text that it repeatedly sends once a second is a good idea


zoomx
Wed Jun 21, 2017 7:39 am
The classic “The quick brown fox jumps over the lazy dog” or “lorem ipsum dolor sit amet consectetur adipiscing elit” that seems latin but mean nothing….
Or an ASCII table.
Or the bootloader identification and version.

RogerClark
Wed Jun 21, 2017 7:56 am
[zoomx – Wed Jun 21, 2017 7:39 am] –

Or the bootloader identification and version.

I had thought of that, but I’d need to put some magic number marker into the bootloader source, so that the sketch can search and find the version etc

In which case I’d also put the LED port and Pin, so the sketch could read those values and then flash the LED


victor_pv
Sat Jun 24, 2017 9:15 pm
I am thinking it may be easier to:
1.- Take maple mini and wipe it clean.
2.-Load bootloader.
3.-Load blink or whatever example sketch.
4.-Download the flash until the end of actual code with st-link and there you have a merged bin that can be uploaded.

If the question is how to do this for every variant, then that’s a different problem. I dont think it’s worth it. May be better to make the bins available only from a page with a big red banner warning the board will only show as DFU device until a sketch is loaded.


RogerClark
Sat Jun 24, 2017 10:54 pm
Hi Victor

I agree its too much efforft to download to the device and then read it back to make the combined bootloader.

But I already made an exe to merge the binaries.

As long as I only use Serial.print in the shetch it would work on all boards.

I will try to write some text that the sketch part will display on a 1 second loop


ag123
Sun Jun 25, 2017 7:58 am
thus far i’m quite happy with just the ‘raw’ bootloader, in fact after i installed the bootloader i deliberately zero out blocks of flash after 0x8002000
if i remember correctly, this leaves it in ‘perpetual’ boot loader mode waiting for sketch install
either way the ‘perpetual mode’ keeps the led blinking
then what’s needed is to install the sketch say from arduino ide or via dfu-util
for new users this should probably be the 1st thing they’d need to learn – to compile and install the blinky sketch
which would give them usb-serial as well
just 2 cents

RogerClark
Sun Jun 25, 2017 10:43 am
[ag123 – Sun Jun 25, 2017 7:58 am] –
thus far i’m quite happy with just the ‘raw’ bootloader, in fact after i installed the bootloader i deliberately zero out blocks of flash after 0x8002000
if i remember correctly, this leaves it in ‘perpetual’ boot loader mode waiting for sketch install
either way the ‘perpetual mode’ keeps the led blinking
then what’s needed is to install the sketch say from arduino ide or via dfu-util
for new users this should probably be the 1st thing they’d need to learn – to compile and install the blinky sketch
which would give them usb-serial as well
just 2 cents

Depends on how people install it, its possible that the BP has a binary already in it.

The Bootloader just looks for a magic number (I think it looks for the stack address or part of it in the start of the sketch code segment).
Its unlikely but not impossible that it would detect something else as a valid sketch and jump to it, then crash


RogerClark
Sat Jul 22, 2017 4:36 am
Guys.

I’ve finally got around to doing a version of this.

See

https://github.com/rogerclarkmelbourne/ … erged_bins

I made a simple sketch that prints out the message

Congratulations, you have installed the STM32duino bootloader
For more information about Arduino on STM32
See https://github.com/rogerclarkmelbourne/ … bootloader
and http://www.stm32duino.com

I have tested this on the Blue Pill and it works fine.

I have not tested on the Maple mini, but it should work as I use a different sketch for the maple binaries

If this seems to work for everyone, I’ll put these combined binaries into the binaries folder, to replace the files that contain just the bootloader.

BTW. I can’t recall if the other larger maple boards have different disconnect hardware from the Maple mini, in which case I’d need a different sketch for them, which is not what I’ve done at the moment.

But its taken me long enough getting this far, so if the larger Maple boards have an issue I’ll simply delete the combined binary and those users can use the bootloader without sketch


mrburnette
Sun Jul 23, 2017 3:00 pm
[RogerClark – Mon Jun 19, 2017 1:52 am] –
Guys

A problem that we get over and over again, is people expecting to get the Serial device when they first load the bootloader
<…>


History

Long ago, a forum was spun-off from a massively long Arduino.cc thread by a group of advanced Arduino users; said purpose of that new site was to give knowledgeable uC users a core compatible with IDE 1.5x to support the STM32F103xx Maple Mini inexpensive Chinese boards from Baite. Said core was a hack from the abandoned LeafLabs core effort.

The idea is that the STM32F103 board would give previous AVR Arduino users a cheap solution to extending performance and headroom while maintaining as-much Arduino’ish look ‘n feel as possible. At the time, members agreed that the forum would address advanced users as the 8-bit AVR official Arduino forum was staffed and moderated for newbies.

IMO:

Newbies should start with the 8-bit Arduino UNO and learn the basic terminologies and procedures and capabilities and limitations. When they have acquainted themselves with the fundamentals of the Arduino language, bootloaders, serial, I2C, SPI, and basic electronics then they have a foundation for moving up the ecosystem and being productive with the STM32F1xx boards.

The time to move from 8-bit Arduino to 32-bit STM32 will depend on the individual; but, with so much Internet material available for Arduino atmega328P, the timeframe could be as short as a few weeks of vacation. Couple in some darn-good YouTube videos on Arduino and C/C++ as implemented in the Arduino ecosystem and many people can shed the novice handle in a few months. (Students at the 300-400 or advanced classes likely have formal classes that provide the required foundational prerequisites.)

I do not think if we provide a true-valued service by making things foolproof and novice friendly. Roger has a few YouTube videos that are excellent and there is the WiKi that addresses far more than the commercial Maple Mini product of Leaf Labs.

A lots of effort can be wasted for little value gain when we get off-course and start looking to improve that which is working correctly. … not to mention making the simple core complex.

Opinion by Ray


ag123
Mon Jul 24, 2017 7:56 am
i didn’t actually have an avr, i started messing with mcu’s in stm32 & is quite happy that way, :lol:
i’d think stm32f1 is actually a good mcu to get started feature rich but an initial rather steep learning curve. the initial goofs as it seemed tend to be messing with those ‘perpetual bootloader’ buttons with maple mini and possibly installing the bootloader itself for the bluepill

for those who are truly ‘newbies’ in the mcu or even stm32 world, they should probably start with maple mini that has the bootloader pre-installed by the vendor. this is apparently the case for boards maple mini from baite & olimex. https://www.olimex.com/Products/Duino/S … e-hardware. i actually started off with the olimex’s board which is at a somewhat premium vs the cheap chinese MM and BP. the olimex’s board is still good value as it is a stm32f103RB and that it conform to the arduino uno headers which makes it usable with shields and is packed in addition with a uSD card slot on board, separate LDO for analog & digital, on board lipo charger

but the pre-installed boot loader means that i actually started without st-link, ft232 usb-serial etc, i started straight installing a blinky sketch via usb with the original maple bootloader installed by olimex. i’d guess that pretty much shortened the initial learning curve.
& of all things i actually used the ‘ancient’ *maple IDE*, simple no-nonsense, small footprint, works straight out of box on maple mini & olimex’s board
:lol:


Leave a Reply

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