Inter-Process communication
ErNa
Posts: 1,842
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.
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:
Now, as the main routine starts, the process has to be initialized:
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
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

Comments
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
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
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-rateAnd I was so proud to have a piece of self modifying code!
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
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
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
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