Shop OBEX P1 Docs P2 Docs Learn Events
I'm stumped: Cog doesn't like relaunching with the same method — Parallax Forums

I'm stumped: Cog doesn't like relaunching with the same method

varnonvarnon Posts: 184
edited 2013-06-30 05:27 in Propeller 1
Hello all,

So I'm working on updating some old code, and I've tracked down a peculiar error in some of my programs. I have been able to replicate the error. To save time, I'm going to discuss a greatly simplified example where I encounter the same problem. (The actually application is a set of tone generators for my experiment controller.)

The general problem seems to be launching a method in a new cog, terminating that cog, then launching the same method again in a new cog.

In the example (code below) I have a method called blink1. Blink1 pulses a pin on and off until the variable stop1 equals 1. At this point, it resets the dira and outa register for the pin and terminates the cog. I also have a method called blink2. It does the same thing, except it repeats until stop2 equals 1. Essentially, these are identical methods that terminate their cog in different conditions.

The main program can run the blink methods in a variety of manners. Some work as expected. Some do not.

In method 1, both blink methods are repeatedly launched in separate cogs, then terminated together. This works fine.

In method 2, blink1 is launched and terminated, then blink2 is launched and terminated. Separate stacks are used. This works fine.

In method 3, blink 1 is launched and terminated, then launched and terminated again. The same stack space is used. For some reason the second use of blink1 never works.

In method 4, blink1 is explicitly launched in two different cogs. For some reason the second use of blink1 never works.

In method 5, blink1 is launched in the same cog with unique stack space. For some reason the second use of blink1 never works.

In method 6, blink 1 is lauched in distinct cogs with distinct stack sapce. For some reason the second use of blink1 never works.

In method 7, the same cogs and the same stack space are used, but blink1 is launched in the first, and blink2 launched in the second. This method works as expected.


I'm not really sure what to make of this. Methods 1, 2 and 7 work as expected while methods 3-6 do not. The difference appears to be that methods 1, 2 and 7 used blink1 then blink2, while the other methods repeatedly used blink1. I'm not sure why this would be an issue, as methods 1, 2 and 7 are repeatedly using blink1, they just happen to be using blink2 in between blink1 uses.


Does anyone know what to make of this? In my application, this problem is likely only going to be encountered by myself in testing... but I would really like to understand what is going on. I can't seem to find any solid statements in the manual that suggest why this is an issue. Maybe I've been staring at the computer for too long and it is something really obvious? I hope so.


CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000


VAR


  Long Stack1[40]
  Long Stack2[40]


  byte Stop1
  byte Stop2


PUB Main


  ' Provide method 1-7.
  Method7


PUB Method1
  repeat  ' This method works.
    cognew(blink1(16,100),@stack1)
    pause(1000)
    cognew(blink2(17,200),@stack2)
    pause(1000)
    Stop1:=1
    Stop2:=1
    pause(1000)
    Stop1:=0
    Stop2:=0


PUB Method2
  repeat  ' This method works.
    cognew(blink1(16,100),@stack1)
    pause(1000)
    Stop1:=1
    cognew(blink2(17,200),@stack2)
    pause(1000)
    Stop2:=1
    pause(1000)
    Stop1:=0
    Stop2:=0


PUB Method3
  repeat   ' This method does NOT work.
    cognew(blink1(16,100),@stack1)
    pause(1000)
    Stop1:=1
    pause(1000) ' No amount of pause seems to be long enough for the cog to close and restart the same method in the same stack space.
    cognew(blink1(17,200),@stack1)
    pause(1000)
    Stop2:=1
    pause(1000)
    Stop1:=0
    Stop2:=0


PUB Method4
  repeat  ' This method does NOT work.
    coginit(1,blink1(16,100),@stack1)
    pause(1000)
    Stop1:=1
    pause(1000) ' No amount of pause seems to be long enough for the cog to close and restart the same method in the same stack space.
    coginit(2,blink1(17,200),@stack1)
    pause(1000)
    Stop2:=1
    pause(1000)
    Stop1:=0
    Stop2:=0


PUB Method5
  repeat   ' This method does NOT work.
    coginit(1,blink1(16,100),@stack1)
    pause(1000)
    Stop1:=1
    pause(1000) ' No amount of pause seems to be long enough for the cog to close and restart the same method in the same stack space.
    coginit(1,blink1(17,200),@stack2)
    pause(1000)
    Stop2:=1
    pause(1000)
    Stop1:=0
    Stop2:=0


PUB Method6
  repeat   ' This method does NOT work.
    coginit(1,blink1(16,100),@stack1)
    pause(1000)
    Stop1:=1
    pause(1000) ' No amount of pause seems to be long enough for the cog to close and restart the same method in the same stack space.
    coginit(2,blink1(17,200),@stack2)
    pause(1000)
    Stop2:=1
    pause(1000)
    Stop1:=0
    Stop2:=0


PUB Method7
  repeat   ' This method does work.
    coginit(1,blink1(16,100),@stack1)
    pause(1000)
    Stop1:=1
    coginit(1,blink2(17,200),@stack1)
    pause(1000)
    Stop2:=1
    pause(1000)
    Stop1:=0
    Stop2:=0


PUB blink1(pin, ms)
  dira[pin]:=1
  repeat until stop1==1
    !outa[pin]
    pause(ms)
  outa[pin]:=0
  dira[pin]:=0
  cogstop(cogID)


PUB blink2(pin, ms)
  dira[pin]:=1
  repeat until stop2==1
    !outa[pin]
    pause(ms)
  outa[pin]:=0
  dira[pin]:=0
  cogstop(cogID)


PUB Pause(Milliseconds)
  waitcnt(clkfreq/1000*Milliseconds+cnt)

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-06-30 05:12
    varnon wrote: »
    In method 3, blink 1 is launched and terminated, then launched and terminated again. The same stack space is used. For some reason the second use of blink1 never works.
    Method blink1 only ever monitors Stop1. Using Stop2 (to control it) won't have any effect. Also, at the time you do the second invocation Stop1 is still 1, IOW the loop body is never executed (during the second run).
    PUB Method3
      repeat
        cognew(blink1(16,100),@stack1)
        pause(1000)
        Stop1:=1
        pause(1000)
        [COLOR="#FF0000"]Stop1 := 0[/COLOR]
        cognew(blink1(17,200),@stack1)
        pause(1000)
        Stop1:=1
        pause(1000)
        Stop1:=0
    
    FWIW, there is no point resetting the I/O pins when the next thing you do is calling cogstop. Exiting the method stops the cog automatically.
    PUB blink1(pin, ms)
      dira[pin]:=1
      repeat until stop1==1
        !outa[pin]
        pause(ms)
    
    The remainder most likely suffers from similar issues.
  • varnonvarnon Posts: 184
    edited 2013-06-30 05:27
    Ugh. Shouldn't have been messing with this right before I went to bed. I can't believe I overlooked that. I was so focused on the cogs, that I completely ignored the controlling variable. I'm not sure that is the issue in my actual application. But thanks for proof reading that code for me. I really should have caught that.
Sign In or Register to comment.