Cogs, Spin and Variable sharing
Timothy D. Swieter
Posts: 1,613
Boy am I glad forums exist because it is the best place to turn to have spending hours of trying to figure it out myself!
My problem:· I have a Spin routine executing in cog 0.· The cog 0 routine has a variable that it is incrementing.· I have another spin routine executing in cog 1 and it needs to see the variable in cog 0.·
Now, if the spin routine executing in cog 1 is started from within the same file as cog 0, then everything seems to work fine. (i.e. one·".spin" file contains the PUB for·cog 0 and cog 1"· When I move the PUB routine for cog 1 into its own file and add the proper OBJ code to include it then the code no longer works.· What am I missing?· I searched through the forums but have not seen anything addressing this specifically (could be that I am getting too tired though).
This code works.· Note all the code in the same file.
While this code does not work.· In other words the LEDs are not updating with the incrementing of the variable in the other cog.··Note that the following code is broken into two different files.
·Thank you for the help!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark of imagination is all it takes for an idea to explode
My problem:· I have a Spin routine executing in cog 0.· The cog 0 routine has a variable that it is incrementing.· I have another spin routine executing in cog 1 and it needs to see the variable in cog 0.·
Now, if the spin routine executing in cog 1 is started from within the same file as cog 0, then everything seems to work fine. (i.e. one·".spin" file contains the PUB for·cog 0 and cog 1"· When I move the PUB routine for cog 1 into its own file and add the proper OBJ code to include it then the code no longer works.· What am I missing?· I searched through the forums but have not seen anything addressing this specifically (could be that I am getting too tired though).
This code works.· Note all the code in the same file.
VAR byte myTestVar long stack0[noparse][[/noparse]10] PUB main myTestVar := 0 COGNEW(spincog1(@myTestVar), @stack0) repeat myTestVar ++ PauseMSec(250) PUB spincog1(_pointer) | local1 DIRA[noparse][[/noparse]16..23] := %11111111 'Make I/O's 16 to 23 OUTPUTs repeat local1 := byte[noparse][[/noparse]_pointer] OUTA[noparse][[/noparse]16..23] := local1 PRI PauseMSec(Duration) {{Pause execution in milliseconds. PARAMETERS: Duration = number of milliseconds to delay. }} waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
While this code does not work.· In other words the LEDs are not updating with the incrementing of the variable in the other cog.··Note that the following code is broken into two different files.
VAR byte myTestVar long stack0[noparse][[/noparse]10] OBJ Blinker : "test2.spin" PUB main myTestVar := 0 COGNEW(blinker.spincog1(@myTestVar), @stack0) repeat myTestVar ++ PauseMSec(250) PRI PauseMSec(Duration) {{Pause execution in milliseconds. PARAMETERS: Duration = number of milliseconds to delay. }} waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt) _________________________________________________________________________________________________ The following code is in a file called "test2.spin" _________________________________________________________________________________________________ PUB spincog1(_pointer) | local1 DIRA[noparse][[/noparse]16..23] := %11111111 'Make I/O's 16 to 23 OUTPUTs repeat local1 := byte[noparse][[/noparse]_pointer] OUTA[noparse][[/noparse]16..23] := local1
·Thank you for the help!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark of imagination is all it takes for an idea to explode
Comments
'myTestVar' gets placed after the stack so a stack overflow would corrupt what was held there. Other than that I can see nothing wrong your code.
You can't start a Spin routine in another object using COGNEW/COGINIT. In other words, using blinker.spincog1 is not allowed.
You can put a dummy startup routine in the main object that only calls blinker.spincog1 or you can put a start routine in blinker that does the COGNEW/COGINIT.
This is mentioned somewhere in Propeller Tips and Traps as I recall.
This issue is not explained anywhere in Paralax's documentation.
The least thing to happen should be the compiler issue an error!
The workaround is as this:
To have moved the definition of stack0 to "test2" should even be considered a good thing
Edit: Oops: Just didn't do that... but now!
Post Edited (deSilva) : 10/3/2007 10:08:56 AM GMT
100% agree.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Logically I would expect the two to be differentiated as COGNEW(@method,@stack) and COGNEW(method,@stack).
Added : Anyone got a pointer to where this is discussed before because I cannot find it through search.parallax.com ?
Post Edited (hippy) : 10/2/2007 8:40:41 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
N.B. :For the first "@stack" read "thePar"... Here is one http://forums.parallax.com/showthread.php?p=662426
So my next question is how do you recommend to deal with arrays when passing variables by pointers in spin? I have an array of byte LED and cog0 writes to this array while cog1 (or other) reads the array and performs the function. In the loop of cog1 there could be code the loads the array like the following:
repeat 'main loop of cog
led0 := byte[noparse][[/noparse]_pointer]
led1 := byte[noparse][[/noparse]_pointer+1]
This particular code looks cluncky so I feel like I am missing something in simplifying the code. Is there a way to initialize a variable in cog1 to be always pointing to the variable in cog0 without have to repeatedly do "led0 := byte[noparse][[/noparse]_pointer]".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark of imagination is all it takes for an idea to explode
led0 := byte[noparse][[/noparse] _pointer ][noparse][[/noparse] 0 ]
led1 := byte[noparse][[/noparse] _pointer ][noparse][[/noparse] 1 ]
You can't have a pointer in one cog point to a variable in another cog. You can, however, pass a pointer to HUB memory to a cog and have another cog access it as well. This is where your array should be if you want to share it between cogs.
Dang...Mikey beat me to it again!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
YIKES! My post above looks terrible. I must have hit a font increase in the middle of my typing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark of imagination is all it takes for an idea to explode
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
But there is also no "overhead": It will perform as fast as it would with whatever "syntactic sugar" around.
It has sometimes been observed that
byte[noparse][[/noparse] _pointer+1 ]
is noticeably faster than
byte[noparse][[/noparse] _pointer][noparse][[/noparse] 1 ]
This is plausible, but I have not measured it. Following that theory
byte[noparse][[/noparse] ++copy_of_pointer ]
should even be faster!
Post Edited (deSilva) : 10/3/2007 9:12:01 AM GMT
My gut feeling from that is 'byte[noparse][[/noparse] _pointer+1 ]' would have been slower than 'byte[noparse][[/noparse] _pointer][noparse][[/noparse] 1 ]' but that's contrary to reported observations. This is an area where it would be productive to run some tests.