Skip to content

Commit

Permalink
Implemented a safer names structure. The Initializable class now stor…
Browse files Browse the repository at this point in the history
…es the names and the getters for them. Names are stored in a fixed-size buffer for each class, and are copied out in the getter. This required changing all the classes which is why there appear to be so many changes. Also, initializable is still a virtual class but it's no longer an interface i.e. it does have a cpp.
  • Loading branch information
aclowmclaughlin committed Nov 23, 2024
1 parent 9b8081f commit ae2b6d4
Show file tree
Hide file tree
Showing 17 changed files with 126 additions and 119 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
20 changes: 14 additions & 6 deletions include/core/rtos/BytePool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <core/rtos/BytePoolBase.hpp>
#include <cstdint>
#include <cstring>

namespace core::rtos {

Expand All @@ -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
Expand Down Expand Up @@ -73,14 +78,17 @@ class BytePool : public BytePoolBase {
return static_cast<TXError>(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;
Expand Down
15 changes: 11 additions & 4 deletions include/core/rtos/BytePoolBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
#include <cstdint>
#include <tx_api.h>

#ifndef BYTEPOOL_NAME_MAX_LENGTH
#define BYTEPOOL_NAME_MAX_LENGTH 26
#endif //BYTEPOOL_NAME_MAX_LENGTH


namespace core::rtos {

/**
Expand Down Expand Up @@ -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
Expand Down
16 changes: 4 additions & 12 deletions include/core/rtos/EventFlags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _EVT_RTOS_EVENTFLAGS_

#include <core/rtos/Initializable.hpp>
#include <cstring>

namespace core::rtos {

Expand All @@ -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.
Expand Down Expand Up @@ -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
*
Expand All @@ -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;
Expand Down
30 changes: 30 additions & 0 deletions include/core/rtos/Initializable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <core/rtos/Enums.hpp>
#include <tx_api.h>

#ifndef INITIALIZABLE_NAME_MAX_LENGTH
#define INITIALIZABLE_NAME_MAX_LENGTH 26
#endif //INITIALIZABLE_NAME_MAX_LENGTH

namespace core::rtos {

/**
Expand All @@ -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
Expand Down
16 changes: 2 additions & 14 deletions include/core/rtos/Mutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down
16 changes: 2 additions & 14 deletions include/core/rtos/Queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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;

Expand Down
14 changes: 2 additions & 12 deletions include/core/rtos/Semaphore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
*
Expand All @@ -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;

Expand Down
24 changes: 5 additions & 19 deletions include/core/rtos/Thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _EVT_RTOS_THREAD_

#include <core/rtos/Initializable.hpp>
#include <type_traits>
#include <cstdint>

namespace core::rtos {
Expand All @@ -21,9 +22,10 @@ template<typename T, typename = typename std::enable_if<sizeof(T) <= 4>::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.
Expand All @@ -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) {}

Expand Down Expand Up @@ -182,19 +184,6 @@ class Thread : public Initializable {
return static_cast<TXError>(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
*
Expand Down Expand Up @@ -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;

Expand Down
13 changes: 5 additions & 8 deletions include/core/rtos/Timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _EVT_TIMER_HPP

#include <core/rtos/Initializable.hpp>
#include <type_traits>

namespace core::rtos {

Expand All @@ -14,15 +15,16 @@ 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<typename T>
template<typename T, typename = typename std::enable_if<sizeof(T) <= 4>::type>
class Timer : public Initializable {
public:
/**
* Construct a Timer object, but does not initialize it. Must call init before using \n\n
*
* 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
Expand All @@ -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) {}

/**
Expand Down Expand Up @@ -84,8 +86,6 @@ class Timer : public Initializable {
return static_cast<TXError>(errorCode);
}

// Getters

/**
* Get the name of this timer
*
Expand Down Expand Up @@ -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);

Expand Down
Loading

0 comments on commit ae2b6d4

Please sign in to comment.