#include #include #include #include #include "freertos/software_timer.hpp" struct FakeTimer { TickType_t period; bool auto_reload; bool active; void * context; TimerCallbackFunction_t callback; }; extern "C" TimerHandle_t xTimerCreateStatic( const char *, TickType_t period, BaseType_t auto_reload, void * context, TimerCallbackFunction_t callback, StaticTimer_t * storage ) { static_assert( sizeof( FakeTimer ) <= sizeof( StaticTimer_t ) ); return new ( storage->bytes ) FakeTimer{ period, auto_reload != pdFALSE, false, context, callback }; } extern "C" BaseType_t xTimerStart( TimerHandle_t timer, TickType_t ) { timer->active = true; return pdPASS; } extern "C" BaseType_t xTimerReset( TimerHandle_t timer, TickType_t ) { timer->active = true; return pdPASS; } extern "C" BaseType_t xTimerChangePeriod( TimerHandle_t timer, TickType_t period, TickType_t ) { timer->period = period; timer->active = true; return pdPASS; } extern "C" BaseType_t xTimerStop( TimerHandle_t timer, TickType_t ) { timer->active = false; return pdPASS; } extern "C" BaseType_t xTimerIsTimerActive( TimerHandle_t timer ) { return timer->active ? pdTRUE : pdFALSE; } extern "C" TickType_t xTimerGetPeriod( TimerHandle_t timer ) { return timer->period; } extern "C" void * pvTimerGetTimerID( TimerHandle_t timer ) { return timer->context; } static void fire( TimerHandle_t timer ) { assert( timer->active ); if( !timer->auto_reload ) { timer->active = false; } timer->callback( timer ); } struct Probe { std::uint32_t calls{}; TimerHandle_t seen{}; void on_timer( TimerHandle_t timer ) noexcept { ++calls; seen = timer; } }; int main() { StaticTimer_t one_storage{}; StaticTimer_t periodic_storage{}; Probe one_probe{}; Probe periodic_probe{}; freertos::OneShotTimer< Probe > one( one_storage, "one", 5U, one_probe ); freertos::PeriodicTimer< Probe > periodic( periodic_storage, "periodic", 2U, periodic_probe ); static_assert( !std::is_copy_constructible_v< decltype( one ) > ); static_assert( !std::is_move_constructible_v< decltype( periodic ) > ); assert( one.valid() && periodic.valid() ); assert( one.start() == freertos::TimerCommand::accepted ); assert( periodic.start() == freertos::TimerCommand::accepted ); assert( one_probe.calls == 0U && periodic_probe.calls == 0U ); fire( one.native_handle() ); fire( periodic.native_handle() ); assert( one_probe.calls == 1U && one_probe.seen == one.native_handle() ); assert( !one.active() && periodic.active() ); assert( one.reset() == freertos::TimerCommand::accepted ); assert( one.active() ); assert( periodic.change_period( 3U ) == freertos::TimerCommand::accepted ); assert( periodic.period() == 3U ); fire( periodic.native_handle() ); assert( periodic_probe.calls == 2U ); assert( periodic.stop() == freertos::TimerCommand::accepted ); assert( !periodic.active() ); }