Confusion on objects and cogs
Lucky
Posts: 98
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.
···
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"The man who smiles when things go wrong has thought of someone to blame it on."
-Lucky[size=-1][/size]
'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
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).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"The man who smiles when things go wrong has thought of someone to blame it on."
-Lucky[size=-1][/size]
anyway this is a kind of question that you can find an answer by writing some testocde too
best regards
Stefan
Post Edited (StefanL38) : 4/5/2010 5:43:50 AM GMT
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.
@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]