Shop OBEX P1 Docs P2 Docs Learn Events
Correct way to share data between cogs — Parallax Forums

Correct way to share data between cogs

Ron CzapalaRon Czapala Posts: 2,418
edited 2011-08-20 11:31 in Propeller 1
I've been studying the reference manual and I am trying to determine how cogs can share data. It seems to me that passing the address to a method running in a separate cog is one way.
Is it the best and/or only way?

Thanks!
VAR
  long stack[10]
  long cval
OBJ
  Debug           : "Extended_FDSerial.spin"
 
PUB LaunchCogs | cognum
  Debug.start(31, 30, 0, 57600)    ' ignore tx echo on rx
  waitcnt(clkfreq * 3 + cnt)       ' Pause for FullDuplexSerial.spin to initialize
  Debug.tx(16)        'cls   
  cognum := cognew(Sensor([COLOR=red]@cval[/COLOR]), @stack)
  repeat 50
    Debug.Dec(cval)
    Debug.tx(13) 
    waitcnt(clkfreq / 2 + cnt)
 
 
PUB Sensor([COLOR=red]cvaladdr[/COLOR]) | sval
  sval := 0
  repeat 100
    sval++
    LONG[[COLOR=red]cvaladdr[/COLOR]] := sval
    waitcnt(clkfreq/2 + cnt)

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-08-28 09:06
    It's easier than that. If the code running on the two cogs is all within one object (source file) as in your example, you can just reference the same global variables directly like this:
    VAR long myvariable, mystack[20]
    
    PUB main
       cognew(other,@mystack)
       waitcnt(clkfreq/10 + cnt) ' wait for cog to start
       Debug.dec(myvariable)
    
    PRI other
       repeat
          myvariable := ina[3..0] ' update every 100ms
          waitcnt(clkfreq/10 + cnt)
    
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-28 09:10
    Mike,
    What if the second cog is in another object?
  • Mike GreenMike Green Posts: 23,101
    edited 2010-08-28 09:14
    If the 2nd cog is in another object, then you have to pass an address. This is because you now have 2 objects and has nothing to do with using 2 cogs. One object cannot directly reference variables in another object. A parent object can refer to constants and methods in a child object, not variables.
  • T ChapT Chap Posts: 4,223
    edited 2010-08-28 09:17
    Ron, the code you posted is good for passing variables between cogs not all in the same file. Also, you can access other Long variables in a similar way that follow the first var declaration:

    LONG cval, cval2, cval3, cval4
    
    or 
    
    LONG cval[5]
    
    can be accessed from the object like:
    
    getvar1 := LONG[cvaladdr]
    getvar2 := LONG[cvaladdr+4]
    getvar3 := LONG[cvaladdr+8]
    getvar4 := LONG[cvaladdr+12]
    
    

    This way you only have to pass one pointer.
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-08-28 09:37
    Thanks Mike and T Chap.

    I had a version using multiple cogs and an array where I was using the cogid to index into the array.

    I am creating various examples for future reference...

    Thanks again.
    VAR
      long stack[20]
      long cval[8] 
     
    PUB Main
      cognew(example(@cval), @stack[0])
      cognew(example(@cval), @stack[10])
     
     
    PUB example(cvaladdr) 
      ...
      LONG[cvaladdr][cogid] :=    'some value
    
  • Dirkimus MaxDirkimus Max Posts: 7
    edited 2011-08-12 09:18
    Mike Green wrote: »
    It's easier than that. If the code running on the two cogs is all within one object (source file) as in your example, you can just reference the same global variables directly like this:

    Hi Mike,
    As a newbie; I hope this is posted in the right place; i.e., starting a new cog. I recently aquired a huge pile of DMX addressable neon lights (135 of them! a picture of one is my avatar). I obtained one of the Jon Williams DMX interfaces, and with his assembly driver he graciously provided, I have been able to control them with my propeller board. I hope to eventually use one cog to handle the I/O, using an array location for each light to store light intenisities (0-255), and have other cogs modify the code either with random numbers, or external I/O. However, something has gone wrong with my implementation of your code (o: Please see my code below. I know the hardware and driver works, as I am able to turn the lights on and off via the first bit of code in MAIN. For starters (walk before running(o:) I attempted to launch another cog within the same object and repeat the same code, but after the initial "on/off" executed by the MAIN, no lights work. Any suggestions? Thanks in advance!
    [/B]
    obj
    dmxout : "OBEXDMXout"
    CON
      _clkmode        = xtal1 + pll16x           ' Feedback and PLL multiplier
      _xinfreq        = 5_000_000                ' External oscillator = 5 MHz
    var
      long onoffs, address
      long myvariable, lights[20]
      byte brightness[37]       
    pub main
     
    dira[25] := outa[25] := 1 'brings the TX enable high
    dmxout.start(26) ' starts the dmxout
    'sending dmx values couldn't be easier - just;
    'dmxout.Write(2, 255) 'channel = 2, value =255
       cognew(DMXoutput,@lights)
       waitcnt(clkfreq/10 + cnt) ' wait for cog to start
       'Debug.dec(myvariable)
       waitcnt(clkfreq/10 + cnt)
          dmxout.Write(1, 255)
          dmxout.Write(2, 255)
          dmxout.Write(3, 255)   
          waitcnt(clkfreq/2 + cnt)
          dmxout.Write(1, 0)
          dmxout.Write(2, 0)
          dmxout.Write(3, 0)    
          waitcnt(clkfreq/4 + cnt)
    Pri DMXoutput
       repeat
          'myvariable := ina[3..0] ' update every 100ms
          waitcnt(clkfreq/10 + cnt)
          dmxout.Write(1, 255)
          dmxout.Write(2, 255)
          dmxout.Write(3, 255)   
          waitcnt(clkfreq/2 + cnt)
          dmxout.Write(1, 0)
          dmxout.Write(2, 0)
          dmxout.Write(3, 0)    
          waitcnt(clkfreq/4 + cnt)
     
    [B]
    
  • ElectricAyeElectricAye Posts: 4,561
    edited 2011-08-12 10:34
    ...

    Hi Mike,
    As a newbie; I hope this is posted in the right place; i.e., starting a new cog....

    Dirkimus,

    you might find this helpful:

    attachment.php?attachmentid=78421&d=1297987572
  • Dirkimus MaxDirkimus Max Posts: 7
    edited 2011-08-12 11:07
    Thanks, Aye! I'll do better next time! (o:
  • ElectricAyeElectricAye Posts: 4,561
    edited 2011-08-12 11:11
    Thanks, Aye! I'll do better next time! (o:

    You can change what you've already posted by clicking on the Edit button at the bottom of that above post and then insert the code tags, if you so desire.
  • Dirkimus MaxDirkimus Max Posts: 7
    edited 2011-08-12 11:29
    Done! Thanks for the help, 'Aye!
  • PropGuy2PropGuy2 Posts: 360
    edited 2011-08-19 18:15
    On the same theme - What is the correct way to share ASCII character data / strings between cogs. In my application I want to send RTC clock data as HH:MM:SS as a string, instead of individual HH, MM and SS numeric variable data.
  • Mike GMike G Posts: 2,702
    edited 2011-08-19 18:26
    Write the string to RAM memory using the bytemove command. Make sure you zero terminate the string and ASCII encode the digits. Then simply pass a pointer to the start of the string.
  • HarpritHarprit Posts: 539
    edited 2011-08-20 11:31
    This is being discussed in the "Propeller Assembly for beginners" thread right now.
    In some detail and the experts are chiming in.
    You may find it interesting.

    Harprit.
Sign In or Register to comment.