Shop OBEX P1 Docs P2 Docs Learn Events
When cogs collide — Parallax Forums

When cogs collide

varnonvarnon Posts: 184
edited 2012-12-21 02:47 in Propeller 1
I've notice that when using objects that launch new cogs, such as the Parallax Serial Terminal or FSRW, the order the cogs are launched seems to matter. Sometimes if one object is started before another one the second object will not start properly. I really don't understand why this happens. I thought cognew looked for an unused cog and launched code there. I don't understand why there would be conflicts.


I've scraped together some methods from other projects to give you an idea of what I am talking about. Here I test the Parallax Serial Terminal, FSRW, RealRandom, and a clock method I use. I have had order issues with each one of these.

CON
  {{ Sets the clock mode }}
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

OBJ

  pst           : "Parallax Serial Terminal"
  SD            : "FSRW"        ' Uses "mb_small_spi"
  RR            : "RealRandom"
  numbers       : "Simple_Numbers"

VAR

  long clock
  long clockstack[10]
  byte ClockCogID

PUB Main

  Write
  Read

PUB Write

  LaunchEverything

  SD.popen(string("Testfile.txt"),"w")
  pst.str(string("Test file created...",13,13))

  repeat 10
    SD.pputs(numbers.dec(randomrange(10,99)))
    SD.pputc(32)
    SD.pputs(numbers.dec(time(0)))
    SD.pputc(13)
  SD.pclose
  pst.str(string("Data written...",13,13))

PUB LaunchEverything

  pst.start(115_200)
  pst.str(string(13,13,"PST starting...",13,13))

  rr.start
  pst.str(string("RealRandom starting...",13,13))

  ClockCogID:=cognew(sysclock, @clockstack)
  pst.str(string("Clock starting...",13,13))

  sd.mount_explicit(0,1,2,3)
  pst.str(string("SD card mounted...",13,13))

PUB Read | x

  SD.popen(string("Testfile.txt"),"r")
  pst.str(string("Test file opened...",13,13))

  x:=SD.pgetc
  repeat until x==-1
    pst.char(x)
    x:=SD.pgetc
  pst.char(13)
  SD.pclose

  StopEverything

PUB StopEverything

  SD.unmount                                                                    ' Unmounts the SD Card.
  pst.str(string("SD card unmounted...",13,13))

  rr.stop
  pst.str(string("RealRandom stopped...",13,13))

  Cogstop(ClockCogID)                                                           ' Stops the clock.
  pst.str(string("Clock stopped...",13,13))

  waitcnt(clkfreq/1000*2000+cnt)
  pst.stop

PUB RandomRange(Minimum,Maximum) | value, range

  range:=||(Minimum-Maximum)                                                    ' The range is the absolute value of the difference between the numbers.
  value:=rr.random                                                              ' Use realrandom to generate a random number.
  value:=||(value//(range+1))                                                   ' Divide the random number by range+1 and save the remainder.
  value+=Minimum                                                                ' The final value is the remainer plus the smaller number.

  return value                                                                  ' Return the selected value.

PUB Time(Event)
  '' Reports time since an event. If time(0) is called it returns the current time.

  return (Clock-Event)

PRI SysClock | systime

  systime:=cnt                                                                  ' Finds current value of system counter.
  repeat
    waitcnt(systime += clkfreq/1000)                                            ' Waits one millisecond. A synchronized pause.
    clock++                                                                     ' After a millisecond passes, add 1 to the clock.


To test the cog order issues I changed the order the cogs were launched in LaunchEverything. Print lines were commented out if PST was not launched yet.
I found that the following orders were successful:
pst, rr, clock, fsrw
rr, pst, clock, fsrw
rr, clock, pst, fsrw
fsrw, clock, rr, pst
fsrw, clock, pst, rr


These orders were caused the program to lock up when attempting to launch one of the objects:
pst, rr, fsrw, clock
rr, clock, sfsrw, pst
rr, fsrw, clock, pst


Previously I have found issues where FSRW could write files, but not read them until another cog was closed. I was not able to replicate this issue. I have also previously found that the clock may return incorrect values when the cogs are launched in certain orders, but I was not able to replicate this either.


Does anyone have any explanation for why this happens? It is easy enough to change the order of the code, but I feel like that should be unnecessary. Any thoughts?

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-12-20 20:20
    varnon wrote: »
    These orders were caused the program to lock up when attempting to launch one of the objects:
    pst, rr, fsrw, clock
    rr, clock, sfsrw, pst
    rr, fsrw, clock, pst
    Could this lock-up simply be an abort from the filesystem? As there aren't any abort traps in your code it will look like lock-up. I certainly don't have any issues running your bad examples without an SD card present provided I trap the abort(s).

    It may well be something else but we should check the simple explanations first.
  • AribaAriba Posts: 2,690
    edited 2012-12-20 20:23
    Have you tried it with "mb_safe_spi" inside the FSRW object? I don't now what SPI methode "mb_small_spi" uses, but if it's the same as "mb_raw_spi" then this very fast SPI code may cause such troubles, because it works not with all Cog / PortPin combinations. That's why the Safe-SPI code exists.

    Andy
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-20 20:27
    Ariba wrote: »
    I don't now what SPI methode "mb_small_spi" uses, but if it's the same as "mb_raw_spi" then this very fast SPI code may cause such troubles, because it works not with all Cog / PortPin combinations.

    Good point, that seems to be the case here (20Mb reader).
  • varnonvarnon Posts: 184
    edited 2012-12-20 20:52
    Thanks for the thoughts so far.
    kuroneko wrote: »
    Could this lock-up simply be an abort from the filesystem? As there aren't any abort traps in your code it will look like lock-up. I certainly don't have any issues running your bad examples without an SD card present provided I trap the abort(s).
    I'm sure an abort trap would work fine, but I don't think it wouldn't really solve the problem. I would just be presented with an abort message printed to the screen instead of a lock up. I actually do have an abort traps for the SD card being present in my actual programs.
    Ariba wrote: »
    Have you tried it with "mb_safe_spi" inside the FSRW object? I don't now what SPI methode "mb_small_spi" uses, but if it's the same as "mb_raw_spi" then this very fast SPI code may cause such troubles, because it works not with all Cog / PortPin combinations. That's why the Safe-SPI code exists.

    Andy

    I switched the SPI object to mb_safe_spi. So far things are okay. I can't remember if there was a reason I was using mb_small_spi or not. Is there any good reason not to use mb_safe_spi? I can't imagine speed will be an issue for my uses. I do some quick data notes to the SD card during the main program, but any complicated processing and reading/writing is done at the end of the program when time is not an issue.

    I'll keep testing to see if I can get any other collisions.
    Thanks.
  • Heater.Heater. Posts: 21,230
    edited 2012-12-21 00:36
    After all these years and all those Prop users with thousands of projects if the were such a lock up problem I'm pretty sure we would have seen it by now.
    There must be hardly a corner case of the Prop not explored by those of so inclined to want to break such things.

    My money is on a fault in your code somewhere.

    Unless, of course, this is one of the first stitches of the universe coming undone as we approach the end of time:)
  • varnonvarnon Posts: 184
    edited 2012-12-21 02:32
    Heater. wrote: »
    After all these years and all those Prop users with thousands of projects if the were such a lock up problem I'm pretty sure we would have seen it by now.
    There must be hardly a corner case of the Prop not explored by those of so inclined to want to break such things.

    My money is on a fault in your code somewhere.

    Not really a very helpful response. Did you read my post? I wasn't intending to suggest a Propeller bug. (Maybe "lock-up" is a weighted phrase? Programing is at least a tertiary skill/hobby so my language is not always the best.) I think you are correct. It is the code. But I only wrote a small fraction of the code in this example. Given the simplicity of my clock cog, I really doubt that is causing an issue. Unfortunately, my PASM isn't great and I haven't had any luck looking into the other code to see what the error might be.

    I haven't been able to make any errors since I switched FRSW to safe_spi, so I think I can point to the direction of the problem. I do wish I understood it a bit better though.
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-21 02:37
    varnon wrote: »
    I haven't been able to make any errors since I switched FRSW to safe_spi, so I think I can point to the direction of the problem. I do wish I understood it a bit better though.
    There is nothing much to it. The SPI driver you used before uses a method to read bits at 1 bit/insn which is highly susceptible to cog/pin pairings. As your pins for the SD adapter stay the same, changing the object start order will move the SPI driver around to a different cog. This will change the timing and may not work at all for certain combinations.

    If you want more details check this thread about [thread=127653]waitpxx cog synchronisation[/thread], especially the section about counter DUTY mode.
  • varnonvarnon Posts: 184
    edited 2012-12-21 02:47
    Okay, I've tested everything combination. Zero problems now. I can't generate any of the issues I described previously.
    Thanks for the help. I knew you guys would have some good (and simple) idea that I missed.
    (Thanks for the link too, I'll read up on that.)
Sign In or Register to comment.