diff --git a/library.json b/library.json index 44bb3bbd..17e6bacb 100644 --- a/library.json +++ b/library.json @@ -16,7 +16,7 @@ "maintainer": true } ], - "version": "1.7.5", + "version": "1.7.6", "license": "MIT", "frameworks": "arduino", "platforms": "*" diff --git a/library.properties b/library.properties index f7e63914..06e09768 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=QuarkTS -version=1.7.5 +version=1.7.6 license=MIT author=J. Camilo Gomez C. maintainer=J. Camilo Gomez C. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ac716fd1..6df74fd3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required( VERSION 3.2 ) project( quarkts-cpp - VERSION 1.7.5 + VERSION 1.7.6 DESCRIPTION "An open-source OS for small embedded applications" LANGUAGES CXX ) diff --git a/src/QuarkTS.h b/src/QuarkTS.h index 77840f39..08e44cba 100644 --- a/src/QuarkTS.h +++ b/src/QuarkTS.h @@ -1,7 +1,7 @@ /*! * @file QuarkTS.h * @author J. Camilo Gomez C. - * @version 1.7.5 + * @version 1.7.6 * @note This file is part of the QuarkTS++ distribution. * @brief Global inclusion header **/ @@ -41,8 +41,8 @@ This file is part of the QuarkTS++ OS distribution. #ifndef QOS_CPP_H #define QOS_CPP_H -#define QUARKTS_CPP_VERSION "1.7.5" -#define QUARKTS_CPP_VERNUM ( 175u ) +#define QUARKTS_CPP_VERSION "1.7.6" +#define QUARKTS_CPP_VERNUM ( 176u ) #define QUARKTS_CPP_CAPTION "QuarkTS++ OS " QUARKTS_CPP_VERSION #include "config/config.h" @@ -66,7 +66,7 @@ This file is part of the QuarkTS++ OS distribution. namespace qOS { namespace build { - constexpr const uint32_t number = 4144; + constexpr const uint32_t number = 4149; constexpr const char* date = __DATE__; constexpr const char* time = __TIME__; constexpr const char* std = "c++11"; @@ -76,7 +76,7 @@ namespace qOS { constexpr const uint8_t number = QUARKTS_CPP_VERNUM; constexpr const uint8_t mayor = 1U; constexpr const uint8_t minor = 7U; - constexpr const uint8_t rev = 5U; + constexpr const uint8_t rev = 6U; } namespace product { constexpr const char* author = "J. Camilo Gomez C."; diff --git a/src/include/bytebuffer.hpp b/src/include/bytebuffer.hpp index 8f281155..605d178e 100644 --- a/src/include/bytebuffer.hpp +++ b/src/include/bytebuffer.hpp @@ -14,7 +14,7 @@ namespace qOS { /** * @brief A Byte-sized buffer object */ - class byteBuffer { + class byteBuffer : private nonCopyable { private: volatile byte_t *buffer{ nullptr }; volatile index_t tail{ 0U }; @@ -96,6 +96,20 @@ namespace qOS { * @return Number of elements in the byte-sized Buffer. */ size_t count( void ) const noexcept; + /** + * @brief Check if the byteBuffer instance has been initialized. + * @return @c true if instance has been initialized + */ + bool isInitialized( void ) const { + return ( nullptr != buffer ); + } + /** + * @brief Check if the byteBuffer instance has been initialized. + * @return @c true if instance has been initialized + */ + explicit operator bool() const noexcept { + return isInitialized(); + } }; /** @}*/ diff --git a/src/include/cli.hpp b/src/include/cli.hpp index 3e7f95ce..257ad295 100644 --- a/src/include/cli.hpp +++ b/src/include/cli.hpp @@ -299,7 +299,7 @@ namespace qOS { /** * @brief An AT-Command object */ - class command : protected node { + class command : protected node, private nonCopyable { private: commandCallback_t cmdCallback{ nullptr }; options_t cmdOpt{ 0U }; @@ -313,10 +313,21 @@ namespace qOS { /*! @cond */ virtual ~command() {} /*! @endcond */ + /** + * @brief Retrieve the command user-defined parameter. + * @return @c A generic pointer to the user-defined parameter + */ inline void* getParam( void ) noexcept { return param; } + /** + * @brief Check if the byteBuffer instance has been initialized. + * @return @c true if instance has been initialized + */ + explicit operator bool() const noexcept { + return ( nullptr != Text ) && ( nullptr != cmdCallback ); + } friend class qOS::commandLineInterface; }; /** @}*/ @@ -330,7 +341,7 @@ namespace qOS { * The instance should be initialized using the commandLineInterface::setup() * method. */ - class commandLineInterface : protected cli::input { + class commandLineInterface : protected cli::input, private nonCopyable { private: list subscribed; cli::commandHandler handler; @@ -462,6 +473,20 @@ namespace qOS { { handler.Data = pData; } + /** + * @brief Check if the CLI instance has been initialized. + * @return @c true if instance has been initialized + */ + bool isInitialized( void ) const { + return ( nullptr != cli::input::storage ); + } + /** + * @brief Check if the CLI instance has been initialized. + * @return @c true if instance has been initialized + */ + explicit operator bool() const noexcept { + return isInitialized(); + } friend class cli::commandHandler; friend class core; }; diff --git a/src/include/coroutine.hpp b/src/include/coroutine.hpp index 72bb861e..4e56d77c 100644 --- a/src/include/coroutine.hpp +++ b/src/include/coroutine.hpp @@ -77,6 +77,13 @@ namespace qOS { * @brief Try to execute co::setPosition() statement externally. */ void try_set( co::state p ) noexcept; + /** + * @brief Check if the Co-Routine handle is valid. + * @return @c true if handle is valid + */ + explicit operator bool() const noexcept { + return ( nullptr != ctx ); + } friend class co::coContext; }; diff --git a/src/include/fsm.hpp b/src/include/fsm.hpp index 317d8d52..3ef87d8d 100644 --- a/src/include/fsm.hpp +++ b/src/include/fsm.hpp @@ -355,7 +355,7 @@ namespace qOS { #endif /*! @cond */ - class stateHandler { + class stateHandler : private nonCopyable { protected: state *StartState{ nullptr }; state *NextState{ nullptr }; @@ -364,10 +364,8 @@ namespace qOS { historyMode TransitionHistory{ historyMode::NO_HISTORY }; status Status{ SUCCESS }; signalID Signal{ signalID::SIGNAL_NONE }; - stateHandler( stateHandler const& ) = delete; /* not copyable*/ - void operator=( stateHandler const& ) = delete; /* not assignable*/ - public: stateHandler() = default; + public: virtual ~stateHandler() {} void *SignalData{ nullptr }; /**< The data with which the signal is associated*/ void *Data{ nullptr }; /**< The user storage pointer. If the FSM its running as a task, this will point to the event_t structure*/ @@ -1032,6 +1030,20 @@ namespace qOS { * @c false. */ bool run( sm::signal_t sig ) noexcept; + /** + * @brief Check if the state machine instance has been initialized. + * @return @c true if instance has been initialized + */ + bool isInitialized( void ) const { + return ( nullptr != top.initState ); + } + /** + * @brief Check if the state machine instance has been initialized. + * @return @c true if instance has been initialized + */ + explicit operator bool() const noexcept { + return isInitialized(); + } friend class core; }; /** @}*/ diff --git a/src/include/input.hpp b/src/include/input.hpp index 926ce5a7..0fb60652 100644 --- a/src/include/input.hpp +++ b/src/include/input.hpp @@ -257,7 +257,7 @@ namespace qOS { * @param[in] inputChannel The specified channel(pin) number to read. * @param[in] invert To invert/negate the raw-reading. */ - digitalChannel( const uint8_t inputChannel, bool invert = false ) : channel( inputChannel ), negate( invert) {} + explicit digitalChannel( const uint8_t inputChannel, bool invert = false ) : channel( inputChannel ), negate( invert) {} /** * @brief Get the channel type. * @return The channel type. @@ -453,7 +453,7 @@ namespace qOS { /** * @brief The digital input-channel watcher class. */ - class watcher : protected node { + class watcher : protected node, private nonCopyable { private: eventCallback_t exception{ nullptr }; list digitalChannels; @@ -462,8 +462,6 @@ namespace qOS { qOS::duration_t debounceTime{ 100_ms }; digitalReaderFcn_t digitalReader{ nullptr }; analogReaderFcn_t analogReader{ nullptr }; - watcher( watcher const& ) = delete; - void operator=( watcher const& ) = delete; public: /*! @cond */ virtual ~watcher() {} @@ -473,7 +471,7 @@ namespace qOS { * @param[in] timeDebounce The specified time to bypass the * bounce of the digital input channels */ - watcher( const qOS::duration_t dt = 100_ms ) : debounceTime( dt ) {} + explicit watcher( const qOS::duration_t dt = 100_ms ) : debounceTime( dt ) {} /** * @brief Constructor for the input-watcher instance * @param[in] rDigital A pointer to a function that reads the specific diff --git a/src/include/kernel.hpp b/src/include/kernel.hpp index 5ff0e0d3..4a99de76 100644 --- a/src/include/kernel.hpp +++ b/src/include/kernel.hpp @@ -80,7 +80,7 @@ namespace qOS { * @brief The class to interface the OS * @note Use the predefined os instance */ - class core final : protected taskEvent { + class core final : protected taskEvent, private nonCopyable { private: task idle; taskFcn_t releaseSchedCallback{ nullptr }; @@ -452,6 +452,13 @@ namespace qOS { * @return Returns @c true if success, otherwise returns @c false. */ bool remove( input::watcher &w ) noexcept; + /** + * @brief Check if the OS instance has been initialized. + * @return @c true if OS instance has been initialized + */ + explicit operator bool() const noexcept { + return ( 0U == idle.entry ); + } }; /** @brief The predefined instance of the OS kernel interface */ extern core& os; // skipcq: CXX-W2011, CXX-W2009 diff --git a/src/include/list.hpp b/src/include/list.hpp index 5e62d605..cbb8c717 100644 --- a/src/include/list.hpp +++ b/src/include/list.hpp @@ -72,7 +72,7 @@ namespace qOS { * @brief Get a pointer to the list in which this node is contained. * @return A pointer to the list container. */ - inline list* getContainer( void ) noexcept + inline list* getContainer( void ) const noexcept { return container; } @@ -249,6 +249,13 @@ namespace qOS { * @return An iterator to the @a offset of the sequence container. */ listIterator from( void *offset ) noexcept; + /** + * @brief Check if the list has items (is non-empty). + * @return @c true if instance has items + */ + explicit operator bool() const noexcept { + return ( nullptr != head ); + } friend class listIterator; }; diff --git a/src/include/logger.hpp b/src/include/logger.hpp index e313859c..733a7b64 100644 --- a/src/include/logger.hpp +++ b/src/include/logger.hpp @@ -304,7 +304,7 @@ namespace qOS { extern const char * const wht; /*! @cond */ - class _logger final { + class _logger final : private nonCopyable { private: _logger() = default; _logger( _logger &other ) = delete; diff --git a/src/include/memory.hpp b/src/include/memory.hpp index 01b9dbf4..ceb1384d 100644 --- a/src/include/memory.hpp +++ b/src/include/memory.hpp @@ -107,6 +107,20 @@ namespace qOS { * @return The size of the unallocated heap. */ size_t getFreeSize( void ) const noexcept; + /** + * @brief Check if the memory pool instance has been initialized. + * @return @c true if instance has been initialized + */ + bool isInitialized( void ) const { + return ( nullptr != poolMemory ) && ( poolMemSize > 0U ); + } + /** + * @brief Check if the memory pool instance has been initialized. + * @return @c true if instance has been initialized + */ + explicit operator bool() const noexcept { + return isInitialized(); + } }; /** @}*/ diff --git a/src/include/prioqueue.hpp b/src/include/prioqueue.hpp index c99cbb2e..81f26fd4 100644 --- a/src/include/prioqueue.hpp +++ b/src/include/prioqueue.hpp @@ -15,7 +15,7 @@ namespace qOS { }; } - class prioQueue { + class prioQueue : private nonCopyable { private: volatile base_t index{ -1 }; void *data{ nullptr }; diff --git a/src/include/queue.hpp b/src/include/queue.hpp index ccedc619..65441426 100644 --- a/src/include/queue.hpp +++ b/src/include/queue.hpp @@ -41,7 +41,7 @@ namespace qOS { * writer and could be statically allocated at compile time or in run-time * using the memory management extension. */ - class queue { + class queue : private nonCopyable { private: uint8_t *head{ nullptr }; uint8_t *tail{ nullptr }; @@ -53,8 +53,6 @@ namespace qOS { void moveReader( void ) noexcept; void copyDataFromQueue( void * const dst ) noexcept; void copyDataToQueue( const void *itemToQueue, const queueSendMode xPosition ) noexcept; - queue( queue const& ) = delete; - void operator=( queue const& ) = delete; public: queue() = default; /*! @cond */ @@ -148,6 +146,13 @@ namespace qOS { */ bool isInitialized( void ) const noexcept; /** + * @brief Check if the queue is already initialized by using queue::setup() + * @return @c true if the queue is initialized, @c false if not. + */ + explicit operator bool() const noexcept { + return isInitialized(); + } + /** * @brief Get the size(in bytes) used for every item in the queue. * @return The item-size in bytes. */ diff --git a/src/include/response.hpp b/src/include/response.hpp index c61a79ca..ba5ce997 100644 --- a/src/include/response.hpp +++ b/src/include/response.hpp @@ -24,7 +24,7 @@ namespace qOS { /** * @brief A Response Handler object. */ - class response { + class response : private nonCopyable { private: char *pattern2Match{ nullptr }; timer timeout; @@ -32,8 +32,6 @@ namespace qOS { size_t patternLength{ 0U }; volatile size_t matchedCount{ 0U }; volatile bool responseReceived{ false }; - response( response const& ) = delete; - void operator=( response const& ) = delete; public: response() = default; /*! @cond */ @@ -75,6 +73,14 @@ namespace qOS { * @return @c true if the response object is initialized, @c false if not. */ bool isInitialized( void ) const noexcept; + /** + * @brief Check if the response object is already initialized by + * using response::setup() + * @return @c true if the response object is initialized, @c false if not. + */ + explicit operator bool() const noexcept { + return isInitialized(); + } }; /** @}*/ diff --git a/src/include/task.hpp b/src/include/task.hpp index bb973b3c..07f023dc 100644 --- a/src/include/task.hpp +++ b/src/include/task.hpp @@ -345,7 +345,7 @@ namespace qOS { * execution-state for that task, preventing the activation of other tasks. * @note Do not access any member of this structure directly. */ - class task : protected node { + class task : protected node, private nonCopyable { friend class core; private: void *taskData{ nullptr }; @@ -377,8 +377,6 @@ namespace qOS { static const uint32_t BIT_REMOVE_REQUEST; static const uint32_t EVENT_FLAGS_MASK; static const uint32_t QUEUE_FLAGS_MASK; - task( task const& ) = delete; - void operator=( task const& ) = delete; protected: virtual void activities( event_t e ); public: @@ -586,6 +584,13 @@ namespace qOS { * @return A @c void pointer to the attached object. */ queue* getQueue( void ) noexcept; + /** + * @brief Check if the task has been added to the OS scheduler. + * @return @c true if task is already added to the scheduler + */ + explicit operator bool() const noexcept { + return ( SIZE_MAX != entry ) && ( nullptr == getContainer() ); + } /** @brief A constant to indicate that the task will run every time * its timeout has expired. */ diff --git a/src/include/timer.hpp b/src/include/timer.hpp index ee55d31a..e4d0e97e 100644 --- a/src/include/timer.hpp +++ b/src/include/timer.hpp @@ -150,6 +150,14 @@ namespace qOS { * @param[in] en @c true for reload of @c false to disarm. */ void operator()( const bool en ); + /** + * @brief Non-Blocking timer check + * @return Returns @c true when timer expires, otherwise, returns @c false. + * @note A disarmed timer also returns @c false. + */ + explicit operator bool() const noexcept { + return expired(); + } /** @brief Constant that defines the status of an armed timer*/ static const bool ARMED; /** @brief Constant that defines the status of a disarmed timer*/ diff --git a/src/include/types.hpp b/src/include/types.hpp index 82a9f92e..c47f9e37 100644 --- a/src/include/types.hpp +++ b/src/include/types.hpp @@ -122,6 +122,16 @@ namespace qOS { #else using string = std::string; #endif + + class nonCopyable { + protected: + nonCopyable() {} + ~nonCopyable() {} + private: + nonCopyable( const nonCopyable & ); + nonCopyable& operator=( const nonCopyable & ); + }; + /*! @endcond */ /** diff --git a/src/kernel.cpp b/src/kernel.cpp index a3ea9def..af5156e2 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -253,6 +253,8 @@ bool core::checkIfReady( void ) noexcept critical::exit(); #endif xTask->setFlags( task::BIT_REMOVE_REQUEST, false ); + --core::taskEntries; + xTask->entry = SIZE_MAX; } else { list * const xList = ( trigger::None != xTask->Trigger ) ? &coreLists[ xTask->priority ] : &suspendedList;