Files
lab-rv32i-freertos-sw-timer/include/freertos/software_timer.hpp
T
2026-07-21 19:14:20 +02:00

118 lines
3.0 KiB
C++

#ifndef FREERTOS_SOFTWARE_TIMER_HPP
#define FREERTOS_SOFTWARE_TIMER_HPP
#include <type_traits>
extern "C"
{
#include "FreeRTOS.h"
#include "timers.h"
}
namespace freertos
{
enum class TimerPolicy
{
one_shot,
periodic
};
enum class TimerCommand
{
rejected = 0,
accepted = 1
};
template< typename Context, TimerPolicy Policy >
class SoftwareTimer final
{
public:
SoftwareTimer( StaticTimer_t & storage,
const char * name,
TickType_t period,
Context & context ) noexcept
: handle_( xTimerCreateStatic( name,
period,
Policy == TimerPolicy::periodic ? pdTRUE : pdFALSE,
&context,
&SoftwareTimer::trampoline,
&storage ) )
{
}
SoftwareTimer( const SoftwareTimer & ) = delete;
SoftwareTimer & operator=( const SoftwareTimer & ) = delete;
SoftwareTimer( SoftwareTimer && ) = delete;
SoftwareTimer & operator=( SoftwareTimer && ) = delete;
[[nodiscard]] bool valid() const noexcept
{
return handle_ != nullptr;
}
[[nodiscard]] TimerCommand start( TickType_t queue_wait = 0U ) noexcept
{
return command_result( xTimerStart( handle_, queue_wait ) );
}
[[nodiscard]] TimerCommand reset( TickType_t queue_wait = 0U ) noexcept
{
return command_result( xTimerReset( handle_, queue_wait ) );
}
[[nodiscard]] TimerCommand change_period( TickType_t period,
TickType_t queue_wait = 0U ) noexcept
{
return command_result( xTimerChangePeriod( handle_, period, queue_wait ) );
}
[[nodiscard]] TimerCommand stop( TickType_t queue_wait = 0U ) noexcept
{
return command_result( xTimerStop( handle_, queue_wait ) );
}
[[nodiscard]] bool active() const noexcept
{
return xTimerIsTimerActive( handle_ ) != pdFALSE;
}
[[nodiscard]] TickType_t period() const noexcept
{
return xTimerGetPeriod( handle_ );
}
[[nodiscard]] TimerHandle_t native_handle() const noexcept
{
return handle_;
}
private:
static TimerCommand command_result( BaseType_t result ) noexcept
{
return result == pdPASS ? TimerCommand::accepted : TimerCommand::rejected;
}
static void trampoline( TimerHandle_t timer ) noexcept
{
auto * const context = static_cast< Context * >( pvTimerGetTimerID( timer ) );
configASSERT( context != nullptr );
context->on_timer( timer );
}
TimerHandle_t handle_;
};
template< typename Context >
using OneShotTimer = SoftwareTimer< Context, TimerPolicy::one_shot >;
template< typename Context >
using PeriodicTimer = SoftwareTimer< Context, TimerPolicy::periodic >;
static_assert( !std::is_copy_constructible_v< OneShotTimer< int > > );
static_assert( !std::is_move_constructible_v< OneShotTimer< int > > );
} // namespace freertos
#endif