1 // Copyright 2020 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include "FreeRTOS.h" 17 #include "pw_assert/assert.h" 18 #include "pw_thread/thread.h" 19 #include "pw_thread_freertos/config.h" 20 #include "pw_thread_freertos/context.h" 21 #include "task.h" 22 23 namespace pw::thread::freertos { 24 25 class Context; 26 27 // pw::thread::Options for FreeRTOS. 28 // 29 // Example usage: 30 // 31 // // Uses the default stack size and priority, but specifies a custom name. 32 // pw::Thread example_thread( 33 // pw::thread::freertos::Options() 34 // .set_name("example_thread"), 35 // example_thread_function); 36 // 37 // // Provides the name, priority, and pre-allocated context. 38 // pw::Thread static_example_thread( 39 // pw::thread::freertos::Options() 40 // .set_name("static_example_thread") 41 // .set_priority(kFooPriority) 42 // .set_static_context(static_example_thread_context), 43 // example_thread_function); 44 // 45 class Options : public thread::Options { 46 public: 47 constexpr Options() = default; 48 constexpr Options(const Options&) = default; 49 constexpr Options(Options&&) = default; 50 51 // Sets the name for the FreeRTOS task, note that this will be truncated 52 // based on configMAX_TASK_NAME_LEN. 53 // This is deep copied by FreeRTOS into the task's task control block (TCB). set_name(const char * name)54 constexpr Options& set_name(const char* name) { 55 name_ = name; 56 return *this; 57 } 58 59 // Sets the priority for the FreeRTOS task. This must be a value between 60 // 0 to PW_THREAD_FREERTOS_CONFIG_MAXIMUM_PRIORITY. Higher priority 61 // values have a higher priority. 62 // 63 // Note that the idle task priority, tskIDLE_PRIORITY, is fixed to 0. 64 // See the FreeRTOS documentation on the idle task for more details. 65 // 66 // Precondition: This must be <= PW_THREAD_FREERTOS_CONFIG_MAXIMUM_PRIORITY. set_priority(UBaseType_t priority)67 constexpr Options& set_priority(UBaseType_t priority) { 68 PW_DASSERT(priority <= config::kMaximumPriority); 69 priority_ = priority; 70 return *this; 71 } 72 73 #if PW_THREAD_FREERTOS_CONFIG_DYNAMIC_ALLOCATION_ENABLED 74 // Set the stack size of dynamic thread allocations. 75 // 76 // Precondition: size_words must be >= configMINIMAL_STACK_SIZE set_stack_size(size_t size_words)77 constexpr Options& set_stack_size(size_t size_words) { 78 PW_DASSERT(size_words >= config::kMinimumStackSizeWords); 79 stack_size_words_ = size_words; 80 return *this; 81 } 82 #endif // PW_THREAD_FREERTOS_CONFIG_DYNAMIC_ALLOCATION_ENABLED 83 84 // Set the pre-allocated context (all memory needed to run a thread), see the 85 // pw::thread::freertos::StaticContext for more detail. set_static_context(StaticContext & context)86 constexpr Options& set_static_context(StaticContext& context) { 87 context_ = &context; 88 return *this; 89 } 90 91 // Returns name of FreeRTOS task. 92 // 93 // Note that this thread name may not match the actual thread name. See the 94 // FreeRTOS documentation on how names must be <= configMAX_TASK_NAME_LEN in 95 // order to avoid truncation. name()96 const char* name() const { return name_; } 97 98 private: 99 friend Context; 100 // FreeRTOS requires a valid name when asserts are enabled, 101 // configMAX_TASK_NAME_LEN may be as small as one character. 102 static constexpr char kDefaultName[] = "pw::Thread"; 103 priority()104 UBaseType_t priority() const { return priority_; } 105 #if PW_THREAD_FREERTOS_CONFIG_DYNAMIC_ALLOCATION_ENABLED stack_size_words()106 size_t stack_size_words() const { return stack_size_words_; } 107 #endif // PW_THREAD_FREERTOS_CONFIG_DYNAMIC_ALLOCATION_ENABLED static_context()108 StaticContext* static_context() const { return context_; } 109 110 const char* name_ = kDefaultName; 111 UBaseType_t priority_ = config::kDefaultPriority; 112 #if PW_THREAD_FREERTOS_CONFIG_DYNAMIC_ALLOCATION_ENABLED 113 size_t stack_size_words_ = config::kDefaultStackSizeWords; 114 #endif // PW_THREAD_FREERTOS_CONFIG_DYNAMIC_ALLOCATION_ENABLED 115 StaticContext* context_ = nullptr; 116 }; 117 118 } // namespace pw::thread::freertos 119