PDA

View Full Version : Need rules on COGs calling methods in parent progam objects...



gibbod
10-21-2011, 02:52 AM
I was playing around with the QuickStart 5: MulticogTwinkleDemo.spin program and noticed an anomaly, or at least what I considered an anomaly. Even though the Twinkle(..) method was submitted to three different cogs, with three different LED duty cycle rates, I noticed that all LEDs were waxing and waning in sync, albeit at a very oddly fluctuating frequency.

I'm embarrassed by how long it took me to figure out what was happening. It seems that the Twinkle(..) method was indeed running in three separate cogs, but in order to modify the duty rate of it's LED each Twinkle(..) instance called a method in the E555_LEDEngine.spin object which had been declared in the main (cog 0) program.

Apparently (from my debug code), the E555_LEDEngine.spin object method considered itself to be executing in cog 0, at least that's what cogid reported, and it would explain the odd LED symptoms if it was cog 0's frqb that was being updated (by three different cogs) and used to control LED brightness for all three LEDs.

First question, could someone verify exactly what is going on here? (I'm just speculating based on some debug code returns.) Second question, are there some rules on how to use Spin calls from within methods which have been submitted to other cogs? I'd like to be able to avoid this kind of unexpected (at least by me) behavior in the future.

Thanks for your time!

Phil Pilgrim (PhiPi)
10-21-2011, 03:04 AM
giggod,

Welcome to the forum and to the Parallax Propeller family!

Without looking at the code, I can say categorically that a cog cannot write to or otherwise directly influence the counter registers in another cog. They're all independent. However, the outputs are not. The outputs from all the cogs with corresponding dira bits set are ORed together. So if one cog's counter is outputting a 0 pin P2, say, and another cog is outputting a 1 on P2, P2 will be high. What you might be seeing is the result of the ORing.

-Phil

frank freedman
10-21-2011, 04:27 AM
While you can not directly write into cogb from coga, one way to approximate that would be to use a loop through the counter setup part of the cog program and have it read a shared hub location. Once the value is deposited into the location and retrieved by the cog controlling the counter, then an mvi/s/d instruction could modify the counter setup accordingly and the new function/values set up with the same but modified counter instructions initially coded. Or of course there could be an if structure to select which counter word of a selection was sent to the counter......

While I have not tried this yet, there does not seem to be anything against it working. Just have to watch that self modifiying code bug, so many ideas, so little time... I plan to try this either in playing with my ADC/DAC setup or in the refinements of the curve tracer once I finish building it. Too much to still explore on the ADC/DAC breadboard I posted a little while back.

Frank

Heater.
10-21-2011, 05:16 AM
Frank,
What "self modifying code bug"?

frank freedman
10-21-2011, 07:29 AM
Frank,
What "self modifying code bug"?

The one that when you realize just what you can do with modifying things on the fly in certain conditions leads to a flood of ideas and other ways to apply this technique......... One I did not think initially had much value to offer....... oops....

And the same bug that bites you in the @$$ when you get to deep in the woods with the same and end up executing data because of a mis-modified i/d/s value........

That kind of bug, not code, not hardware, just human bug...............


Frank

Heater.
10-21-2011, 10:35 AM
Ah yes, human bug.
They come in so many species. Some are very resistant to treatment.
One of the peskiest being the recurrent "forgetting the one instruction gap between modifying an instruction and executing it" bug.

Just though it might be some Prop quirk I have missed over the years.

MagIO2
10-21-2011, 11:16 AM
After rereading the initial post I think not all questions (including the questions you read between the lines ;o) have been answered so far.

First question, could someone verify exactly what is going on here?
Answer: Yes, a lot of us would be willing to verify if we would know your code!


Second question, are there some rules on how to use Spin calls from within methods which have been submitted to other cogs?
Answer: If you do not code some communication code which let's one COG start a function in another COG, all COGs are totally independent. Let me emphasize this: The COGs are independent - the only dependency and interference can be added by using the same HUB-RAM concurrently.
Functions are not dedicated to one COG! If you call function A from COG 0 it's running in COG 0. If you call function A from COG 1 it's running in COG 1. All local variables and parameters live on the stack that is dedicated to the COG when calling cognew. So, usually functions are reentrant. Problems may occur if you use variables defined in VAR or DAT sections. Let's say you have a set of variables which belong together - for example LED-pin, LED-repeat and LED-blink-rate - you have to take care that each COG has it's own set of these variables or that the access is atomic or synchronized between the different COGs.

If you really want to have COG 0 execute a function triggered by COG 1, then you have to code it. That's what drivers usually do. Both have to know a place in HUB-RAM where COG 0 expects commands and COG 1 knows this place to "send" a command.

kuroneko
10-21-2011, 12:42 PM
I was playing around with the QuickStart 5: MulticogTwinkleDemo.spin program and noticed an anomaly, or at least what I considered an anomaly. Even though the Twinkle(..) method was submitted to three different cogs, with three different LED duty cycle rates, I noticed that all LEDs were waxing and waning in sync, albeit at a very oddly fluctuating frequency.
The loop variable Counter is a global but is used by all cogs as index. Change it to a local one and you'll get the intended effect.

VAR

' byte Counter 'Establish Counter Variable
long stack[90] 'Establish working space

PUB Main

cognew(Twinkle(16,clkfreq/50), @stack[0]) 'start Twinkle cog 1
cognew(Twinkle(19,clkfreq/150), @stack[30]) 'start Twinkle cog 2
cognew(Twinkle(22,clkfreq/100), @stack[60]) 'start Twinkle cog 3

PUB Twinkle(PIN,RATE) | Counter 'Method declaration

MagIO2
10-21-2011, 01:38 PM
Ups ... rereading did not did not help for not missing this point: "...QuickStart 5: MulticogTwinkleDemo.spin..." ;o)

Shame on me for that, but at least the description in my last post turned out to explain the problem.

Here is one more tipp for you: You dramatically increase the chance to get good tipps if you post your code even if the changes you made are small. For example I don't have a glue where to find Quck Start code. If you add every bit of information needed to the post also people that have a quick glance into the forum have a chance to give you a quick tipp.

And hey ... welcome to the forum and the world of propellerheads.

gibbod
10-22-2011, 09:14 AM
Hey, thanks all for your replies. It's 2 am, and I have to get up at 7:30 am, so I'll not test the code right now, but I think kuroneko may have nailed it. If the global variable is being pulled in different directions by three cogs all thinking they have exclusive ownership, that would explain the cross-talk. -- Out of town tomorrow, but I'll let you guys know what I find on Sunday.

Thanks, Don