cogstart error in C++
I am getting the following error
"invalid conversion from 'void(*)()' to 'void(*)(void*)'"
on the line
int cogID=cogstart((&Blinker), NULL, &cogStack, sizeof(cogStack));
of the following program
/*
* This is a simple example of a method running in its own cog. This class will toggle the indicated pin
* at the frequency received as the second argument, the toggling method runs in its own cog.
*/
#include <propeller.h>
#include "pin.h"
#define LMM_STACK_AREA 40 // Number of int locations for the cog method to work
#define NUMBER_OF_INT_LOCAL_VARIABLES 0 //
class Toggler
{
static int waitTime; // Time interval between blinks
static int ledPin; // The pin for the LED we will blink
static int cogStack[LMM_STACK_AREA + NUMBER_OF_INT_LOCAL_VARIABLES]; // Stack area used by the cog
public:
Toggler(int ledPinArg, int timesPerSecondArg) // Starts toggling ledPinArg at a frequency of timePerSecondArg
{
// Prepare things
waitTime=CLKFREQ/timesPerSecondArg;
ledPin=ledPinArg;
// Start the cog
int cogID=cogstart((&Blinker), NULL, &cogStack, sizeof(cogStack));
}
private:
static void Blinker() // Does the actual blinking, it will run in a different cog
{
// Set the pin for output
pinOutput(ledPin);
while(1)
{
// Turn the LED on and wait
pinHigh(ledPin);
waitcnt(CNT+waitTime);
// Turn the LED off and wait
pinLow(ledPin);
waitcnt(CNT+waitTime);
}
}
};
What am I doing wrong?
Thanks,
Enrique
"invalid conversion from 'void(*)()' to 'void(*)(void*)'"
on the line
int cogID=cogstart((&Blinker), NULL, &cogStack, sizeof(cogStack));
of the following program
/*
* This is a simple example of a method running in its own cog. This class will toggle the indicated pin
* at the frequency received as the second argument, the toggling method runs in its own cog.
*/
#include <propeller.h>
#include "pin.h"
#define LMM_STACK_AREA 40 // Number of int locations for the cog method to work
#define NUMBER_OF_INT_LOCAL_VARIABLES 0 //
class Toggler
{
static int waitTime; // Time interval between blinks
static int ledPin; // The pin for the LED we will blink
static int cogStack[LMM_STACK_AREA + NUMBER_OF_INT_LOCAL_VARIABLES]; // Stack area used by the cog
public:
Toggler(int ledPinArg, int timesPerSecondArg) // Starts toggling ledPinArg at a frequency of timePerSecondArg
{
// Prepare things
waitTime=CLKFREQ/timesPerSecondArg;
ledPin=ledPinArg;
// Start the cog
int cogID=cogstart((&Blinker), NULL, &cogStack, sizeof(cogStack));
}
private:
static void Blinker() // Does the actual blinking, it will run in a different cog
{
// Set the pin for output
pinOutput(ledPin);
while(1)
{
// Turn the LED on and wait
pinHigh(ledPin);
waitcnt(CNT+waitTime);
// Turn the LED off and wait
pinLow(ledPin);
waitcnt(CNT+waitTime);
}
}
};
What am I doing wrong?
Thanks,
Enrique

Comments
to this:
cogstart will pass its second parameter to Blinker in the 'arg' parameter. You can use this parameter to communicate information between the main program and the program you're starting on another COG.
Thanks for the reply
Your suggestion got rid of the previous error and I am now getting a new one
'lvalue required as unary & operand'
on the line
int cogID=cogstart((&Toggler::Blinker(NULL)), NULL, &cogStack, sizeof(cogStack));
This is what the code looks like now
/*
* This is a simple example of a method running in its own cog. This class will toggle the indicated pin
* at the frequency received as the second argument, the toggling method runs in its own cog.
*/
#include <propeller.h>
#include "pin.h"
#define LMM_STACK_AREA 40 // Number of int locations for the cog method to work
#define NUMBER_OF_INT_LOCAL_VARIABLES 0 //
class Toggler
{
int waitTime; // Time interval between blinks
int ledPin; // The pin for the LED we will blink
int cogStack[LMM_STACK_AREA + NUMBER_OF_INT_LOCAL_VARIABLES]; // Stack area used by the cog
public:
Toggler(int ledPinArg, int timesPerSecondArg);
private:
void Blinker(void *arg);
};
Toggler::Toggler(int ledPinArg, int timesPerSecondArg) // Starts toggling ledPinArg at a frequency of timePerSecondArg
{
// Prepare things
waitTime=CLKFREQ/timesPerSecondArg;
ledPin=ledPinArg;
// Start the cog
int cogID=cogstart((&Toggler::Blinker(NULL)), NULL, &cogStack, sizeof(cogStack));
}
void Toggler::Blinker(void *arg) // Does the actual blinking, it will run in a different cog
{
// Set the pin for output
pinOutput(ledPin);
while(1)
{
// Turn the LED on and wait
pinHigh(ledPin);
waitcnt(CNT+waitTime);
// Turn the LED off and wait
pinLow(ledPin);
waitcnt(CNT+waitTime);
}
}
I would suggest that you do not do this is C++.
Even if the bulk of your program is C++ I would define the function to be loaded to COG as C function. If it needs parameters passed into par I would use a regular struct.
Also, you should not try to pass an argument to the function. "&func(NULL)" means "the address of the result of func(NULL)", whereas "&func" just means "the address of func". The second one, namely the address of the function itself, is what you want to pass to cogstart,
Thanks,
Enrique
You should be able to use a function with a global namespace. For example ::do_toggle below works fine for me. The start function is slightly different, but it shouldn't matter. The example is a small modification for the toggle/lmm_c_toggle demo.
/** * @file toggle.c * This program demonstrates starting another COG running * LMM code. * The cog makes all IO except 28..31 toggle. * * Copyright (c) 2011 Parallax, Inc. * MIT Licensed (see at end of file for exact terms) */ #include <stdio.h> #include <propeller.h> #include <sys/thread.h> #define STACK_SIZE 16 /* stack for cog 1 */ static int cog1_stack[STACK_SIZE]; /* per-thread library variables ("Thread Local Storage") */ static _thread_state_t thread_data; /* variables that we share between cogs */ volatile unsigned int wait_time; volatile unsigned int pins; /* * here's the toggle code that runs in another cog */ void do_toggle(void *arg __attribute__((unused)) ) { unsigned int nextcnt; /* get a half second delay from parameters */ _DIRA = pins; /* figure out how long to wait the first time */ nextcnt = _CNT + wait_time; /* loop forever, updating the wait time from the mailbox */ for(;;) { _OUTA ^= pins; /* update the pins */ /* sleep until _CNT == nextcnt, and return the new _CNT + wait_time */ nextcnt = __builtin_propeller_waitcnt(nextcnt, wait_time); } } /* * main code * This is the code running in the LMM cog (cog 0). * It launches another cog to actually run the * toggling code */ #define MIN_GAP 400000 class Toggle { public: int start (void) { int n; int result; unsigned int startTime; unsigned int endTime; unsigned int executionTime; unsigned int rawTime; printf("hello, world!\n"); /* set up the parameters for the C cog */ pins = 0xfffffff; wait_time = _clkfreq; /* start by waiting for 1 second */ /* start the new cog */ n = _start_cog_thread(cog1_stack + STACK_SIZE, ::do_toggle, NULL, &thread_data); printf("toggle cog %d has started\n", n); /* every 2 seconds update the flashing frequency so the light blinks faster and faster */ while(1) { waitcnt(CNT+CLKFREQ/2); wait_time = wait_time >> 1; if (wait_time < MIN_GAP) wait_time = _clkfreq; } return 0; } }; int main (void) { Toggle t; t.start(); while(1); } /* +-------------------------------------------------------------------- * ¦ TERMS OF USE: MIT License * +-------------------------------------------------------------------- * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +-------------------------------------------------------------------- */