mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #94 from geky/callback
Improve FunctionPointer class
commit
cde78ec095
|
@ -21,14 +21,16 @@
|
|||
*/
|
||||
#include "Thread.h"
|
||||
|
||||
#include "mbed_error.h"
|
||||
#include "mbed.h"
|
||||
#include "rtos_idle.h"
|
||||
|
||||
namespace rtos {
|
||||
|
||||
Thread::Thread(osPriority priority,
|
||||
uint32_t stack_size, unsigned char *stack_pointer):
|
||||
_tid(NULL), _dynamic_stack(stack_pointer == NULL) {
|
||||
void Thread::constructor(osPriority priority,
|
||||
uint32_t stack_size, unsigned char *stack_pointer) {
|
||||
_tid = NULL;
|
||||
_dynamic_stack = (stack_pointer == NULL);
|
||||
|
||||
#ifdef __MBED_CMSIS_RTOS_CM
|
||||
_thread_def.tpriority = priority;
|
||||
_thread_def.stacksize = stack_size;
|
||||
|
@ -36,15 +38,17 @@ Thread::Thread(osPriority priority,
|
|||
#endif
|
||||
}
|
||||
|
||||
Thread::Thread(void (*task)(void const *argument), void *argument,
|
||||
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer):
|
||||
_tid(NULL), _dynamic_stack(stack_pointer == NULL) {
|
||||
void Thread::constructor(Callback<void()> task,
|
||||
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
|
||||
_tid = NULL;
|
||||
_dynamic_stack = (stack_pointer == NULL);
|
||||
|
||||
#ifdef __MBED_CMSIS_RTOS_CM
|
||||
_thread_def.tpriority = priority;
|
||||
_thread_def.stacksize = stack_size;
|
||||
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
|
||||
#endif
|
||||
switch(start(task, argument)) {
|
||||
switch(start(task)) {
|
||||
case osErrorResource:
|
||||
error("OS ran out of threads!\n");
|
||||
break;
|
||||
|
@ -58,13 +62,13 @@ Thread::Thread(void (*task)(void const *argument), void *argument,
|
|||
}
|
||||
}
|
||||
|
||||
osStatus Thread::start(void (*task)(void const *argument), void *argument) {
|
||||
osStatus Thread::start(Callback<void()> task) {
|
||||
if (_tid != NULL) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
#ifdef __MBED_CMSIS_RTOS_CM
|
||||
_thread_def.pthread = task;
|
||||
_thread_def.pthread = (void (*)(const void *))Callback<void()>::thunk;
|
||||
if (_thread_def.stack_pointer == NULL) {
|
||||
_thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
|
||||
if (_thread_def.stack_pointer == NULL)
|
||||
|
@ -76,7 +80,8 @@ osStatus Thread::start(void (*task)(void const *argument), void *argument) {
|
|||
_thread_def.stack_pointer[i] = 0xE25A2EA5;
|
||||
}
|
||||
#endif
|
||||
_tid = osThreadCreate(&_thread_def, argument);
|
||||
_task = task;
|
||||
_tid = osThreadCreate(&_thread_def, &_task);
|
||||
if (_tid == NULL) {
|
||||
if (_dynamic_stack) delete[] (_thread_def.stack_pointer);
|
||||
return osErrorResource;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os.h"
|
||||
#include "Callback.h"
|
||||
|
||||
namespace rtos {
|
||||
|
||||
|
@ -37,26 +38,87 @@ public:
|
|||
*/
|
||||
Thread(osPriority priority=osPriorityNormal,
|
||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||
unsigned char *stack_pointer=NULL);
|
||||
unsigned char *stack_pointer=NULL) {
|
||||
constructor(priority, stack_size, stack_pointer);
|
||||
}
|
||||
|
||||
/** Create a new thread, and start it executing the specified function.
|
||||
@param task function to be executed by this thread.
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
|
||||
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
|
||||
*/
|
||||
Thread(mbed::Callback<void()> task,
|
||||
osPriority priority=osPriorityNormal,
|
||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||
unsigned char *stack_pointer=NULL) {
|
||||
constructor(task, priority, stack_size, stack_pointer);
|
||||
}
|
||||
|
||||
/** Create a new thread, and start it executing the specified function.
|
||||
@param obj argument to task.
|
||||
@param method function to be executed by this thread.
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
|
||||
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
|
||||
*/
|
||||
template <typename T>
|
||||
Thread(T *obj, void (T::*method)(),
|
||||
osPriority priority=osPriorityNormal,
|
||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||
unsigned char *stack_pointer=NULL) {
|
||||
constructor(mbed::Callback<void()>(obj, method),
|
||||
priority, stack_size, stack_pointer);
|
||||
}
|
||||
|
||||
/** Create a new thread, and start it executing the specified function.
|
||||
@param obj argument to task.
|
||||
@param method function to be executed by this thread.
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
|
||||
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
|
||||
*/
|
||||
template <typename T>
|
||||
Thread(T *obj, void (*method)(T *),
|
||||
osPriority priority=osPriorityNormal,
|
||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||
unsigned char *stack_pointer=NULL) {
|
||||
constructor(mbed::Callback<void()>(obj, method),
|
||||
priority, stack_size, stack_pointer);
|
||||
}
|
||||
|
||||
/** Create a new thread, and start it executing the specified function.
|
||||
Provided for backwards compatibility
|
||||
@param task function to be executed by this thread.
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||
@param priority initial priority OF the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
|
||||
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
|
||||
*/
|
||||
Thread(void (*task)(void const *argument), void *argument=NULL,
|
||||
osPriority priority=osPriorityNormal,
|
||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||
unsigned char *stack_pointer=NULL);
|
||||
unsigned char *stack_pointer=NULL) {
|
||||
constructor(mbed::Callback<void()>(argument, (void (*)(void *))task),
|
||||
priority, stack_size, stack_pointer);
|
||||
}
|
||||
|
||||
/** Starts a thread executing the specified function.
|
||||
@param task function to be executed by this thread.
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||
@return status code that indicates the execution status of the function.
|
||||
*/
|
||||
osStatus start(void (*task)(void const *argument), void *argument=NULL);
|
||||
osStatus start(mbed::Callback<void()> task);
|
||||
|
||||
/** Starts a thread executing the specified function.
|
||||
@param obj argument to task.
|
||||
@param method function to be executed by this thread.
|
||||
@return status code that indicates the execution status of the function.
|
||||
*/
|
||||
template <typename T, typename M>
|
||||
osStatus start(T *obj, M method) {
|
||||
return start(mbed::Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
/** Wait for thread to terminate
|
||||
@return status code that indicates the execution status of the function.
|
||||
|
@ -165,6 +227,17 @@ public:
|
|||
virtual ~Thread();
|
||||
|
||||
private:
|
||||
// Required to share definitions without without
|
||||
// delegated constructors
|
||||
void constructor(osPriority priority=osPriorityNormal,
|
||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||
unsigned char *stack_pointer=NULL);
|
||||
void constructor(mbed::Callback<void()> task,
|
||||
osPriority priority=osPriorityNormal,
|
||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||
unsigned char *stack_pointer=NULL);
|
||||
|
||||
mbed::Callback<void()> _task;
|
||||
osThreadId _tid;
|
||||
osThreadDef_t _thread_def;
|
||||
bool _dynamic_stack;
|
||||
|
|
|
@ -0,0 +1,267 @@
|
|||
#include "mbed.h"
|
||||
#include "test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
|
||||
// static functions
|
||||
template <typename T>
|
||||
T static_func5(T a0, T a1, T a2, T a3, T a4) { return a0 | a1 | a2 | a3 | a4; }
|
||||
template <typename T>
|
||||
T static_func4(T a0, T a1, T a2, T a3) { return a0 | a1 | a2 | a3; }
|
||||
template <typename T>
|
||||
T static_func3(T a0, T a1, T a2) { return a0 | a1 | a2; }
|
||||
template <typename T>
|
||||
T static_func2(T a0, T a1) { return a0 | a1; }
|
||||
template <typename T>
|
||||
T static_func1(T a0) { return a0; }
|
||||
template <typename T>
|
||||
T static_func0() { return 0; }
|
||||
|
||||
// class functions
|
||||
template <typename T>
|
||||
struct Thing {
|
||||
T t;
|
||||
Thing() : t(0x80) {}
|
||||
|
||||
T member_func5(T a0, T a1, T a2, T a3, T a4) { return t | a0 | a1 | a2 | a3 | a4; }
|
||||
T member_func4(T a0, T a1, T a2, T a3) { return t | a0 | a1 | a2 | a3; }
|
||||
T member_func3(T a0, T a1, T a2) { return t | a0 | a1 | a2; }
|
||||
T member_func2(T a0, T a1) { return t | a0 | a1; }
|
||||
T member_func1(T a0) { return t | a0; }
|
||||
T member_func0() { return t; }
|
||||
};
|
||||
|
||||
// bound functions
|
||||
template <typename T>
|
||||
T bound_func5(Thing<T> *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; }
|
||||
template <typename T>
|
||||
T bound_func4(Thing<T> *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; }
|
||||
template <typename T>
|
||||
T bound_func3(Thing<T> *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; }
|
||||
template <typename T>
|
||||
T bound_func2(Thing<T> *t, T a0, T a1) { return t->t | a0 | a1; }
|
||||
template <typename T>
|
||||
T bound_func1(Thing<T> *t, T a0) { return t->t | a0; }
|
||||
template <typename T>
|
||||
T bound_func0(Thing<T> *t) { return t->t; }
|
||||
|
||||
|
||||
// function call and result verification
|
||||
template <typename T>
|
||||
struct Verifier {
|
||||
static void verify5(Callback<T(T,T,T,T,T)> func) {
|
||||
T result = func(0x01, 0x02, 0x04, 0x08, 0x10);
|
||||
TEST_ASSERT_EQUAL(result, 0x1f);
|
||||
}
|
||||
|
||||
template <typename O, typename M>
|
||||
static void verify5(O *obj, M method) {
|
||||
Callback<T(T,T,T,T,T)> func(obj, method);
|
||||
T result = func(0x01, 0x02, 0x04, 0x08, 0x10);
|
||||
TEST_ASSERT_EQUAL(result, 0x9f);
|
||||
}
|
||||
|
||||
static void verify4(Callback<T(T,T,T,T)> func) {
|
||||
T result = func(0x01, 0x02, 0x04, 0x08);
|
||||
TEST_ASSERT_EQUAL(result, 0x0f);
|
||||
}
|
||||
|
||||
template <typename O, typename M>
|
||||
static void verify4(O *obj, M method) {
|
||||
Callback<T(T,T,T,T)> func(obj, method);
|
||||
T result = func(0x01, 0x02, 0x04, 0x08);
|
||||
TEST_ASSERT_EQUAL(result, 0x8f);
|
||||
}
|
||||
|
||||
static void verify3(Callback<T(T,T,T)> func) {
|
||||
T result = func(0x01, 0x02, 0x04);
|
||||
TEST_ASSERT_EQUAL(result, 0x07);
|
||||
}
|
||||
|
||||
template <typename O, typename M>
|
||||
static void verify3(O *obj, M method) {
|
||||
Callback<T(T,T,T)> func(obj, method);
|
||||
T result = func(0x01, 0x02, 0x04);
|
||||
TEST_ASSERT_EQUAL(result, 0x87);
|
||||
}
|
||||
|
||||
static void verify2(Callback<T(T,T)> func) {
|
||||
T result = func(0x01, 0x02);
|
||||
TEST_ASSERT_EQUAL(result, 0x03);
|
||||
}
|
||||
|
||||
template <typename O, typename M>
|
||||
static void verify2(O *obj, M method) {
|
||||
Callback<T(T,T)> func(obj, method);
|
||||
T result = func(0x01, 0x02);
|
||||
TEST_ASSERT_EQUAL(result, 0x83);
|
||||
}
|
||||
|
||||
static void verify1(Callback<T(T)> func) {
|
||||
T result = func(0x01);
|
||||
TEST_ASSERT_EQUAL(result, 0x01);
|
||||
}
|
||||
|
||||
template <typename O, typename M>
|
||||
static void verify1(O *obj, M method) {
|
||||
Callback<T(T)> func(obj, method);
|
||||
T result = func(0x01);
|
||||
TEST_ASSERT_EQUAL(result, 0x81);
|
||||
}
|
||||
|
||||
static void verify0(Callback<T()> func) {
|
||||
T result = func();
|
||||
TEST_ASSERT_EQUAL(result, 0x00);
|
||||
}
|
||||
|
||||
template <typename O, typename M>
|
||||
static void verify0(O *obj, M method) {
|
||||
Callback<T()> func(obj, method);
|
||||
T result = func();
|
||||
TEST_ASSERT_EQUAL(result, 0x80);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// test dispatch
|
||||
template <typename T>
|
||||
void test_dispatch5() {
|
||||
Thing<T> thing;
|
||||
Verifier<T>::verify5(static_func5<T>);
|
||||
Verifier<T>::verify5(&thing, &Thing<T>::member_func5);
|
||||
Verifier<T>::verify5(&thing, &bound_func5<T>);
|
||||
|
||||
Callback<T(T,T,T,T,T)> callback(static_func5);
|
||||
Verifier<T>::verify5(callback);
|
||||
callback.attach(&thing, &bound_func5<T>);
|
||||
Verifier<T>::verify5(&callback, &Callback<T(T,T,T,T,T)>::call);
|
||||
Verifier<T>::verify5((void*)&callback, &Callback<T(T,T,T,T,T)>::thunk);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_dispatch4() {
|
||||
Thing<T> thing;
|
||||
Verifier<T>::verify4(static_func4<T>);
|
||||
Verifier<T>::verify4(&thing, &Thing<T>::member_func4);
|
||||
Verifier<T>::verify4(&thing, &bound_func4<T>);
|
||||
|
||||
Callback<T(T,T,T,T)> callback(static_func4);
|
||||
Verifier<T>::verify4(callback);
|
||||
callback.attach(&thing, &bound_func4<T>);
|
||||
Verifier<T>::verify4(&callback, &Callback<T(T,T,T,T)>::call);
|
||||
Verifier<T>::verify4((void*)&callback, &Callback<T(T,T,T,T)>::thunk);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_dispatch3() {
|
||||
Thing<T> thing;
|
||||
Verifier<T>::verify3(static_func3<T>);
|
||||
Verifier<T>::verify3(&thing, &Thing<T>::member_func3);
|
||||
Verifier<T>::verify3(&thing, &bound_func3<T>);
|
||||
|
||||
Callback<T(T,T,T)> callback(static_func3);
|
||||
Verifier<T>::verify3(callback);
|
||||
callback.attach(&thing, &bound_func3<T>);
|
||||
Verifier<T>::verify3(&callback, &Callback<T(T,T,T)>::call);
|
||||
Verifier<T>::verify3((void*)&callback, &Callback<T(T,T,T)>::thunk);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_dispatch2() {
|
||||
Thing<T> thing;
|
||||
Verifier<T>::verify2(static_func2<T>);
|
||||
Verifier<T>::verify2(&thing, &Thing<T>::member_func2);
|
||||
Verifier<T>::verify2(&thing, &bound_func2<T>);
|
||||
|
||||
Callback<T(T,T)> callback(static_func2);
|
||||
Verifier<T>::verify2(callback);
|
||||
callback.attach(&thing, &bound_func2<T>);
|
||||
Verifier<T>::verify2(&callback, &Callback<T(T,T)>::call);
|
||||
Verifier<T>::verify2((void*)&callback, &Callback<T(T,T)>::thunk);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_dispatch1() {
|
||||
Thing<T> thing;
|
||||
Verifier<T>::verify1(static_func1<T>);
|
||||
Verifier<T>::verify1(&thing, &Thing<T>::member_func1);
|
||||
Verifier<T>::verify1(&thing, &bound_func1<T>);
|
||||
|
||||
Callback<T(T)> callback(static_func1);
|
||||
Verifier<T>::verify1(callback);
|
||||
callback.attach(&thing, &bound_func1<T>);
|
||||
Verifier<T>::verify1(&callback, &Callback<T(T)>::call);
|
||||
Verifier<T>::verify1((void*)&callback, &Callback<T(T)>::thunk);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_dispatch0() {
|
||||
Thing<T> thing;
|
||||
Verifier<T>::verify0(static_func0<T>);
|
||||
Verifier<T>::verify0(&thing, &Thing<T>::member_func0);
|
||||
Verifier<T>::verify0(&thing, &bound_func0<T>);
|
||||
|
||||
Callback<T()> callback(static_func0);
|
||||
Verifier<T>::verify0(callback);
|
||||
callback.attach(&thing, &bound_func0<T>);
|
||||
Verifier<T>::verify0(&callback, &Callback<T()>::call);
|
||||
Verifier<T>::verify0((void*)&callback, &Callback<T()>::thunk);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_fparg1() {
|
||||
Thing<T> thing;
|
||||
FunctionPointerArg1<T,T> fp(static_func1<T>);
|
||||
Verifier<T>::verify1(fp);
|
||||
Verifier<T>::verify1(fp.get_function());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_fparg0() {
|
||||
Thing<T> thing;
|
||||
FunctionPointerArg1<T,void> fp(static_func0<T>);
|
||||
Verifier<T>::verify0(fp);
|
||||
Verifier<T>::verify0(fp.get_function());
|
||||
}
|
||||
|
||||
|
||||
// Test setup
|
||||
status_t test_setup(const size_t number_of_cases) {
|
||||
GREENTEA_SETUP(40, "default_auto");
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("Testing callbacks with 5 ints", test_dispatch5<int>),
|
||||
Case("Testing callbacks with 4 ints", test_dispatch4<int>),
|
||||
Case("Testing callbacks with 3 ints", test_dispatch3<int>),
|
||||
Case("Testing callbacks with 2 ints", test_dispatch2<int>),
|
||||
Case("Testing callbacks with 1 ints", test_dispatch1<int>),
|
||||
Case("Testing callbacks with 0 ints", test_dispatch0<int>),
|
||||
|
||||
Case("Testing callbacks with 5 uchars", test_dispatch5<unsigned char>),
|
||||
Case("Testing callbacks with 4 uchars", test_dispatch4<unsigned char>),
|
||||
Case("Testing callbacks with 3 uchars", test_dispatch3<unsigned char>),
|
||||
Case("Testing callbacks with 2 uchars", test_dispatch2<unsigned char>),
|
||||
Case("Testing callbacks with 1 uchars", test_dispatch1<unsigned char>),
|
||||
Case("Testing callbacks with 0 uchars", test_dispatch0<unsigned char>),
|
||||
|
||||
Case("Testing callbacks with 5 uint64s", test_dispatch5<uint64_t>),
|
||||
Case("Testing callbacks with 4 uint64s", test_dispatch4<uint64_t>),
|
||||
Case("Testing callbacks with 3 uint64s", test_dispatch3<uint64_t>),
|
||||
Case("Testing callbacks with 2 uint64s", test_dispatch2<uint64_t>),
|
||||
Case("Testing callbacks with 1 uint64s", test_dispatch1<uint64_t>),
|
||||
Case("Testing callbacks with 0 uint64s", test_dispatch0<uint64_t>),
|
||||
|
||||
Case("Testing FunctionPointerArg1 compatibility", test_fparg1<int>),
|
||||
Case("Testing FunctionPointer compatibility", test_fparg0<int>),
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
||||
int main() {
|
||||
return !Harness::run(specification);
|
||||
}
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "can_api.h"
|
||||
#include "can_helper.h"
|
||||
#include "FunctionPointer.h"
|
||||
#include "Callback.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -206,34 +206,28 @@ public:
|
|||
/** Attach a function to call whenever a CAN frame received interrupt is
|
||||
* generated.
|
||||
*
|
||||
* @param fptr A pointer to a void function, or 0 to set as none
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
* @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, CAN::TxIrq for transmitted or aborted, CAN::EwIrq for error warning, CAN::DoIrq for data overrun, CAN::WuIrq for wake-up, CAN::EpIrq for error passive, CAN::AlIrq for arbitration lost, CAN::BeIrq for bus error)
|
||||
*/
|
||||
void attach(void (*fptr)(void), IrqType type=RxIrq);
|
||||
void attach(Callback<void()> func, IrqType type=RxIrq);
|
||||
|
||||
/** Attach a member function to call whenever a CAN frame received interrupt
|
||||
* is generated.
|
||||
*
|
||||
* @param tptr pointer to the object to call the member function on
|
||||
* @param mptr pointer to the member function to be called
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error)
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
|
||||
if((mptr != NULL) && (tptr != NULL)) {
|
||||
_irq[type].attach(tptr, mptr);
|
||||
can_irq_set(&_can, (CanIrqType)type, 1);
|
||||
}
|
||||
else {
|
||||
can_irq_set(&_can, (CanIrqType)type, 0);
|
||||
}
|
||||
void attach(T* obj, void (T::*method)(void), IrqType type=RxIrq) {
|
||||
attach(Callback<void()>(obj, method), type);
|
||||
}
|
||||
|
||||
static void _irq_handler(uint32_t id, CanIrqType type);
|
||||
|
||||
protected:
|
||||
can_t _can;
|
||||
FunctionPointer _irq[9];
|
||||
can_t _can;
|
||||
Callback<void()> _irq[9];
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#ifndef MBED_CALLCHAIN_H
|
||||
#define MBED_CALLCHAIN_H
|
||||
|
||||
#include "FunctionPointer.h"
|
||||
#include "Callback.h"
|
||||
#include <string.h>
|
||||
|
||||
namespace mbed {
|
||||
|
@ -57,7 +57,7 @@ namespace mbed {
|
|||
* @endcode
|
||||
*/
|
||||
|
||||
typedef FunctionPointer* pFunctionPointer_t;
|
||||
typedef Callback<void()> *pFunctionPointer_t;
|
||||
|
||||
class CallChain {
|
||||
public:
|
||||
|
@ -70,34 +70,34 @@ public:
|
|||
|
||||
/** Add a function at the end of the chain
|
||||
*
|
||||
* @param function A pointer to a void function
|
||||
* @param func A pointer to a void function
|
||||
*
|
||||
* @returns
|
||||
* The function object created for 'function'
|
||||
* The function object created for 'func'
|
||||
*/
|
||||
pFunctionPointer_t add(void (*function)(void));
|
||||
pFunctionPointer_t add(Callback<void()> func);
|
||||
|
||||
/** Add a function at the end of the chain
|
||||
*
|
||||
* @param tptr pointer to the object to call the member function on
|
||||
* @param mptr pointer to the member function to be called
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
*
|
||||
* @returns
|
||||
* The function object created for 'tptr' and 'mptr'
|
||||
* The function object created for 'obj' and 'method'
|
||||
*/
|
||||
template<typename T>
|
||||
pFunctionPointer_t add(T *tptr, void (T::*mptr)(void)) {
|
||||
return common_add(new FunctionPointer(tptr, mptr));
|
||||
template<typename T, typename M>
|
||||
pFunctionPointer_t add(T *obj, M method) {
|
||||
return add(Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
/** Add a function at the beginning of the chain
|
||||
*
|
||||
* @param function A pointer to a void function
|
||||
* @param func A pointer to a void function
|
||||
*
|
||||
* @returns
|
||||
* The function object created for 'function'
|
||||
* The function object created for 'func'
|
||||
*/
|
||||
pFunctionPointer_t add_front(void (*function)(void));
|
||||
pFunctionPointer_t add_front(Callback<void()> func);
|
||||
|
||||
/** Add a function at the beginning of the chain
|
||||
*
|
||||
|
@ -107,9 +107,9 @@ public:
|
|||
* @returns
|
||||
* The function object created for 'tptr' and 'mptr'
|
||||
*/
|
||||
template<typename T>
|
||||
pFunctionPointer_t add_front(T *tptr, void (T::*mptr)(void)) {
|
||||
return common_add_front(new FunctionPointer(tptr, mptr));
|
||||
template<typename T, typename M>
|
||||
pFunctionPointer_t add_front(T *obj, M method) {
|
||||
return add_front(Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
/** Get the number of functions in the chain
|
||||
|
@ -162,8 +162,6 @@ public:
|
|||
|
||||
private:
|
||||
void _check_size();
|
||||
pFunctionPointer_t common_add(pFunctionPointer_t pf);
|
||||
pFunctionPointer_t common_add_front(pFunctionPointer_t pf);
|
||||
|
||||
pFunctionPointer_t* _chain;
|
||||
int _size;
|
||||
|
|
|
@ -0,0 +1,861 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2015 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_CALLBACK_H
|
||||
#define MBED_CALLBACK_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
||||
/** Callback class based on template specialization
|
||||
*/
|
||||
template <typename F>
|
||||
class Callback;
|
||||
|
||||
/** Templated function class
|
||||
*/
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
|
||||
class Callback<R(A0, A1, A2, A3, A4)> {
|
||||
public:
|
||||
/** Create a Callback with a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
Callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a static function and bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with another Callback
|
||||
* @param func Callback to attach
|
||||
*/
|
||||
Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Attach a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
void attach(R (*func)(A0, A1, A2, A3, A4)) {
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = func ? &Callback::_staticthunk : 0;
|
||||
}
|
||||
|
||||
/** Attach a static function with a bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template <typename T>
|
||||
void attach(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_boundthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_methodthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a Callback
|
||||
* @param func The Callback to attach
|
||||
*/
|
||||
void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
|
||||
_obj = func._obj;
|
||||
memcpy(&_func, &func._func, sizeof _func);
|
||||
_thunk = func._thunk;
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return _thunk(_obj, &_func, a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return call(a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
/** Test if function has been attached
|
||||
*/
|
||||
operator bool() const {
|
||||
return _thunk;
|
||||
}
|
||||
|
||||
/** Static thunk for passing as C-style function
|
||||
* @param func Callback to call passed as void pointer
|
||||
*/
|
||||
static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return static_cast<Callback<R(A0, A1, A2, A3, A4)>*>(func)
|
||||
->call(a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal thunks for various function types
|
||||
static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return (*reinterpret_cast<R (**)(A0, A1, A2, A3, A4)>(func))
|
||||
(a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3, A4)>(func))
|
||||
(static_cast<T*>(obj), a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
return (static_cast<T*>(obj)->*
|
||||
(*reinterpret_cast<R (T::**)(A0, A1, A2, A3, A4)>(func)))
|
||||
(a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
// Stored as pointer to function and pointer to optional object
|
||||
// Function pointer is stored as union of possible function types
|
||||
// to garuntee proper size and alignment
|
||||
struct _class;
|
||||
union {
|
||||
void (*_staticfunc)();
|
||||
void (*_boundfunc)(_class *);
|
||||
void (_class::*_methodfunc)();
|
||||
} _func;
|
||||
|
||||
void *_obj;
|
||||
|
||||
// Thunk registered on attach to dispatch calls
|
||||
R (*_thunk)(void*, void*, A0, A1, A2, A3, A4);
|
||||
};
|
||||
|
||||
/** Templated function class
|
||||
*/
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
class Callback<R(A0, A1, A2, A3)> {
|
||||
public:
|
||||
/** Create a Callback with a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
Callback(R (*func)(A0, A1, A2, A3) = 0) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a static function and bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (T::*func)(A0, A1, A2, A3)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with another Callback
|
||||
* @param func Callback to attach
|
||||
*/
|
||||
Callback(const Callback<R(A0, A1, A2, A3)> &func) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Attach a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
void attach(R (*func)(A0, A1, A2, A3)) {
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = func ? &Callback::_staticthunk : 0;
|
||||
}
|
||||
|
||||
/** Attach a static function with a bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template <typename T>
|
||||
void attach(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_boundthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *obj, R (T::*func)(A0, A1, A2, A3)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_methodthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a Callback
|
||||
* @param func The Callback to attach
|
||||
*/
|
||||
void attach(const Callback<R(A0, A1, A2, A3)> &func) {
|
||||
_obj = func._obj;
|
||||
memcpy(&_func, &func._func, sizeof _func);
|
||||
_thunk = func._thunk;
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R call(A0 a0, A1 a1, A2 a2, A3 a3) {
|
||||
return _thunk(_obj, &_func, a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R operator()(A0 a0, A1 a1, A2 a2, A3 a3) {
|
||||
return call(a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
/** Test if function has been attached
|
||||
*/
|
||||
operator bool() const {
|
||||
return _thunk;
|
||||
}
|
||||
|
||||
/** Static thunk for passing as C-style function
|
||||
* @param func Callback to call passed as void pointer
|
||||
*/
|
||||
static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
|
||||
return static_cast<Callback<R(A0, A1, A2, A3)>*>(func)
|
||||
->call(a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal thunks for various function types
|
||||
static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
|
||||
return (*reinterpret_cast<R (**)(A0, A1, A2, A3)>(func))
|
||||
(a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
|
||||
return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3)>(func))
|
||||
(static_cast<T*>(obj), a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
|
||||
return (static_cast<T*>(obj)->*
|
||||
(*reinterpret_cast<R (T::**)(A0, A1, A2, A3)>(func)))
|
||||
(a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
// Stored as pointer to function and pointer to optional object
|
||||
// Function pointer is stored as union of possible function types
|
||||
// to garuntee proper size and alignment
|
||||
struct _class;
|
||||
union {
|
||||
void (*_staticfunc)();
|
||||
void (*_boundfunc)(_class *);
|
||||
void (_class::*_methodfunc)();
|
||||
} _func;
|
||||
|
||||
void *_obj;
|
||||
|
||||
// Thunk registered on attach to dispatch calls
|
||||
R (*_thunk)(void*, void*, A0, A1, A2, A3);
|
||||
};
|
||||
|
||||
/** Templated function class
|
||||
*/
|
||||
template <typename R, typename A0, typename A1, typename A2>
|
||||
class Callback<R(A0, A1, A2)> {
|
||||
public:
|
||||
/** Create a Callback with a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
Callback(R (*func)(A0, A1, A2) = 0) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a static function and bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (*func)(T*, A0, A1, A2)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (T::*func)(A0, A1, A2)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with another Callback
|
||||
* @param func Callback to attach
|
||||
*/
|
||||
Callback(const Callback<R(A0, A1, A2)> &func) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Attach a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
void attach(R (*func)(A0, A1, A2)) {
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = func ? &Callback::_staticthunk : 0;
|
||||
}
|
||||
|
||||
/** Attach a static function with a bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template <typename T>
|
||||
void attach(T *obj, R (*func)(T*, A0, A1, A2)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_boundthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *obj, R (T::*func)(A0, A1, A2)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_methodthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a Callback
|
||||
* @param func The Callback to attach
|
||||
*/
|
||||
void attach(const Callback<R(A0, A1, A2)> &func) {
|
||||
_obj = func._obj;
|
||||
memcpy(&_func, &func._func, sizeof _func);
|
||||
_thunk = func._thunk;
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R call(A0 a0, A1 a1, A2 a2) {
|
||||
return _thunk(_obj, &_func, a0, a1, a2);
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R operator()(A0 a0, A1 a1, A2 a2) {
|
||||
return call(a0, a1, a2);
|
||||
}
|
||||
|
||||
/** Test if function has been attached
|
||||
*/
|
||||
operator bool() const {
|
||||
return _thunk;
|
||||
}
|
||||
|
||||
/** Static thunk for passing as C-style function
|
||||
* @param func Callback to call passed as void pointer
|
||||
*/
|
||||
static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
|
||||
return static_cast<Callback<R(A0, A1, A2)>*>(func)
|
||||
->call(a0, a1, a2);
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal thunks for various function types
|
||||
static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2) {
|
||||
return (*reinterpret_cast<R (**)(A0, A1, A2)>(func))
|
||||
(a0, a1, a2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) {
|
||||
return (*reinterpret_cast<R (**)(T*, A0, A1, A2)>(func))
|
||||
(static_cast<T*>(obj), a0, a1, a2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) {
|
||||
return (static_cast<T*>(obj)->*
|
||||
(*reinterpret_cast<R (T::**)(A0, A1, A2)>(func)))
|
||||
(a0, a1, a2);
|
||||
}
|
||||
|
||||
// Stored as pointer to function and pointer to optional object
|
||||
// Function pointer is stored as union of possible function types
|
||||
// to garuntee proper size and alignment
|
||||
struct _class;
|
||||
union {
|
||||
void (*_staticfunc)();
|
||||
void (*_boundfunc)(_class *);
|
||||
void (_class::*_methodfunc)();
|
||||
} _func;
|
||||
|
||||
void *_obj;
|
||||
|
||||
// Thunk registered on attach to dispatch calls
|
||||
R (*_thunk)(void*, void*, A0, A1, A2);
|
||||
};
|
||||
|
||||
/** Templated function class
|
||||
*/
|
||||
template <typename R, typename A0, typename A1>
|
||||
class Callback<R(A0, A1)> {
|
||||
public:
|
||||
/** Create a Callback with a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
Callback(R (*func)(A0, A1) = 0) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a static function and bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (*func)(T*, A0, A1)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (T::*func)(A0, A1)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with another Callback
|
||||
* @param func Callback to attach
|
||||
*/
|
||||
Callback(const Callback<R(A0, A1)> &func) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Attach a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
void attach(R (*func)(A0, A1)) {
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = func ? &Callback::_staticthunk : 0;
|
||||
}
|
||||
|
||||
/** Attach a static function with a bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template <typename T>
|
||||
void attach(T *obj, R (*func)(T*, A0, A1)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_boundthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *obj, R (T::*func)(A0, A1)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_methodthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a Callback
|
||||
* @param func The Callback to attach
|
||||
*/
|
||||
void attach(const Callback<R(A0, A1)> &func) {
|
||||
_obj = func._obj;
|
||||
memcpy(&_func, &func._func, sizeof _func);
|
||||
_thunk = func._thunk;
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R call(A0 a0, A1 a1) {
|
||||
return _thunk(_obj, &_func, a0, a1);
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R operator()(A0 a0, A1 a1) {
|
||||
return call(a0, a1);
|
||||
}
|
||||
|
||||
/** Test if function has been attached
|
||||
*/
|
||||
operator bool() const {
|
||||
return _thunk;
|
||||
}
|
||||
|
||||
/** Static thunk for passing as C-style function
|
||||
* @param func Callback to call passed as void pointer
|
||||
*/
|
||||
static R thunk(void *func, A0 a0, A1 a1) {
|
||||
return static_cast<Callback<R(A0, A1)>*>(func)
|
||||
->call(a0, a1);
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal thunks for various function types
|
||||
static R _staticthunk(void*, void *func, A0 a0, A1 a1) {
|
||||
return (*reinterpret_cast<R (**)(A0, A1)>(func))
|
||||
(a0, a1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _boundthunk(void *obj, void *func, A0 a0, A1 a1) {
|
||||
return (*reinterpret_cast<R (**)(T*, A0, A1)>(func))
|
||||
(static_cast<T*>(obj), a0, a1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _methodthunk(void *obj, void *func, A0 a0, A1 a1) {
|
||||
return (static_cast<T*>(obj)->*
|
||||
(*reinterpret_cast<R (T::**)(A0, A1)>(func)))
|
||||
(a0, a1);
|
||||
}
|
||||
|
||||
// Stored as pointer to function and pointer to optional object
|
||||
// Function pointer is stored as union of possible function types
|
||||
// to garuntee proper size and alignment
|
||||
struct _class;
|
||||
union {
|
||||
void (*_staticfunc)();
|
||||
void (*_boundfunc)(_class *);
|
||||
void (_class::*_methodfunc)();
|
||||
} _func;
|
||||
|
||||
void *_obj;
|
||||
|
||||
// Thunk registered on attach to dispatch calls
|
||||
R (*_thunk)(void*, void*, A0, A1);
|
||||
};
|
||||
|
||||
/** Templated function class
|
||||
*/
|
||||
template <typename R, typename A0>
|
||||
class Callback<R(A0)> {
|
||||
public:
|
||||
/** Create a Callback with a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
Callback(R (*func)(A0) = 0) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a static function and bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (*func)(T*, A0)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (T::*func)(A0)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with another Callback
|
||||
* @param func Callback to attach
|
||||
*/
|
||||
Callback(const Callback<R(A0)> &func) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Attach a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
void attach(R (*func)(A0)) {
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = func ? &Callback::_staticthunk : 0;
|
||||
}
|
||||
|
||||
/** Attach a static function with a bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template <typename T>
|
||||
void attach(T *obj, R (*func)(T*, A0)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_boundthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *obj, R (T::*func)(A0)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_methodthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a Callback
|
||||
* @param func The Callback to attach
|
||||
*/
|
||||
void attach(const Callback<R(A0)> &func) {
|
||||
_obj = func._obj;
|
||||
memcpy(&_func, &func._func, sizeof _func);
|
||||
_thunk = func._thunk;
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R call(A0 a0) {
|
||||
return _thunk(_obj, &_func, a0);
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R operator()(A0 a0) {
|
||||
return call(a0);
|
||||
}
|
||||
|
||||
/** Test if function has been attached
|
||||
*/
|
||||
operator bool() const {
|
||||
return _thunk;
|
||||
}
|
||||
|
||||
/** Static thunk for passing as C-style function
|
||||
* @param func Callback to call passed as void pointer
|
||||
*/
|
||||
static R thunk(void *func, A0 a0) {
|
||||
return static_cast<Callback<R(A0)>*>(func)
|
||||
->call(a0);
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal thunks for various function types
|
||||
static R _staticthunk(void*, void *func, A0 a0) {
|
||||
return (*reinterpret_cast<R (**)(A0)>(func))
|
||||
(a0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _boundthunk(void *obj, void *func, A0 a0) {
|
||||
return (*reinterpret_cast<R (**)(T*, A0)>(func))
|
||||
(static_cast<T*>(obj), a0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _methodthunk(void *obj, void *func, A0 a0) {
|
||||
return (static_cast<T*>(obj)->*
|
||||
(*reinterpret_cast<R (T::**)(A0)>(func)))
|
||||
(a0);
|
||||
}
|
||||
|
||||
// Stored as pointer to function and pointer to optional object
|
||||
// Function pointer is stored as union of possible function types
|
||||
// to garuntee proper size and alignment
|
||||
struct _class;
|
||||
union {
|
||||
void (*_staticfunc)();
|
||||
void (*_boundfunc)(_class *);
|
||||
void (_class::*_methodfunc)();
|
||||
} _func;
|
||||
|
||||
void *_obj;
|
||||
|
||||
// Thunk registered on attach to dispatch calls
|
||||
R (*_thunk)(void*, void*, A0);
|
||||
};
|
||||
|
||||
/** Templated function class
|
||||
*/
|
||||
template <typename R>
|
||||
class Callback<R()> {
|
||||
public:
|
||||
/** Create a Callback with a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
Callback(R (*func)() = 0) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a static function and bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (*func)(T*)) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
Callback(T *obj, R (T::*func)()) {
|
||||
attach(obj, func);
|
||||
}
|
||||
|
||||
/** Create a Callback with another Callback
|
||||
* @param func Callback to attach
|
||||
*/
|
||||
Callback(const Callback<R()> &func) {
|
||||
attach(func);
|
||||
}
|
||||
|
||||
/** Attach a static function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
void attach(R (*func)()) {
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = func ? &Callback::_staticthunk : 0;
|
||||
}
|
||||
|
||||
/** Attach a static function with a bound pointer
|
||||
* @param obj Pointer to object to bind to function
|
||||
* @param func Static function to attach
|
||||
*/
|
||||
template <typename T>
|
||||
void attach(T *obj, R (*func)(T*)) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_boundthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
* @param obj Pointer to object to invoke member function on
|
||||
* @param func Member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *obj, R (T::*func)()) {
|
||||
_obj = static_cast<void*>(obj);
|
||||
memcpy(&_func, &func, sizeof func);
|
||||
_thunk = &Callback::_methodthunk<T>;
|
||||
}
|
||||
|
||||
/** Attach a Callback
|
||||
* @param func The Callback to attach
|
||||
*/
|
||||
void attach(const Callback<R()> &func) {
|
||||
_obj = func._obj;
|
||||
memcpy(&_func, &func._func, sizeof _func);
|
||||
_thunk = func._thunk;
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R call() {
|
||||
return _thunk(_obj, &_func);
|
||||
}
|
||||
|
||||
/** Call the attached function
|
||||
*/
|
||||
R operator()() {
|
||||
return call();
|
||||
}
|
||||
|
||||
/** Test if function has been attached
|
||||
*/
|
||||
operator bool() const {
|
||||
return _thunk;
|
||||
}
|
||||
|
||||
/** Static thunk for passing as C-style function
|
||||
* @param func Callback to call passed as void pointer
|
||||
*/
|
||||
static R thunk(void *func) {
|
||||
return static_cast<Callback<R()>*>(func)
|
||||
->call();
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal thunks for various function types
|
||||
static R _staticthunk(void*, void *func) {
|
||||
return (*reinterpret_cast<R (**)()>(func))
|
||||
();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _boundthunk(void *obj, void *func) {
|
||||
return (*reinterpret_cast<R (**)(T*)>(func))
|
||||
(static_cast<T*>(obj));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static R _methodthunk(void *obj, void *func) {
|
||||
return (static_cast<T*>(obj)->*
|
||||
(*reinterpret_cast<R (T::**)()>(func)))
|
||||
();
|
||||
}
|
||||
|
||||
// Stored as pointer to function and pointer to optional object
|
||||
// Function pointer is stored as union of possible function types
|
||||
// to garuntee proper size and alignment
|
||||
struct _class;
|
||||
union {
|
||||
void (*_staticfunc)();
|
||||
void (*_boundfunc)(_class *);
|
||||
void (_class::*_methodfunc)();
|
||||
} _func;
|
||||
|
||||
void *_obj;
|
||||
|
||||
// Thunk registered on attach to dispatch calls
|
||||
R (*_thunk)(void*, void*);
|
||||
};
|
||||
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
|
@ -16,187 +16,49 @@
|
|||
#ifndef MBED_FUNCTIONPOINTER_H
|
||||
#define MBED_FUNCTIONPOINTER_H
|
||||
|
||||
#include "Callback.h"
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mbed {
|
||||
|
||||
/* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */
|
||||
|
||||
/** A class for storing and calling a pointer to a static or member function
|
||||
*/
|
||||
// Declarations for backwards compatibility
|
||||
// To be foward compatible, code should adopt the Callback class
|
||||
template <typename R, typename A1>
|
||||
class FunctionPointerArg1{
|
||||
class FunctionPointerArg1 : public Callback<R(A1)> {
|
||||
public:
|
||||
/** Create a FunctionPointer, attaching a static function
|
||||
*
|
||||
* @param function The static function to attach (default is none)
|
||||
*/
|
||||
FunctionPointerArg1(R (*function)(A1) = 0) {
|
||||
attach(function);
|
||||
}
|
||||
FunctionPointerArg1(R (*function)(A1) = 0)
|
||||
: Callback<R(A1)>(function) {}
|
||||
|
||||
/** Create a FunctionPointer, attaching a member function
|
||||
*
|
||||
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
|
||||
* @param function The address of the member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
FunctionPointerArg1(T *object, R (T::*member)(A1)) {
|
||||
attach(object, member);
|
||||
}
|
||||
FunctionPointerArg1(T *object, R (T::*member)(A1))
|
||||
: Callback<R(A1)>(object, member) {}
|
||||
|
||||
/** Attach a static function
|
||||
*
|
||||
* @param function The static function to attach (default is none)
|
||||
*/
|
||||
void attach(R (*function)(A1)) {
|
||||
_p.function = function;
|
||||
_membercaller = 0;
|
||||
R (*get_function())(A1) {
|
||||
return *reinterpret_cast<R (**)(A1)>(this);
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
*
|
||||
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
|
||||
* @param function The address of the member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *object, R (T::*member)(A1)) {
|
||||
_p.object = static_cast<void*>(object);
|
||||
*reinterpret_cast<R (T::**)(A1)>(_member) = member;
|
||||
_membercaller = &FunctionPointerArg1::membercaller<T>;
|
||||
}
|
||||
|
||||
/** Call the attached static or member function
|
||||
*/
|
||||
R call(A1 a) {
|
||||
if (_membercaller == 0 && _p.function) {
|
||||
return _p.function(a);
|
||||
} else if (_membercaller && _p.object) {
|
||||
return _membercaller(_p.object, _member, a);
|
||||
}
|
||||
return (R)0;
|
||||
}
|
||||
|
||||
/** Get registered static function
|
||||
*/
|
||||
R(*get_function(A1))() {
|
||||
return _membercaller ? (R(*)(A1))0 : (R(*)(A1))_p.function;
|
||||
}
|
||||
|
||||
#ifdef MBED_OPERATORS
|
||||
R operator ()(A1 a) {
|
||||
return call(a);
|
||||
}
|
||||
operator bool(void) const {
|
||||
return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
template<typename T>
|
||||
static R membercaller(void *object, uintptr_t *member, A1 a) {
|
||||
T* o = static_cast<T*>(object);
|
||||
R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member);
|
||||
return (o->**m)(a);
|
||||
}
|
||||
|
||||
union {
|
||||
R (*function)(A1); // static function pointer
|
||||
void *object; // object this pointer
|
||||
} _p;
|
||||
uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
|
||||
R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object
|
||||
};
|
||||
|
||||
/** A class for storing and calling a pointer to a static or member function (R ()(void))
|
||||
*/
|
||||
template <typename R>
|
||||
class FunctionPointerArg1<R, void>{
|
||||
class FunctionPointerArg1<R, void> : public Callback<R()> {
|
||||
public:
|
||||
/** Create a FunctionPointer, attaching a static function
|
||||
*
|
||||
* @param function The static function to attach (default is none)
|
||||
*/
|
||||
FunctionPointerArg1(R (*function)(void) = 0) {
|
||||
attach(function);
|
||||
}
|
||||
FunctionPointerArg1(R (*function)() = 0)
|
||||
: Callback<R()>(function) {}
|
||||
|
||||
/** Create a FunctionPointer, attaching a member function
|
||||
*
|
||||
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
|
||||
* @param function The address of the void member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
FunctionPointerArg1(T *object, R (T::*member)(void)) {
|
||||
attach(object, member);
|
||||
}
|
||||
FunctionPointerArg1(T *object, R (T::*member)())
|
||||
: Callback<R()>(object, member) {}
|
||||
|
||||
/** Attach a static function
|
||||
*
|
||||
* @param function The void static function to attach (default is none)
|
||||
*/
|
||||
void attach(R (*function)(void)) {
|
||||
_p.function = function;
|
||||
_membercaller = 0;
|
||||
R (*get_function())() {
|
||||
return *reinterpret_cast<R (**)()>(this);
|
||||
}
|
||||
|
||||
/** Attach a member function
|
||||
*
|
||||
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
|
||||
* @param function The address of the void member function to attach
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T *object, R (T::*member)(void)) {
|
||||
_p.object = static_cast<void*>(object);
|
||||
*reinterpret_cast<R (T::**)(void)>(_member) = member;
|
||||
_membercaller = &FunctionPointerArg1::membercaller<T>;
|
||||
}
|
||||
|
||||
/** Call the attached static or member function
|
||||
*/
|
||||
R call(){
|
||||
if (_membercaller == 0 && _p.function) {
|
||||
return _p.function();
|
||||
} else if (_membercaller && _p.object) {
|
||||
return _membercaller(_p.object, _member);
|
||||
}
|
||||
return (R)0;
|
||||
}
|
||||
|
||||
/** Get registered static function
|
||||
*/
|
||||
R(*get_function())() {
|
||||
return _membercaller ? (R(*)())0 : (R(*)())_p.function;
|
||||
}
|
||||
|
||||
#ifdef MBED_OPERATORS
|
||||
R operator ()(void) {
|
||||
return call();
|
||||
}
|
||||
operator bool(void) const {
|
||||
return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
static R membercaller(void *object, uintptr_t *member) {
|
||||
T* o = static_cast<T*>(object);
|
||||
R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member);
|
||||
return (o->**m)();
|
||||
}
|
||||
|
||||
union {
|
||||
R (*function)(void); // static function pointer
|
||||
void *object; // object this pointer
|
||||
} _p;
|
||||
uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
|
||||
R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object
|
||||
};
|
||||
|
||||
typedef FunctionPointerArg1<void, void> FunctionPointer;
|
||||
typedef FunctionPointerArg1<void, int> event_callback_t;
|
||||
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "gpio_api.h"
|
||||
#include "gpio_irq_api.h"
|
||||
#include "FunctionPointer.h"
|
||||
#include "Callback.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -70,36 +70,34 @@ public:
|
|||
|
||||
/** Attach a function to call when a rising edge occurs on the input
|
||||
*
|
||||
* @param fptr A pointer to a void function, or 0 to set as none
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
*/
|
||||
void rise(void (*fptr)(void));
|
||||
void rise(Callback<void()> func);
|
||||
|
||||
/** Attach a member function to call when a rising edge occurs on the input
|
||||
*
|
||||
* @param tptr pointer to the object to call the member function on
|
||||
* @param mptr pointer to the member function to be called
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
*/
|
||||
template<typename T>
|
||||
void rise(T* tptr, void (T::*mptr)(void)) {
|
||||
_rise.attach(tptr, mptr);
|
||||
gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
|
||||
template<typename T, typename M>
|
||||
void rise(T *obj, M method) {
|
||||
rise(Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
/** Attach a function to call when a falling edge occurs on the input
|
||||
*
|
||||
* @param fptr A pointer to a void function, or 0 to set as none
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
*/
|
||||
void fall(void (*fptr)(void));
|
||||
void fall(Callback<void()> func);
|
||||
|
||||
/** Attach a member function to call when a falling edge occurs on the input
|
||||
*
|
||||
* @param tptr pointer to the object to call the member function on
|
||||
* @param mptr pointer to the member function to be called
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
*/
|
||||
template<typename T>
|
||||
void fall(T* tptr, void (T::*mptr)(void)) {
|
||||
_fall.attach(tptr, mptr);
|
||||
gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
|
||||
template<typename T, typename M>
|
||||
void fall(T *obj, M method) {
|
||||
fall(Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
/** Set the input pin mode
|
||||
|
@ -124,8 +122,8 @@ protected:
|
|||
gpio_t gpio;
|
||||
gpio_irq_t gpio_irq;
|
||||
|
||||
FunctionPointer _rise;
|
||||
FunctionPointer _fall;
|
||||
Callback<void()> _rise;
|
||||
Callback<void()> _fall;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#if DEVICE_SERIAL
|
||||
|
||||
#include "Stream.h"
|
||||
#include "FunctionPointer.h"
|
||||
#include "Callback.h"
|
||||
#include "serial_api.h"
|
||||
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
|
@ -89,25 +89,20 @@ public:
|
|||
|
||||
/** Attach a function to call whenever a serial interrupt is generated
|
||||
*
|
||||
* @param fptr A pointer to a void function, or 0 to set as none
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
* @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
|
||||
*/
|
||||
void attach(void (*fptr)(void), IrqType type=RxIrq);
|
||||
void attach(Callback<void()> func, IrqType type=RxIrq);
|
||||
|
||||
/** Attach a member function to call whenever a serial interrupt is generated
|
||||
*
|
||||
* @param tptr pointer to the object to call the member function on
|
||||
* @param mptr pointer to the member function to be called
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
|
||||
if((mptr != NULL) && (tptr != NULL)) {
|
||||
_irq[type].attach(tptr, mptr);
|
||||
serial_irq_set(&_serial, (SerialIrq)type, 1);
|
||||
} else {
|
||||
serial_irq_set(&_serial, (SerialIrq)type, 0);
|
||||
}
|
||||
template<typename T, typename M>
|
||||
void attach(T *obj, M method, IrqType type=RxIrq) {
|
||||
attach(Callback<void()>(obj, method), type);
|
||||
}
|
||||
|
||||
/** Generate a break condition on the serial line
|
||||
|
@ -210,9 +205,9 @@ protected:
|
|||
DMAUsage _rx_usage;
|
||||
#endif
|
||||
|
||||
serial_t _serial;
|
||||
FunctionPointer _irq[2];
|
||||
int _baud;
|
||||
serial_t _serial;
|
||||
Callback<void()> _irq[2];
|
||||
int _baud;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#define MBED_TICKER_H
|
||||
|
||||
#include "TimerEvent.h"
|
||||
#include "FunctionPointer.h"
|
||||
#include "Callback.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -65,22 +65,22 @@ public:
|
|||
|
||||
/** Attach a function to be called by the Ticker, specifiying the interval in seconds
|
||||
*
|
||||
* @param fptr pointer to the function to be called
|
||||
* @param func pointer to the function to be called
|
||||
* @param t the time between calls in seconds
|
||||
*/
|
||||
void attach(void (*fptr)(void), float t) {
|
||||
attach_us(fptr, t * 1000000.0f);
|
||||
void attach(Callback<void()> func, float t) {
|
||||
attach_us(func, t * 1000000.0f);
|
||||
}
|
||||
|
||||
/** Attach a member function to be called by the Ticker, specifiying the interval in seconds
|
||||
*
|
||||
* @param tptr pointer to the object to call the member function on
|
||||
* @param mptr pointer to the member function to be called
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param t the time between calls in seconds
|
||||
*/
|
||||
template<typename T>
|
||||
void attach(T* tptr, void (T::*mptr)(void), float t) {
|
||||
attach_us(tptr, mptr, t * 1000000.0f);
|
||||
template<typename T, typename M>
|
||||
void attach(T *obj, M method, float t) {
|
||||
attach(Callback<void()>(obj, method), t);
|
||||
}
|
||||
|
||||
/** Attach a function to be called by the Ticker, specifiying the interval in micro-seconds
|
||||
|
@ -88,8 +88,8 @@ public:
|
|||
* @param fptr pointer to the function to be called
|
||||
* @param t the time between calls in micro-seconds
|
||||
*/
|
||||
void attach_us(void (*fptr)(void), timestamp_t t) {
|
||||
_function.attach(fptr);
|
||||
void attach_us(Callback<void()> func, timestamp_t t) {
|
||||
_function.attach(func);
|
||||
setup(t);
|
||||
}
|
||||
|
||||
|
@ -99,10 +99,9 @@ public:
|
|||
* @param mptr pointer to the member function to be called
|
||||
* @param t the time between calls in micro-seconds
|
||||
*/
|
||||
template<typename T>
|
||||
void attach_us(T* tptr, void (T::*mptr)(void), timestamp_t t) {
|
||||
_function.attach(tptr, mptr);
|
||||
setup(t);
|
||||
template<typename T, typename M>
|
||||
void attach_us(T *obj, M method, timestamp_t t) {
|
||||
attach_us(Callback<void()>(obj, method), t);
|
||||
}
|
||||
|
||||
virtual ~Ticker() {
|
||||
|
@ -118,8 +117,8 @@ protected:
|
|||
virtual void handler();
|
||||
|
||||
protected:
|
||||
timestamp_t _delay; /**< Time delay (in microseconds) for re-setting the multi-shot callback. */
|
||||
FunctionPointer _function; /**< Callback. */
|
||||
timestamp_t _delay; /**< Time delay (in microseconds) for re-setting the multi-shot callback. */
|
||||
Callback<void()> _function; /**< Callback. */
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
#include "sleep_api.h"
|
||||
#include "rtc_time.h"
|
||||
|
||||
// mbed Non-hardware components
|
||||
#include "Callback.h"
|
||||
#include "FunctionPointer.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -67,9 +67,9 @@ int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle
|
|||
return can_filter(&_can, id, mask, format, handle);
|
||||
}
|
||||
|
||||
void CAN::attach(void (*fptr)(void), IrqType type) {
|
||||
if (fptr) {
|
||||
_irq[(CanIrqType)type].attach(fptr);
|
||||
void CAN::attach(Callback<void()> func, IrqType type) {
|
||||
if (func) {
|
||||
_irq[(CanIrqType)type].attach(func);
|
||||
can_irq_set(&_can, (CanIrqType)type, 1);
|
||||
} else {
|
||||
can_irq_set(&_can, (CanIrqType)type, 0);
|
||||
|
|
|
@ -12,12 +12,19 @@ CallChain::~CallChain() {
|
|||
delete _chain;
|
||||
}
|
||||
|
||||
pFunctionPointer_t CallChain::add(void (*function)(void)) {
|
||||
return common_add(new FunctionPointer(function));
|
||||
pFunctionPointer_t CallChain::add(Callback<void()> func) {
|
||||
_check_size();
|
||||
_chain[_elements] = new Callback<void()>(func);
|
||||
_elements ++;
|
||||
return _chain[_elements];
|
||||
}
|
||||
|
||||
pFunctionPointer_t CallChain::add_front(void (*function)(void)) {
|
||||
return common_add_front(new FunctionPointer(function));
|
||||
pFunctionPointer_t CallChain::add_front(Callback<void()> func) {
|
||||
_check_size();
|
||||
memmove(_chain + 1, _chain, _elements * sizeof(pFunctionPointer_t));
|
||||
_chain[0] = new Callback<void()>(func);
|
||||
_elements ++;
|
||||
return _chain[0];
|
||||
}
|
||||
|
||||
int CallChain::size() const {
|
||||
|
@ -72,19 +79,4 @@ void CallChain::_check_size() {
|
|||
_chain = new_chain;
|
||||
}
|
||||
|
||||
pFunctionPointer_t CallChain::common_add(pFunctionPointer_t pf) {
|
||||
_check_size();
|
||||
_chain[_elements] = pf;
|
||||
_elements ++;
|
||||
return pf;
|
||||
}
|
||||
|
||||
pFunctionPointer_t CallChain::common_add_front(pFunctionPointer_t pf) {
|
||||
_check_size();
|
||||
memmove(_chain + 1, _chain, _elements * sizeof(pFunctionPointer_t));
|
||||
_chain[0] = pf;
|
||||
_elements ++;
|
||||
return pf;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -39,9 +39,9 @@ void InterruptIn::mode(PinMode pull) {
|
|||
gpio_mode(&gpio, pull);
|
||||
}
|
||||
|
||||
void InterruptIn::rise(void (*fptr)(void)) {
|
||||
if (fptr) {
|
||||
_rise.attach(fptr);
|
||||
void InterruptIn::rise(Callback<void()> func) {
|
||||
if (func) {
|
||||
_rise.attach(func);
|
||||
gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
|
||||
} else {
|
||||
_rise.attach(NULL);
|
||||
|
@ -49,9 +49,9 @@ void InterruptIn::rise(void (*fptr)(void)) {
|
|||
}
|
||||
}
|
||||
|
||||
void InterruptIn::fall(void (*fptr)(void)) {
|
||||
if (fptr) {
|
||||
_fall.attach(fptr);
|
||||
void InterruptIn::fall(Callback<void()> func) {
|
||||
if (func) {
|
||||
_fall.attach(func);
|
||||
gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
|
||||
} else {
|
||||
_fall.attach(NULL);
|
||||
|
|
|
@ -66,13 +66,6 @@ bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq)
|
|||
return false;
|
||||
if (!_chains[irq_pos]->remove(handler))
|
||||
return false;
|
||||
// If there's a single function left in the chain, swith the interrupt vector
|
||||
// to call that function directly. This way we save both time and space.
|
||||
if (_chains[irq_pos]->size() == 1 && NULL != _chains[irq_pos]->get(0)->get_function()) {
|
||||
NVIC_SetVector(irq, (uint32_t)_chains[irq_pos]->get(0)->get_function());
|
||||
delete _chains[irq_pos];
|
||||
_chains[irq_pos] = (CallChain*) NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,9 +48,9 @@ int SerialBase::writeable() {
|
|||
return serial_writable(&_serial);
|
||||
}
|
||||
|
||||
void SerialBase::attach(void (*fptr)(void), IrqType type) {
|
||||
if (fptr) {
|
||||
_irq[type].attach(fptr);
|
||||
void SerialBase::attach(Callback<void()> func, IrqType type) {
|
||||
if (func) {
|
||||
_irq[type].attach(func);
|
||||
serial_irq_set(&_serial, (SerialIrq)type, 1);
|
||||
} else {
|
||||
serial_irq_set(&_serial, (SerialIrq)type, 0);
|
||||
|
|
|
@ -148,7 +148,7 @@ int Socket::getsockopt(int level, int optname, void *optval, unsigned *optlen)
|
|||
|
||||
}
|
||||
|
||||
void Socket::attach(FunctionPointer callback)
|
||||
void Socket::attach(Callback<void()> callback)
|
||||
{
|
||||
_lock.lock();
|
||||
|
||||
|
|
|
@ -145,9 +145,9 @@ public:
|
|||
* The callback may be called in an interrupt context and should not
|
||||
* perform expensive operations such as recv/send calls.
|
||||
*
|
||||
* @param callback Function to call on state change
|
||||
* @param func Function to call on state change
|
||||
*/
|
||||
void attach(FunctionPointer callback);
|
||||
void attach(Callback<void()> func);
|
||||
|
||||
/** Register a callback on state change of the socket
|
||||
*
|
||||
|
@ -158,12 +158,12 @@ public:
|
|||
* The callback may be called in an interrupt context and should not
|
||||
* perform expensive operations such as recv/send calls.
|
||||
*
|
||||
* @param tptr Pointer to object to call method on
|
||||
* @param mptr Method to call on state change
|
||||
* @param obj Pointer to object to call method on
|
||||
* @param method Method to call on state change
|
||||
*/
|
||||
template <typename T, typename M>
|
||||
void attach(T *tptr, M mptr) {
|
||||
attach(FunctionPointer(tptr, mptr));
|
||||
void attach(T *obj, M method) {
|
||||
attach(Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -176,7 +176,7 @@ protected:
|
|||
NetworkStack *_iface;
|
||||
void *_socket;
|
||||
uint32_t _timeout;
|
||||
FunctionPointer _callback;
|
||||
Callback<void()> _callback;
|
||||
rtos::Mutex _lock;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue