Shop OBEX P1 Docs P2 Docs Learn Events
Confusion on objects and cogs — Parallax Forums

Confusion on objects and cogs

LuckyLucky Posts: 98
edited 2010-04-05 05:55 in Propeller 1
All this time I have been using the prop, I have only been using one cog for programs. I use two every so often,but thats the FullDuplexSerial object, which is already written and doesn't really count. Now that I am trying to use two,I find myself struggling with some of the concepts. I know how to do method calls and object-method references (object.method(parameters)), but thats all in using one cog. When it comes to starting a method from another object in a second cog and sending variables back for monitoring and whatever, I·have no clue how to set it all up. So below I have set up a little program for demonstration purposes. The top object declares the clkfreq and two objects. The main method in the top object is supposed to send a hex value representing a char (acsii table)·to the parallax serial terminal. Now before the repeat loop there is a key.start(parameters). Now that goes to the object keyboard driver's start method which launches the main method into another cog. Now this is where it gets confusing for me. My thinking right now, is that when the start method launches the keyboard_Driver's main method into another cog, the method has to be in a endless repeat loop to monitor keyboard and to update the keybuffer, keystates,lock LEDS, etc. So how does one now access these values from the top objects main method so the key presses can be viewed on the parallax serial terminal. This is why I have a debug.tx(key.???) because i don't know what to put there. I want the top objects's main method to be able to access the keybuffer and keystate at any time.
'Top Object
CON
   _clkmode = xtal1 + pll16x
   _xinfreq = 5_000_000
   Datapin = 19
   Clkpin  = 20
OBJ
   Key    : "Keyboard_Driver"
   Debug : "FullDuplexSerial"
 
PUB Main
 
   debug.start(31, 30, 0, 115_200) 
   Key.start(Datapin, Clkpin)
 
   repeat
      debug.tx(Key.???)     'display character from keyboard
      debug.tx($0D)           'Next line    

···
'Keyboard_Driver 
VAR
   Long stack[noparse][[/noparse]50]
   Byte Datapin, Clkpin
   Byte key
   Long keybuffer[noparse][[/noparse]4]
PUB start (dpin, cpin)
   stop
   
   Datapin = dpin
   Clkpin = cpin
   
   success := (cog := cognew(Main, @stack)+1)
PUB stop
   ifnot(cog == 0) 
      cogstop(cog~ -  1)
PUB Main
   repeat
      key := getKey
      KeyState(key)
      if(key == CapLock)
         SendByte
         
PUB getKey
  'wait for a key press and return value to key
Pub SendByte
   'send byte to keyboard to update 
PUB Keystate(key)
   'update whether button is pressed or not

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"The man who smiles when things go wrong has thought of someone to blame it on."


-Lucky[size=-1][/size]

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-04-05 03:45
    Cogs and Objects are two independent concepts even though most multi-cog stuff is organized using multiple objects with each cog associated with an object. Look at some of the exercises for the Propeller Education Kit (http://forums.parallax.com/showthread.php?p=617192).

    I suggest you experiment with multiple cogs without using objects at all and experiment with objects without using multiple cogs (except in pre-packaged stuff). It'll keep things simpler.

    Remember that, with an object, you can't access the variables inside the object, only the constants and public methods. You have to access the variables via public methods. A method could return the address of the first (long) variable in the object and all other variables could be accessed relative to that with all the longs first, then all the words, then the bytes. This technique works, but is error prone, particularly if you change the object (and maybe add a variable).
  • LuckyLucky Posts: 98
    edited 2010-04-05 04:10
    Can two methods from the same object, but running in different cogs have access to the same global variables?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "The man who smiles when things go wrong has thought of someone to blame it on."


    -Lucky[size=-1][/size]
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-04-05 05:38
    yes they can

    anyway this is a kind of question that you can find an answer by writing some testocde too

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      
    VAR
      long heart_stack[noparse][[/noparse] 20]
      long CogStack1[noparse][[/noparse] 20]
      long CogStack2[noparse][[/noparse] 20]
      
      long MyTestVar
    
    OBJ
      debug : "FullDuplexSerial"
    
    
    PUB Main
    'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run
      debug.start(31, 30, 0, 115200)
      
      MyTestVar := 100
      debug.str(string("Start MyTestVar="))
      debug.dec(MyTestVar)
      debug.Tx(13)
    
      'both cognew-commands are in the SAME file
      'in this case you can access variables simply by the variable-name
      cognew(M1,@CogStack1)
      cognew(M2,@CogStack2)
      
      repeat
        waitcnt(clkfreq + cnt)
        debug.str(string("MyTestVar="))
        debug.dec(MyTestVar)
        debug.Tx(13)
    
    
    PUB M1
      repeat
        waitcnt(ClkFreq * 3 + cnt)
        MyTestVar := 1
    
    
    PUB M2
      repeat
        waitcnt(ClkFreq * 5 + cnt)
        MyTestVar := 2
    
    


    best regards

    Stefan

    Post Edited (StefanL38) : 4/5/2010 5:43:50 AM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2010-04-05 05:41
    Yes

    If you have some variables declared in an object, these variables are accessible to all methods in that object regardless of which cog is running. If you have two cogs accessing the same variables, you have to have some way to prevent both cogs from trying to change the same variable at the same time. For this, you can use a semaphore (LOCK) or you can design the program so only one cog will change a particular variable. This is often used for filling / emptying a buffer. A semaphore is not normally needed for that because only one cog will ever change the input pointer and only one cog will ever change the output pointer. The cog that's filling the buffer will work fine if the buffer looks full (briefly) when it's not really and the cog that's emptying the buffer will work fine if the buffer looks empty (briefly) when it's not really. This is the single producer / single consumer case in multiprocessing that doesn't need a semaphore to work.
  • LuckyLucky Posts: 98
    edited 2010-04-05 05:55
    @StefanL38: I would write some code up, but there is some nasty homework that I have put off over spring break that I have to attend to.cry.gif

    @Mike Green: Thanks too. I had not thought that locks would be needed.Found LOCKNEW, LOCKRET, LOCKSET, and [font=Parallax,Parallax][font=Parallax,Parallax]LOCKCLR·in the·Prop Manual and will look in to it.·[/font][/font]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "The man who smiles when things go wrong has thought of someone to blame it on."


    -Lucky[size=-1][/size]
Sign In or Register to comment.