Shop OBEX P1 Docs P2 Docs Learn Events
How to start a c-function in another cog — Parallax Forums

How to start a c-function in another cog

Christof Eb.Christof Eb. Posts: 1,197
edited 2022-08-28 09:36 in C/C++

Hi,
in the help-file of flexprop, it says:
_cogstart_C
int _cogstart_C(void (*func)(void *), void *arg, void *stack_base, uint32_t stack_size)
Starts C code in another COG. func is the address of a C function which expects one argument, and which will run in another COG (cpu core). arg is the argument to pass to the function for this invocation. stack_base is the base address of a block of memory to use for the stack. stack_size is the size in bytes of the memory.

I don't know, what a 'void *arg' is. My code does crash invoking:

char stack1[2000];
int dummy;
....
main {
...
_cogstart_C(MC6809Exec(),&dummy,&stack1[0],2000);
....
}

Here: https://forums.parallax.com/discussion/172036/catalina/p4

it's just:
_cogstart_C(func, arg, stack_base, stack_size);
But that does crash too.

Where can I find a working example?
Many thanks!

Edit: Even more confusing:
_cogstart_C(MC6809Exec(),dummy,2000,stack1);
gives
error: Expected pointer to stack as last parameter to coginit/cogid

Comments

  • Cog program example:

    /**
     * @brief Start a COG with Parameters
     * @date Feburary 19, 2021
     * @version 1.0
     * 
    */
    
    #include <stdio.h>
    #include <propeller.h>
    
    int Stack[50];
    void DoCog(struct items *);
    
    struct items {
        int item1;
        int item2;
    } parms;
    
    int main(int argc, char** argv)
    {
    
        parms.item1 = 245;
        parms.item2 = 125;
    
        cogstart(DoCog, &parms, Stack, 50);
    
        printf("Done\n");
        while (1)
        {
            _waitms(1000);
        }
    }
    
    void DoCog(struct items *p)
    {
        if (p->item1 == 245)
            _pinl(56);
        if (p->item2 == 125)
            _pinl(57);
    
        while (1)
        {
            _waitms(1000);
        }
    }
    

    Mike

  • Thanks, Mike!
    Now found out via experiment:

    _cogstart_C(MC6809Exec,dummy,stack1,2000);
    

    works.
    So @Eric: would you like to update the Help file and include an example?

  • evanhevanh Posts: 15,915
    edited 2022-08-28 15:09

    Specified stack size will be in bytes I'd think. The usual way to handle such is:_cogstart_C(MC6809Exec,dummy,stack1,sizeof(stack1));

  • evanhevanh Posts: 15,915

    Oh, the crash was because MC6809Exec(), with the brackets, tries to call that function, rather than passing its address to the cogstart().

  • @"Christof Eb." Thank you for the feedback, I will add some examples to the docs. _cogstart_C is provided for compatiblity with other C compiilers (like Catalina and PropGCC). If you're just using FlexC, then _builtin_cogstart is the easiest method to start a function in another COG. It's a special macro unique to FlexC, and the first argument is just the function call you want to happen in another COG, and the second is that starting address of the stack:

    #include <stdio.h>
    #include <propeller.h>
    
    // define the pin to blink
    #ifdef __P2__
    #define BASEPIN 56
    #else
    #define BASEPIN 16
    #endif
    
    // define the delay between toggles
    #define TOGGLE_DELAY 40'000'000
    
    // stack for other COG to run in (must be at least 64 bytes)
    unsigned char stack[128];
    
    // function to blink a pin with a delay
    void blink(int pin, unsigned delay) {
        // now just loop toggling the pin
        for(;;) {
            _pinnot(pin);
            _waitx(delay);
        }
    }
    
    // and now the main program
    void main() {
        int cog;
    
        cog = __builtin_cogstart(blink(BASEPIN, TOGGLE_DELAY), stack);
        printf("started cog %d to blink pin %d\n", cog, BASEPIN);
    
        // we could do other things here (like blink a different pin)
        for(;;)
            ;
    }
    
Sign In or Register to comment.