Booting from secondary EEPROM (non SD bootloader)
WBA Consulting
Posts: 2,935
This is for the Thermistor Cable Tester I am currently making. A "key" that contains an EEPROM will be used to select the configuration program to run. I would like the main program to initialize the LCD and prompt for a key to be inserted if one is not there. If I just use the "key" EEPROM as the main EEPROM, then nothing will prompt the operator top insert a key if one is not inserted.
I have been scouring the forums looking for bootloader code examples that load a program from a secondary EEPROM, but can only find ones that grab programs from SD Cards. I'll have a secondary EEPROM addressed differently than the onboard EEPROM to use. I found a few threads discussing using "sdspiFemto.spin" from Mike Green's FemtoBasic, but I can't find any examples to help me understand the command usage for EEPROMs because they all discuss using SD Cards. The docs for sdspiFemto are a bit above my head for explaining some commands (I think I should somehow make use of the "spin" command, but can't understand the explanation.
Anyone know of any examples that boot from a main EEPROM, check for a secondary EEPROM, then load a program from the secondary EEPROM?
I have been scouring the forums looking for bootloader code examples that load a program from a secondary EEPROM, but can only find ones that grab programs from SD Cards. I'll have a secondary EEPROM addressed differently than the onboard EEPROM to use. I found a few threads discussing using "sdspiFemto.spin" from Mike Green's FemtoBasic, but I can't find any examples to help me understand the command usage for EEPROMs because they all discuss using SD Cards. The docs for sdspiFemto are a bit above my head for explaining some commands (I think I should somehow make use of the "spin" command, but can't understand the explanation.
Anyone know of any examples that boot from a main EEPROM, check for a secondary EEPROM, then load a program from the secondary EEPROM?
Comments
From "loader.spin", "srwFemto.spin", and "sdspiFemto.spin" (from Nick's link), I have narrowed down my focus to the following sections:
In loader.spin, the lines 120-147 that drives reading from the SD card and writing that data to EEPROM At first, I was getting confused at the calls to the SD object for writing to the EEPROM, but after looking at the object in detail, I see that it is just passing those calls right to sdspiFemto, lines 160-174.
So, my thoughts are that I need to look at how to utilize the readEEPROM PUB from sdspiFemto to load the secondary EEPROM contents into hub ram and run it as the main program. Messing with hub ram is way over my head, so I am walking blindly now.
Any thoughts on whether or not I am on the right track?
The spin file in the zip uses Mike Greens I2C object and uses both the EEPROM read and EEPROM write routines.
If I remember correctly it writes the whole 32K but this would probably not be neccessary , bytes 8 and 9 of the binary determine the program size.
http://forums.parallax.com/showthread.php?122891-Help-with-a-EEPROM-boot-loader
Jeff T.
http://forums.parallax.com/showthread.php?126798-NEW-EEPROM-expansion-%28bank-switch-adapter%29
Robert
All cogs are eventually stopped except the one with the PASM routines for the loader (started by bootEEPROM) and that is the one used to do the COGINIT for the loaded program. This is done because the new program might overwrite the entire hub RAM.
bootEEPROM assumes that you want to load a full 32K like the Prop ROM's bootloader. It's possible to change the routine to read less than that.
Using the bootEEPROM PUB in sdspiFemto.spin, I can pass it an address of $71000 (for the 23 bit address will be 11100010000000000000000) and it will boot from a secondary EEPROM with the A0 pin pulled high that it is on the same i2C bus as the onboard EEPROM. Attached is the Excel "brainstorming" that I had to do to have the 23 bit addressing make complete sense, because in sdspiFemto, you only have this:
To give you the address of the boot EEPROM which had me lost. But, I broke it down using Mike's post and the comments in the file and used Excel to track my thinking. It seems to make sense now and hopefully I can try it out tomorrow. thanks Mike!
However, I then tried to utilize the checkPresence routine and calling that routine just puts the chip into lala land and never recovers. I cannot figure out why, because it's so simple. I simply want the main program to check for the secondary EEPROM and if it is present, boot from it. If not, the main program will run an "idle" loop that will check for a secondary EEPROM every few seconds while displaying a message on screen that states such.
Anyone see why the checkpresence routine is not working? If I comment out the "EEprsnt := EEP.checkPresence(cfgEEaddr)" line and manually set the state of EEprsnt in the code, I get the desired results.
I came to the conclusion that for me the simplest and most versatile method would be to use a copy of the Propellers own bootloader. Chip made the ROM executable open source at this thread http://forums.parallax.com/showthread.php?101483-Propeller-ROM-source-code-HERE&highlight=bootloader
The assembly is well documented and not too hard to follow. By modifying mask_sda and mask_scl any pin pair can be selected for your EEPROM(s). The ee_wait routine checks for EEPROM presence and goes to a shutdown routine if not found , the shutdown routine could be replaced with a message routine if prefered.
If expanded to take parameters this bootloader would give many options of memory size , external memory addresses and different media by which a program could be loaded.
I have attached a version of the original source that has the serial routine stripped out , as is it will boot the standard EEPROM of a Propeller when loaded into RAM from the Prop Tool IDE. The byte code is less than 500 bytes.
Something to consider , if not this time maybe in the future
Jeff T.
The bootEEPROM is the only routine in sdspiFemto that initializes the assembly cog before it does its own work. checkPresence is just a read without doing any reading and, like all the other public methods in sdspiFemto, requires you to have initialized the assembly cog by calling the start method first.
Jeff, that looks really promising. PASM is way over my head, but some of that code is making sense to me, so I may dig into it further since I have another project that will need on the fly configuring and a "key" is a good solution so that the box can remain sealed shut.
I'm not PASM fluent either but Chip's "Pnut" source was easy for me to modify and use as a standalone routine. I'm sure it's been used by others but for me it was a discovery that opened up a bunch of possibilities.
I have tested it on a development board with a secondary EEPROM on P0 and P1 and so far I can flip flop between launching EEPROM #1 and EEPROM #2 , if I get time later today I would like to attach two EEPROMs to P0 and P1 and see if I can pass address's and pin numbers to the pasm routine (easy for some but like I said I am not an asm guru ).
The "key" concept is smart I hope the completed project is posted.
Jeff T.
There's a bug in the bootEEPROM routine for the situation where it returns with an error code. It starts up the assembly cog using a control block in a local (stack) variable. This is fine if it's successful since the assembly cog won't use the control block once it starts loading the program. bootEEPROM needs to call stop on an error return like this: The SD card boot routine doesn't have this problem since it assumes that there will need to be some additional cleanup if the program fails to load, like turning off the SD card, and your program will furnish the control block area rather than the boot routine creating one on the stack.
I have an idea I may want to try this. What I would like to be able to do is serially transmit the new code to an upper portion of EEPROM. Then have it set a flag and reboot. Is this possible?
Assuming there is just the one 64K EEPROM attached and you want to independently load the upper or lower 32K without affecting the other and you also want to use the Prop tool as the interface then as far as I can see you are going to need a second serial connection and a modified boot loader
On reset the Props boot loader will check the serial port for a handshake from the Prop tool, if there is no activity on the serial line the lower 32K is loaded and launched from EEPROM.
To extend this behavior so as to load a program into a different area of EEPROM ( or into RAM if desired ) from a different rx/tx pin pair a modified copy of the Props boot loader can be loaded to RAM first.
The modifications to the boot loader include a change in EEPROM address, a change in rx,tx pair and the removal of the time out. The secondary serial connection is just the rx and tx there is no dtr because there is no need to do a reset.
There is a procedure
1./ In the IDE Port management implicitly set the port to the default programming port
2./ Download the modified boot loader to RAM (F10)
3./ Switch to the program you want in the upper 32K
4./ In the IDE Port management implicitly set the port to the secondary programming port.
5./ Download to the upper 32K (F11)
If you wanted to try this I have attached a modified loader that uses P0 and P1 as rx and tx and has the time out inhibited. I have not adjusted the EEPROM settings so for now it will still load the first 32K or launch to RAM if desired.
Jeff T.
So am I understanding this correctly that once the Prop is up and running that I could overwrite the lower half of the eeprom with a new program and once the Prop resets it will then load and run the new program? In reality do I even need a boot loader other that what is in the Prop already?
Again I think it more feasible using a modified loader, something much simpler than the last example. This modified loader has got to end up in RAM when the time comes to re program the Prop. So it has to be included as a part of each program that is downloaded or stored and loaded from an attached memory source which could be additional EEPROM. Every program would also need a resource to monitor the serial port looking for a command to load the loader.
I am saying this not knowing whether the Prop tool would be able to synch up via Bluetooth, it would be nice if it were possible, my assumption is that the download would be made using a custom GUI.
You may get answers regarding the Bluetooth programming, as Andrew suggested it may be best to start another thread with that question. In the mean time I am going to hook up a BT module and do a little experimenting.
If you knew in advance what the programs were an alternative might be to store several programs to EEPROM (s) and load them as required using a slot approach
E.g.: http://forums.parallax.com/showthread.php?130615-Slot-Programming-the-Propeller
Jeff T.
EDIT: to answer the question about programming while up and running. You can read and write at will to the EEPROM while running but you need a means to do that. What I suggested means halting program execution while a new program uses the RAM to load the EEPROM
Jeff T.