Multiple Cog Global variables
EMHmark7
Posts: 93
Hi,
On Propeller, if I am using several cogs, namely one constantly scanning the state of a sensor, because it is more complicated than just its actual state (like a busy writing on a SD card, but need to make sure the writing occured, a fact that a non-busy state cannot say alone)
What is the right way to communicate the result to a Global variable that other cogs can read and write?
Do they have access to the same RAM?
Thanks,
Marc
On Propeller, if I am using several cogs, namely one constantly scanning the state of a sensor, because it is more complicated than just its actual state (like a busy writing on a SD card, but need to make sure the writing occured, a fact that a non-busy state cannot say alone)
What is the right way to communicate the result to a Global variable that other cogs can read and write?
Do they have access to the same RAM?
Thanks,
Marc
Comments
The main issue you need to deal with is that only one cog should attempt to change (write to) the variable unless you use a lock or semaphore. Other cogs can read the variable waiting for specific changes, but only one cog can attempt to change the variable at a time. You may need to use a lock or semaphore to guarantee this. In Spin, the LOCKSET and LOCKCLR statements do this (see the Propeller Manual for details and examples). I'm not sure what the equivalent is in C. You'll have to check the documentation. If your global variable is more complex than a single byte, word, or long, you'll need to use a lock or semaphore.
Cogs each have their own private RAM (2K bytes) and have access to a shared common hub RAM (32K byte). There's a shared common ROM as well with font tables and transcendental tables.
Ya, with my programming experience, that's also a thing I was thinking about, like smelling something in the air for a dog.... : )
1) What can we do with the shared common hub RAM (32K byte)? Are the 2K and 32K for Spin compiler use only?
2) I already use - I think in the CON block - a var name, followed with many coma separated values,
and because all values do not hold in a single line without stretching further than the anyway scrollable window,
I add other lines beginning with a variable name, followed by another list of coma delimited values. It can be for few lines.
Then, I access these values with the variable name beginning the first line with an index in [ ].
3) Can we do that with other variables? Other threads seem to say no.
Another way to see it is: can we make sure several vars are stored contiguous in RAM so we can pass just one pointer for the whole block?
Thanks,
Marc
The variables in the VAR section will get rearranged if you don't order them long, word and byte.
If you don't have your variables in this order the compiler will place them in this order. Even still, if you have a group of uninterrupted longs, they will be placed in memory in the same order as you list them. You often see in a program comments like "keep these variables together and in order" so someone using the code at a later time doesn't rearrange them. This does allow the address of a large block of variables to be passed by just passing the address of the first variable.
You only deal with cog RAM if you're using PASM. All variables in Spin live in the hub. Any cog running Spin code can access any global variable as long as it's in the same object. In Spin, objects effect the way variables can be accessed, not cogs.
Thanks, I DID not understand these 2 statements above.
But now Ok, now I catch, as stated in doc v1.2 page 212:
During compilation of an object, all declarations in its collective VAR blocks are grouped together by type. The variables in RAM are arranged with all the longs first, followed by all words, and finally by all bytes. This is done so that RAM space is allocated efficiently without unnecessary gaps. Keep this in mind when writing code that accesses variables indirectly based on relative positions to each other.
Thanks again
2) If you use a DAT block with LONGs, WORDs, and/or BYTEs, these are stored in hub memory mixed in with the rest of your program. The order of the data is exactly the way you wrote them (unlike with VAR variables where they're rearranged by alignment as described in the manual). There is padding to storage boundaries so LONGs always start at an address divisible by 4, WORDs at an address divisible by 2, etc. If you use a label on a LONG, Spin "knows" that you're using LONGs when you use that label as a variable. Similarly, if the label is on a WORD statement, Spin "knows" that you're using WORDs when you use the label, etc. If you have an unlabelled statement following a labelled one, those values can be reference using the label.
These can be referenced by using table[ x ] where x is a value from 0 to 9. table[ 8 ] is the value consisting of 14 in bits 16-31 and 13 in bits 0-15. You can have labels on the other statements and references to table[ x ] where x is greater than 9 will just reference 4 byte long values further in memory.
StepIO byte 00_0000
stepIO2 byte 00_1100, 01_1011, 10_1010, 11_1001, 11_0000, 11_0001, 10_0010, 01_0011
stepIO3 byte 00_0100, 11_0101, 10_0110, 01_0111, 00_0111, 01_0111, 10_0110, 11_0101
stepIO4 byte 00_0100, 01_0011, 10_0010, 11_0001, 11_0000, 11_1001, 10_1010, 01_1011
stepIO5 byte 00_1100, 11_1101, 10_1110, 01_1111, 00_1111, 01_1111, 10_1110, 11_1101
Someday, I will submit my step motor program as a contrib, including a spreadsheet helping to figure out each step bytes, depending on their position on the PCB and IO, not necessarily in the right order.. But for now, as a matter bits and bytes: (a bit out of topic I know) (I know this is a bit leasy on my side, I could do some write/read test, but unless you already know)
I am setting a variation of values in decimal, like this:
StepIO byte 90,246,211,119,85,117,209,244,88,109,201,236,168,172,137,45
byte 24,180,145,53 ,21,55 ,147,182,26, 47,139,174,170,238,203,111
When we do outa[7...0]:=123 (any decimal value) Do you think it places the least significant bit of the value on the last specified index,
or from the first specified index bit?
Thanks for support.
Marc
What are the possible consequences if 2 cogs writing at same time on that value? (besides unpredicted behavior, but on the cogs or the program or its ability to continue running)
The variable can only be accessed by one cog at a time. The Spin interpreter running in a cog will use a wrlong to write to the variable (assuming it's a long). It will only be able to write during its turn to access the hub.
if 2 cogs attempt to write at the same time? (Just that one will write like in the air without effect because one did behind?)
Thanks,
Marc
I don't really understand your question. 2 cogs can't attempt to write at the same time because they take turns. One cog would write the value it intends to write and the next cog would write the value it intends to write. The last cog to write a value "wins".