Shop OBEX P1 Docs P2 Docs Learn Events
Accessing hub variables from multiple cogs — Parallax Forums

Accessing hub variables from multiple cogs

I'm doing an application with the P2 Edge and Spin2. Everything is working fine but now I'm delving into using multiple cogs. I'm starting them like this:

cogspin(NEWCOG, @CogMethod, @CogStack)

And now I'm running into occasions where the P2 just locks up. I'm still trying to pinpoint the exact code, but the common thread seems to be situations where multiple cogs are trying to access the same hub variables. (I assume this is the location of spin variables defined in VAR.)

Are there any precautions that need to be taken when multiple cogs access the same global variables? The P2 datasheet indicates that there are safeguards in place to prevent problems, but it seems mostly geared toward PASM.

I understand that in these instances care would need to be taken to prevent corrupted data, with locks and such, but I'm puzzled as to why this would cause a processor crash.


  • JonnyMacJonnyMac Posts: 8,894

    I allow Spin cogs to access global variables quite frequently, and have never had an issue. Can you upload a demo project that exhibits the behavior you're seeing?

  • Thanks Jon. Yes I'll try to post something tonight. But in the meantime this is a very simplified version of my setup:

      long globalVar, cogStack[64]
    PUB Main()
      cogspin(NEWCOG, @ParallelTask, @cogStack)
        [some code here]
        if [condition to access var]
    PUB ParallelTask()
        [some code]
        globalVar := something
    PRI AccessVar(x)
      globalVar := x

    Both cogs will run happily together until the instant when my main cog executes AccessVar(5). This is the point where there could be multiple accesses of globalVar. There are no other relations between the two cogs other than globalVar. If I modify the AccessVar method so that it's reading globalVar instead of writing, the crash still occurs. If I eliminate the line that starts the second cog, then the crash does not occur.

    I feel like I'm missing something really simple here.

  • JonnyMacJonnyMac Posts: 8,894

    It's possible you have a race condition and maybe you need to gate access in some fashion. I wrote a LANC driver that runs in the background and updates a global frame counter when a new frame is ready. The frame consumer looks for a change in the frame counter before grabbing the new frame data; this prevents races and sync issues. Still, if one cog is a producer of value(s) and another is a consumer of value(s) there should be no issued. For my friend John at, I wrote a little embedded cog that reads and averages the last for readings of ADC inputs (this is on the P1). The foreground cog only reads the average values and we never have problems with one stepping on the other.

  • RossHRossH Posts: 5,322

    Use locks to protect access to shared variables from multiple cogs.

    I don't know the spin syntax, but it would be something like locknew, locktry and/or lockrel.

  • AribaAriba Posts: 2,678

    Have you tried to increase the stack size?

  • Are you meant to be able to pass the address of a function to cogspin like that (@CogMethod as opposed to just CogMethod())? It could be a difference between how the available toolchains work, but in FlexSpin I don't think I've ever tried to; I've only ever used it like cogspin(NEWCOG, cog_method(), @cog_stack). The spin2 docs don't seem to offer details on the parameters:

    COGSPIN(CogNum, Method({Pars}), StkAddr)
    Start Spin2 method in a cog, returns cog's ID if used as an expression element, -1 = no cog free.


  • Thanks for everyone's replies. It all turned out to be a red herring. I had a similar problem in multiple places which led me to suspect a memory access conflict. But after no one here saw an obvious issue, I looked harder at my code and found unrelated problems in both places that were causing the P2 freeze. One was an array index out of range, aarrgghhhh.

    avsa242, good eye, yes in my cogspin example I should have put CogMethod() as the second argument. That's what I get for trying to do things from memory.

Sign In or Register to comment.