Shop OBEX P1 Docs P2 Docs Learn Events
Multiple Cog Global variables — Parallax Forums

Multiple Cog Global variables

EMHmark7EMHmark7 Posts: 93
edited 2014-04-21 11:51 in Propeller 1
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

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2014-04-20 15:16
    Are you programming in Spin or C? The same issues apply to both, but the details vary. In C, you can have global variables that are accessible from all of the pieces (source files) of a program. In Spin, global variables are directly accessible only within a particular object (source file). They can be accessed from other objects, but only by passing the variable's address to the other objects.

    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.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-20 15:30
    If you're using Spin, you might want to check this thread dealing with the topic of variables, cogs and objects.
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-20 21:52
    I am using Spin.
    Mike Green wrote: »
    The main issue you need to deal with is that only one cog should attempt to change (write to).

    Ya, with my programming experience, that's also a thing I was thinking about, like smelling something in the air for a dog.... : )
    Mike Green wrote: »
    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.

    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
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-20 22:13
    EMHmark7 wrote: »
    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?

    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.
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-21 06:37
    Duane Degn wrote: »
    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.

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2014-04-21 07:51
    1) In Spin, the cog memory is used for the Spin interpreter which is automatically loaded from the Propeller's ROM. The hub RAM is what you normally think of memory. It holds the program, its data, and the stack area needed for the program.

    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.
    table   long  5, 6, 7, 8
            long 9, 10, 11, 12
            word 13, 14, 15, 16
    
    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.
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-21 08:08
    OK, I was using it with a dummy label beginning each line. So you're telling me it is not needed.

    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
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-21 10:37
    Beside my previous post, I see that, for the abort request, I need to face the possibility of possibly 2 cogs writing on the same variable. (a request or a clear up)
    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)
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-21 10:58
    EMHmark7 wrote: »
    Beside my previous post, I see that, for the abort request, I need to face the possibility of possibly 2 cogs writing on the same variable. (a request or a clear up)
    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.
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-21 11:05
    I catch that cogs need to wait their turn. But what can occur (besides an update happening before another one in the wrong order, avoiding needed processing,. etc.)
    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
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-04-21 11:46
    EMHmark7 wrote: »
    I catch that cogs need to wait their turn. But what can occur (besides an update happening before another one in the wrong order, avoiding needed processing,. etc.)
    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".
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-21 11:51
    Mike Green wrote: »
    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.
Sign In or Register to comment.