diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ca8c32..cf9e8e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(cpputest-for-qpcpp-lib VERSION 1.4.0) +project(cpputest-for-qpcpp-lib VERSION 1.5.0) include(FetchContent) set(CMAKE_CXX_STANDARD 17) @@ -15,7 +15,7 @@ if(NOT DEFINED CMS_QPCPP_TOP_DIR) set(CMS_QPCPP_TOP_DIR ${CMS_EXTERNALS_TOP_DIR}/qpcpp) FetchContent_Declare(qpcpp GIT_REPOSITORY https://github.com/QuantumLeaps/qpcpp.git - GIT_TAG 10441f7a03fa956b9e4772a073a05a96487983e2 #7.3.4 + GIT_TAG fa83cb0dc85c25b40075a1685fd8a148b89b9b3a #8.0.4 SOURCE_DIR ${CMS_QPCPP_TOP_DIR} ) message("Fetching QP/C++ git repository") diff --git a/README.md b/README.md index c252a1f..79df727 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ version too: See https://youtu.be/hr1qkNH1wSA. # Environment -This project was developed and proven in Ubuntu 20.04 and 22.04. In theory any +This project was developed and proven in Ubuntu, now 24.04. In theory any build or host operating system environment supported by CppUTest will be compatible with this code. @@ -65,8 +65,8 @@ be compatible with this code. Define the cmake variable CMS_QPCPP_TOP_DIR before including the internal CMakeLists.txt. * or: * Do not define CMS_QPCPP_TOP_DIR, and the internal cmake will fetch the appropriate QP/C++ repo. -* CppUTest (version 3.8-7 or version 4.0) (3.8 is the default in Ubuntu 20.04 while 4.0 is the default in Ubuntu 22.04) -* This project requires support for C++14. +* CppUTest (version 4.0, may still work with 3.8, but no longer being confirmed) +* This project requires support for C++17. ## Continuous Integration diff --git a/cpputest-for-qpcpp-lib/include/cmsDummyActiveObject.hpp b/cpputest-for-qpcpp-lib/include/cmsDummyActiveObject.hpp index 5330797..b6e0aed 100644 --- a/cpputest-for-qpcpp-lib/include/cmsDummyActiveObject.hpp +++ b/cpputest-for-qpcpp-lib/include/cmsDummyActiveObject.hpp @@ -134,7 +134,7 @@ class DummyActiveObject : public QP::QActive { static QP::QState initial(DummyActiveObject* const me, QP::QEvt const* const) { - return Q_TRAN(&running); + return me->tran(Q_STATE_CAST(&running)); } static QP::QState running(DummyActiveObject* const me, @@ -143,7 +143,7 @@ class DummyActiveObject : public QP::QActive { QP::QState rtn; switch (e->sig) { case Q_INIT_SIG: - rtn = Q_SUPER(&top); + rtn = me->super(&top); break; case Q_ENTRY_SIG: // purposeful fall through case Q_EXIT_SIG: @@ -153,7 +153,7 @@ class DummyActiveObject : public QP::QActive { if ((me->m_eventHandler != nullptr) && (e->sig != 0)) { me->m_eventHandler(e); } - rtn = Q_SUPER(&top); + rtn = me->super(&top); break; } diff --git a/cpputest-for-qpcpp-lib/include/cmsOrthogonalContainer.hpp b/cpputest-for-qpcpp-lib/include/cmsOrthogonalContainer.hpp index 1288fc9..6cc9186 100644 --- a/cpputest-for-qpcpp-lib/include/cmsOrthogonalContainer.hpp +++ b/cpputest-for-qpcpp-lib/include/cmsOrthogonalContainer.hpp @@ -78,7 +78,7 @@ class OrthogonalContainer : public QP::QActive { { ForEachInTuple(me->m_components, [](auto& component) { component.start(); }); - return Q_TRAN(&running); + return me->tran(Q_STATE_CAST(&running)); } static QP::QState running(OrthogonalContainer* const me, @@ -102,7 +102,7 @@ class OrthogonalContainer : public QP::QActive { rtn = Q_HANDLED(); } else { - rtn = Q_SUPER(&top); + rtn = me->super(&top); } } break; } diff --git a/cpputest-for-qpcpp-lib/include/qp_port.hpp b/cpputest-for-qpcpp-lib/include/qp_port.hpp index 01b44c4..a0b9127 100644 --- a/cpputest-for-qpcpp-lib/include/qp_port.hpp +++ b/cpputest-for-qpcpp-lib/include/qp_port.hpp @@ -11,6 +11,10 @@ #include "qp_config.hpp" // external QP configuration #endif +#ifndef QP_API_VERSION +#define QP_API_VERSION 700 //cpputest for qpcpp support v7.x.x and v8.x.x +#endif + // no-return function specifier (C++11 Standard) // removed due to certain cpputest test functions #define Q_NORETURN void diff --git a/cpputest-for-qpcpp-lib/src/cpputest_qf_port.cpp b/cpputest-for-qpcpp-lib/src/cpputest_qf_port.cpp index b761eef..4630b7c 100644 --- a/cpputest-for-qpcpp-lib/src/cpputest_qf_port.cpp +++ b/cpputest-for-qpcpp-lib/src/cpputest_qf_port.cpp @@ -6,11 +6,11 @@ /// @endcond /// -#define QP_IMPL // this is QP implementation -#include "qp_port.hpp" // QF port -#include "qp_pkg.hpp" // QF package-scope interface -#include "qsafe.h" // QP embedded systems-friendly assertions -#ifdef Q_SPY // QS software tracing enabled? +#define QP_IMPL // this is QP implementation +#include "qp_port.hpp" // QF port +#include "qp_pkg.hpp" // QF package-scope interface +#include "qsafe.h" // QP embedded systems-friendly assertions +#ifdef Q_SPY // QS software tracing enabled? #error "Q_SPY not supported in the cpputest port" #else #include "qs_dummy.hpp" // disable the QS software tracing @@ -39,25 +39,42 @@ int_t QF::run() } #endif +/** + * Fake cpputest event loop for QActive. Only loops + * until queue is empty, then removes it from the + * ready set. + * @param act an active object to run an event loop upon. + */ +void QActive::evtLoop_(QActive* act) +{ + while (!act->m_eQueue.isEmpty()) { + QEvt const* e = act->get_(); + act->dispatch(e, act->m_prio); + QF::gc(e); + } + + if (act->m_eQueue.isEmpty()) { + cpputest_readySet_.remove(act->m_prio); + } +} + void RunUntilNoReadyActiveObjects() { while (cpputest_readySet_.notEmpty()) { std::uint_fast8_t p = cpputest_readySet_.findMax(); + #if QP_VERSION > 800 + QActive* a = QP::QActive::fromRegistry(p); + #elif QP_VERSION > 700 QActive* a = QP::QActive::registry_[p]; + #else + #error "unsupported QP version" + #endif // the active object 'a' must still be registered in QF // (e.g., it must not be stopped) Q_ASSERT_ID(320, a != nullptr); - while (!a->getEQueue().isEmpty()) { - const auto e = a->get_(); - a->dispatch(e, 0); - QF::gc(e); - } - - if (a->getEQueue().isEmpty()) { /* empty queue? */ - cpputest_readySet_.remove(p); - } + QActive::evtLoop_(a); } } @@ -68,23 +85,22 @@ void QF::stop() } //**************************************************************************** -void QActive::start( QPrioSpec const prioSpec, - QEvt const * * const qSto, std::uint_fast16_t const qLen, - void * const stkSto, std::uint_fast16_t const stkSize, - void const * const par) +void QActive::start(QPrioSpec const prioSpec, QEvt const** const qSto, + std::uint_fast16_t const qLen, void* const stkSto, + std::uint_fast16_t const stkSize, void const* const par) { // unused parameters in the cpputest port Q_UNUSED_PAR(stkSto); Q_UNUSED_PAR(stkSize); - m_prio = static_cast(prioSpec & 0xFFU); // QF-priority - m_pthre = static_cast(prioSpec >> 8U); // preemption-thre. - register_(); // make QF aware of this AO + m_prio = static_cast(prioSpec & 0xFFU); // QF-priority + m_pthre = static_cast(prioSpec >> 8U); // preemption-thre. + register_(); // make QF aware of this AO m_eQueue.init(qSto, qLen); - this->init(par, m_prio); // execute initial transition (virtual call) - QS_FLUSH(); // flush the QS trace buffer to the host + this->init(par, m_prio); // execute initial transition (virtual call) + QS_FLUSH(); // flush the QS trace buffer to the host } //............................................................................ diff --git a/cpputest-for-qpcpp-lib/tests/orthogonalComponentTests.cpp b/cpputest-for-qpcpp-lib/tests/orthogonalComponentTests.cpp index 14b110e..573caaa 100644 --- a/cpputest-for-qpcpp-lib/tests/orthogonalComponentTests.cpp +++ b/cpputest-for-qpcpp-lib/tests/orthogonalComponentTests.cpp @@ -78,7 +78,7 @@ class TestComponent : public OrthogonalComponent { static QP::QState initial(TestComponent* const me, QP::QEvt const* const) { - return Q_TRAN(&running); + return me->tran(Q_STATE_CAST(&running)); } static QP::QState running(TestComponent* const me, QP::QEvt const* const e) @@ -109,7 +109,7 @@ class TestComponent : public OrthogonalComponent { rtn = Q_HANDLED(); break; default: - rtn = Q_SUPER(&top); + rtn = me->super(&top); break; } return rtn; diff --git a/cpputest-for-qpcpp-lib/tests/orthogonalContainerTests.cpp b/cpputest-for-qpcpp-lib/tests/orthogonalContainerTests.cpp index 126a8f4..8241c52 100644 --- a/cpputest-for-qpcpp-lib/tests/orthogonalContainerTests.cpp +++ b/cpputest-for-qpcpp-lib/tests/orthogonalContainerTests.cpp @@ -104,7 +104,7 @@ class TestComponent : public OrthogonalComponent { static QP::QState initial(TestComponent* const me, QP::QEvt const* const) { - return Q_TRAN(&running); + return me->tran(Q_STATE_CAST(&running)); } static QP::QState running(TestComponent* const me, QP::QEvt const* const e) @@ -144,7 +144,7 @@ class TestComponent : public OrthogonalComponent { rtn = Q_HANDLED(); break; default: - rtn = Q_SUPER(&top); + rtn = me->super(&top); break; } return rtn;