Passing a variable value between cogs
Charles Edmondson
Posts: 46
in Propeller 1
Ok, I have a couple of problems, but it all boils down to this: How can I pass a variable value between cogs?
My situation? In one cog I am determining the state of my system, basically by measuring a voltage and comparing it to a test value. Now, I need to pass this state value to my display cog, where i will change several ranges on the display due to this state.
This should be pretty basic, but I can't figure it out. I am doing maintenance on this code, and the original author had all kinds of complex data structures set up to pass values, but I need something simple.
What have I tried? I tried establishing a VAR and setting it, but then couldn't reference it directly from another cog. I then tried setting up a routine whose job is just to return this value. This almost worked, but I realized while testing that it wasn't actually reading the value of the variable that was being set. If I understand correctly, when I run the routine from a different cog, it still only sees what is on the new cog, not the one being run from its original file.
Can someone give me a little simple help?
My situation? In one cog I am determining the state of my system, basically by measuring a voltage and comparing it to a test value. Now, I need to pass this state value to my display cog, where i will change several ranges on the display due to this state.
This should be pretty basic, but I can't figure it out. I am doing maintenance on this code, and the original author had all kinds of complex data structures set up to pass values, but I need something simple.
What have I tried? I tried establishing a VAR and setting it, but then couldn't reference it directly from another cog. I then tried setting up a routine whose job is just to return this value. This almost worked, but I realized while testing that it wasn't actually reading the value of the variable that was being set. If I understand correctly, when I run the routine from a different cog, it still only sees what is on the new cog, not the one being run from its original file.
Can someone give me a little simple help?
Comments
The variable would typically be part of the display program and it's address passed to the measurement cog on startup. The specific value to indicate the display cog has read the data would be some value that would never be seen as a measurement.
A hub variable is just a VAR variable. If two Spin cogs are started from the same object, nothing special needs to be done, since both cogs automatically share the VAR variables declared in that object. But if the second cog is started from an external object, you need to pass that object's start routine the address of the VAR variable (e.g. @MyVariable) so it knows where to read/save data.
-Phil
What programming language are you using for the cogs?
The only time sharing variables between cogs is an issue is if the cog is running PASM code rather than Spin. All Spin variables are stored in the hub.
PUB PWM | ooga
where "ooga" is the local variable's name. Hope this helps!
@atdiy
Sorry, I am using Spin for everything.
Can you attach (as spin or zip files) the measurement and display code along with the cognew commands that start them?
You mean stating them as longs? Or something else?
COGNEW (ReadMethod (@CommVar, @Stack )
COGNEW (DisplayMethod (@CommVar, @Stack )
Both the read and display methods now have the address of the variable.
CON
sizeOfStack_ = 25
#0 'enum for standard COG data block
rho 'size of data block
cogNum 'local copy of cog number
cogStatus
StackAddr
stackSize
sizeOfDataBlk_
'The address of the cog datablock is returned by the cog.start function
DAT {administrative storage for COG}
podMgrStack long 0[sizeOfStack_]
DAT {public data}
podMgrDB LONG sizeOfDataBlk_, {number of elements in this datablock
}$deadbeef, {cog number
}$deadbeef, {status
}@podMgrStack, {address of the cog stack
}sizeOfStack_ {number of elements in cog stack}
And, this is followed by the following code in the start routine:
'setup the standard datablock
podMgrDB[stackAddr] := @podMgrStack 'This changes the compileTime offset into runTime address
'return
podMgrDB[cogNum] := COGNEW(PodMgrCOG, @podMgrStack) + 1 'trick, failure = 0 ==> false
So, he was passing some sort of values to the hub, I just don't know for sure what!
So this is the code in the child object's "Start" method right?
As long as you're aware the value of the cog is one more than the one actually being used, it looks pretty straight forward.
Why do you think the information isn't being passed back to the parent correctly?
My guess is you're accessing the memory incorrectly. You may be adding an @ symbol when one isn't needed.
I think we need to see part of the parent object's code to know what the problem is.
Edit (edited): One possible problem with the program is the way an address is used as a variable in the data initialized in the DAT section. The address "@podMgrStack" used as a value in the DAT section will have a different value than @podMgrStack when evaluated at runtime. In order to store the correct address of "podMgrStack" the address needs to be evaluated at runtime (or corrected for the compile time offset). By storing the address at runtime, the correct address will be in the data structure. I believe the different ways memory addresses are evaluated is covered in the Propeller manual in the section about the "@" address symbol and/or the "@@" symbol section. I've seen the notation "@@@" used as a why to let compilers know what value to use but this notation isn't used by the Propeller Tool. After looking through your subsequent posts, I don't think this address offset issue is related to the problem you're having.
PUB start | x ' COG 0
data.init
data.set(data#packSummaryDataset, data#officialCellCount, conf#maxCellsPerPack_) '<rea num="20121228">
rtMgrDB := rtMgr.Start
podMgrDB := podMgr.Start
canMgrDB := canMgr.Start(canMgr#xmitOnly)
REPEAT UNTIL (long[podMgrDB][podMgr#cogStatus] )
IF (conf#SpecifiedCellCount == 0)
data.set(data#packSummaryDataset, data#officialCellCount, data.get(data#packSummaryDataset, data#observedCellCount))
ELSE
data.set(data#packSummaryDataset, data#officialCellCount, conf#SpecifiedCellCount)
menu.main 'and never return
I am trying to use the variable in the menu object!
[code]
If the parent is already compensating for the address offset then my addition may cause problems.
Using a memory address in a DAT variable as done in the code you posted will be incorrect.
To post code in the forum follow the directions in the post linked below.
http://forums.parallax.com/discussion/comment/1337853/#Comment_1337853
Edit: I don't think the address offset issue is causing the problems you're experiencing.
All the variables PV, Cnt and NumPacks are defined in THIS object. I then run this routine with other.Packs and I get a 1 every time. Those variables don't seem to have a value other than 0.
Any ideas?
If you could post enough code to replicate the problem you're seeing we may be able to spot the issue. I'm personally having a hard time following along with little pieces of the program.
I don't think the problem is related to passing values between cogs. I think the issue is passing values between objects.
mysharedvar long 0
In either COG, reference it with @mysharedvar
This is a simple global.
If you want, you can put it at the top of your program too. You can make multiple CON, DAT, VAR sections, and the DAT section is where assembly language and data typically go. That's shared due to it being a simple HUB memory declaration.
If it's a PASM program, you start it with a COGSTART @myprogram and if it's just some data, you access it with the label associated with that data @mysharedvar style.
Are there multiple instances of the object? Variables are persistent in both VAR and DAT but the DAT ones are shared among multiple instances of an object.