diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cc678ea..5c8bb5bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,6 +129,7 @@ if(USE_RTOS) src/core/rtos/Queue.cpp src/core/rtos/Semaphore.cpp src/core/rtos/Threadx.cpp + src/core/rtos/Initializable.cpp src/core/rtos/tsio/ThreadUART.cpp ) endif() diff --git a/include/core/rtos/BytePool.hpp b/include/core/rtos/BytePool.hpp index 11a6b920..fe12a32d 100644 --- a/include/core/rtos/BytePool.hpp +++ b/include/core/rtos/BytePool.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace core::rtos { @@ -18,9 +19,13 @@ class BytePool : public BytePoolBase { * Construct a BytePool, including creating a buffer to hold the * information for the pool and the buffer for the pool itself * - * @param[in] name String name of the BytePool + * @param[in] name String name of the BytePool, should be no longer than BYTEPOOL_NAME_MAX_LENGTH bytes. + * The name is copied into this object */ - BytePool(char* name) : name(name), buffer(), txBytePool() {} + explicit BytePool(char* name) : txBytePool(), buffer() { + strncpy(this->name, name, BYTEPOOL_NAME_MAX_LENGTH+1); + this->name[BYTEPOOL_NAME_MAX_LENGTH] = '\0'; + } /** * BytePool deconstructor @@ -73,14 +78,17 @@ class BytePool : public BytePoolBase { return static_cast(status); } - TXError getName(char** name) override { - *name = this->name; - return TXE_SUCCESS; + void getName(char* destination, size_t size) override { + if (size > BYTEPOOL_NAME_MAX_LENGTH+1) { + size = BYTEPOOL_NAME_MAX_LENGTH+1; + } + strncpy(destination, this->name, size); + destination[size-1] = 0; } private: /** The name of the Bytepool */ - char* name; + char name[BYTEPOOL_NAME_MAX_LENGTH] = {}; /** The struct that the threadx application uses to hold information about the bytepool */ TX_BYTE_POOL txBytePool; diff --git a/include/core/rtos/BytePoolBase.hpp b/include/core/rtos/BytePoolBase.hpp index dd9dff5f..2b129460 100644 --- a/include/core/rtos/BytePoolBase.hpp +++ b/include/core/rtos/BytePoolBase.hpp @@ -5,6 +5,11 @@ #include #include +#ifndef BYTEPOOL_NAME_MAX_LENGTH + #define BYTEPOOL_NAME_MAX_LENGTH 26 +#endif //BYTEPOOL_NAME_MAX_LENGTH + + namespace core::rtos { /** @@ -70,12 +75,14 @@ class BytePoolBase { virtual TXError getNumSuspendedThreads(uint32_t* numSuspendedThreads) = 0; /** - * Get the name of this BytePool + * Copy the name of this BytePool object into the character array pointed to by destination & + * insert a null-terminating character at the end of the given array for safety * - * @param[out] name The returned name - * @return The first error found by the function or TXE_SUCCESS if there was no error + * @param[out] destination Character array to copy the name into. + * Should be BYTEPOOL_NAME_MAX_LENGTH bytes long + * @param[in] size the size of the output array */ - virtual TXError getName(char** name) = 0; + virtual void getName(char* name, size_t size) = 0; }; } // namespace core::rtos diff --git a/include/core/rtos/EventFlags.hpp b/include/core/rtos/EventFlags.hpp index 130dab22..b68070a2 100644 --- a/include/core/rtos/EventFlags.hpp +++ b/include/core/rtos/EventFlags.hpp @@ -2,6 +2,7 @@ #define _EVT_RTOS_EVENTFLAGS_ #include +#include namespace core::rtos { @@ -18,9 +19,10 @@ class EventFlags : public Initializable { /** * Constructor for EventFlags. * - * @param[in] name the name of the EventFlags. + * @param[in] name the name of the EventFlags, should be no longer than INITIALIZABLE_NAME_MAX_LENGTH bytes. + * The name is copied into this object */ - EventFlags(char* name); + explicit EventFlags(char* name); /** * Destructor for EventFlags. @@ -73,14 +75,6 @@ class EventFlags : public Initializable { */ TXError registerNotifyFunction(void (*notifyFunction)(EventFlags* eventFlags)); - /** - * Get the name of this EventFlags - * - * @param[out] name The returned name - * @return The first error found by the function or TXE_SUCCESS if there was no error - */ - TXError getName(char** name); - /** * Get the current values that the flags are set to as a uint32_t * @@ -106,8 +100,6 @@ class EventFlags : public Initializable { TXError getNumSuspendedThreads(uint32_t* numSuspendedThreads); private: - /** The name of this object */ - char* name; /** The threadx struct that represents this object in the threadx kernel */ TX_EVENT_FLAGS_GROUP txEventFlagsGroup; diff --git a/include/core/rtos/Initializable.hpp b/include/core/rtos/Initializable.hpp index 41d0ea2b..ab2f8f37 100644 --- a/include/core/rtos/Initializable.hpp +++ b/include/core/rtos/Initializable.hpp @@ -5,6 +5,10 @@ #include #include +#ifndef INITIALIZABLE_NAME_MAX_LENGTH + #define INITIALIZABLE_NAME_MAX_LENGTH 26 +#endif //INITIALIZABLE_NAME_MAX_LENGTH + namespace core::rtos { /** @@ -20,6 +24,32 @@ class Initializable { * @return The first error found by the function or TXE_SUCCESS if there was no error */ virtual TXError init(BytePoolBase& pool) = 0; + + /** + * Copy the name of this Initializable object into the character array pointed to by destination & + * insert a null-terminating character at the end of the given array for safety + * + * @param[out] destination Character array to copy the name into. + * Should be INITIALIZABLE_NAME_MAX_LENGTH bytes long + * @param[in] size the size of the output array. Should be INITIALIZABLE_NAME_MAX_LENGTH bytes, unless you + * want the name to be truncated. If the given size is larger than INITIALIZABLE_NAME_MAX_LENGTH, it will be + * set to INITIALIZABLE_NAME_MAX_LENGTH + */ + void getName(char* destination, size_t size); + +protected: + + /** + * Initializable constructor + * @param[in] name pointer to the name of the Initializable. The first INITIALIZABLE_NAME_MAX_LENGTH bytes of the + * name will be copied into the local name array. + */ + explicit Initializable(char *name); + + /** + * The name of this initializable object + */ + char name[INITIALIZABLE_NAME_MAX_LENGTH]; }; } // namespace core::rtos diff --git a/include/core/rtos/Mutex.hpp b/include/core/rtos/Mutex.hpp index af2925b6..8e87bf17 100644 --- a/include/core/rtos/Mutex.hpp +++ b/include/core/rtos/Mutex.hpp @@ -18,7 +18,8 @@ class Mutex : public Initializable { * Construct a Mutex object, but do not initialize it (must call init or startKernel or another method that * registers the Mutex with the ThreadX kernel before using) * - * @param[in] name The name of the Mutex + * @param[in] name The name of the Mutex, should be no longer than INITIALIZABLE_NAME_MAX_LENGTH bytes. + * The name is copied into this object * @param[in] priorityInheritance Whether or not threads currently holding this mutex should raise their priority * to that of the highest priority thread waiting for the mutex */ @@ -56,16 +57,6 @@ class Mutex : public Initializable { */ TXError prioritize(); - // Getters - - /** - * Get the name of this Mutex - * - * @param[out] name The returned name - * @return The first error found by the function or TXE_SUCCESS if there was no error - */ - TXError getName(char** name); - /** * Get the ownership count of this mutex. The ownership count is how many times the current * owner of this mutex has locked this mutex. Each time the owner unlocks this mutex, the ownership @@ -101,9 +92,6 @@ class Mutex : public Initializable { TXError getNumSuspendedThreads(uint32_t* numSuspendedThreads); private: - /** Pointer to the name of the Mutex */ - char* name; - /** Threadx struct that actually holds all of the information for the Mutex */ TX_MUTEX txMutex; diff --git a/include/core/rtos/Queue.hpp b/include/core/rtos/Queue.hpp index 4dc41ada..578e5eaa 100644 --- a/include/core/rtos/Queue.hpp +++ b/include/core/rtos/Queue.hpp @@ -23,7 +23,8 @@ class Queue : public Initializable { * than the max value of a uint32_t (roughly 4.2 billion), the calculation will overflow and your queue will be * incorrectly sized. Take care to ensure this does not happen. * - * @param[in] name The name of the queue + * @param[in] name The name of the queue, should be no longer than INITIALIZABLE_NAME_MAX_LENGTH bytes. + * The name is copied into this object * @param[in] messageSize Size (in 4-byte words) of each message in the queue. The message size can be at most 16 * @param[in] numMessages Number of messages the queue can fit */ @@ -92,16 +93,6 @@ class Queue : public Initializable { */ TXError sendToFront(void* messagePointer, uint32_t waitOption); - // Getters - - /** - * Get the name of this Queue - * - * @param[out] name The returned name - * @return The first error found by the function or TXE_SUCCESS if there was no error - */ - TXError getName(char** name); - /** * Get the number of enqueued messages in this Queue * @@ -135,9 +126,6 @@ class Queue : public Initializable { TXError getNumSuspendedThreads(uint32_t* numSuspendedThreads); private: - /** The name of this object */ - char* name; - /** The threadx struct that represents this object in the threadx kernel */ TX_QUEUE txQueue; diff --git a/include/core/rtos/Semaphore.hpp b/include/core/rtos/Semaphore.hpp index f031bcc3..bc62e294 100644 --- a/include/core/rtos/Semaphore.hpp +++ b/include/core/rtos/Semaphore.hpp @@ -17,7 +17,8 @@ class Semaphore : public Initializable { /** * Construct a Semaphore object, but does not initialize it (must call init before using) * - * @param[in] name The name of the Semaphore + * @param[in] name The name of the Semaphore, should be no longer than INITIALIZABLE_NAME_MAX_LENGTH bytes. + * The name is copied into this object * @param[in] initialCount What number the Semaphore will start at */ Semaphore(char* name, uint32_t initialCount); @@ -70,14 +71,6 @@ class Semaphore : public Initializable { */ TXError prioritize(); - /** - * Get the name of this Semaphore - * - * @param[out] name The returned name - * @return The first error found by the function or TXE_SUCCESS if there was no error - */ - TXError getName(char** name); - /** * Get the current count of this Semaphore * @@ -103,9 +96,6 @@ class Semaphore : public Initializable { TXError getNumSuspendedThreads(uint32_t* numSuspendedThreads); private: - /** The name of the Semaphore */ - char* name; - /** Threadx struct that actually holds all of the information for the Semaphore */ TX_SEMAPHORE txSemaphore; diff --git a/include/core/rtos/Thread.hpp b/include/core/rtos/Thread.hpp index b4c92b54..2e6a031f 100644 --- a/include/core/rtos/Thread.hpp +++ b/include/core/rtos/Thread.hpp @@ -2,6 +2,7 @@ #define _EVT_RTOS_THREAD_ #include +#include #include namespace core::rtos { @@ -21,9 +22,10 @@ template::type> class Thread : public Initializable { public: /** - * Constructor for a Thread object. Thread will not start until init() method is called + * Constructor for a Thread object. Thread will not start until init() method is called. * - * @param[in] name Pointer to a null-terminated character string representing the name of the thread + * @param[in] name The name of the Thread, should be no longer than INITIALIZABLE_NAME_MAX_LENGTH bytes. + * The name is copied into this object * @param[in] entryFunction Pointer to the function the thread will be running * @param[in] data Pointer to the data the thread's function requires * @param[in] stackSize How much stack space (in bytes) this thread is allocated. @@ -41,7 +43,7 @@ class Thread : public Initializable { */ Thread(char* name, void (*entryFunction)(T), T data, std::size_t stackSize, uint32_t priority, uint32_t preemptThreshold, uint32_t timeSlice, bool autoStart) - : txThread(), name(name), entryFunction(entryFunction), data(data), stackSize(stackSize), + : Initializable(name), txThread(), entryFunction(entryFunction), data(data), stackSize(stackSize), initialPriority(priority), initialPreemptThreshold(preemptThreshold), initialTimeSlice(timeSlice), autoStart(autoStart) {} @@ -182,19 +184,6 @@ class Thread : public Initializable { return static_cast(errorCode); } - // Getters - - /** - * Get the name of this thread - * - * @param[out] name The returned name pointer - * @return The first error found by the function or TXE_SUCCESS if there was no error - */ - TXError getName(char* const* name) { - *name = this->name; - return TXE_SUCCESS; - } - /** * Get the state of this thread * @@ -256,9 +245,6 @@ class Thread : public Initializable { } private: - /** Pointer to the name of this thread */ - char* name; - /** Threadx struct that holds the information for the thread */ TX_THREAD txThread; diff --git a/include/core/rtos/Timer.hpp b/include/core/rtos/Timer.hpp index c80163a5..4a5e9280 100644 --- a/include/core/rtos/Timer.hpp +++ b/include/core/rtos/Timer.hpp @@ -2,6 +2,7 @@ #define _EVT_TIMER_HPP #include +#include namespace core::rtos { @@ -14,7 +15,7 @@ namespace core::rtos { * @tparam T what type of data the timer's expiration function will take. Should be at most 32 bits. (so generally * should be a pointer). */ -template +template::type> class Timer : public Initializable { public: /** @@ -22,7 +23,8 @@ class Timer : public Initializable { * * NOTE: T (the template parameter) should only be 32 bits. if it is any bigger things will break. * - * @param[in] name Name of this timer + * @param[in] name Name of this timer, should be no longer than INITIALIZABLE_NAME_MAX_LENGTH bytes. + * The name is copied into this object * @param[in] expirationFunction The function the timer will call when it expires * @param[in] expirationInput The input to the expiration function * @param[in] initialTicks How long (in ticks) this timer will wait after it is activated @@ -33,7 +35,7 @@ class Timer : public Initializable { */ Timer(char* name, void (*expirationFunction)(T), T expirationInput, uint32_t initialTicks, uint32_t rescheduleTicks, bool autoActivate) - : txTimer(), name(name), expirationFunction(expirationFunction), expirationInput(expirationInput), + : txTimer(), Initializable(name), expirationFunction(expirationFunction), expirationInput(expirationInput), initialTicks(initialTicks), rescheduleTicks(rescheduleTicks), autoActivate(autoActivate) {} /** @@ -84,8 +86,6 @@ class Timer : public Initializable { return static_cast(errorCode); } - // Getters - /** * Get the name of this timer * @@ -134,9 +134,6 @@ class Timer : public Initializable { /** The threadx struct that represents this object in the threadx kernel */ TX_TIMER txTimer; - /** the name of this object */ - char* name; - /** The expiration function registered to this timer */ void (*expirationFunction)(T); diff --git a/samples/rtos/threadx-demo/main.cpp b/samples/rtos/threadx-demo/main.cpp index f6906aee..0c111de5 100644 --- a/samples/rtos/threadx-demo/main.cpp +++ b/samples/rtos/threadx-demo/main.cpp @@ -52,11 +52,14 @@ typedef struct counters { */ typedef struct number_gen_thread_args { rtos::Queue* outputQueue; // The queue of numbers that the number gen thread add it's generated number to + rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or printing // to uart at the same time these shouldn't necessarily need to be mutually exclusive, // as they are generally thread-safe, but it also shows an example implementation of a // semaphore. + rtos::tsio::ThreadUART* threadUART; // The instance of ThreadUART that this thread will use to print. + counters_t* counters; // The struct of counters for the number gen thread to print out the counts of each thread } number_gen_thread_args_t; @@ -65,12 +68,17 @@ typedef struct number_gen_thread_args { */ typedef struct number_consumer_thread_args { rtos::Queue* inputQueue; // The queue that the threads will pull values that the number gen thread adds - rtos::Semaphore* - semaphore; // A semaphore that mutually excludes the threads from accessing the queue or printing to uart + + rtos::Semaphore* semaphore; // A semaphore that mutually excludes the threads from accessing the queue or + // printing to uart + rtos::tsio::ThreadUART* threadUART; // The instance of ThreadUART that this thread will use to print. + rtos::EventFlags* eventFlags; // the EventFlags that the number consumer threads will use to show they have gotten a // number, which will trigger the eventFlagThread to run it's own method. + uint8_t num; // What number this thread is + counters_t* counters; // the struct of counters for the number consumer threads to increase their counters when they // get a number } number_consumer_thread_args_t; @@ -105,7 +113,7 @@ int main() { number_gen_thread_args_t generatorThreadArgs = {&q1, &semaphore, &threadUART, &counters}; // create thread 0 - rtos::Thread generatorThread((char*) "Controller Thread", + rtos::Thread generatorThread((char*) "Generator Thread", generatorThreadEntry, &generatorThreadArgs, DEMO_STACK_SIZE, @@ -131,7 +139,15 @@ int main() { rtos::Thread eventFlagThread( (char*) "Thread 3", eventFlagThreadEntry, &thread_3_args, DEMO_STACK_SIZE, 1, 1, MS_TO_TICKS(50), true); - uart.printf("About to start the kernel.\n\r"); + + uart.printf("\n\rAbout to start the kernel.\n\r"); + + //Example implementation of getting an initializable object's name + char nameTest[INITIALIZABLE_NAME_MAX_LENGTH]; + generatorThread.getName(nameTest, INITIALIZABLE_NAME_MAX_LENGTH); + + uart.printf("(Making sure names work) The name of the UART Thread is: %s\n\r", nameTest); + /* * Most RTOS objects are initializable, which means we need to register them with the threadx kernel for them @@ -165,6 +181,11 @@ void generatorThreadEntry(number_gen_thread_args_t* args) { args->threadUART->printf("\n\rThread 0 Created\n\r"); + char nameTest[INITIALIZABLE_NAME_MAX_LENGTH]; + args->threadUART->getName(nameTest, INITIALIZABLE_NAME_MAX_LENGTH); + + args->threadUART->printf("(Making sure names work) The name of the UART Thread is: %s\n\r", nameTest); + // Test that the threadUART handles long messages correctly args->threadUART->printf( "\n\rThis is a very long message wow it is so long that's so crazy how long this is wowee\n\r"); @@ -235,7 +256,7 @@ void consumerThreadEntry(number_consumer_thread_args_t* args) { if (queue_status == rtos::TXE_SUCCESS) { if (received_message >= 20) { - flag_status = args->eventFlags->set(0x1, false); + flag_status = args->eventFlags->set(0b01); } args->counters->global_count++; diff --git a/src/core/rtos/EventFlags.cpp b/src/core/rtos/EventFlags.cpp index c7fd57f6..c28e0a51 100644 --- a/src/core/rtos/EventFlags.cpp +++ b/src/core/rtos/EventFlags.cpp @@ -2,7 +2,8 @@ namespace core::rtos { -EventFlags::EventFlags(char* name) : name(name), txEventFlagsGroup() {} +EventFlags::EventFlags(char* name) : Initializable(name), txEventFlagsGroup() { +} TXError EventFlags::init(core::rtos::BytePoolBase& pool) { return static_cast(tx_event_flags_create(&txEventFlagsGroup, name)); @@ -32,11 +33,6 @@ TXError EventFlags::registerNotifyFunction(void (*notifyFunction)(EventFlags*)) return TXE_FEATURE_NOT_ENABLED; } -TXError EventFlags::getName(char** name) { - *name = (this->name); - return TXE_SUCCESS; -} - TXError EventFlags::getCurrentFlags(uint32_t* flags) { uint32_t status = tx_event_flags_info_get(&txEventFlagsGroup, nullptr, flags, nullptr, nullptr, nullptr); return static_cast(status); diff --git a/src/core/rtos/Initializable.cpp b/src/core/rtos/Initializable.cpp new file mode 100644 index 00000000..5631bfa0 --- /dev/null +++ b/src/core/rtos/Initializable.cpp @@ -0,0 +1,18 @@ +#include + +namespace core::rtos { + +void Initializable::getName(char* destination, size_t size) { + if (size > INITIALIZABLE_NAME_MAX_LENGTH) { + size = INITIALIZABLE_NAME_MAX_LENGTH; + } + strncpy(destination, this->name, size); + destination[size-1] = '\0'; +} + +Initializable::Initializable(char* name) { + strncpy(this->name, name, INITIALIZABLE_NAME_MAX_LENGTH); + this->name[INITIALIZABLE_NAME_MAX_LENGTH-1] = '\0'; +} + +} //namespace core::rtos diff --git a/src/core/rtos/Mutex.cpp b/src/core/rtos/Mutex.cpp index 1534a045..e58d4fc9 100644 --- a/src/core/rtos/Mutex.cpp +++ b/src/core/rtos/Mutex.cpp @@ -2,7 +2,7 @@ namespace core::rtos { -Mutex::Mutex(char* name, bool priorityInheritance) : txMutex(), name(name), priorityInheritance(priorityInheritance) {} +Mutex::Mutex(char* name, bool priorityInheritance) : Initializable(name), txMutex(), priorityInheritance(priorityInheritance) {} TXError Mutex::init(BytePoolBase& pool) { return static_cast(tx_mutex_create(&txMutex, name, (UINT) priorityInheritance)); @@ -24,11 +24,6 @@ TXError Mutex::prioritize() { return static_cast(tx_mutex_prioritize(&txMutex)); } -TXError Mutex::getName(char** name) { - *name = this->name; - return TXE_SUCCESS; -} - TXError Mutex::getOwnershipCount(uint32_t* ownershipCount) { uint32_t status = tx_mutex_info_get(&txMutex, nullptr, ownershipCount, nullptr, nullptr, nullptr, nullptr); return static_cast(status); diff --git a/src/core/rtos/Queue.cpp b/src/core/rtos/Queue.cpp index a8b815da..88e74b29 100644 --- a/src/core/rtos/Queue.cpp +++ b/src/core/rtos/Queue.cpp @@ -4,7 +4,7 @@ namespace core::rtos { Queue::Queue(char* name, uint8_t messageSize, uint32_t numMessages) - : name(name), messageSize(messageSize), queueSize(messageSize * numMessages) {} + : Initializable(name), messageSize(messageSize), queueSize(messageSize * numMessages) {} Queue::~Queue() { tx_queue_delete(&txQueue); @@ -48,11 +48,6 @@ TXError Queue::sendToFront(void* messagePointer, uint32_t waitOption) { return static_cast(tx_queue_front_send(&txQueue, messagePointer, waitOption)); } -TXError Queue::getName(char** name) { - *name = this->name; - return TXE_SUCCESS; -} - TXError Queue::getNumEnqueuedMessages(uint32_t* numEnqueuedMessages) { uint32_t status = tx_queue_info_get(&txQueue, nullptr, numEnqueuedMessages, nullptr, nullptr, nullptr, nullptr); return static_cast(status); diff --git a/src/core/rtos/Semaphore.cpp b/src/core/rtos/Semaphore.cpp index 786e2044..0306d666 100644 --- a/src/core/rtos/Semaphore.cpp +++ b/src/core/rtos/Semaphore.cpp @@ -2,7 +2,7 @@ namespace core::rtos { -Semaphore::Semaphore(char* name, uint32_t initialCount) : name(name), txSemaphore(), initialCount(initialCount) {} +Semaphore::Semaphore(char* name, uint32_t initialCount) : Initializable(name), txSemaphore(), initialCount(initialCount) {} TXError Semaphore::init(BytePoolBase& pool) { return static_cast(tx_semaphore_create(&txSemaphore, name, initialCount)); @@ -33,11 +33,6 @@ TXError Semaphore::putWithCeiling(uint32_t ceiling) { return static_cast(tx_semaphore_ceiling_put(&txSemaphore, ceiling)); } -TXError Semaphore::getName(char** name) { - *name = this->name; - return TXE_SUCCESS; -} - TXError Semaphore::getCount(uint32_t* currentCount) { uint32_t status = tx_semaphore_info_get(&txSemaphore, nullptr, currentCount, nullptr, nullptr, nullptr); return static_cast(status); diff --git a/src/core/rtos/tsio/ThreadUART.cpp b/src/core/rtos/tsio/ThreadUART.cpp index 8c6c43e0..84de4a82 100644 --- a/src/core/rtos/tsio/ThreadUART.cpp +++ b/src/core/rtos/tsio/ThreadUART.cpp @@ -30,7 +30,7 @@ namespace { ThreadUART::ThreadUART(io::UART& uart, std::size_t threadStackSize, uint32_t threadPriorityLevel, uint32_t threadPreemptThreshold, uint32_t threadTimeSlice) - : UART(uart), copyUART(uart), + : Initializable((char*) "ThreadUART"), UART(uart), copyUART(uart), queue((char*) "ThreadUART Queue", THREADUART_QUEUE_MESSAGE_SIZE, THREADUART_QUEUE_NUM_MESSAGES), thread((char*) "ThreadUART Thread", uartThreadEntryFunction, this, threadStackSize, threadPriorityLevel, threadPreemptThreshold, threadTimeSlice, true),