Files
2026-07-21 19:14:20 +02:00

121 lines
3.3 KiB
C++

#include <cassert>
#include <cstdint>
#include <new>
#include <type_traits>
#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() );
}