Shop OBEX P1 Docs P2 Docs Learn Events
Need ideas: bootloading prop from another MCU — Parallax Forums

Need ideas: bootloading prop from another MCU

pemspems Posts: 70
edited 2008-11-05 20:45 in Propeller 1
Hi all

I mentioned this subproject of mine before, but i have reached an important milestone in it this morning, so let me lay it out for you so you can give me your suggestions and feedback

Project:
My project involves inter-working a propeller with another math-friendly MCU (i.e both of them on same PCB). The project will be GPL'ed, so anyone interested would be free to poke their nose in.

Subproject:
One of the constraints is to have prop up and running as soon as possible after the power reset. A second or so is not acceptable. Therefore, it challenges me to come up with a solution that would maximally reduce the startup power-on time for the prop. (and eliminate the need for the i2c flash while i am at it)

Abstract implementation:
The plan is simple: Create a tiny prop program, that the other MCU will load into the prop via the standard P30,31 serial boot protocol at startup. Then, once the tiny program is running on the prop, it sets the clock to 80Mhz, then streams in and the main prop firmware via a wide bus and saves it into prop's hub ram. In the end, the tiny bootloader executes the newly received firmware by means of COGINIT (for each cog) and overwrites itself. Furthermore, the idea is to execute the more startup-time sensitive cogs earlier than other cogs that are less sensitive.

Usage pattern:
So i finally got the prototype of this to work this morning (thanks Baggers for catching this last bug).
To make the whole process user friendly, i've streamlined it as follows:
1. Load bootload.spin (the initial tiny bootloader) into MCU's designated flash area (have a helper app that uploads it over a USB virtual com)
2. Similarly load testfw.spin into firmware designated flash area
3. power-cycle, and bingo - everything works!

Now, here is what i need some help with:
The firmware will be more complex than just flashing led, and will utilize all cogs with shared data structures residing in the hub ram. Oh and did i mention i am not going to be using any SPIN? that's right - everything but the bootloader's preamble i plan to be pasm. So i really need to figure out a way for convenient binary generation that would contain the 2k blocks for each cog + hub data ready to be trivially uploaded and executed on the prop.
And I would also REALLY like to make the process of generation these firmware binary blocks windows-free. I guess one way would be to just make 8 .spinfiles containing minimal non-pasm stuff in proptool, then combine them somehow, but this seems to be ugly. Also i want to avoid dealing with *.spin file specific object pointers/structure and such - as i said as close to plain-structured pasm as possible.
I've been coming across the headlines on the forum about people making their own pasm tools, so maybe they can comment.

any other ideas on how to make this more convenient are welcome

EDIT: now that i think about it, maybe i should just come up with a binary format X, that would organize the pasm chunks with such metadata as which chunk goes into what cog, how large chunks are (to avoid uploading full 2k if not needed) and so on. Then just have an app that would extract pasm binary chunks from *.spin files and combine them in such format X. Then stream this X-formatted binary to the bootloader, which would know how to parse this format X and would populate the hub ram with the chunks for each cog prior to finally running coginit on the

Thanks

Comments

  • OwenSOwenS Posts: 173
    edited 2008-11-03 20:44
    I haven't updated it in a while (Sorry 'bout that; got distracted... and dishartened by lack of interest), but my PropTools works directly from the Linux/Windows/Probably OS X command line, generate a binary in whatever format you want (See the linker scripts & crt0.s), and support assembly, LMM assembly and assembly for my unreleased virtual machine ("VMM")
  • pemspems Posts: 70
    edited 2008-11-03 21:32
    Hi Owen
    OwenS said...
    I haven't updated it in a while (Sorry 'bout that; got distracted... and dishartened by lack of interest), ...

    lack of your own interest or interest from community ? If the latter, you are in luck wink.gif cause i really need a linux tool to generate clean binaries out of plain pasm code.

    Cheers
  • tpw_mantpw_man Posts: 276
    edited 2008-11-03 22:04
    Could you just have a loader that would be in assembly, but stream a propeller binary over? Your program in the binary could start all the cogs as needed, with their code. Would it matter if the binary had spin to start all the cogs it needed?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I am 1011, so be surprised!


    Advertisement sponsored by dfletch:
    Come and join us on the Propeller IRC channel for fast and easy help!
    Channel: #propeller
    Server: irc.freenode.net or freenode.net
    If you don't want to bother installing an IRC client, use Mibbit. www.mibbit.com
  • Cluso99Cluso99 Posts: 18,069
    edited 2008-11-04 08:58
    @pems:

    Once you have the prop running (spin or pasm) in minimal mode(presume cog 0), cog 0 will load the pasm code·for cog 1,·followed by cog 2, 3, 4, 5, 6, 7, and lastly by cog 0 (the reloaded code).

    So for example:

    cog 0 (presume running mini loader in either spin or pasm)

    cog 1 ($100 longs of instructions and preinitialised variables)

    cog 2 ($50 longs of instr+data)

    cog 3 ($40 longs of instr+data)

    Therefore, Cog 0 will load hub (say at $1000) with 100 + 50 + 40 + .. + .. + .. + .. + .. longs (the length is only the length of code and preset variables for all cogs together). This is the pasm code for cogs 1, followed by 2, 3, 4, 5, 6, 7 and finally the new pasm code for cog 0.

    Cog 0 will then·coginit each cog, just passing the start address.

    So, in the example above, cog 1 starts (loads 496 longs from) $1000, cog 1 from $1100 ($1000+$100), 2 from $1150, 3 from $1190, etc.

    Note that each coginit will automatically load the cog with the full 2k (actually 496 longs) from hub. So, in the example above, cog 1 will actually load 496 longs from $1000, so it will also load the other cogs instructions into it's cog ram, but that doesn't matter as it will not be used.

    Finally, once cog 0 has started (coginit) all cogs 1 thru 7, it will then coginit itself with the it,s new hub address ($1000+$100+...), and voila, all your cogs are now running your pasm code.

    I hope this makes sense.·
  • pemspems Posts: 70
    edited 2008-11-04 16:08
    Thanks Cluso

    you've just saved me a bunch of hub ram wink.gif , as i was going to pad each pasm chunk to get 2k overall size. You're right that padding isn't needed.

    btw, i just finished implementing (still need to test) a tool that takes a bunch of *.binary files (proptool's output) and extracts the pasm code out of them, then organizes these pasm chunks nicely in a single file. Moreover, i embed such metadata as number of cogs for each chunk.
    This is for situations like, for example, if i want one code chunk to be loaded into 2 cogs and the second code chunk into other 6 cogs.
    My bootloader recognizes this format now and loads cogs accordingly with appropriate chunks, while giving a unique id through PAR to the cogs running same chunks

    hope that maskes sense
  • Cluso99Cluso99 Posts: 18,069
    edited 2008-11-05 07:15
    Yes. You can reuse the hub code to start more than 1 cog and as you have realised, you can pass a parameter in PAR to identify the cog. You could also have used cogid to find out which cog you are running.

    You could just compile the pasm code in one file with a tiny spin stub at the beginning and use this binary file as is. If you use the Homespun compiler you get a listing output which will help enormously.
  • OwenSOwenS Posts: 173
    edited 2008-11-05 20:45
    PLink's crt0.s (Should probably be named art0, since it's the assembly runtime :P ) is a simple bootstrapper that has the Spin bytecode embedded into it to immediately reboot cog0 in PASM. IIRC the default linker script (Theyre written in Lua 5.1) automatically includes this, as well as updating the checksum byte.

    Theres also a flat.ld, which just generates a flat binary. You specify that you want to use flat.ld with -s flat
    (To use a custom linker script, use -s <name> to specify one in PLink's directory, and -S <name> to specify one in the working directory or by absolute path)

    I note that standard.ld doesn't include crt0.o automatically. I ought to re-add this (Presumably I removed it during development)

    Post Edited (OwenS) : 11/5/2008 8:53:20 PM GMT
Sign In or Register to comment.