Community article "Using FreeRTOS ...

sven-de wrote on Wednesday, July 13, 2011:

Original thread:

Resulting article by Richard Damon:

I’m trying to understand, how the code in the mentioned article works. This is way beyond anything I learned about C++ in school or books, so my current understanding is still a bit shaky. I’d be glad to put it on solid ground with your kind help.

class myclass {
    void taskfun();
} obj;
extern "C" void taskfunwrapper(void* parm) {
xTaskCreate(&taskfunwrapper, (const signed char*)"taskname", stackDepth, &obj, prioriry, NULL);

I couldn’t find anything about the way obj is defined, but I assume it’s similar to structs some sort of name, referring to this class. When creating the task, this name is passed as parameter to the handler which uses it to call the method in question.

What I don’t understand: Where do the instances of myclass come into play? How can I create several tasks with the same method but from different instances?

Or is obj already an instance of myclass? Would I then miss obj and pass on this instead of &obj in xTaskCreate? I believe Richard’s task-class does it this way.

Would the same trick be possible with ISRs? (probably not since one can’t pass parameters to them)
Why is there a referencing-operator (&) with the taskname in xTaskCreate while there usually doesn’t have to be one?

(Background: I’d like to have tasks as member methods and start/create them with the constructor of this very class.)

richard_damon wrote on Wednesday, July 13, 2011:

That piece of code defines a class with name “myclass” then creates an instance of it named “obj”. It is a standard short cut for

class myclass {
myclass obj;

You seem to be confusing this with the Cism idiom of

typedef struct mystructtag { ....} mystruct; 

which creates a type name mystruct that doesn’t need to be qualified by struct for each usage (like mystructtag would need). (Note the second uses the keyword typedef).

To use that wrapper for several instances of an class, just pass the different objects to the xTaskCreate function. One thing to note, is that the object can even be of a derived class, IF, in the create call, you cast the address to be a pointer to the same type that the wrapper casts the void* to.

One thing that I have done with ISRs, if I have multiple interrupts of similar types (like multiple serial ports) is to make the base ISR just a wrapper that calls a member function of an object that does the main processing.

As to using &taskfunwrapper instead of just taskfunwrapper, that is just a style issue. both are syntactically equivalent,   I just set my lint tools to flag the implicit conversion as it sometimes gets me in trouble ( writing things like if(fun) instead of if(fun())) so i am just in the habit of explicitly taking addresses of functions.

This reminds me that I really do need to find time to prepare my wrapper class for formal submission to Richard Barry

sven-de wrote on Thursday, July 21, 2011:

Hi Richard,
thanks for your reply and sorry about my late reaction. Implentation of the whole class took a while and today I was able to test it. Even though I had completely understood how this was supposed to work (due to your explanation) I was utterly amazed, that it’s REALLY working :wink:

The only downer is that I had to put an additional wrapper in between which is plain C. Same issue as here I suppose: