[sdiy] Simple MIDI Seq for firmware updates

ASSI Stromeko at nexgo.de
Sat Mar 13 08:09:33 CET 2010


On Saturday 13 March 2010, MTG wrote:
> I'm working on a bootloader of sorts to allow me to update the
> firmware of a new MIDI device.  Because of the CPU architecture
> and memory constraints I have to send realtively small blocks. 
[...]

You have to be really careful with sysex/MIDI.  For starters, several 
popular sequencers don't easily send sysex from MIDI files with the 
standard settings in effect and most programs to send sysex strip the 
timing information off if they read it in from a MIDI file.  Be 
prepared to get MIDI clock and other realtime data inbetween the sysex 
bytes.  There will be power fails during the update, people will try 
to send the data faster or slower, etc. pp.  So you really need to be 
able to recover from a very wide range of error conditions.  Forget 
ACK/NAK handshaking unless you write your own updater to handle that 
and are prepared to support all platforms that people would want to 
run it on(*).  What this boils down to, IMHO, is that you will need a 
minimal system that you don't overwrite during the update (ideally 
never) and can get the device into a state where it will be able to 
take a fresh system image regardless of what went wrong before (quite 
like the serial bootloaders most uC have these days).  Updating the 
updater is something you'll hopefully never need to do, but if you 
want to make that failsafe you'll have to jumps through even more 
hoops. 

For stuffing the image I'd put each data block into a separate sysex 
message.  Prepend with a sequence number and the total number of 
packets so you can stop the processing when you miss a packet and give 
the user a chance to re-play the sysex (this assumes a display or some 
other means to signal this condition).  For the data coding itself you 
could use nibbles, but that wastes 3/7 of the capacity (not much of a 
problem until your update is very large).  However if you use the 
upper three bits as another (modulo 8) sequence counter, you have more 
assurance that you got all the bits in the correct order.  The other 
option is to just send eight MIDI bytes to get seven uC bytes.  
There's multiple ways of doing that, but sending all seven MSBit first 
(right-aligned) and then all bytes with the MSBit cut off seems to be 
the most popular as it allows to have runt packets with less than 
seven bytes(**).  Whatever method you chose, you will want a good 
checksum over your whole data block.  MIDI normally uses two's 
complement, which is inadequate for the data.  I'd have two checksums, 
a 2's complement over the whole message just for the MIDI transmission 
and another one embedded in the data that uses something better like a 
CRC and is checked in memory.

You will probably have to wait some time between sysex blocks for the 
unpacking, checking and the write.  While you can easily set this in a 
MIDI file (but then it is dependant on playback tempo) and you can 
tell users what sysex delay to use for other programs, it tends to go 
wrong anyway.  If your device can still operate the MIDI In while it 
is processing an update block, I'd just use a NOP sysex message to 
incur the correct delay so that whatever someone tries you never get 
the data faster than that.

Lat but not least, you can always check out what other people are 
doing: for instance www.midibox.org has code and applications that you 
could check out.

(*)  Using the JUCE library seems to become poular for this sort of 
thing.  I've not used it myself, but it seems to be worth a look.
(**) This format, among others, is described in the SoundDiver 
Programming Manual for Adaptations.


Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

DIY Stuff:
http://Synth.Stromeko.net/DIY.html




More information about the Synth-diy mailing list