1

So, I have the following situation:

  • I'm coding for the mbed online compliler, on a low-memory microcontroller.

  • Real Time performance is very important, I want this to take less than a microsecond. 10 microseconds would be tolerable.

  • I'm using their timeout library, which provides an API for calling an ISR after a specified time, but requires that the ISR be a void/void function. (including a member function.

    void TimeoutCallback(void) { do stuff that I want to do on timeout.} // ISR
    
    Timeout to; 
    to.attach_us(&TimeoutCallback, 750) // Call TimeoutCallback in 750 us. 
    
  • I created a vector of Timeout objects, which all get set at once, to the same function, with a different amount of time. I want to somehow pass into the TimeoutCallback which Timeout object called it.

My initial thought was to overload the Timeout class to allow it to accept int function(int) function pointers, and to accept a number in the overloaded attach function that gets passed to said function pointer. However, I'm unsure whether this is actually practical given the messy (and device-specific) inheritance of the Timeout class.

Now, I wonder whether there is a way to programatically create a void/void function that wraps a void/int function, and included a changeable reference int which is passed to the wrapped function.

4

2 回答 2

1

While Tony D's solution is appropriate if using the mbed Ticker class, there is an alternative method using the mbed RtosTimer.

The RtosTimer constructor takes a void* argument that is passed to the handler on timeout. The handler has the signature:

void handler(void const* n) 

Where n is the pointer argument passed to the constructor and can be used to ID the specific timeout.

Unlike Ticker where the timeout function runs in the interrupt context, for RtosTimer the handler runs as a thread, so gives greater flexibility, but potentially greater latency.

于 2015-06-30T06:22:54.047 回答
0

As your library can call member functions, you can create an adapter ala...

template <typename Func, Func func>
struct Adapter
{
    Adapter(int n) : n_(n) { }

    void f() { func(n_); }
    int n_;
};

To use it:

Adapter<void(*)(int), My_Function_Expecting_An_Int> adapter(the_int);
to.attach_us(&adapter, &decltype(adapter)::f, timeout_us);

Make sure the adapter's lifetime lasts until the callback....


To call a member function:

#include <iostream>
#include <string>
#include <vector>

struct MyObj
{
    void f(int n) { std::cout <<"hi " << n << "\n"; }
};

template <typename Class, typename PFunc>
struct Adapter
{
    Adapter(Class& object, PFunc pFunc, int n) : object_(object), pFunc_(pFunc), n_(n) { }

    void f() { (object_.*pFunc_)(n_); }

    Class& object_;
    PFunc pFunc_;
    int n_;
};

int main()
{
    MyObj myObj;

    Adapter<MyObj, void(MyObj::*)(int)> adapter(myObj, &MyObj::f, 43);
    adapter.f();
}
于 2015-06-29T02:20:00.533 回答