134 lines
3.3 KiB
C++
134 lines
3.3 KiB
C++
#include <cassert>
|
|
#include <type_traits>
|
|
|
|
#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 );
|
|
}
|