Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"maintainer": true
}
],
"version": "1.7.6",
"version": "1.7.7",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*"
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=QuarkTS
version=1.7.6
version=1.7.7
license=MIT
author=J. Camilo Gomez C. <kmilo17pet@gmail.com>
maintainer=J. Camilo Gomez C. <kmilo17pet@gmail.com>
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required( VERSION 3.2 )
project( quarkts-cpp
VERSION 1.7.6
VERSION 1.7.7
DESCRIPTION "An open-source OS for small embedded applications"
LANGUAGES CXX )

Expand Down
10 changes: 5 additions & 5 deletions src/QuarkTS.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*!
* @file QuarkTS.h
* @author J. Camilo Gomez C.
* @version 1.7.6
* @version 1.7.7
* @note This file is part of the QuarkTS++ distribution.
* @brief Global inclusion header
**/
Expand Down Expand Up @@ -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.6"
#define QUARKTS_CPP_VERNUM ( 176u )
#define QUARKTS_CPP_VERSION "1.7.7"
#define QUARKTS_CPP_VERNUM ( 177u )
#define QUARKTS_CPP_CAPTION "QuarkTS++ OS " QUARKTS_CPP_VERSION

#include "config/config.h"
Expand All @@ -66,7 +66,7 @@ This file is part of the QuarkTS++ OS distribution.

namespace qOS {
namespace build {
constexpr const uint32_t number = 4149;
constexpr const uint32_t number = 4181;
constexpr const char* date = __DATE__;
constexpr const char* time = __TIME__;
constexpr const char* std = "c++11";
Expand All @@ -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 = 6U;
constexpr const uint8_t rev = 7U;
}
namespace product {
constexpr const char* author = "J. Camilo Gomez C.";
Expand Down
2 changes: 1 addition & 1 deletion src/include/cli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ namespace qOS {
volatile bool ready{ false };
void flush( void );
void operator=( input const& ) = delete;
input() {}
input() noexcept {}
};
/*! @endcond */

Expand Down
2 changes: 1 addition & 1 deletion src/include/clock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ namespace qOS {
/*! @cond */
static volatile qOS::clock_t sysTick_Epochs; // skipcq: CXX-W2009
static qOS::clock_t internalTick( void ) noexcept;
clock();
clock() = default;
/*! @endcond */
public:
clock( clock &other ) = delete;
Expand Down
8 changes: 4 additions & 4 deletions src/include/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace qOS {
public:
/*! @cond */
virtual ~channel() {}
channel( uint8_t channelNumber ) : number( channelNumber ) {}
channel( uint8_t channelNumber ) noexcept : number( channelNumber ) {}
/*! @endcond */

/**
Expand Down Expand Up @@ -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.
*/
explicit digitalChannel( const uint8_t inputChannel, bool invert = false ) : channel( inputChannel ), negate( invert) {}
explicit digitalChannel( const uint8_t inputChannel, bool invert = false ) noexcept : channel( inputChannel ), negate( invert) {}
/**
* @brief Get the channel type.
* @return The channel type.
Expand Down Expand Up @@ -373,7 +373,7 @@ namespace qOS {
* @param[in] upperThreshold The upper threshold value.
* @param[in] h Hysteresis for the in-band transition.
*/
analogChannel( const uint8_t inputChannel, const analogValue_t lowerThreshold, const analogValue_t upperThreshold, const analogValue_t h = 20 )
analogChannel( const uint8_t inputChannel, const analogValue_t lowerThreshold, const analogValue_t upperThreshold, const analogValue_t h = 20 ) noexcept
: channel( inputChannel ),
high( upperThreshold ),
low( lowerThreshold ),
Expand Down Expand Up @@ -453,7 +453,7 @@ namespace qOS {
/**
* @brief The digital input-channel watcher class.
*/
class watcher : protected node, private nonCopyable {
class watcher : private nonCopyable {
private:
eventCallback_t exception{ nullptr };
list digitalChannels;
Expand Down
41 changes: 22 additions & 19 deletions src/include/kernel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ namespace qOS {
list coreLists[ Q_PRIORITY_LEVELS + 2 ]; // skipcq: CXX-W2066
list& waitingList; // skipcq: CXX-W2012, CXX-W2010
list& suspendedList; // skipcq: CXX-W2012, CXX-W2010
list inputWatchers;
//list inputWatchers;
void(*cpuIdle)(void){ nullptr };
static const priority_t MAX_PRIORITY_VALUE;
static const uint32_t BIT_INIT;
static const uint32_t BIT_FCALL_IDLE;
Expand All @@ -104,8 +105,7 @@ namespace qOS {
void dispatchTaskFillEventInfo( task *Task ) noexcept;
void dispatch( list * const xList ) noexcept;
void dispatchIdle( void ) noexcept;
void handleInputWatchers( void ) noexcept;
core() : waitingList( coreLists[ Q_PRIORITY_LEVELS ] ), suspendedList( coreLists[ Q_PRIORITY_LEVELS + 1 ] ) {}
core() noexcept : waitingList( coreLists[ Q_PRIORITY_LEVELS ] ), suspendedList( coreLists[ Q_PRIORITY_LEVELS + 1 ] ) {}
core( core &other ) = delete;
void operator=( const core & ) = delete;
public:
Expand All @@ -131,6 +131,8 @@ namespace qOS {
* @param[in] callbackIdle Callback function to the Idle Task. To
* disable the Idle-Task activities, ignore this parameter of pass
* @c nullptr as argument.
* @param[in] coreIdleFcn The function that sets the CPU into
* low-power or idle state
* @return @c true on success. Otherwise return @c false.
*
* Example : When tick is already provided
Expand Down Expand Up @@ -165,7 +167,7 @@ namespace qOS {
* }
* @endcode
*/
bool init( const getTickFcn_t tFcn = nullptr, taskFcn_t callbackIdle = nullptr ) noexcept;
bool init( const getTickFcn_t tFcn = nullptr, taskFcn_t callbackIdle = nullptr, void(*coreIdleFcn)(void) = nullptr ) noexcept;
/**
* @brief Add a task to the scheduling scheme. The task is scheduled to run
* every @a t time units, @a n times and executing @a callback method on
Expand Down Expand Up @@ -262,6 +264,15 @@ namespace qOS {
bool add( task &Task, commandLineInterface &cli, const priority_t p, void *arg = nullptr ) noexcept;
/** @}*/
#endif

/**
* @brief Add an input-watcher so that its function is executed by
* the kernel
* @note The input-watcher is considered as an always-active task
* @param[in] w The input watcher.
* @return Returns @c true if success, otherwise returns @c false.
*/
bool add( task &Task, input::watcher &w, const priority_t p = HIGHEST_PRIORITY, const taskState s = taskState::ENABLED_STATE, void *arg = nullptr ) noexcept;
/**
* @brief Set/Change the callback for the Idle-task
* @param[in] callback A pointer to a void callback method with a qOS::event_t
Expand All @@ -277,6 +288,13 @@ namespace qOS {
*/
bool setNameIdleTask( const char *tName ) noexcept;
/**
* @brief Set the function that puts the CPU into a low-power or
* idle state until an interrupt occurs.
* @param[in] pFcn The function to put the CPU into low-power or idle-state
* @return @c true on success. Otherwise return @c false.
*/
bool setCoreIdleFcn( void(*pFcn)(void) ) noexcept;
/**
* @brief Disables the kernel scheduling. The main thread will continue
* after the core::run() call.
*/
Expand Down Expand Up @@ -438,21 +456,6 @@ namespace qOS {
*/
globalState getGlobalState( task &Task ) const noexcept;
/**
* @brief Add an input-watcher so that its function is executed by
* the kernel
* @note The input-watcher is considered as an always-active task
* @param[in] w The input watcher.
* @return Returns @c true if success, otherwise returns @c false.
*/
bool add( input::watcher &w ) noexcept;
/**
* @brief Remove an input-watcher so that the kernel stops executing
* its function
* @param[in] w The input-watcher.
* @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
*/
Expand Down
2 changes: 1 addition & 1 deletion src/include/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace qOS {
{
return container;
}
node() : next(nullptr), prev(nullptr), container(nullptr) {}
node() noexcept : next(nullptr), prev(nullptr), container(nullptr) {}
/*! @cond */
virtual ~node() {}
/*! @endcond */
Expand Down
20 changes: 18 additions & 2 deletions src/include/timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace qOS {
qOS::clock_t tStart{ 0U };
qOS::clock_t tv{ 0U };
public:
timer();
timer() noexcept;
/*! @cond */
virtual ~timer() {}
/*! @endcond */
Expand Down Expand Up @@ -85,7 +85,23 @@ namespace qOS {
* @return Returns @c true on success, otherwise, returns @c false.
* @note A disarmed timer also returns @c false.
*/
bool freeRun( const qOS::duration_t tTime ) noexcept;
bool reloadIfExpired( const qOS::duration_t tTime ) noexcept;
/**
* @brief Non-Blocking timer check with automatic arming.
*
* Behavior:
* If disarmed, it gets armed immediately with the previous
* specified time.
*
* If armed, the API only checks for expiration. When the time
* expires, the timer gets armed immediately using the previously
* assigned time.
* @note After the timer expiration, this method re-arms the timer
* @note The OS must be running before using a timer.
* @return Returns @c true on success, otherwise, returns @c false.
* @note A disarmed timer also returns @c false.
*/
bool reloadIfExpired( void ) noexcept;
/**
* @brief Retrieve the remaining time in epochs
* @return The remaining time specified in epochs.
Expand Down
2 changes: 1 addition & 1 deletion src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ void input::analogChannel::steadyInBandState( input::analogChannel& c )
/*============================================================================*/
bool input::watcher::watch( void ) noexcept
{
const bool act = waitDebounce.freeRun( debounceTime );
const bool act = waitDebounce.reloadIfExpired( debounceTime );
if ( ( digitalChannels.length() > 0U ) && act ) {
for ( auto i = digitalChannels.begin(); i.untilEnd() ; i++ ) {
input::channel& c = *i.get<input::channel*>();
Expand Down
77 changes: 48 additions & 29 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ const priority_t core::MEDIUM_PRIORITY = static_cast<priority_t>( Q_PRIORITY_LEV
const priority_t core::HIGHEST_PRIORITY = static_cast<priority_t>( Q_PRIORITY_LEVELS ) - 1U;
const notifier_t MAX_NOTIFICATION_VALUE = UINT32_MAX - 1UL;

#if ( Q_CLI == 1 )
#if ( Q_FSM == 1 )
static void fsmTaskCallback( event_t e );
#endif
#if ( Q_CLI == 1 )
static void cliTaskCallback( event_t e );
static void cliNotifyFcn( commandLineInterface *cli );
#endif

static void inputWatcherTaskCallback( event_t e );
/*============================================================================*/
core& core::getInstance( void ) noexcept
{
Expand All @@ -35,13 +37,14 @@ core& core::getInstance( void ) noexcept
}
/*============================================================================*/
/*cstat -MISRAC++2008-7-1-2*/
bool core::init( const getTickFcn_t tFcn, taskFcn_t callbackIdle ) noexcept
bool core::init( const getTickFcn_t tFcn, taskFcn_t callbackIdle, void(*coreIdleFcn)(void) ) noexcept
{
(void)clock::setTickProvider( tFcn );
(void)setNameIdleTask( "idle" );
(void)idle.setPriority( core::LOWEST_PRIORITY );
(void)idle.setState( taskState::DISABLED_STATE );
(void)idle.setCallback( callbackIdle );
(void)setCoreIdleFcn( coreIdleFcn );
idle.entry = 0U;
return true;
}
Expand Down Expand Up @@ -122,6 +125,26 @@ bool core::add( task &Task, commandLineInterface &cli, const priority_t p, void
}
#endif /*Q_CLI*/
/*============================================================================*/
static void inputWatcherTaskCallback( event_t e )
{
/*cstat -CERT-EXP36-C_b*/
input::watcher * const w = static_cast<input::watcher*>( e.thisTask().getBindedObject() );
/*cstat +CERT-EXP36-C_b*/
(void)w->watch();
}
/*============================================================================*/
bool core::add( task &Task, input::watcher &w, const priority_t p, const taskState s, void *arg ) noexcept
{
bool retValue = core::add( Task, inputWatcherTaskCallback, p, 10_ms, task::PERIODIC, s, arg );

if ( retValue ) {
Task.aObj = &w;
retValue = true;
}

return retValue;
}
/*============================================================================*/
/*cstat -MISRAC++2008-7-1-2*/
bool core::setIdleTask( taskFcn_t callback ) noexcept
{
Expand All @@ -143,6 +166,18 @@ bool core::setNameIdleTask( const char *tName ) noexcept
return retValue;
}
/*============================================================================*/
bool core::setCoreIdleFcn( void(*pFcn)(void) ) noexcept
{
bool retValue = false;

if ( pFcn != cpuIdle ) {
cpuIdle = pFcn;
retValue = true;
}

return retValue;
}
/*============================================================================*/
bool core::schedulerRelease( void ) noexcept
{
bits::multipleSet( flag, BIT_RELEASE_SCHED );
Expand Down Expand Up @@ -373,7 +408,9 @@ bool core::run( void ) noexcept
/*cstat +MISRAC++2008-0-1-6*/

do {
if ( checkIfReady() ) {
const bool anyActiveTask = checkIfReady();

if ( anyActiveTask) {
priority_t xPriorityListIndex = MAX_PRIORITY_VALUE;

do {
Expand All @@ -383,21 +420,20 @@ bool core::run( void ) noexcept
}
} while( 0U != xPriorityListIndex-- );
}
else {
if ( nullptr != idle.callback ) {
dispatchIdle();
}
}
if ( inputWatchers.length() > 0U ) {
handleInputWatchers();
}
if ( suspendedList.length() > 0U ) {
(void)waitingList.move( suspendedList, listPosition::AT_BACK );
#if ( Q_PRESERVE_TASK_ENTRY_ORDER == 1 )
/*preseve the entry order by sorting the new waiting-list*/
(void)waitingList.sort( taskEntryOrderPreserver );
#endif
}

if ( !anyActiveTask ) {
dispatchIdle();
if ( nullptr != cpuIdle ) {
cpuIdle();
}
}
}
#if ( Q_ALLOW_SCHEDULER_RELEASE == 1 )
while ( !bits::multipleGet( flag, BIT_RELEASE_SCHED ) );
Expand Down Expand Up @@ -601,20 +637,3 @@ globalState core::getGlobalState( task &Task ) const noexcept
return retValue;
}
/*============================================================================*/
bool core::add( input::watcher &w ) noexcept
{
return inputWatchers.insert( &w );
}
/*============================================================================*/
bool core::remove( input::watcher &w ) noexcept
{
return inputWatchers.remove( &w );
}
/*============================================================================*/
void core::handleInputWatchers( void ) noexcept
{
for ( auto i = inputWatchers.begin(); i.untilEnd() ; i++ ) {
input::watcher * const w = i.get<input::watcher*>();
(void)w->watch();
}
}
Loading
Loading