Shop OBEX P1 Docs P2 Docs Learn Events
Inter-Process communication — Parallax Forums

Inter-Process communication

ErNaErNa Posts: 1,742
edited 2011-01-24 12:45 in Propeller 1
I like to present a method I now use for some time to synchronize processes, running in parallel on different cogs.

One of the reasons is, that calling a method may need a lot of parameters to pass and that is sometimes uncomfortable.

The idea behind that is: start a cog by loading a spin or asm method and have the method initialized, then running idle. Sending a command to the method triggers an action, which may be running ones or persistant.

Communication runs via a process control block, like PCB_IEnc for an incremental encoder.
CON   NmbIEncPar = 12      'Number of parameters, handed over to the incremental encoder process
Dat
PCB_IEnc  long   @IEncCmd, @IEncPos, @IEncOfs, @IEncRes, @IEncVTim, @IEncVCnt, @IEncTiSl, @IEncSens
               long   @IEncTiBa, @ScVal053, @ScVal054, @ScVal055

First I declare a constant NmbIEncPar, which is the number of parameters, passed to the process. Then, there is a table of NmbIEncPar pointers to the actual variables in global memories.

Then there is an enumeration of the process commands:

'CommandSet  of incremental encoder process
#1, Idle, Run, FreeRun, DetReso, LoadPar, Sweep

Now, as the main routine starts, the process has to be initialized:



IEncCmd  :=  NmbIEncPar     ' Tell the process how many pointers to initialize
i             :=  IEnc.start(@PCB_IEnc,@@0)-1   ' Start incremental encoder process
ifIEncRes  ==0
     ActState := CmdInvok (@IEncCmd, DetReso, i)  Returns if resolution of encoder detected, stays in 'FreeRun'
else
    ActState := CmdInvok (@IEncCmd, Run, 255)   'Run the incremental encoder in triggered mode (to be explained)

Now the incremental encoder is running and the position will be in IEncPos.
As a special feature: it may happen, that the resolution of the encoder is not fixed. If unknown at the start (hardware could be plugged in), then the default value of resolution is set to 0. If this is true, then the incremental encoder first has to pass the index signal twice running into the same direction, so resolution is known, stored to IEncRes and the programm run continues.
If the resolution is known, than the initial position is set to a value more than twice the resolution. When the encoder reaches index, the position is set to the correct value.

To be continued

cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
Hello Rest Of The World
Hello Debris
Install a propeller and blow them away wink.gif

Comments

  • ErNaErNa Posts: 1,742
    edited 2010-06-30 19:54
    There is now a little bit of rather cryptic code, but, it's worth to think a little bit about it.
    This code is nearly independ from starting a Spin or an ASM process.
    PUB Start( GlobPtr, AddrOffs) | i 
    
      Stop  ' Start can restart, therefore stop a possibly running cog first
      ' Create a local copy of the global pointer array and do the address correction "quick and dirty"
      repeat i from 0 to LONG[noparse][[/noparse]LONG[noparse][[/noparse]GlobPtr +   0]+AddrOffs]-1        ' The first parameter is the number of parameters
        LONG[noparse][[/noparse]@LoclPtr + (i<<2)] := LONG[noparse][[/noparse]GlobPtr + (i<<2)] + AddrOffs ' all pointers are 32 bit, the pointer address is byte oriented
          
      ifnot ID_cog
       [b] ID_cog := cognew(CogProc, @Sk) + 1[/b] ' starting spin
       [b] ID_cog := cognew(@ASM_Entry, 0) + 1[/b] 'starting ASM
    
      Result := ID_Cog 
    
    PRI Stop
      if ID_cog
        cogstop(ID_cog~ - 1)
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
    Hello Rest Of The World
    Hello Debris
    Install a propeller and blow them away wink.gif
  • ErNaErNa Posts: 1,742
    edited 2010-07-01 22:12
    This is the main loop of an assembler process
    DAT     org  0
    
    ASM_Entry
            mov       Command,  #0                  ' Reset Command to zero
            wrlong    Command,  CommandPtr          ' Acknowledge: Process running
    
            mov       Command,  #5                  ' Number of implemented commands +1, to check range
            rdlong    DrGTimSli, DrGTiSlPtr         ' Get the time slice for speed measurement
            mov       DrGVelTim, cnt                ' Initialize start time
            jmp       #:Initial                                                  
    :LoopCmd
            rdlong    Command,  CommandPtr          ' Poll for new command
    :Initial
            cmp       Command,  #MaxCmd       wc    ' check for upper limit
    if_nc   mov       Command,  #0                  ' if exceeded, replace by NOP
            add       Command,  #1            wz    ' Address one more in jump-table !
            add       Command,  #:JmpTab
            movs      :JmpTab,  Command
            nop                                      ' nop to allow emptying of pipeline
    :JmpTab
            jmp       #0-0        ' Entry, now jump to jump to command
            jmp       #:LoopCmd ' 0: No command, continue polling       
            jmp       #:Idle    ' 1: Enter idle mode, here: stay in Idle mode        
            jmp       #:TrigRun ' 2: run incremental encoder in triggered mode      
            jmp       #:FreeRun ' 3: run incremental freely, without trigger      
            jmp       #:DetReso ' 4: determine resolution of incremental encoder
            jmp       #:LoadPar ' 5: reload parameters
            jmp       #:Sweep   ' 6: sweep in accordance with sweep-rate
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
    Hello Rest Of The World
    Hello Debris
    Install a propeller and blow them away wink.gif
  • ErNaErNa Posts: 1,742
    edited 2010-07-02 09:39
    kuroneko pointed me to this:
    DAT     org  0
    
    ASM_Entry
            mov       Command,  #0                  ' Reset Command to zero
            wrlong    Command,  CommandPtr          ' Acknowledge: Process running
    
            mov       Command,  #5                  ' Number of implemented commands +1, to check range
            rdlong    DrGTimSli, DrGTiSlPtr         ' Get the time slice for speed measurement
            mov       DrGVelTim, cnt                ' Initialize start time
            jmp       #:Initial                                                  
    :LoopCmd
            rdlong    Command,  CommandPtr          ' Poll for new command
    :Initial
            cmp       Command,  #MaxCmd       wc    ' check for upper limit
    if_nc   mov       Command,  #0                  ' if exceeded, replace by NOP
    [s]        add       Command,  #1            wz    ' Address one more in jump-table ![/s]
            add       Command,  #:JmpTab
          [b]  jmp      Command[/b]
     [s]       movs      :JmpTab,  Command
            nop                                      ' nop to allow emptying of pipeline[/s]
    :JmpTab
    [s]        jmp       #0-0        ' Entry, now jump to jump to command[/s]
            jmp       #:LoopCmd ' 0: No command, continue polling       
            jmp       #:Idle    ' 1: Enter idle mode, here: stay in Idle mode        
            jmp       #:TrigRun ' 2: run incremental encoder in triggered mode      
            jmp       #:FreeRun ' 3: run incremental freely, without trigger      
            jmp       #:DetReso ' 4: determine resolution of incremental encoder
            jmp       #:LoadPar ' 5: reload parameters
            jmp       #:Sweep   ' 6: sweep in accordance with sweep-rate
    
    



    And I was so proud to have a piece of self modifying code! cool.gif
    Thank you for this hint. By the way: this asm module realizes an quadrature encoder with speed measurement. Will come in parts after I return from holidays

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
    Hello Rest Of The World
    Hello Debris
    Install a propeller and blow them away wink.gif
  • ErNaErNa Posts: 1,742
    edited 2010-07-03 09:19
    When the start method is called, all the pointers are stored to a data field starting at LoclPtr
    LoclPtr  ' All the pointers to global memory, like defined in PCB_table
    CommandPtr    long      0       ' Pointer to the command
    DreGebPtr     long      0       ' Pointer to the global encoder value
    DreGOfsPtr    long      0       ' Pointer to an offset to "adjust" encoder position
    DrGeResPtr    long      0       ' Pointer to the number of increments per resolution
    DrGVelTPtr    long      0       ' Pointer to a speed value (time between counts, slow speed)
    DrGVelCPtr    long      0       ' Pointer to a speed value (increments per time, high speed)
    DrGTiSlPtr    long      0       ' Pointer to duration of time slice for speed measurement
    DrGSensPtr    long      0       ' Pointer to rotational direction
    
    DrGTiBaPtr    long      0       ' Pointer to timebase value, if encoder is simulated
    ScVal53Ptr    long      0       ' Test
    ScVal54Ptr    long      0       ' Test
    ScVal55Ptr    long      0       ' Test
    
    



    more to follow

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    cmapspublic3.ihmc.us:80/servlet/SBReadResourceServlet?rid=1181572927203_421963583_5511&partName=htmltext
    Hello Rest Of The World
    Hello Debris
    Install a propeller and blow them away wink.gif
  • RS_JimRS_Jim Posts: 1,753
    edited 2011-01-24 05:53
    Hi ErNa,
    This post came up on my recient post about memory so I thought I would give it a read. The problem I am having is that the snippets are confusing me. Is it possible you could post or PM me a file that shows the complete process from the top method thru to the assembly obj. I think I am seeing a pointer to a series of pointers that is being fed to the new cog.
    RS_Jim
  • JonnyMacJonnyMac Posts: 8,927
    edited 2011-01-24 12:45
    I use the [unsigned] min and max operators to limit the command from hub before using a jump table.
    getcmd                  rdlong  tmp1, cmdpntr                   ' check for command
                            min     tmp1, #0                        ' limit range
                            max     tmp1, #4                        ' commands + 1
                            add     tmp1, #jmptable                 ' prep for jump
                            jmp     tmp1                            ' do it
                           
    jmptable                jmp     #cmdexit
    do_cmd1                 jmp     #cmd1                       
    do_cmd2                 jmp     #cmd2
    do_cmd3                 jmp     #cmd3
    
    cmdexit                 mov     tmp1, #0                        ' clear old command
                            wrlong  tmp1, cmdpntr
                            jmp     #getcmd
    
  • ErNaErNa Posts: 1,742
    This will be another entry to create method for making use of the pscpb
Sign In or Register to comment.