[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