etl::delegate_service
The following code can be found in
examples\FunctionInterruptSimulation-Delegates
This code demonstrates using the delegate service for five example ARM interrupts.
Timer1 interrupt is handled by an instance of class Timer. The member callback function is wrapped by the most
efficient version of etl::delegate in which all of the information it requires is known at compile time.
Timer2 interrupt is handled by a global function.
Timer3 has no entry in the callback service and will therefore trigger execution of the unhandled handler.
USART1 and USART2 interrupts are handled by instances of Uart.
There callbacks are defined withing the class and are initialised in the Uart constructor.
#include <iostream>
#include "etl/delegate.h"
#include "etl/delegate_service.h"
enum VectorId
{
TIM1_CC_IRQ_HANDLER = 42,
TIM2_IRQ_HANDLER = 43,
TIM3_IRQ_HANDLER = 44,
USART1_IRQ_HANDLER = 52,
USART2_IRQ_HANDLER = 53,
VECTOR_ID_END,
VECTOR_ID_OFFSET = TIM1_CC_IRQ_HANDLER,
VECTOR_ID_RANGE = VECTOR_ID_END - VECTOR_ID_OFFSET
};
using InterruptVectors = etl::delegate_service<VECTOR_ID_RANGE, VECTOR_ID_OFFSET>;
InterruptVectors& GetInterruptVectorsInstance()
{
static InterruptVectors interruptVectors;
return interruptVectors;
}
extern "C"
{
InterruptVectors& interruptVectors = GetInterruptVectorsInstance();
void TIM1_CC_IRQHandler()
{
interruptVectors.call<TIM1_CC_IRQ_HANDLER>();
}
void TIM2_IRQHandler()
{
interruptVectors.call<TIM2_IRQ_HANDLER>();
}
void TIM3_IRQHandler()
{
interruptVectors.call<TIM3_IRQ_HANDLER>();
}
void USART1_IRQHandler()
{
interruptVectors.call<USART1_IRQ_HANDLER>();
}
void USART2_IRQHandler()
{
interruptVectors.call<USART2_IRQ_HANDLER>();
}
}
class Timer
{
public:
void InterruptHandler(const size_t id)
{
std::cout << "Timer interrupt (member) : ID " << id << "\n";
}
};
void FreeTimerInterruptHandler(const size_t id)
{
std::cout << "Timer interrupt (free) : ID " << id << "\n";
}
class Uart
{
public:
Uart(int port_id, size_t interruptId)
: port_id(port_id)
, callback(etl::delegate<void(size_t)>::create<Uart, &Uart::InterruptHandler>(*this))
{
GetInterruptVectorsInstance().register_delegate(interruptId, callback);
}
void InterruptHandler(const size_t id)
{
std::cout << "UART" << port_id << " : ID " << id << "\n";
}
etl::delegate<void(size_t)> callback;
int port_id;
};
void UnhandledInterrupt(const size_t id)
{
std::cout << "Unhandled Interrupt : ID " << id << "\n";
}
Timer timer;
Uart uart1(0, USART1_IRQ_HANDLER);
Uart uart2(1, USART2_IRQ_HANDLER);
etl::delegate<void(size_t)> timer_member_callback =
etl::delegate<void(size_t)>::create<Timer, timer, &Timer::InterruptHandler>();
etl::delegate<void(size_t)> timer_free_callback =
etl::delegate<void(size_t)>::create<FreeTimerInterruptHandler>();
etl::delegate<void(size_t)> unhandled_callback =
etl::delegate<void(size_t)>::create<UnhandledInterrupt>();
int main()
{
InterruptVectors& interruptVectors = GetInterruptVectorsInstance();
interruptVectors.register_delegate<TIM1_CC_IRQ_HANDLER>(timer_member_callback);
interruptVectors.register_delegate<TIM2_IRQ_HANDLER>(timer_free_callback);
interruptVectors.register_unhandled_delegate(unhandled_callback);
TIM1_CC_IRQHandler();
TIM2_IRQHandler();
USART1_IRQHandler();
USART2_IRQHandler();
TIM3_IRQHandler();
return 0;
}
__________________________________________________________________________________________________
Output
Timer interrupt (member) : ID 42
Timer interrupt (free) : ID 43
UART0 : ID 52
UART1 : ID 53
Unhandled Interrupt : ID 44