Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nickshl/DevCore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickshl <nicolai.shlapunov@gmail.com>2018-10-05 04:23:23 +0300
committernickshl <nicolai.shlapunov@gmail.com>2018-10-05 04:23:23 +0300
commitdea80e6a1743a02e119fe0a9bb4a00c3e6301d1e (patch)
tree808bc1a5ca97e81650b6ab0fe8e22164b78f5eb2 /Framework
parent07550101d661d0c1d6bbb4d84c3ca3f1a11b4daf (diff)
DevCore - initial version
Diffstat (limited to 'Framework')
-rw-r--r--Framework/AppTask.cpp274
-rw-r--r--Framework/AppTask.h185
-rw-r--r--Framework/Result.h232
3 files changed, 691 insertions, 0 deletions
diff --git a/Framework/AppTask.cpp b/Framework/AppTask.cpp
new file mode 100644
index 0000000..aeedc1f
--- /dev/null
+++ b/Framework/AppTask.cpp
@@ -0,0 +1,274 @@
+//******************************************************************************
+// @file AppTask.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: Application Task Base Class, implementation
+//
+// @copyright Copyright (c) 2016, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "AppTask.h"
+#include "RtosMutex.h"
+
+// *****************************************************************************
+// *** Static variables ****************************************************
+// *****************************************************************************
+static RtosMutex startup_mutex;
+static uint32_t startup_cnt = 0U;
+
+// *****************************************************************************
+// *** Create task function ************************************************
+// *****************************************************************************
+void AppTask::CreateTask()
+{
+ Result result = Result::RESULT_OK;
+
+ // If interval timer period isn't zero or task queue present
+ if((timer.GetTimerPeriod() != 0U) || (task_queue.GetQueueLen() != 0U))
+ {
+ // Set Control Queue name
+ ctrl_queue.SetName(task_name, "Ctrl");
+ // Create control queue
+ result = ctrl_queue.Create();
+ }
+ // If task queue present
+ if(task_queue.GetQueueLen() != 0U)
+ {
+ // Set Task Queue name
+ task_queue.SetName(task_name, "Task");
+ // Create task queue
+ result |= task_queue.Create();
+ }
+ // If interval timer period isn't zero
+ if(timer.GetTimerPeriod() != 0U)
+ {
+ // Create timer
+ result |= timer.Create();
+ }
+ // Create task: function - TaskFunctionCallback(), parameter - pointer to "this"
+ result |= Rtos::TaskCreate(TaskFunctionCallback, task_name, stack_size, this, task_priority);
+
+ // Check result
+ if(result.IsBad())
+ {
+ // TODO: implement error handling
+ Break();
+ }
+}
+
+// *****************************************************************************
+// *** SendTaskMessage function ********************************************
+// *****************************************************************************
+Result AppTask::SendTaskMessage(const void* task_msg, bool is_priority)
+{
+ Result result = Result::RESULT_OK;
+
+ // Send task message to front or back of task queue
+ if(is_priority == true)
+ {
+ result = task_queue.SendToFront(task_msg);
+ }
+ else
+ {
+ result = task_queue.SendToBack(task_msg);
+ }
+
+ // If successful - send message to the control queue
+ if(result.IsGood())
+ {
+ CtrlQueueMsg ctrl_msg;
+ ctrl_msg.type = CTRL_TASK_QUEUE_MSG;
+ result = SendControlMessage(ctrl_msg, is_priority);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** IntLoop function ****************************************************
+// *****************************************************************************
+Result AppTask::IntLoop()
+{
+ Result result = Result::RESULT_OK;
+
+ while(result.IsGood())
+ {
+ // Buffer for control message
+ CtrlQueueMsg ctrl_msg;
+ // Read on the control queue
+ result = ctrl_queue.Receive(&ctrl_msg, timer.GetTimerPeriod() * 2U);
+ // If successful
+ if(result.IsGood())
+ {
+ // Check message type
+ switch(ctrl_msg.type)
+ {
+ case CTRL_TIMER_MSG:
+ result = TimerExpired();
+ break;
+
+ case CTRL_TASK_QUEUE_MSG:
+ {
+ // Non blocking read from the task queue
+ result = task_queue.Receive(task_msg_ptr, 0U);
+ // If successful
+ if(result.IsGood())
+ {
+ // Process it!
+ result = ProcessMessage();
+ }
+ break;
+ }
+
+ default:
+ result = Result::ERR_INVALID_ITEM;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** TaskFunctionCallback ************************************************
+// *****************************************************************************
+void AppTask::TaskFunctionCallback(void* ptr)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(ptr != nullptr)
+ {
+ // Set good result
+ result = Result::RESULT_OK;
+ // Get reference to the task object
+ AppTask& app_task = *(static_cast<AppTask*>(ptr));
+
+ // Increment counter before call Setup()
+ ChangeCnt(true);
+ // Call virtual Setup() function from AppTask class
+ app_task.Setup();
+ // Decrement counter after call Setup()
+ ChangeCnt(false);
+ // Pause for give other tasks run Setup()
+ RtosTick::DelayTicks(1U);
+ // Pause while other tasks run Setup() before executing any Loop()
+ while(startup_cnt) RtosTick::DelayTicks(1U);
+
+ // If no timer or queue - just call Loop() function
+ if((app_task.timer.GetTimerPeriod() == 0U) && (app_task.task_queue.GetQueueLen() == 0U))
+ {
+ // Call virtual Loop() function from AppTask class
+ while(app_task.Loop() == Result::RESULT_OK);
+ }
+ else
+ {
+ // Start task timer if needed
+ if(app_task.timer.GetTimerPeriod() != 0U)
+ {
+ result = app_task.timer.Start();
+ }
+ // Check result
+ if(result.IsGood())
+ {
+ // Call internal AppTask function
+ result = app_task.IntLoop();
+ }
+ // Stop task timer if needed
+ if(app_task.timer.GetTimerPeriod() != 0U)
+ {
+ result |= app_task.timer.Stop();
+ }
+ }
+ }
+
+ // Check result
+ if(result.IsBad())
+ {
+ // TODO: implement error handling
+ Break();
+ }
+
+ // Delete task after exit
+ Rtos::TaskDelete();
+}
+
+// *****************************************************************************
+// *** TimerCallback function **********************************************
+// *****************************************************************************
+void AppTask::TimerCallback(void* ptr)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(ptr != nullptr)
+ {
+ // Get reference to the task object
+ AppTask& task = *((AppTask*)ptr);
+
+ // Create control timer message
+ CtrlQueueMsg timer_msg;
+ timer_msg.type = CTRL_TIMER_MSG;
+
+ // Send message to the control queue
+ result = task.SendControlMessage(timer_msg);
+ }
+
+ // Check result
+ if(result.IsBad())
+ {
+ // TODO: implement error handling
+ Break();
+ }
+}
+
+// *****************************************************************************
+// *** SendControlMessage function *****************************************
+// *****************************************************************************
+Result AppTask::SendControlMessage(const CtrlQueueMsg& ctrl_msg, bool is_priority)
+{
+ Result result;
+
+ if(is_priority == true)
+ {
+ result = ctrl_queue.SendToFront(&ctrl_msg);
+ }
+ else
+ {
+ result = ctrl_queue.SendToBack(&ctrl_msg);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Change counter ******************************************************
+// *****************************************************************************
+void AppTask::ChangeCnt(bool is_up)
+{
+ // Take semaphore before change counter
+ startup_mutex.Lock();
+ // Check direction
+ if(is_up == true)
+ {
+ // Increment counter
+ startup_cnt++;
+ }
+ else
+ {
+ // Decrement counter
+ startup_cnt--;
+ }
+ // Give semaphore after changes
+ startup_mutex.Release();
+}
diff --git a/Framework/AppTask.h b/Framework/AppTask.h
new file mode 100644
index 0000000..bf54487
--- /dev/null
+++ b/Framework/AppTask.h
@@ -0,0 +1,185 @@
+//******************************************************************************
+// @file AppTask.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: Application Task Base Class, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2016, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef AppTask_h
+#define AppTask_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+
+// *****************************************************************************
+// * AppTask class. This class is wrapper for call C++ function from class. ****
+// *****************************************************************************
+class AppTask
+{
+ public:
+ // *************************************************************************
+ // *** Init Task *******************************************************
+ // *************************************************************************
+ virtual void InitTask(void) {CreateTask();}
+
+ protected:
+ // *************************************************************************
+ // *** Constructor *****************************************************
+ // *************************************************************************
+ AppTask(uint16_t stk_size, uint8_t task_prio, const char name[],
+ uint16_t queue_len = 0U, uint16_t queue_msg_size = 0U,
+ void* task_msg_p = nullptr, uint32_t task_interval_ms = 0U) :
+ ctrl_queue((queue_len + 2U), sizeof(CtrlQueueMsg)),
+ task_queue(queue_len, queue_msg_size), task_msg_ptr(task_msg_p),
+ timer(task_interval_ms, RtosTimer::REPEATING, TimerCallback, (void*)this),
+ stack_size(stk_size), task_priority(task_prio), task_name(name) {};
+
+ // *************************************************************************
+ // *** Virtual destructor - prevent warning ****************************
+ // *************************************************************************
+ virtual ~AppTask() {};
+
+ // *************************************************************************
+ // *** Create task function ********************************************
+ // *************************************************************************
+ // * This function creates new task in FreeRTOS, provide pointer to function
+ // * and pointer to class as parameter. When TaskFunctionCallback() called
+ // * from FreeRTOS, it use pointer to class from parameter to call virtual
+ // * functions.
+ void CreateTask();
+
+ // *************************************************************************
+ // *** Setup function **************************************************
+ // *************************************************************************
+ // * * virtual function - some tasks may not have Setup() actions
+ virtual Result Setup() {return Result::RESULT_OK;}
+
+ // *************************************************************************
+ // *** IntervalTimerExpired function ***********************************
+ // *************************************************************************
+ // * Empty virtual function - some tasks may not have TimerExpired() actions
+ virtual Result TimerExpired() {return Result::RESULT_OK;}
+
+ // *************************************************************************
+ // *** ProcessMessage function *****************************************
+ // *************************************************************************
+ // * Empty virtual function - some tasks may not have ProcessMessage() actions
+ virtual Result ProcessMessage() {return Result::RESULT_OK;}
+
+ // *************************************************************************
+ // *** Loop function ***************************************************
+ // *************************************************************************
+ // * Empty virtual function - some tasks may not have Loop() actions
+ virtual Result Loop() {return Result::RESULT_OK;}
+
+ // *************************************************************************
+ // *** SendTaskMessage function ****************************************
+ // *************************************************************************
+ Result SendTaskMessage(const void* task_msg, bool is_priority = false);
+
+ private:
+ // Task control queue message types
+ enum CtrlQueueMsgType
+ {
+ CTRL_TIMER_MSG,
+ CTRL_TASK_QUEUE_MSG
+ };
+ // Task control queue message struct
+ struct CtrlQueueMsg
+ {
+ CtrlQueueMsgType type;
+ };
+ // Task control queue
+ RtosQueue ctrl_queue;
+
+ // Task queue
+ RtosQueue task_queue;
+ // Pointer to receive message buffer
+ void* task_msg_ptr;
+
+ // Timer object
+ RtosTimer timer;
+
+ // Task stack size
+ uint16_t stack_size;
+ // Task priority
+ uint8_t task_priority;
+ // Pointer to the task name
+ const char* task_name;
+
+ // *************************************************************************
+ // *** IntLoop function ************************************************
+ // *************************************************************************
+ Result IntLoop();
+
+ // *************************************************************************
+ // *** TaskFunctionCallback ********************************************
+ // *************************************************************************
+ static void TaskFunctionCallback(void* ptr);
+
+ // *************************************************************************
+ // *** IntervalTimerCallback function **********************************
+ // *************************************************************************
+ static void TimerCallback(void* ptr);
+
+ // *************************************************************************
+ // *** SendControlMessage function *************************************
+ // *************************************************************************
+ Result SendControlMessage(const CtrlQueueMsg& ctrl_msg, bool is_priority = false);
+
+ // *************************************************************************
+ // *** Change counter **************************************************
+ // *************************************************************************
+ static void ChangeCnt(bool is_up);
+
+ // *************************************************************************
+ // *** Private constructor and assign operator - prevent copying *******
+ // *************************************************************************
+ AppTask();
+ AppTask(const AppTask&);
+ AppTask& operator=(const AppTask&);
+};
+
+#endif
diff --git a/Framework/Result.h b/Framework/Result.h
new file mode 100644
index 0000000..74d27b9
--- /dev/null
+++ b/Framework/Result.h
@@ -0,0 +1,232 @@
+//******************************************************************************
+// @file Result.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: Result codes, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2016, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef Result_h
+#define Result_h
+
+// *****************************************************************************
+// *** Result **************************************************************
+// *****************************************************************************
+class Result
+{
+ public:
+ // *************************************************************************
+ // *** Enum with all possible result codes *****************************
+ // *************************************************************************
+ enum ResultCode
+ {
+ // *** No error ******************************************************
+ RESULT_OK = 0,
+
+ // *** Generic *******************************************************
+ ERR_NULL_PTR,
+ ERR_BAD_PARAMETER,
+ ERR_INVALID_ITEM,
+ ERR_NOT_IMPLEMENTED,
+ ERR_BUSY,
+
+ // *** RTOS errors ***************************************************
+ ERR_TASK_CREATE,
+ ERR_QUEUE_CREATE,
+ ERR_QUEUE_GENERAL,
+ ERR_QUEUE_EMPTY,
+ ERR_QUEUE_READ,
+ ERR_QUEUE_WRITE,
+ ERR_QUEUE_RESET,
+ ERR_TIMER_CREATE,
+ ERR_TIMER_START,
+ ERR_TIMER_UPDATE,
+ ERR_TIMER_STOP,
+ ERR_MUTEX_CREATE,
+ ERR_MUTEX_LOCK,
+ ERR_MUTEX_RELEASE,
+ ERR_SEMAPHORE_CREATE,
+ ERR_SEMAPHORE_TAKE,
+ ERR_SEMAPHORE_GIVE,
+
+ // *** UART errors ***************************************************
+ ERR_UART_GENERAL,
+ ERR_UART_TRANSMIT,
+ ERR_UART_RECEIVE,
+ ERR_UART_EMPTY,
+ ERR_UART_BUSY,
+ ERR_UART_TIMEOUT,
+ ERR_UART_UNKNOWN,
+
+ // *** I2C errors ****************************************************
+ ERR_I2C_GENERAL,
+ ERR_I2C_BUSY,
+ ERR_I2C_TIMEOUT,
+ ERR_I2C_UNKNOWN,
+
+ // *** SPI errors ****************************************************
+ ERR_SPI_GENERAL,
+ ERR_SPI_BUSY,
+ ERR_SPI_TIMEOUT,
+ ERR_SPI_UNKNOWN,
+
+ // *** Elements count ************************************************
+ RESULTS_CNT
+ };
+
+ // *************************************************************************
+ // *** Result **********************************************************
+ // *************************************************************************
+ Result() {};
+
+ // *************************************************************************
+ // *** Result **********************************************************
+ // *************************************************************************
+ Result(ResultCode res)
+ {
+ result = res;
+ }
+
+ // *************************************************************************
+ // *** IsGood **********************************************************
+ // *************************************************************************
+ bool IsGood() const
+ {
+ return result == RESULT_OK;
+ }
+
+ // *************************************************************************
+ // *** IsBad ***********************************************************
+ // *************************************************************************
+ bool IsBad() const
+ {
+ return result != RESULT_OK;
+ }
+
+ // *************************************************************************
+ // *** operator ResultCode *********************************************
+ // *************************************************************************
+ operator ResultCode() const
+ {
+ return result;
+ }
+
+ // *************************************************************************
+ // *** operator= *******************************************************
+ // *************************************************************************
+ Result& operator=(ResultCode res)
+ {
+ result = res;
+ return *this;
+ }
+
+ // *************************************************************************
+ // *** operator= *******************************************************
+ // *************************************************************************
+ Result& operator=(const Result& r_arg)
+ {
+ result = r_arg.result;
+ return *this;
+ }
+
+ // *************************************************************************
+ // *** operator|= ******************************************************
+ // *************************************************************************
+ Result& operator|=(ResultCode res)
+ {
+ if(result == RESULT_OK)
+ {
+ result = res;
+ }
+ return *this;
+ }
+
+ // *************************************************************************
+ // *** operator|= ******************************************************
+ // *************************************************************************
+ Result& operator|=(const Result& r_arg)
+ {
+ if(result == RESULT_OK)
+ {
+ result = r_arg.result;
+ }
+ return *this;
+ }
+
+ // *************************************************************************
+ // *** operator== ******************************************************
+ // *************************************************************************
+ bool operator==(ResultCode res) const
+ {
+ return(result == res);
+ }
+
+ // *************************************************************************
+ // *** operator== ******************************************************
+ // *************************************************************************
+ bool operator==(const Result& r_arg) const
+ {
+ return result == r_arg.result;
+ }
+
+ // *************************************************************************
+ // *** operator!= ******************************************************
+ // *************************************************************************
+ bool operator!=(ResultCode res) const
+ {
+ return(result != res);
+ }
+
+ // *************************************************************************
+ // *** operator!= ******************************************************
+ // *************************************************************************
+ bool operator!=(const Result& r_arg) const
+ {
+ return(result != r_arg.result);
+ }
+
+ private:
+ // Result code
+ ResultCode result = RESULT_OK;
+};
+
+#endif