Shop OBEX P1 Docs P2 Docs Learn Events
Launch PASM into Cog 0 running SPIN interpreter — Parallax Forums

Launch PASM into Cog 0 running SPIN interpreter

escherescher Posts: 138
edited 2018-02-19 04:51 in Propeller 1
I don't have my equipment with me so I can't test this on my own, and searching forums/datasheet/manual haven't answered this:

Is is possible to launch PASM in Cog 0 which is loaded with the SPIN interpreter on startup? e.g.:
    coginit   newcog
    
    '                  Address to PAR  Code address New CogID   
    '                |---------------|--------------|-|---|    
    newcog    long    %XXXXXXXXXXXXXX_XXXXXXXXXXXXXX_1_000

Or can you actually just call coginit from the Cog 0 SPIN interpreter, and the process of copying the instructions from hub RAM to overwrite the interpreter won't actually interrupt it?

I see in the API this statement for coginit:
Since COGINIT operates on a specific cog, as directed by the CogID parameter, it can be used to stop and restart an active cog in one step. This includes the current cog; i.e., a cog can use COGINIT to stop and restart itself to run, perhaps, completely different code.

That appears to answer my question, but then how would one start a SPIN interpreter cog from a PASM cog?

Thanks!

Comments

  • Heater.Heater. Posts: 21,230
    You can indeed start PASM in COG 0 from Spin in COG 0. Thus killing off the original Spin and replacing it with the newly running PASM. I have done this.

    Given that the Spin interpreter code is in the ROM it must be possible to start it running using COGINIT.

    Sorry I don't know the address of the Spin interpreter code. Somebody here will know it. Somehow one will have to pass the address of the Spin code it should run as well.
  • AribaAriba Posts: 2,690
    The spin interpreter starts at $F004 in ROM. You need a pointer to a structre with base pointers for code and data and stack in PAR. For the top object this structure is at address 4 in Hub:
    pasm
              ...
              coginit spin_vm        'start Spin interpreter
              ...
    
    spin_vm   long  ($0004 << 16) | ($F004 << 2) | 0   'top object, cog 0
    

    Andy
  • evanhevanh Posts: 15,916
    long  ($0004 << 16) | ($F004 << 2) | 0
    

    Is that really correct? It looks like there is 2 bits of overlap.

  • AribaAriba Posts: 2,690
    evanh wrote: »
    long  ($0004 << 16) | ($F004 << 2) | 0
    

    Is that really correct? It looks like there is 2 bits of overlap.

    I think so, It's written like that to show the real addresses. The $0004 goes into PAR and the two lowest bits of this address must always be zero.
  • Cluso99Cluso99 Posts: 18,069
    IIRC it's because only 30 bits are passed in par. The two 16 bit addresses in spin rely on the fact that the bottom two bits of the addresses are 00.

    If you look at the booter PASM code you will see how to launch spin directly.
  • I have used the following code to start up the main function ('begin') in another cog so I could use cog 0 for other things. It needs to be the first PUB function in your Top Object File.
    '' Note: this function needs to be PUB, not PRI
    PUB stub_start
      ' Free up cog 0 for better things!  (ADC or SD card access, anyone?)
      ' Transition the main code to a new cog, but I need
      ' a good stack pointer.  Use the original stack
      ' pointer (7th word in RAM), plus I need 80 extra
      ' bytes to handle this routine while the transition
      ' occurs.
      cognew( begin, 80 + word[0][7] )
      ' now we just expire gracefully
      cogstop( cogid )
    
    Once the 'begin' function is running in another cog, it can launch whatever code you want in cog 0.

    thanks,
    Jonathan
  • lonesock wrote: »
    I have used the following code to start up the main function ('begin') in another cog so I could use cog 0 for other things. It needs to be the first PUB function in your Top Object File.
    '' Note: this function needs to be PUB, not PRI
    PUB stub_start
      ' Free up cog 0 for better things!  (ADC or SD card access, anyone?)
      ' Transition the main code to a new cog, but I need
      ' a good stack pointer.  Use the original stack
      ' pointer (7th word in RAM), plus I need 80 extra
      ' bytes to handle this routine while the transition
      ' occurs.
      cognew( begin, 80 + word[0][7] )
      ' now we just expire gracefully
      cogstop( cogid )
    
    Once the 'begin' function is running in another cog, it can launch whatever code you want in cog 0.

    thanks,
    Jonathan

    Your Alley-oop is quite graceful :smile:
  • lonesock wrote: »
    I have used the following code to start up the main function ('begin') in another cog so I could use cog 0 for other things. It needs to be the first PUB function in your Top Object File.
    '' Note: this function needs to be PUB, not PRI
    PUB stub_start
      ' Free up cog 0 for better things!  (ADC or SD card access, anyone?)
      ' Transition the main code to a new cog, but I need
      ' a good stack pointer.  Use the original stack
      ' pointer (7th word in RAM), plus I need 80 extra
      ' bytes to handle this routine while the transition
      ' occurs.
      cognew( begin, 80 + word[0][7] )
      ' now we just expire gracefully
      cogstop( cogid )
    
    Once the 'begin' function is running in another cog, it can launch whatever code you want in cog 0.

    thanks,
    Jonathan

    Interesting technique; I'm attempting it now. How did you calculate the "80 extra bytes" needed?
  • I'm embarrassed to admit I don't remember how I came by that 80-byte padding. Most likely there was the "find the threshold where it crashes" phase, followed by the "multiply by 2 just to be safe" phase. [8^)

    thanks,
    Jonathan
  • Not sure whether this is needed, but here's the link to Chip's "runner", booter and interpreter code
    http://forums.parallax.com/discussion/comment/1359516/#Comment_1359516
  • escher wrote: »
    Is is possible to launch PASM in Cog 0 which is loaded with the SPIN interpreter on startup

    It's possible to have PASM running in all 8 cogs if you use coginit and load cog 0 last.
  • Cluso99Cluso99 Posts: 18,069
    In actual fact, all cogs only run PASM. The spin Interpreter is a PASM program loaded into a COG(s)
  • Heater.Heater. Posts: 21,230
    edited 2018-02-21 10:51
    Sure it is Alexander. Bin there, done that. Works a treat.

    No need to load COG 0 last. One could imagine that 0 starts 1, 1 restarts 0, ... 1 starts 2.... Or whatever scheme you like.
  • Cluso99Cluso99 Posts: 18,069
    Mostly, you don't even require to know which cog runs what code, so a cognew will work just as well.
  • Heater.Heater. Posts: 21,230
    Yes, mostly it's better not to even need to know which COG is running what.

    With the slight complication I guess that if you want to start 8 cogs running PASM from a Spin object you had better know which COG is running that Spin object so that you kill of the right COG to run that 8th PASM part. And such like scenarios.

    One could assume the Spin is always COG 0 but that might be a bit iffy sometimes.


  • I guess you could instantiate consecutive cogs passing an array of COGIDs already instantiated to the next cog, choosing that next cog by excluding the already instantiated COGIDs from a pool of COGIDs available to be instantiated and

    a7Yyjg8.gif
  • Cluso99Cluso99 Posts: 18,069
    Or just start 7 cogs with cognew, then restart the current cog with coginit(cogid, , )
  • Cluso99 wrote: »
    Or just start 7 cogs with cognew, then restart the current cog with coginit(cogid, , )

    dVDJiez.gif

    I guess I assumed that calling coginit on yourself would result in a race condition... because there has to be some code running somewhere which transfers your targeted PASM code to overwrite the interpreter, and I assume that code has to be running via the interpreter itself.
  • Heater.Heater. Posts: 21,230
    Well there is the thing. COGINIT/NEW are not just some software functions you call to copy code around and start a COG. They are actual processor instructions. So all that loading and running is done in hardware. The Propeller does not care that the code that runs those instructions stops running, it just goes ahead and runs something else for you.
Sign In or Register to comment.