View Full Version : Cog starts, but next line of code isn't executed - why?

Ken Gracey
01-25-2009, 08:31 AM
Hey there,

I've set up a program in which I'd like the sensors to run in their own cog, continuously (pingAverager). The pingAverager object is attached. I'm not passing any parameters to that object when it starts, but I'd like global access to the variables created in the pingAverager·object (leftDistance, centerDistance, etc.).

This is my top program. When I run it, the cog launches the Start method in pingAverager but the next line of code doesn't begin (HB25.Start). If I comment out the new cog launch then the HB25 object works fine. I'm not receiving the COG result, either. What's keeping the HB25.Start object from executing?


Ken Gracey

'Propeller Robot
'Object Avoidance Using Three Ping))) Ultrasonic Sensors
'Set clock speed to 80 MHz
· _clkmode = xtal1 + pll16x······· 'Sets the clock speed to 80 MHz using a times 16 multiplier
· _xinfreq = 5_000_000············ 'Crystal speed: 5 MHz
· stopLeft = 1500
· stopRight= 1500
· fastLeft = 1800
· fastRight= 1800
· long· Stack[50]
· long· rightDrive
· long· leftDrive
· long· count
· HB25···· : "HB25"
· Ser····· : "FullDuplexSerial"
· Distance : "PingAverager"··
PUB Main
· cognew(Distance.Start, @Stack)
· HB25.Start(13,1,1)············
· repeat count from 1500 to 1800
··· HB25.set_motor1(count)
··· HB25.set_motor2(count)
··· WaitCnt(300_000 + Cnt)

Erik Friesen
01-25-2009, 08:40 AM
I don't think you can call an cognew to an outside object. I think it is starting distance.start in the same cog. I believe you will need to set up the start within the Pingaverager and call the cognew from there.

Ken Gracey
01-25-2009, 08:49 AM
Bingo! Problem solved. Thanks Erik!

Feel free to throw the book at me anytime.

Ken Gracey

Erik Friesen
01-25-2009, 08:50 AM
I was going to add that to get global access to these variables it would be easiest to park the averager code in your top object as your code isn't that long anyway.

Phil Pilgrim (PhiPi)
01-25-2009, 09:26 AM

Your example sheds some interesting light on the inner workings of the compiler. At first I thought, "If you can't cognew an external method, why didn't it cause a syntax error?" But, given that Distance.Start actually ran, here's what I think happened: The compiler, seeing that it was an external method, called it to get the start address of an assembly cog. Then it started a cog at the address returned by Distance.Start, passing @Stack in PAR. The assembly code — who knows what random instructions or where? — screwed up further execution of the main cog.

This begs the question of how you might use a local method to compute the address of an assembly routine. Initially, I though something like

cognew(Local_compute_address(5) + 0, par_value)

might work to disambiguate the two. But the compiler doesn't like the "+0", so I guess that would not work.


01-25-2009, 10:48 AM
Phil, the problem with the +0 is the compiler sees the spin method as the first parameter and assumes its launching a spin cog. In that instance any form of mathematics in the first parameter is a no-no.

It would be nice if the Parallax compiler emitted a warning or an error if it sees people trying to launch a cog from a method in a sub-object. It seems a pretty common error that repeatedly bites people.

Better still, it'd be even nicer if it actually worked :) I've not looked hard enough at the stack-foo surrounding launching a spin cog to determine if sufficient compiler magic could actually make it work though.

Cardinal Fang! Fetch the comfy chair.

Phil Pilgrim (PhiPi)
01-25-2009, 04:48 PM

I wonder if "0+" would work instead. At least the compiler would know that it was dealing with an expression before seeing the method call. 'Might have to try that tomorrow. Still, I can't imagine ever needing to call a local method to compute the start address of an assembly cog. I'm sure Chip considered that when deciding how to disambiguate the two forms of cognew.

It's only marginally more likely that you'd call a remote method to return such an address, given that the remote method could just as easily start the new cog itself. So maybe it should be a flaggable error.


Phil Pilgrim (PhiPi)
01-26-2009, 02:16 AM
I tried the "0+", and it works as expected. Here's the code I used to test it:


_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000


long stack[*30]

PUB Start

cognew(0 + Local(@false_start), 0)

PUB Local(addr)

return addr + 4


org 0
false_start jmp #false_start

org 0
mov dira,#1
:loop or outa,#1
andn outa,#1
jmp #:loop

The program that begins after false_start is the one that runs. So, apparently, the cue to the compiler is the first thing it sees in the first argument to cognew.