Shop OBEX P1 Docs P2 Docs Learn Events
Cog starts, but next line of code isn't executed - why? — Parallax Forums

Cog starts, but next line of code isn't executed - why?

Ken GraceyKen Gracey Posts: 7,401
edited 2009-01-25 19:16 in Propeller 1
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?

Thanks,

Ken Gracey

'Propeller Robot
'Object Avoidance Using Three Ping))) Ultrasonic Sensors
'
CON
'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
VAR
· long· Stack[noparse][[/noparse]50]
· long· rightDrive
· long· leftDrive
· long· count
··················
OBJ
· 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)

Comments

  • Erik FriesenErik Friesen Posts: 1,071
    edited 2009-01-25 01:40
    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 GraceyKen Gracey Posts: 7,401
    edited 2009-01-25 01:49
    Bingo! Problem solved. Thanks Erik!

    Feel free to throw the book at me anytime.

    Ken Gracey
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2009-01-25 01:50
    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)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-01-25 02:26
    Ken,

    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.

    -Phil
  • BradCBradC Posts: 2,601
    edited 2009-01-25 03:48
    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 [noparse]:)[/noparse] 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)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-01-25 09:48
    Brad,

    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
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-01-25 19:16
    I tried the "0+", and it works as expected. Here's the code I used to test it:

    [b]CON[/b]
    
       [b]_clkmode[/b]       = [b]xtal1[/b] + [b]pll16x[/b]
       [b]_xinfreq[/b]       = 5_000_000
    
    [b]VAR[/b]
    
      [b]long[/b] stack[noparse][[/noparse]*30]
      
    
    [b]PUB[/b] Start
    
      [b]cognew[/b](0 + Local(@false_start), 0)
    
    [b]PUB[/b] Local(addr)
    
      [b]return[/b] addr + 4
    
    [b]DAT[/b]
    
                  [b]org[/b]       0
    false_start   [b]jmp[/b]       #false_start
    
                  [b]org[/b]       0
                  [b]mov[/b]       [b]dira[/b],#1
    :loop         [b]or[/b]        [b]outa[/b],#1
                  [b]andn[/b]      [b]outa[/b],#1
                  [b]jmp[/b]       #: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.

    -Phil
Sign In or Register to comment.