#include #include #include #include "freertos/task.hpp" namespace { size_t create_calls; TaskFunction_t captured_entry; void * captured_context; int fake_tcb; class ProbeTask final : public freertos::Task< ProbeTask > { friend class freertos::Task< ProbeTask >; public: explicit constexpr ProbeTask( const char * name ) noexcept : Task { name, 128U, 2U } { } private: void run() noexcept { } }; } // namespace extern "C" BaseType_t xTaskCreate( TaskFunction_t entry, const char * name, configSTACK_DEPTH_TYPE, void * context, UBaseType_t, TaskHandle_t * handle ) { ++create_calls; captured_entry = entry; captured_context = context; if( name[ 0 ] == 'f' && name[ 1 ] == 'a' && name[ 2 ] == 'i' && name[ 3 ] == 'l' && name[ 4 ] == '\0' ) { return pdFAIL; } *handle = &fake_tcb; return pdPASS; } extern "C" void vTaskDelete( TaskHandle_t ) { } static_assert( !std::is_copy_constructible< ProbeTask >::value ); static_assert( !std::is_move_constructible< ProbeTask >::value ); static_assert( !std::is_polymorphic< ProbeTask >::value ); int main() { ProbeTask task { "probe" }; assert( create_calls == 0U ); assert( task.state() == freertos::TaskState::constructed ); assert( task.native_handle() == nullptr ); assert( task.start() ); assert( create_calls == 1U ); assert( captured_entry != nullptr ); assert( captured_context == &task ); assert( task.native_handle() == &fake_tcb ); assert( task.state() == freertos::TaskState::ready ); assert( !task.start() ); assert( create_calls == 1U ); ProbeTask failed { "fail" }; assert( !failed.start() ); assert( failed.state() == freertos::TaskState::start_failed ); assert( failed.native_handle() == nullptr ); return 0; }