#include #include #include "freertos/kernel.hpp" namespace { BaseType_t scheduler_state = taskSCHEDULER_NOT_STARTED; unsigned scheduler_depth; unsigned critical_depth; unsigned starts; unsigned resumes; unsigned yields; unsigned current_token; TickType_t ticks = 123U; uint32_t critical_path( uint32_t path ) { freertos::CriticalSection guard; assert( critical_depth == 1U ); if( path == 0U ) return 10U; if( path == 1U ) return 20U; return 30U; } uint32_t scheduler_path( uint32_t path ) { freertos::SchedulerSuspendGuard guard; assert( scheduler_depth == 1U ); assert( freertos::Scheduler::state() == freertos::SchedulerState::suspended ); if( path == 0U ) return 40U; if( path == 1U ) return 50U; return 60U; } } // namespace extern "C" void vTaskStartScheduler() { ++starts; scheduler_state = taskSCHEDULER_RUNNING; } extern "C" BaseType_t xTaskGetSchedulerState() { if( scheduler_depth != 0U ) return taskSCHEDULER_SUSPENDED; return scheduler_state; } extern "C" void vTaskSuspendAll() { ++scheduler_depth; } extern "C" BaseType_t xTaskResumeAll() { assert( scheduler_depth > 0U ); --scheduler_depth; ++resumes; return pdFALSE; } extern "C" TaskHandle_t xTaskGetCurrentTaskHandle() { return ¤t_token; } extern "C" TickType_t xTaskGetTickCount() { return ticks; } extern "C" void k09_mock_yield() { ++yields; } extern "C" void k09_mock_enter_critical() { ++critical_depth; } extern "C" void k09_mock_exit_critical() { assert( critical_depth > 0U ); --critical_depth; } static_assert( !std::is_default_constructible< freertos::Scheduler >::value ); static_assert( !std::is_copy_constructible< freertos::CriticalSection >::value ); static_assert( !std::is_move_constructible< freertos::CriticalSection >::value ); static_assert( !std::is_copy_constructible< freertos::SchedulerSuspendGuard >::value ); int main() { assert( freertos::Scheduler::state() == freertos::SchedulerState::not_started ); freertos::Scheduler::start(); assert( starts == 1U ); assert( freertos::Scheduler::state() == freertos::SchedulerState::running ); assert( freertos::this_task::current() == ¤t_token ); assert( freertos::this_task::tick_count() == 123U ); freertos::this_task::yield(); assert( yields == 1U ); for( uint32_t path = 0U; path < 3U; ++path ) { assert( critical_path( path ) == 10U + path * 10U ); assert( critical_depth == 0U ); assert( scheduler_path( path ) == 40U + path * 10U ); assert( scheduler_depth == 0U ); } assert( resumes == 3U ); { freertos::CriticalSection outer; assert( critical_depth == 1U ); { freertos::CriticalSection inner; assert( critical_depth == 2U ); } assert( critical_depth == 1U ); } assert( critical_depth == 0U ); { freertos::SchedulerSuspendGuard outer; assert( scheduler_depth == 1U ); { freertos::SchedulerSuspendGuard inner; assert( scheduler_depth == 2U ); } assert( scheduler_depth == 1U ); assert( freertos::Scheduler::state() == freertos::SchedulerState::suspended ); } assert( scheduler_depth == 0U ); assert( resumes == 5U ); }