#ifndef FREERTOS_CPP_KERNEL_HPP #define FREERTOS_CPP_KERNEL_HPP #include #include extern "C" { #include "FreeRTOS.h" #include "task.h" } #if defined( __GNUC__ ) #define FREERTOS_CPP_ALWAYS_INLINE inline __attribute__( ( always_inline ) ) #else #define FREERTOS_CPP_ALWAYS_INLINE inline #endif namespace freertos { enum class SchedulerState : uint8_t { suspended, not_started, running }; class Scheduler final { public: Scheduler() = delete; static FREERTOS_CPP_ALWAYS_INLINE void start() noexcept { vTaskStartScheduler(); } static FREERTOS_CPP_ALWAYS_INLINE SchedulerState state() noexcept { const BaseType_t raw = xTaskGetSchedulerState(); if( raw == taskSCHEDULER_RUNNING ) { return SchedulerState::running; } if( raw == taskSCHEDULER_NOT_STARTED ) { return SchedulerState::not_started; } return SchedulerState::suspended; } static FREERTOS_CPP_ALWAYS_INLINE void suspend() noexcept { vTaskSuspendAll(); } [[nodiscard]] static FREERTOS_CPP_ALWAYS_INLINE bool resume() noexcept { return xTaskResumeAll() != pdFALSE; } }; namespace this_task { FREERTOS_CPP_ALWAYS_INLINE TaskHandle_t current() noexcept { return xTaskGetCurrentTaskHandle(); } FREERTOS_CPP_ALWAYS_INLINE TickType_t tick_count() noexcept { return xTaskGetTickCount(); } FREERTOS_CPP_ALWAYS_INLINE void yield() noexcept { taskYIELD(); } } // namespace this_task class CriticalSection final { public: FREERTOS_CPP_ALWAYS_INLINE CriticalSection() noexcept { taskENTER_CRITICAL(); } FREERTOS_CPP_ALWAYS_INLINE ~CriticalSection() noexcept { taskEXIT_CRITICAL(); } CriticalSection( const CriticalSection & ) = delete; CriticalSection & operator=( const CriticalSection & ) = delete; CriticalSection( CriticalSection && ) = delete; CriticalSection & operator=( CriticalSection && ) = delete; }; class SchedulerSuspendGuard final { public: FREERTOS_CPP_ALWAYS_INLINE SchedulerSuspendGuard() noexcept { Scheduler::suspend(); } FREERTOS_CPP_ALWAYS_INLINE ~SchedulerSuspendGuard() noexcept { ( void ) Scheduler::resume(); } SchedulerSuspendGuard( const SchedulerSuspendGuard & ) = delete; SchedulerSuspendGuard & operator=( const SchedulerSuspendGuard & ) = delete; SchedulerSuspendGuard( SchedulerSuspendGuard && ) = delete; SchedulerSuspendGuard & operator=( SchedulerSuspendGuard && ) = delete; }; static_assert( !std::is_default_constructible< Scheduler >::value ); static_assert( !std::is_copy_constructible< CriticalSection >::value ); static_assert( !std::is_move_constructible< CriticalSection >::value ); static_assert( !std::is_copy_constructible< SchedulerSuspendGuard >::value ); static_assert( !std::is_move_constructible< SchedulerSuspendGuard >::value ); } // namespace freertos #undef FREERTOS_CPP_ALWAYS_INLINE #endif