Initial commit
This commit is contained in:
49
src/simplified/xf/port/README.md
Normal file
49
src/simplified/xf/port/README.md
Normal file
@ -0,0 +1,49 @@
|
||||
# XF Ports
|
||||
|
||||
## Introduction
|
||||
A XF (execution framework) consists of a view classes which some need to be adjusted
|
||||
when used on another platform.
|
||||
|
||||
Following you will find a list of classes which may be adjusted/reimplemented when
|
||||
changing to another platform/environment:
|
||||
- `XF`
|
||||
- `TimeoutManager`
|
||||
- `Dispatcher`
|
||||
- `EventQueue`
|
||||
- `Mutex`
|
||||
|
||||
These classes are also named `port classes` because they can be ported to another
|
||||
platform. All port classes can be found in the _port_ folder whereas every port is
|
||||
located in a separate folder.
|
||||
|
||||
Every port may pick some default implementation classes from the _common_ folder
|
||||
also located in the _port_ folder.
|
||||
|
||||
## Common Port Classes
|
||||
There are already some common port class implementations present. You can find
|
||||
them in the `common` folder and may suit your needs for a first version
|
||||
of your XF. These default port classes are platform independent and can be
|
||||
used by any port implementation.
|
||||
|
||||
> Note
|
||||
>
|
||||
> Be carefull when changing the code of a class in the _common_ folder. It may
|
||||
> affect other ports and cause them to no more work correctly!
|
||||
|
||||
## Port Folder Structure
|
||||
In case you want to add support for another platform to the XF, you need to add a
|
||||
subfolder to the _port_ folder and put the port class files in there. Best is, to
|
||||
take an already present port which is most similar to what you need, rename it and
|
||||
start adaption of these files.
|
||||
|
||||
You may also mix-up your port with classes from the _common_ folder and your custom
|
||||
folder (or even reference classes from other ports).
|
||||
|
||||
## Available Ports
|
||||
|
||||
Here is a list of currently available ports:
|
||||
|
||||
| Port Name | OS | Platform | Folder Name | Description |
|
||||
|--|--|--|--|--|
|
||||
| PORT_IDF_QT | Qt (IDF) | Qt library based implementation | idf-qt | XF support for macOS, Linux and Windows |
|
||||
| PORT_IDF_STM32 | Bare-Metal (IDF) | STM32CubeIDE/STM32CubeMX based port | idf-stm32 | XF for ARM Cortex based microcontrollers from STMicroelectronics |
|
BIN
src/simplified/xf/port/README.pdf
Normal file
BIN
src/simplified/xf/port/README.pdf
Normal file
Binary file not shown.
62
src/simplified/xf/port/common/README.md
Normal file
62
src/simplified/xf/port/common/README.md
Normal file
@ -0,0 +1,62 @@
|
||||
# XF Common Port
|
||||
|
||||
This folder provides common implementations for some platform
|
||||
indipendent XF classes.
|
||||
You can use these classes to construct the XF needed.
|
||||
|
||||
If these classes do not suit your needs, they can be reimplemented for
|
||||
your platform. Create an additional folder in the 'port' folder and
|
||||
implement there the classes you need for your platform.
|
||||
|
||||
# Available Common Port Classes
|
||||
|
||||
| Class name | File location | Define to set |
|
||||
|--|--|--|
|
||||
| `XFTimeoutManager` | xf/port/common/timeoutmanager.cpp | USE_XF_COMMON_TIMEOUTMANAGER_CLASS |
|
||||
| `XFDispatcher` | xf/port/common/dispatcher.cpp | USE_XF_COMMON_DISPATCHER_CLASS |
|
||||
|
||||
If you need more information about the classes mentioned above, please
|
||||
have a look into their header files and the doxygen comments in code.
|
||||
|
||||
# Platform Dependend Common Port Classes
|
||||
In the following folders you can pick some platform dependend
|
||||
port classes:
|
||||
|
||||
| Platform | Folder |
|
||||
|--|--|
|
||||
| IDF-QT | [idf-qt](../idf-qt) |
|
||||
| IDF-STM32 | [idf-stm32](../idf-stm32) |
|
||||
|
||||
# Example _config/xf-config.h_ File
|
||||
Following you will find some examples giving you a basic idea which define
|
||||
to set in the application specific _config/xf-config.h_ file.
|
||||
|
||||
The _IDF Stm32_ port uses the following defines:
|
||||
|
||||
```c++
|
||||
// Defines used by the IDF STM32 port
|
||||
#define USE_XF_COMMON_TIMEOUTMANAGER_CLASS 1
|
||||
#define USE_XF_COMMON_DISPATCHER_CLASS 1
|
||||
#define USE_XF_IDF_STM32_XF_CLASS 1
|
||||
#define USE_XF_IDF_STM32_EVENT_QUEUE_CLASS 1
|
||||
#define USE_XF_IDF_STM32_MUTEX_CLASS 1
|
||||
|
||||
#include "idf-stm32/eventqueue.h"
|
||||
```
|
||||
> Note:
|
||||
>
|
||||
> Here is also a good place to indicate which `EventQueue` class the XF should use.
|
||||
|
||||
If you want to build an XF on Windows, macOS or Linux, use the _IDF Qt_ port.
|
||||
Following defines need to be set in the application specific
|
||||
_config/xf-config.h_ file:
|
||||
```c++
|
||||
// Defines used by the IDF Qt port
|
||||
#define USE_XF_COMMON_TIMEOUTMANAGER_CLASS 1
|
||||
#define USE_XF_COMMON_DISPATCHER_CLASS 1
|
||||
#define USE_XF_IDF_QT_XF_CLASS 1
|
||||
#define USE_XF_IDF_QT_EVENT_QUEUE_CLASS 1
|
||||
#define USE_XF_IDF_QT_MUTEX_CLASS 1
|
||||
|
||||
#include "idf-qt/eventqueue.h"
|
||||
```
|
BIN
src/simplified/xf/port/common/README.pdf
Normal file
BIN
src/simplified/xf/port/common/README.pdf
Normal file
Binary file not shown.
30
src/simplified/xf/port/common/dispatcher.cpp
Normal file
30
src/simplified/xf/port/common/dispatcher.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include <cassert>
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_COMMON_DISPATCHER_CLASS != 0)
|
||||
#if defined(XF_TRACE_EVENT_PUSH_POP) && (XF_TRACE_EVENT_PUSH_POP != 0)
|
||||
#include "trace/trace.h"
|
||||
#endif // XF_TRACE_EVENT_PUSH_POP
|
||||
#include "xf/interface/timeoutmanager.h"
|
||||
#include "xf/interface/behavior.h"
|
||||
#include "xf/interface/mutex.h"
|
||||
#include "dispatcher.h"
|
||||
|
||||
using interface::XFTimeoutManager; // Allows to use expression 'XFTimeoutManager' instead of 'interface::XFTimeoutManager'.
|
||||
using interface::XFBehavior; // Expression XFBehavior used in code below is in fact the XFBehavior interface class.
|
||||
using Mutex = interface::XFMutex; // Rename XFMutex interface class to Mutex for easier use.
|
||||
|
||||
// Implementation of the getInstance() method of the 'interface::XFDispatcher' class.
|
||||
//
|
||||
// Note: The implementation is done here because only in this file the real XFDispatcher
|
||||
// class is known (port specific class). An instance of the XFDispatcher class is
|
||||
// returned by the 'interface::XFDispatcher' class.
|
||||
interface::XFDispatcher * interface::XFDispatcher::getInstance()
|
||||
{
|
||||
static ::XFDispatcher dispatcher;
|
||||
return &dispatcher;
|
||||
}
|
||||
|
||||
// TODO: Implement code for XFDispatcher class
|
||||
|
||||
#endif // USE_XF_COMMON_DISPATCHER_CLASS
|
60
src/simplified/xf/port/common/dispatcher.h
Normal file
60
src/simplified/xf/port/common/dispatcher.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef XF_COMMON_DISPATCHER_H
|
||||
#define XF_COMMON_DISPATCHER_H
|
||||
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_COMMON_DISPATCHER_CLASS != 0)
|
||||
|
||||
#include "xf/interface/dispatcher.h"
|
||||
#include "xf/interface/mutex.h"
|
||||
|
||||
/*
|
||||
* Please include the XFEventQueueDefault class in the xf-config file!
|
||||
* Example: #include "default/eventqueue-default.h"
|
||||
* and
|
||||
* define the XFEventQueueDefault class as the class representing the
|
||||
* XFEventQueue used by the dispatcher.
|
||||
* Example: using XFEventQueue = XFEventQueueDefault;
|
||||
*
|
||||
* In case you want to provide you own event queue, you must implement
|
||||
* your own XFEventQueue class and include the header file in the xf-config file.
|
||||
*/
|
||||
|
||||
/** @ingroup port_common
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dispatcher used in an IDF (no underlying OS).
|
||||
*
|
||||
* The dispatcher can be used when an IDF on a bare-metal embedded system is needed.
|
||||
*
|
||||
* Only one instance of XFDispatcher is allowed (singleton pattern). It is the interface::XFDispatcher
|
||||
* class providing the single instance of the XFDispatcher class (see interface::XFDispatcher::getInstance()).
|
||||
*/
|
||||
class XFDispatcher : public interface::XFDispatcher
|
||||
{
|
||||
friend class interface::XFDispatcher;
|
||||
public:
|
||||
virtual ~XFDispatcher();
|
||||
|
||||
void pushEvent(XFEvent * pEvent) override;
|
||||
|
||||
void scheduleTimeout(int timeoutId, int interval, interface::XFBehavior * pBehavior) override;
|
||||
void unscheduleTimeout(int timeoutId, interface::XFBehavior * pBehavior) override;
|
||||
|
||||
void executeOnce() override;
|
||||
int execute(const void * param = nullptr) override;
|
||||
|
||||
protected:
|
||||
XFDispatcher(); // Do not allow to create addition objects outside class space (singleton).
|
||||
void dispatchEvent(const XFEvent * pEvent) const override;
|
||||
|
||||
protected:
|
||||
XFEventQueue events_; ///< Queue holding events waiting to get dispatched.
|
||||
interface::XFMutex * pMutex_; ///< Mutex to protect event queue.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_common group
|
||||
#endif // USE_XF_COMMON_DISPATCHER_CLASS
|
||||
#endif // XF_COMMON_DISPATCHER_H
|
6
src/simplified/xf/port/common/port-common.dox
Normal file
6
src/simplified/xf/port/common/port-common.dox
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
/** @defgroup port_common XF Common Port Classes
|
||||
*
|
||||
* XF common port classes.
|
||||
*
|
||||
*/
|
26
src/simplified/xf/port/common/timeoutmanager.cpp
Normal file
26
src/simplified/xf/port/common/timeoutmanager.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_COMMON_TIMEOUTMANAGER_CLASS != 0)
|
||||
|
||||
#include <cassert>
|
||||
#include "xf/interface/behavior.h"
|
||||
#include "xf/interface/mutex.h"
|
||||
#include "timeoutmanager.h"
|
||||
|
||||
using Mutex = interface::XFMutex; // Rename XFMutex interface class to Mutex for easier use.
|
||||
|
||||
// Implementation of the getInstance() method of the 'interface::XFTimeoutManager' class.
|
||||
//
|
||||
// Note: The implementation is done here because only in this file the real XFTimeoutManager
|
||||
// class is known (port specific class). An instance of the XFTimeoutManager class is
|
||||
// returned by the 'interface::XFTimeoutManager' class.
|
||||
interface::XFTimeoutManager * interface::XFTimeoutManager::getInstance()
|
||||
{
|
||||
static ::XFTimeoutManager timeoutManager;
|
||||
return &timeoutManager;
|
||||
}
|
||||
|
||||
// TODO: Implement code for XFTimeoutManager class
|
||||
|
||||
#endif // USE_XF_COMMON_TIMEOUTMANAGER_CLASS
|
51
src/simplified/xf/port/common/timeoutmanager.h
Normal file
51
src/simplified/xf/port/common/timeoutmanager.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef XF_COMMON_TIMEOUTMANAGER_H
|
||||
#define XF_COMMON_TIMEOUTMANAGER_H
|
||||
|
||||
#include <list>
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_COMMON_TIMEOUTMANAGER_CLASS != 0)
|
||||
|
||||
#include "xf/interface/timeoutmanager.h"
|
||||
#include "xf/timeout.h"
|
||||
#include "xf/interface/mutex.h"
|
||||
|
||||
/** @ingroup port_common
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Default implementation of the XF TimeoutManager
|
||||
*/
|
||||
class XFTimeoutManager : public interface::XFTimeoutManager
|
||||
{
|
||||
friend interface::XFTimeoutManager * interface::XFTimeoutManager::getInstance();
|
||||
public:
|
||||
~XFTimeoutManager() override;
|
||||
|
||||
void start(std::function<void(uint32_t)> startTimeoutManagerTimer = nullptr) override; ///< See interface::XFTimeoutManager
|
||||
void scheduleTimeout(int32_t timeoutId, int32_t interval, interface::XFBehavior * pBehavior) override; ///< See interface::XFTimeoutManager
|
||||
void unscheduleTimeout(int32_t timeoutId, interface::XFBehavior * pBehavior) override; ///< See interface::XFTimeoutManager
|
||||
void tick() override; ///< See interface::XFTimeoutManager
|
||||
|
||||
protected:
|
||||
XFTimeoutManager();
|
||||
void addTimeout(XFTimeout * pNewTimeout) override; ///< Adds the timeout to #timeouts_.
|
||||
|
||||
/**
|
||||
* Returns the timeout back to the queue of the dispatcher executing
|
||||
* the behavioral instance.
|
||||
*/
|
||||
void returnTimeout(XFTimeout * pTimeout); ///< Returns timeout back to behavioral class.
|
||||
|
||||
protected:
|
||||
typedef std::list<XFTimeout *> TimeoutList; ///< Type used for the _timeouts property.
|
||||
|
||||
TimeoutList timeouts_; ///< Container holding timeouts to manage.
|
||||
|
||||
interface::XFMutex * pMutex_; ///< Mutex to protect access to TimeoutList.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_common group
|
||||
#endif // USE_XF_COMMON_TIMEOUTMANAGER_CLASS
|
||||
#endif // XF_COMMON_TIMEOUTMANAGER_H
|
16
src/simplified/xf/port/common/xf-port-common.pri
Normal file
16
src/simplified/xf/port/common/xf-port-common.pri
Normal file
@ -0,0 +1,16 @@
|
||||
#
|
||||
# This PRI file takes the classes needed from the 'common' port.
|
||||
#
|
||||
|
||||
INCLUDEPATH += $$PWD/..
|
||||
|
||||
# Path to common port class implementation
|
||||
XF_PORT_COMMON_PATH = $$PWD/../common
|
||||
|
||||
SOURCES += \
|
||||
"$${XF_PORT_COMMON_PATH}/timeoutmanager.cpp" \
|
||||
"$${XF_PORT_COMMON_PATH}/dispatcher.cpp"
|
||||
|
||||
HEADERS += \
|
||||
"$${XF_PORT_COMMON_PATH}/timeoutmanager.h" \
|
||||
"$${XF_PORT_COMMON_PATH}/dispatcher.h"
|
30
src/simplified/xf/port/idf-qt/README.md
Normal file
30
src/simplified/xf/port/idf-qt/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# XF Port - IDF Qt
|
||||
|
||||
This port folder contains specific classes for the _IDF Qt_ XF port.
|
||||
|
||||
# Classes used by the _IDF Qt_ Port
|
||||
|
||||
| Class name | File location | Define to set |
|
||||
|--|--|--|
|
||||
| `XFTimeoutManager` | xf/port/common/timeoutmanager.cpp | USE_XF_COMMON_TIMEOUTMANAGER_CLASS |
|
||||
| `XFDispatcher` | xf/port/common/dispatcher.cpp | USE_XF_COMMON_DISPATCHER_CLASS |
|
||||
| `XF` | xf/port/idf-qt/xf.cpp | USE_XF_IDF_QT_XF_CLASS |
|
||||
| `XFEventQueue` | xf/port/idf-qt/eventqueue.cpp | USE_XF_IDF_QT_EVENT_QUEUE_CLASS |
|
||||
| `XFMutex` | xf/port/idf-qt/mutex.cpp | USE_XF_IDF_QT_MUTEX_CLASS |
|
||||
|
||||
# Example _config/xf-config.h_ File
|
||||
|
||||
```c++
|
||||
// Defines used by the IDF Qt port
|
||||
#define USE_XF_COMMON_TIMEOUTMANAGER_CLASS 1
|
||||
#define USE_XF_COMMON_DISPATCHER_CLASS 1
|
||||
#define USE_XF_IDF_QT_XF_CLASS 1
|
||||
#define USE_XF_IDF_QT_EVENT_QUEUE_CLASS 1
|
||||
#define USE_XF_IDF_QT_MUTEX_CLASS 1
|
||||
|
||||
#include "idf-qt/eventqueue.h"
|
||||
```
|
||||
|
||||
> Note:
|
||||
>
|
||||
> Here is also a good place to indicate which `EventQueue` class the XF should use.
|
BIN
src/simplified/xf/port/idf-qt/README.pdf
Normal file
BIN
src/simplified/xf/port/idf-qt/README.pdf
Normal file
Binary file not shown.
55
src/simplified/xf/port/idf-qt/eventqueue.cpp
Normal file
55
src/simplified/xf/port/idf-qt/eventqueue.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_EVENT_QUEUE_CLASS != 0)
|
||||
|
||||
#include <cassert>
|
||||
#include <QtGlobal>
|
||||
#include <QMutexLocker>
|
||||
#include "eventqueue.h"
|
||||
|
||||
XFEventQueue::XFEventQueue()
|
||||
{
|
||||
}
|
||||
|
||||
XFEventQueue::~XFEventQueue()
|
||||
{
|
||||
newEvents_.wakeAll();
|
||||
}
|
||||
|
||||
bool XFEventQueue::empty() const
|
||||
{
|
||||
return queue_.isEmpty();
|
||||
}
|
||||
|
||||
bool XFEventQueue::push(const XFEvent * pEvent, bool fromISR)
|
||||
{
|
||||
(void)fromISR;
|
||||
QMutexLocker locker(&mutex_);
|
||||
queue_.enqueue(pEvent);
|
||||
// Tell waiting thread(s) there is again an event present
|
||||
newEvents_.wakeAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
const XFEvent * XFEventQueue::front()
|
||||
{
|
||||
return queue_.front();
|
||||
}
|
||||
|
||||
void XFEventQueue::pop()
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
queue_.dequeue();
|
||||
}
|
||||
|
||||
bool XFEventQueue::pend()
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
// Wait for new events. Mutex needs to be in lock-state
|
||||
// prior to call wait()!
|
||||
newEvents_.wait(&mutex_);
|
||||
|
||||
return !queue_.isEmpty();
|
||||
}
|
||||
|
||||
#endif // USE_XF_IDF_QT_EVENT_QUEUE_CLASS
|
45
src/simplified/xf/port/idf-qt/eventqueue.h
Normal file
45
src/simplified/xf/port/idf-qt/eventqueue.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef XF_EVENT_QUEUE_DEFAULT_QT_H
|
||||
#define XF_EVENT_QUEUE_DEFAULT_QT_H
|
||||
|
||||
#include "config/xf-config.h"
|
||||
|
||||
#if (USE_XF_IDF_QT_EVENT_QUEUE_CLASS != 0)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QQueue>
|
||||
#include "xf/interface/eventqueue.h"
|
||||
|
||||
/** @ingroup port_idf_qt
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Default Qt implementation for the XFEventQueue interface.
|
||||
*/
|
||||
class XFEventQueue : public interface::XFEventQueue
|
||||
{
|
||||
public:
|
||||
XFEventQueue();
|
||||
~XFEventQueue() override;
|
||||
|
||||
// XFEventQueue interface implementation
|
||||
public:
|
||||
bool empty() const override; ///< Returns true if no event is in the queue.
|
||||
bool push(const XFEvent * pEvent, bool fromISR = false) override; ///< Pushes the given event onto the queue. Returns false if the event could not be pushed.
|
||||
const XFEvent * front() override; ///< Returns pointer to next event to pop.
|
||||
void pop() override; ///< Pops the next event from the queue.
|
||||
bool pend() override; ///< Wait for the next event to arrive. Returns true if an event is in the queue.
|
||||
|
||||
protected:
|
||||
typedef QQueue<const XFEvent *> EventQueue; ///< Type of the event queue.
|
||||
|
||||
QMutex mutex_; ///< Mutex (non-recursive) protecting access to _queue.
|
||||
QWaitCondition newEvents_; ///< Wait condition to let thread wait until a new event arrives.
|
||||
EventQueue queue_; ///< Internal queue holding the events.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_idf_qt group
|
||||
#endif // USE_XF_IDF_QT_EVENT_QUEUE_CLASS
|
||||
#endif // XF_EVENT_QUEUE_DEFAULT_QT_H
|
18
src/simplified/xf/port/idf-qt/mutex.cpp
Normal file
18
src/simplified/xf/port/idf-qt/mutex.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_MUTEX_CLASS != 0)
|
||||
|
||||
#include <cassert>
|
||||
#include "mutex.h"
|
||||
|
||||
/**
|
||||
* @brief Implementation of interface::XFMutex::create method.
|
||||
*/
|
||||
interface::XFMutex * interface::XFMutex::create()
|
||||
{
|
||||
return new ::XFMutex;
|
||||
}
|
||||
|
||||
// TODO: Implement code for XFMutex class
|
||||
|
||||
#endif // USE_XF_IDF_QT_MUTEX_CLASS
|
38
src/simplified/xf/port/idf-qt/mutex.h
Normal file
38
src/simplified/xf/port/idf-qt/mutex.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef XF_MUTEX_DEFAULT_QT_H
|
||||
#define XF_MUTEX_DEFAULT_QT_H
|
||||
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_MUTEX_CLASS != 0)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <QMutex>
|
||||
#include "xf/interface/mutex.h"
|
||||
|
||||
/** @ingroup port_idf_qt
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Default Qt implementation for the XFMutex interface.
|
||||
*/
|
||||
class XFMutex : public interface::XFMutex
|
||||
{
|
||||
friend class interface::XFMutex;
|
||||
public:
|
||||
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
|
||||
bool tryLock(int32_t timeout = 0) override;
|
||||
|
||||
protected:
|
||||
XFMutex() = default; ///< Do not allow to directly create an object of this class. Call interface::XFMutex::create() instead.
|
||||
|
||||
protected:
|
||||
QMutex mutex_; ///< The real mutex.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_idf_qt group
|
||||
#endif // USE_XF_IDF_QT_MUTEX_CLASS
|
||||
#endif // XF_MUTEX_DEFAULT_QT_H
|
6
src/simplified/xf/port/idf-qt/port-idf-qt.dox
Normal file
6
src/simplified/xf/port/idf-qt/port-idf-qt.dox
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
/** @defgroup port_idf_qt IDF Qt Port Classes
|
||||
*
|
||||
* XF port classes for the `IDF Qt` port.
|
||||
*
|
||||
*/
|
13
src/simplified/xf/port/idf-qt/xf-port-idf-qt.pri
Normal file
13
src/simplified/xf/port/idf-qt/xf-port-idf-qt.pri
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$PWD \
|
||||
$$PWD/..
|
||||
|
||||
SOURCES += \
|
||||
"$$PWD/eventqueue.cpp" \
|
||||
"$$PWD/mutex.cpp" \
|
||||
"$$PWD/xf.cpp"
|
||||
|
||||
HEADERS += \
|
||||
"$$PWD/eventqueue.h" \
|
||||
"$$PWD/mutex.h"
|
134
src/simplified/xf/port/idf-qt/xf.cpp
Normal file
134
src/simplified/xf/port/idf-qt/xf.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_XF_CLASS != 0)
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
#include "xf/interface/timeoutmanager.h"
|
||||
#include "xf/interface/dispatcher.h"
|
||||
#include "xf/xf.h"
|
||||
|
||||
/**
|
||||
* In the Qt port we are going to use a QCoreApplication instance
|
||||
* which gets executed by the XF::exec() method.
|
||||
*
|
||||
* The default dispatcher is active in this port implementation.
|
||||
* This means, the default dispatcher has its own thread.
|
||||
*
|
||||
* The XF::execOnce() method is not applicable for this port.
|
||||
*/
|
||||
|
||||
bool XF::isInitialized_ = false;
|
||||
bool XF::isRunning_ = false;
|
||||
|
||||
/**
|
||||
* @brief Helper class used to call regularly XFTimeoutManager::tick()
|
||||
*
|
||||
* Internally a Qt timer is created to call the
|
||||
* XFTimeoutManager::tick() method
|
||||
* (see QObject::startTimer()).
|
||||
*/
|
||||
static class TimeoutManagerTimer : public QObject
|
||||
{
|
||||
public:
|
||||
TimeoutManagerTimer()
|
||||
: _timerId(0)
|
||||
{
|
||||
}
|
||||
|
||||
void start(int32_t tickInterval)
|
||||
{
|
||||
Q_ASSERT(_timerId == 0); // Method should be called only once!
|
||||
_timerId = startTimer(tickInterval, Qt::PreciseTimer);
|
||||
}
|
||||
|
||||
void timerEvent(QTimerEvent * event) override
|
||||
{
|
||||
if (event->timerId() == _timerId)
|
||||
{
|
||||
interface::XFTimeoutManager::getInstance()->tick();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
int32_t _timerId;
|
||||
} timeoutManagerTimer;
|
||||
|
||||
/**
|
||||
* @brief The DispatcherThread calls the XFDispatcher execute() method in a separate thread.
|
||||
*/
|
||||
class DispatcherThread : public QThread
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief DispatcherThread constructor
|
||||
* @param dispatcher Dispatcher to be executed by the thread.
|
||||
*/
|
||||
DispatcherThread(interface::XFDispatcher * dispatcher)
|
||||
{
|
||||
dispatcher_ = dispatcher;
|
||||
assert(dispatcher_);
|
||||
}
|
||||
|
||||
// QThread interface
|
||||
protected:
|
||||
/**
|
||||
* @brief Method executed by the new thread.
|
||||
*
|
||||
* For more information read the documentation of QThread.
|
||||
*/
|
||||
void run() override
|
||||
{
|
||||
this->dispatcher_->execute();
|
||||
}
|
||||
|
||||
protected:
|
||||
interface::XFDispatcher * dispatcher_; ///< Pointer to dispatcher used by the DispatcherThread.
|
||||
};
|
||||
|
||||
static QCoreApplication & getApplication(int argc = 0, char * argv[] = nullptr)
|
||||
{
|
||||
static QCoreApplication app(argc, argv);
|
||||
return app;
|
||||
}
|
||||
|
||||
void XF::initialize(int timeInterval /* = 10 */, int argc /* = 0 */, char * argv[] /* = nullptr */)
|
||||
{
|
||||
if (!isInitialized_)
|
||||
{
|
||||
// Call getApplication() to create QT application instance
|
||||
::getApplication(argc, argv);
|
||||
|
||||
// Create and initialize TimeoutManager
|
||||
interface::XFTimeoutManager::getInstance()->initialize(timeInterval);
|
||||
// Start it
|
||||
interface::XFTimeoutManager::getInstance()->start(std::bind(&TimeoutManagerTimer::start, &timeoutManagerTimer, std::placeholders::_1));
|
||||
|
||||
isInitialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
int XF::exec()
|
||||
{
|
||||
// Start default dispatcher (in a separate thread)
|
||||
DispatcherThread dispatcherThread(interface::XFDispatcher::getInstance());
|
||||
dispatcherThread.start();
|
||||
|
||||
isRunning_ = true;
|
||||
|
||||
// Start Qt event loop
|
||||
return ::getApplication().exec();
|
||||
}
|
||||
|
||||
int XF::execOnce()
|
||||
{
|
||||
Q_ASSERT(false); // Not applicable for this port
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool XF::isRunning()
|
||||
{
|
||||
return isRunning_;
|
||||
}
|
||||
|
||||
#endif // USE_XF_IDF_QT_XF_CLASS
|
30
src/simplified/xf/port/idf-stm32/README.md
Normal file
30
src/simplified/xf/port/idf-stm32/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# XF Port - IDF STM32
|
||||
|
||||
This port folder contains specific classes for the _IDF STM32_ XF port.
|
||||
|
||||
# Classes used by the _IDF STM32_ Port
|
||||
|
||||
| Class name | File location | Define to set |
|
||||
|--|--|--|
|
||||
| `XFTimeoutManager` | xf/port/common/timeoutmanager.cpp | USE_XF_COMMON_TIMEOUTMANAGER_CLASS |
|
||||
| `XFDispatcher` | xf/port/common/dispatcher.cpp | USE_XF_COMMON_DISPATCHER_CLASS |
|
||||
| `XF` | xf/port/idf-stm32/xf.cpp | USE_XF_IDF_STM32_XF_CLASS |
|
||||
| `XFEventQueue` | xf/port/idf-stm32/eventqueue.cpp | USE_XF_IDF_STM32_EVENT_QUEUE_CLASS |
|
||||
| `XFMutex` | xf/port/idf-stm32/mutex.cpp | USE_XF_IDF_STM32_MUTEX_CLASS |
|
||||
|
||||
# Example _config/xf-config.h_ File
|
||||
|
||||
```c++
|
||||
// Defines used by the IDF STM32 port
|
||||
#define USE_XF_COMMON_TIMEOUTMANAGER_CLASS 1
|
||||
#define USE_XF_COMMON_DISPATCHER_CLASS 1
|
||||
#define USE_XF_IDF_STM32_XF_CLASS 1
|
||||
#define USE_XF_IDF_STM32_EVENT_QUEUE_CLASS 1
|
||||
#define USE_XF_IDF_STM32_MUTEX_CLASS 1
|
||||
|
||||
#include "idf-stm32/eventqueue.h"
|
||||
```
|
||||
|
||||
> Note:
|
||||
>
|
||||
> Here is also a good place to indicate which `EventQueue` class the XF should use.
|
BIN
src/simplified/xf/port/idf-stm32/README.pdf
Normal file
BIN
src/simplified/xf/port/idf-stm32/README.pdf
Normal file
Binary file not shown.
38
src/simplified/xf/port/idf-stm32/c-wrapper-functions.cpp
Normal file
38
src/simplified/xf/port/idf-stm32/c-wrapper-functions.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#include <cassert>
|
||||
#include "mcu/mcu.h"
|
||||
#include "critical/critical.h"
|
||||
#include "xf/xf.h"
|
||||
#include "xf/interface/timeoutmanager.h"
|
||||
#include "c-wrapper-functions.h"
|
||||
|
||||
using interface::XFTimeoutManager;
|
||||
|
||||
/**
|
||||
* SysTick_Handler() function is already implemented in the STM32CubeMX generated
|
||||
* code (see Src/stm32fxxx_it.c file). Therefore, we must provide here a function
|
||||
* which can be explicitly called in SysTick_Handler() to tick the XF.
|
||||
*/
|
||||
void XF_tick()
|
||||
{
|
||||
bInISR = true; // Tell critical section we are in an ISR
|
||||
if (XF::isRunning()) // Call tick only if XF is running
|
||||
{
|
||||
XFTimeoutManager::getInstance()->tick(); // Call framework hook tick function
|
||||
}
|
||||
bInISR = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* C function wrapping getTickInterval() method of XFTimeoutManager.
|
||||
*/
|
||||
int32_t XF_tickIntervalInMilliseconds()
|
||||
{
|
||||
return XFTimeoutManager::getInstance()->getTickInterval();
|
||||
}
|
||||
|
||||
bool XF_isRunning()
|
||||
{
|
||||
return XF::isRunning();
|
||||
}
|
44
src/simplified/xf/port/idf-stm32/c-wrapper-functions.h
Normal file
44
src/simplified/xf/port/idf-stm32/c-wrapper-functions.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef XF_C_WRAPPER_FUNCTIONS_H
|
||||
#define XF_C_WRAPPER_FUNCTIONS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/** @ingroup port_idf_stm32
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Following functions need to have "C" signature as they can be
|
||||
* called in C (and C++).
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Must be called regularly in a timer ISR or software timer callback.
|
||||
*
|
||||
* The XF_tick() function must be called with the same interval given to the
|
||||
* TimeoutManager (tickInterval).
|
||||
*/
|
||||
void XF_tick();
|
||||
|
||||
/**
|
||||
* C function returning the tick interval in milliseconds with which the XF_tick()
|
||||
* function should be called. This is the parameter given to the XF::init() method
|
||||
* and may be different for each project.
|
||||
*/
|
||||
int32_t XF_tickIntervalInMilliseconds();
|
||||
|
||||
/**
|
||||
* C function wrapping to XF::isRunning() method.
|
||||
*/
|
||||
bool XF_isRunning();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/** @} */ // end of port_idf_stm32 group
|
||||
#endif // XF_C_WRAPPER_FUNCTIONS_H
|
17
src/simplified/xf/port/idf-stm32/eventqueue.cpp
Normal file
17
src/simplified/xf/port/idf-stm32/eventqueue.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_STM32_EVENT_QUEUE_CLASS != 0)
|
||||
|
||||
#include <cassert>
|
||||
#include "eventqueue.h"
|
||||
|
||||
// TODO: Implement code for XFEventQueue class
|
||||
|
||||
bool XFEventQueue::pend()
|
||||
{
|
||||
// Method cannot be used in an IDF! Waiting within
|
||||
// this method would block the whole XF
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // USE_XF_IDF_STM32_EVENT_QUEUE_CLASS
|
49
src/simplified/xf/port/idf-stm32/eventqueue.h
Normal file
49
src/simplified/xf/port/idf-stm32/eventqueue.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef XF_IDF_STM32_EVENT_QUEUE_H
|
||||
#define XF_IDF_STM32_EVENT_QUEUE_H
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "config/xf-config.h"
|
||||
|
||||
#if (USE_XF_IDF_STM32_EVENT_QUEUE_CLASS != 0)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <queue>
|
||||
#include "xf/interface/eventqueue.h"
|
||||
#include "mutex.h"
|
||||
|
||||
/** @ingroup port_idf_stm32
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Default implementation of the event queue using a `std::queue` as container.
|
||||
*
|
||||
* This class does not provide a blocking pend() method. This means that this class
|
||||
* can be used in an IDF, but is not the right choice for a RTOS based XF.
|
||||
*/
|
||||
class XFEventQueue : public interface::XFEventQueue
|
||||
{
|
||||
using Mutex = XFMutex;
|
||||
public:
|
||||
XFEventQueue();
|
||||
virtual ~XFEventQueue();
|
||||
|
||||
// XFEventQueue interface implementation
|
||||
public:
|
||||
bool empty() const override; ///< Returns true if no event is in the queue.
|
||||
bool push(const XFEvent * pEvent, bool fromISR = false) override; ///< Pushes the given event onto the queue.
|
||||
const XFEvent * front() override; ///< Returns pointer to next event to pop.
|
||||
void pop() override; ///< Pops the next event from the queue.
|
||||
bool pend() override; ///< Wait for the next event to arrive. Returns true if an event is in the queue.
|
||||
|
||||
protected:
|
||||
typedef std::queue<const XFEvent *> EventQueue; ///< Type of the event queue.
|
||||
|
||||
Mutex mutex_; ///< Mutex protecting access to queue_.
|
||||
EventQueue queue_; ///< Internal queue holding the events.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_idf_stm32 group
|
||||
#endif // USE_XF_IDF_STM32_EVENT_QUEUE_CLASS
|
||||
#endif // __cplusplus
|
||||
#endif // XF_IDF_STM32_EVENT_QUEUE_H
|
18
src/simplified/xf/port/idf-stm32/mutex.cpp
Normal file
18
src/simplified/xf/port/idf-stm32/mutex.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_STM32_MUTEX_CLASS != 0)
|
||||
|
||||
#include "critical/critical.h" // Provided by the platform used
|
||||
#include "mutex.h"
|
||||
|
||||
/**
|
||||
* @brief Implementation of interface::XFMutex::create method.
|
||||
*/
|
||||
interface::XFMutex * interface::XFMutex::create()
|
||||
{
|
||||
return new ::XFMutex;
|
||||
}
|
||||
|
||||
// TODO: Implement code for XFMutex class
|
||||
|
||||
#endif // USE_XF_IDF_STM32_MUTEX_CLASS
|
40
src/simplified/xf/port/idf-stm32/mutex.h
Normal file
40
src/simplified/xf/port/idf-stm32/mutex.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef XF_IDF_STM32_MUTEX_H
|
||||
#define XF_IDF_STM32_MUTEX_H
|
||||
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_STM32_MUTEX_CLASS != 0)
|
||||
|
||||
#include <stdint.h>
|
||||
#include "xf/interface/mutex.h"
|
||||
|
||||
/** @ingroup port_idf_stm32
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Default IDF implementation XFMutex interface.
|
||||
*
|
||||
* This class uses `enterCritical()` and `exitCritical()`
|
||||
* functions which must be provided by the platform.
|
||||
* Therefore, this mutex implementation can be used
|
||||
* in Embedded Systems without OS.
|
||||
*/
|
||||
class XFMutex : public interface::XFMutex
|
||||
{
|
||||
friend class interface::XFMutex;
|
||||
friend class XFEventQueue;
|
||||
public:
|
||||
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
|
||||
bool tryLock(int32_t timeout = 0) override;
|
||||
|
||||
protected:
|
||||
XFMutex() = default; ///< Do not allow to directly create an object of this class. Call interface::XFMutex::create() instead.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_idf_stm32 group
|
||||
#endif // USE_XF_IDF_STM32_MUTEX_CLASS
|
||||
#endif // XF_IDF_STM32_MUTEX_H
|
6
src/simplified/xf/port/idf-stm32/port-idf-stm32.dox
Normal file
6
src/simplified/xf/port/idf-stm32/port-idf-stm32.dox
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
/** @defgroup port_idf_stm32 IDF STM32 Port Classes
|
||||
*
|
||||
* XF port classes for the `IDF STM32` port.
|
||||
*
|
||||
*/
|
29
src/simplified/xf/port/idf-stm32/xf.cpp
Normal file
29
src/simplified/xf/port/idf-stm32/xf.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include <cassert>
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_STM32_XF_CLASS != 0)
|
||||
|
||||
#include "xf/interface/timeoutmanager.h"
|
||||
#include "xf/interface/dispatcher.h"
|
||||
#include "xf/xf.h"
|
||||
|
||||
using interface::XFTimeoutManager;
|
||||
|
||||
void XF_initialize(int timeInterval)
|
||||
{
|
||||
XF::initialize(timeInterval);
|
||||
}
|
||||
|
||||
void XF_exec()
|
||||
{
|
||||
XF::exec();
|
||||
}
|
||||
|
||||
void XF_execOnce()
|
||||
{
|
||||
XF::execOnce();
|
||||
}
|
||||
|
||||
// TODO: Implement code for XF class
|
||||
|
||||
#endif // USE_XF_IDF_STM32_XF_CLASS
|
Reference in New Issue
Block a user