Shop OBEX P1 Docs P2 Docs Learn Events
Executable Spin Files? — Parallax Forums

Executable Spin Files?

Circuitbuilder9Circuitbuilder9 Posts: 85
edited 2012-12-18 19:15 in Propeller 1
Hey everyone,

I wanted to load (by EEPROM) on my propeller quickstart a program without including it in an object block, but rather execute it by turning it into a binary file, and then get the propeller to download and execute it on a mSD. However, I'm not sure how to do that, if it can be done at all. Help?

Thanks
p.s. - the program that i want executed is below

Blink.spin
«1

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-11-15 20:05
    That's possible, but not trivial. There are several I/O drivers for SD cards that will load and execute a program from an SD card file. Kye's driver has a bootPartition method. FemtoBasic has an SD card driver (fsrwFemto.spin + sdspiFemto.spin) that will load and execute a program from an SD card file. The file has to be opened (popen) and run (bootSDCard). Sphinx is an operating system that can load and run programs from an SD card using commands entered from a PS/2 keyboard and displayed on a TV.

    If all you want to do is blink an LED, it's much easier to just do that as part of your program. What are you really trying to do?
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-15 23:21
    Using the mentioned SD card-driver is a good and easy solution. You can even enhance the SD card-driver not to stop all the COGs. Then you can have something like a watchdog running which stops the loaded program after a certain time or if a certain pin goes high. Another nice thing of such a background COG is that you can keep the outputs in a defined state. The SD card-driver will simply stop all COGs other than itself, which means that all outputs (except the ones of the SD card) will go to tri-state-mode again. Depending on what hardware is attached to your prop you might not want this to happen!
    Going back to the program stored in EEPROM can simply be done by doing a software-reset. If I remember right this is described somewhere in http://propeller.wikispaces.com but I could also search for it when I'm back home.

    But for easy programs there is another solution which does not stop your loader program.
    For such small programs you can also load a bin into a buffer start it there with a COGNEW, not leaving your main program! Have a look: http://forums.parallax.com/showthread.php?143182-Spinneret-need-more-Space&p=1135658&viewfull=1#post1135658
    But as I already stated in that thread, this buffer has to be big enough to hold the bin PLUS the main stack that is needed by this loaded program!
    It's also possible to pass parameters into this bin-program. If you need that let me know and I'll search for an example.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 06:16
    Thanks, guys.

    Mr. Green, for clarification, i wanted to use the blinking program as a proof of concept. I wanted to see if it was possible.

    So how would you start? load the spin program you want to execute from the SD into a .bin, then.............
    I've tried a few times, but do not know how to go from there.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-11-17 07:04
    Yes, you compile the program you want to load and save it as a .binary file (actually as a .bin file with an 8.3 character file name). You then copy the .bin file to an SD card, preferably formatted with a 32K cluster size.

    I suggest you get copies of FemtoBasic (for the sdspiFemto.spin and fsrwFemto.spin files) and DongleBasic (to play with) from the Object Exchange. You'll have to edit BB_Definitions.spin to specify which I/O pins you've got for your SD card, then recompile the whole thing (DongleBasic.spin) using the Propeller Tool. Look at the documentation for the SPIN statement which will execute a file from the SD card.

    DongleBasic uses a slightly different arrangement of the I/O drivers than FemtoBasic and it's easier to just take the relevant files (sdspiFemto.spin and fsrwFemto.spin) from FemtoBasic and incorporate them into your program than taking the equivalent files from DongleBasic. With these files, you also get methods to read and write data files from SD cards and to read and write data to EEPROMs.

    FemtoBasic has been used to run a kiosk to run one of several demo / game programs for the Propeller from an SD card using a TV monitor and keyboard to select the demo program.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 07:53
    Great. I'll try it out and inform you if i have any problems.
    Thanks!!
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 08:37
    OK, i have one question concerning the EEPROM.
    I am using a parallax quickstart's EEPROM, so, do i set the upper_eeprom variable to $4000 instead of $8000?
    When i boot the Blink program mentioned earlier, nothing happened.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-11-17 08:56
    OK, i have one question concerning the EEPROM.
    I am using a parallax quickstart's EEPROM, so, do i set the upper_eeprom variable to $4000 instead of $8000?
    When i boot the Blink program mentioned earlier, nothing happened.

    Most QuickStarts have 64K EEPROMs.

    You can check using the program attached to post #24 here. (Only use it to check your EEPROM size, the rest of the program is very buggy.)
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 14:18
    Alright. I tried, but still don't know how to execute the Blink program.

    Here's what i have so far:

    ExecuteSD.spin
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-17 16:03
    First of all your copy-code does not copy the file to EEPROM:
      repeat until (sd.pread(@buffer, 32) <> 0)
      repeat until (sd.writeEEPROM(sdspi#BootAddr + $8000, @buffer, 32) <> 0)
      repeat until (sd.writeWait(sdspi#BootAddr + $8000) <> 0)
    

    The first repeat will read in 32 byte chunks, but it always stores the 32 bytes in the same memory location.
    The second repeat is never ending and always copies the same 32 bytes to the same address of EEPROM.

    What you'd need is to have one single repeat loop
    read from file
    write the chunk to EEPROM
    wait until EEPROM is done

    But I also don't understand why you would copy the program to EEPROM if you have the SD-card. You can also start bin-files from SD card!
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 16:28
    Sorry. I am very confused by how i am to execute this program from the SD.

    Try, try again....
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-17 16:39
    I don't know which version of fsrwFemto you have, but in mine there is a function called bootSDcard.

    You'd simply open the file and then call this function - that's it!



    PS: This is a modified version, which allows to pass a COG-ID of a COG that should NOT be stopped by bootSDcard. I used it to run a timer which would reboot the propeller after a while.

    Here is the code for that timer:
    dat
            org 0
    
    watch   rdbyte  asec, #$3
            cmp     asec, #$ff WZ
      if_Z  jmp     #watch
              
            rdlong  asec, sec
            mov     wtime,cnt
            add     wtime, asec
    loop    waitcnt wtime, asec
            add     sec,#1
            cmp     sec, par WZ
      if_NZ jmp     #loop
    
            clkset bit7set                'set bit7 high in clk register - force hardware reboot
    
    wtime   long 0
    bit7set long $80
    asec    long 0
    sec     long 0
    

    Simply start it with a COGNEW where the second parameter contains the seconds to run. If no additional COG needs to survive, simply pass 8 to the bootSDcard.
  • AribaAriba Posts: 2,690
    edited 2012-11-17 16:51
    Something like that:
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    
    VAR
       long ioControl[2]
    
    OBJ
      sd: "fsrwFemto"
      lcd: "Debug_Lcd"
      
    PUB Start | wdcog, mount
      lcd.init(1, 19200, 4)
      lcd.backlight(true)
      lcd.cls
    
      sd.start(@ioControl)
      mount := \sd.initSDCard(2,3,4,5)
      if mount < 0
        lcd.str(string("Failed to mount"))
        abort
    
      ifnot sd.popen(string("b1.bin"), "r")
        sd.bootSDcard
    
    

    Andy
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 17:13
    Alright. I set up the loop so that it read the data to the buffer by steps of 32.

    But still no effect.
    MagIO2:
    But I also don't understand why you would copy the program to EEPROM if you have the SD-card. You can also start bin-files from SD card!

    i probably should have asked this earlier, because this was my purpose of intention.
    Can i see some code on how you are supposed to do that?
    I don't get the idea of starting a "watchcog" and then shut it down. What's the purpose of that?

    To sum it all up, i want to build a program that executes a spin program on an SD, directly from the SD. So, in context of the program (Blink), i need the parent program to execute "Blink" from the SD. However, i do not know how.

    ExecuteSD.spin
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-17 17:43
    Your loop is still wrong, as you also have to add i to the EEPROM-address that you want to write to. To be honest this is the most important part, as you don't have to increase the buffer-address.
      i := 0
      j := 0 
      repeat while j==32
        j := sd.pread(@buffer, 32)
        sd.writeEEPROM(sdspi#BootAddr + $8000 + i, @buffer, 32)
        sd.writeWait(sdspi#BootAddr + $8000 + i)
        i += j
    
    The changes I did make the loop more flexible, as your bin file size can be any size. In your code you limited it to 500 bytes. Now it reads as many bytes as there are in the file. On the other hand if reading in junks, there is no need to have a 1000 byte buffer.

    For running a bin directly from SD just have a look at Aribas example!

    I don't know what your watchdog in ExecuteSD is really good for?! The watch I posted is a little timer which counts seconds. If the number of seconds is equal to the parameter with which the watch has been started, it's resetting the propeller. This piece of code is copied from a small OS where I can run any bin and I can limit the runtime. This was nice for running demos just for a while and then returning to the OS which is the program loaded into EEPROM.
    But be aware, this watch only works together with my version of fsrwFemto/sdspiFemto, as the original versions would stop any COG except the COGs needed to load the bin. After loading the bin a new SPIN interpreter is started and the remaining running COGs (except the new interpreter COG) are stopped as well.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 17:58
    Thanks.

    I deleted the watchcog method and added MagIO2's repeat loop.
    However, this is getting frustrating. There is no result to the LCD or the Blink program on the SD. The method is supposed to say on the LCD that the program is loading from the EEPROM before actually loading the EEPROM (to see that the statements actually went through).
    But, no avail.

    Help!!

    ExecuteSD.spin
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-17 18:14
    Oh ... sorry ... mistake on my side!

    j should be initialized with 32, otherwise it won't enter the loop at all:

    j := 32
    instead of
    j := 0

    I don't know your LCD driver. Is it starting a COG to send data to the LCD? In that case there might be a problem when bootEEPROM stops this COG to early. Simply wait for half a second before calling bootEEPROM.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 18:17
    I don't know about the cog......

    Do you think that the sdspi program is stopping my cog before it can be executed?
    If so, how do i prevent that?
  • Mike GreenMike Green Posts: 23,101
    edited 2012-11-17 18:25
    Once the boot routine in the I/O driver in sdspiFemto is called, it has to shut down all the other cogs since it knows nothing about what else is in hub memory at that time and it has to be prepared to read in a full 32K program which would overwrite any Spin program still present in hub memory. The boot routine in sdspiFemto is written in assembly and complete resides in the one cog memory that's still running. If, for some reason, you want some other set of assumptions to be made, you'll have to modify the boot routine. For the general case, the current sdspiFemto assumptions are the necessary ones.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-17 18:28
    I suppose your LCD was working fine before?
      lcd.cls  
      lcd.str(string("booting....."))
      waitcnt( clkfreq*5+cnt )
      sd.BootEEPROM(sdspi#BootAddr + $8000)
    

    Then you should see the message at least for 5 sec. But when calling bootEEPROM the backlight will be switched off again, as the COG which drives the backlight pin will be stopped.
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 18:29
    Ok, i think i found one problem to ExecuteSD.spin:

    I didn't start the sd.start method as Ariba posted a few posts ago.
    So, i ended up getting the message on the SD.....

    BUT:

    No blinking lights from the bin file!!!
    Help?
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-17 18:35
    Here's something:

    I opened the b1.bin file from the sd, and it opened a spin program with nothing written on it.
    BUT, i downloaded the file on a binary viewer, and there was code written on it as it was compiled to a bin file previously.....

    I am very confused on why this isn't working. Previously, i thought i was doing something wrong with the code, but when i saw your posts, i was doing everything correctly. The problem lies in the bin file...... but i don't know what.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-11-18 04:45
    A little while back Kye wrote an SD driver, and as Mike Green mentioned, it has some methods for loading files into memory off an SD card and then rebooting the propeller. I was drawn to Kye's driver as I had a pile of SD cards with many brands and his driver worked on all the cards I had. So I wrote a command line operating system based around his driver. It was built for a VGA screen and then Jeff Ledger added a TV driver. You can move around within directories, do a listing of files and run .bin files.

    I've more recently coded a touchscreen version that has the files as icons on the screen and it is also based on Kye's driver.

    The main program is KyeDos3_TV and the comments at the beginning show the steps needed to get this working. There are a number of objects commented out, like the driver for a 20x4 LCD screen, but they have been left in to show how this can work with a number of displays. I had it working sending data to the VGA display, to the 20x4 LCD screen and to the serial port as that was a flexible way of debugging. Comment out the things you don't need.

    Maybe you can find something useful in this?
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-18 11:30
    It looks straightforward. But i think this object uses an SD interface, since it uses a WP pin.

    I am using a mSD.
    I tried executing the program again, but i'm not getting any blinking from the Blink bin program on the mSD. Can someone tell me what's wrong with my code?

    ExecuteSD.spin
  • Mike GreenMike Green Posts: 23,101
    edited 2012-11-18 11:39
    Why are you copying the program to the EEPROM, then attempting to boot it from EEPROM?

    There's another routine in fsrwFemto that will directly boot from the SD card (bootSDcard).

    Here's the code from FemtoBasic that gets the file name into a buffer, mounts the SD card, opens the file, and boots the new program:
    scanFilename(@f0)
    if \fsrw.mount(spiDO,spiClk,spiDI,spiCS) < 0
       abort string("Can't mount SD card")
    if \fsrw.popen(@f0,"r")
       abort string("Can't open file")
    fsrw.bootSDCard
    

    How are you getting the binary file and how are you putting it on the SD card?
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-18 11:45
    How far does it get? Do you see "mounted"?

    You could also add some debug messages inside of the loop.

    I'd not expect that you see "booting..." and you'll definitely not see "done" because bootEEPROM will stop all the COGs not needed for loading from EEPROM.

    Why exactly don't you switch to Aribas code which loads the bin from SD directly?
  • Mike GreenMike Green Posts: 23,101
    edited 2012-11-18 12:01
    This process works. You can execute programs from any EEPROM address and you can execute programs from an SD card (or mSD card) file. You can copy data (including programs) from SD card files to EEPROM and back and from SD card to SD card and from EEPROM to EEPROM. The question is "what's different about what you have and what you're doing compared to others where it works?". I strongly suggest you use something like FemtoBasic or DongleBasic and make sure you have the SD card connected correctly ... It won't mount if it's not connected correctly. FemtoBasic or DongleBasic will let you display the contents of a file byte by byte. There's no built-in hex display, but you can write that in Basic in a couple of lines to make it easier to compare bytes in a file to the Propeller Tool's hex display.
    100 h = $23 : gosub 1000
    110 display 13 : stop
    1000 d = h / 16 : gosub 1030
    1010 d = h // 16 : gosub 1030
    1020 return
    1030 if d > 9 then display (d-10)+"A" : return
    1040 display d + "0" : return
    
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-18 13:29
    I will try to boot it directly from EEPROM.
    I actually had another program made (ExecuteSD 3) that uses Ariba's example. However, the mSD wouldn't boot even though the "booting...." message showed up on my LCD.

    My mSD is set up like so:
    DO -> wire directly to pin 2
    SCLK -> wire directly to pin 3
    DI -> wire direclty to pin 4
    CS -> wire directly to pin 5

    am i supposed to include pull-up resistors? That thought just came to me.

    @Mike Green - sorry for being confusing, but i just wanted to load the sd file to eeprom, then boot from the file that was downloaded to eeprom as a means of proof of concept.

    Oh, and by the way, this is how i put the Blink program to the sd:
    1. F8
    2. save as .bin file (i called it b1.bin) under binary file type
    3. saved to mSD

    There is no other file on the mSD, just the Blink binary.

    ExecuteSD3.spin
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-11-18 13:57
    I presume by mSD you mean micro SD. If so then SD and micro SD (and mini SD half way between the two) are all the same. They all use 4 pins, and you can ignore WP. So 4 pins - DO, DI, SCLK and CS. Generally designs seem to have 10k pullups on these pins.

    Re the program, can you post the full program ie the objects as well, just to double check the order of the pins is correct?
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-18 14:02
    The pin directions are fine, but is it crucial to have pull-ups?
  • Circuitbuilder9Circuitbuilder9 Posts: 85
    edited 2012-11-18 14:08
    I've just added pullups, but the binary file still will not execute(i.e.- no blinking.)
Sign In or Register to comment.