interupts and class members

03 Jan 2011

I am trying to control an external serial device by bit banging as it does not appear to be either SPI or I2C format.
To make things nice and tidy I am writing a self comtained class to hold all code etc.
The problem I have is that I need to attach a function within the class to the ticker interupts.
The only way I have been able to do this is by having a function in the main code which merely calles the function in my class and attaching this to the ticker interupt.

The relevant code is shown below


Ticker      flipper ;
TSL3301     spectro(LED1,LED2,LED3) ;// just for test purposes

void localworker( void)
{
spectro.mainworker() ;
}

int main() { 
//  flipper.attach( &spectro.mainworker,0.5) ; // gives compiler error
//"A pointer to a bound function may only be used to call the function (E300)" in file "/main.cpp"

flipper.attach( &localworker,0.5) ;     // compiles and works



A few questions occurr to me, please bear in mind that this is a learning proect for me.

A)    Is my approach sensible or should I get round this issue by a totally different approach
B)    Why does the compiler find the required function from localworker but not in the call to flipper.attach
C)    My present solution gives the overheads of "unnecessary" subroutine calls and returns, are these significant bearing mind the general advice to keep work within an     interupt as small and fast as possible.

03 Jan 2011

Hi Allan,

Your general approach is spot on (A), but as you suspect, there is a better way of doing it (B). You can attach both static/global functions and member methods to a ticker. You need to pass both a pointer to the object (which could be "this"), and a pointer to the member function. So in your example, you'd do something like this:

flipper.attach(&spectro, &TSL3301::mainworker, 0.5); 

(edit: corrected to include time after subsequent post)

Note &spectro could be replaced with "this" if it was used within the TSL3301 class itself.

Hope that makes sense, and gets you going!

Simon

03 Jan 2011

Simon,

Many thanks for this. The line I actually found to work is

flipper.attach(&spectro, &TSL3301::mainworker,0.5) ;

My question now is of course why/how does this work as to my (novice) eye this is not consistent with the declared argument list for attach. A pointer (no pun intended!!) to where I can find the answer myself will do very nicely thank you.

 

03 Jan 2011

Hi Allan,

The attach function is overloaded, so can accept either a static/global function pointer, or the combination of an object pointer and member method pointer. See:

You'll see the API has both options listed, but easy to overlook. Also, sorry about forgetting to include the time; well corrected.

Simon

03 Jan 2011

Hi Allan,

the answer is two-fold:

  • first, the syntax for defining pointers to member functions in C++ is different than it is in C, see The function pointer tutorial for an explanation
  • second, as Simon already explained, the attach function not only needs to know the address of the method, but of the object as well.

(I think that in non-beta mode the API page has a bug and doesn't show methods which make use of templates in their definition - but this might also be only for old pages. I had this problem with other APIs too that they did not show the methods with templates in them).

hli