diff --git a/.gitignore b/.gitignore index 37875d82..65f5ff83 100644 --- a/.gitignore +++ b/.gitignore @@ -37,17 +37,29 @@ version-* JLink*.* -cert/ +include/qs.h +include/qs_pkg.h +include/qxk.h +src/qs/qs.c +src/qs/qs_64bit.c +src/qs/qs_fp.c +src/qs/qs_rx.c +src/qs/qutest.c +src/qxk/qxk.c +src/qxk/qxk_mutex.c +src/qxk/qxk_sema.c +src/qxk/qxk_xthr.c + +ports/posix-qutest/ +ports/win32-qutest/ + +priv/ html/ latex/ -doxygen/gen/ -test_priv/ dbg/ rel/ spy/ -build/ -build_rel/ -build_spy/ +build*/ settings/ .settings/ targetConfigs/ diff --git a/3rd_party b/3rd_party index aca09a2e..43a99789 160000 --- a/3rd_party +++ b/3rd_party @@ -1 +1 @@ -Subproject commit aca09a2e3571adf97e5ce6cb5b1d645ba2418c1d +Subproject commit 43a99789efed81bd200558e742623745822c779a diff --git a/LICENSES/License.txt b/LICENSES/License.txt index e20f603a..5c32ce95 100644 --- a/LICENSES/License.txt +++ b/LICENSES/License.txt @@ -3,8 +3,8 @@ Quantum Leaps Dual-Licensing: The QP/C Real-Time Embedded Framework is dually-licensed under the following two alternatives: -1. Open source GNU General Public License (GPL) -version 3, or alternatively, +1. Open source GNU General Public License (GPL) version 3, + or alternatively, 2. One of the closed source Quantum Leaps commercial licenses. diff --git a/LICENSES/LicenseRef-QL-dual.qlc b/LICENSES/LicenseRef-QL-dual.qlc index efa44673..85a39e0d 100644 --- a/LICENSES/LicenseRef-QL-dual.qlc +++ b/LICENSES/LicenseRef-QL-dual.qlc @@ -1,8 +1,7 @@ -Any user of the QP/C real-time embedded framework +public qpc 2025-12-31 - -Copyright (C) 2005 Quantum Leaps, LLC . +Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. Q u a n t u m L e a P s ------------------------ @@ -10,21 +9,20 @@ Copyright (C) 2005 Quantum Leaps, LLC . SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -This software is dual-licensed under the terms of the open source GNU -General Public License version 3 (or any later version), or alternatively, -under the terms of one of the closed source Quantum Leaps commercial -licenses. - -The terms of the open source GNU General Public License version 3 -can be found at: - -The terms of the closed source Quantum Leaps commercial licenses -can be found at: +The QP/C software is dual-licensed under the terms of the open-source GNU +General Public License (GPL) or under the terms of one of the closed- +source Quantum Leaps commercial licenses. Redistributions in source code must retain this top-level comment block. Plagiarizing this software to sidestep the license obligations is illegal. -Contact information: +NOTE: +The GPL does NOT permit the incorporation of this code into proprietary +programs. Please contact Quantum Leaps for commercial licensing options, +which expressly supersede the GPL and are designed explicitly for +closed-source distribution. + +Quantum Leaps contact information: -#BC89496843DE5343CECA990E1370BDD6F9ACDC56 \ No newline at end of file +#2BACD81DCE8ED122C193E4F48A14170D660DFF1E \ No newline at end of file diff --git a/README.md b/README.md index 309bcb21..da336f16 100644 --- a/README.md +++ b/README.md @@ -34,15 +34,15 @@ provides instructions on how to download, install, and get started with QP. - [AppNote: "Getting Started with QP Real-Time Embedded Frameworks"][AN] contains also a tutorial, in which you build a simple "Blinky" application. -## Licensing -The QP frameworks (QP/C and QP/C++) are licensed under the +# Licensing +The QP/C real-time embedded framework is licensed under the [dual licensing model](https://www.state-machine.com/licensing), with the following licensing options: 1. [Open-source licensing](https://www.state-machine.com/licensing#Open) under the [GNU General Public License (GPLv3)](https://www.gnu.org/licenses/gpl-3.0.en.html). -> NOTE: GPL requires that all modifications to the original code +> NOTE: The GPL requires that all modifications to the original code as well as your application code (Derivative Works as defined in the Copyright Law) must also be released under the terms of the GPL open source license. @@ -56,6 +56,19 @@ proprietary status of their code. all QP frameworks can be licensed commercially, in which case you don't use any open source license and you do not violate your policy. +## Files Removed from the QP/C Open Source GPL Distribution +Due to the widespread non-compliance with the GPL, as well as infringement on the +[dual-licensing model of QP frameworks][Lic], the following QP/C components +have been **removed from the open-source GPL distribution**: +- QS target-resident software tracing component +- QXK dual-mode kernel + +> NOTE: These components are available to the [commercial licensees][Cust] with +the active Support Term. Please contact [Quantum Leaps technical support][Sup] +to get the complete QP/C framework distribution. + +> NOTE: To request **evaluation** of the complete QP/C framework, please contact +Quantum Leaps at: https://www.state-machine.com/contact # About QP/C QP/C (Quantum Platform in C) is a lightweight, open source @@ -103,7 +116,7 @@ without any traditional RTOS. The framework contains a selection of the [preemptive non-blocking QK kernel][QK], and the preemptive, [dual-mode QXK kernel][QXK] that provides all the features you might expect from a traditional RTOS. Native QP ports and ready-to-use examples are provided -for major CPUs, such as ARM Cortex-M (M0/M0+/M3/M4/M7/M23/M33/M85). +for major CPUs, such as ARM Cortex-M (M0/M0+/M3/M4/M7/M23/M33/...). ## Traditional RTOS/OS QP/C can also work with a traditional RTOS, such as ThreadX, embOS, FreeRTOS, @@ -138,12 +151,18 @@ in your web browser. # How to Help this Project? If you like this project, please give it a star (in the upper-right corner of your browser window): -![GitHub star](https://www.state-machine.com/img/github-star.jpg) +

+
+

[RTEF]: [QP]: [QP/C]: [QP/C++]: + [QS/C]: + [QV]: + [QK]: + [QXK]: [QM]: [QTools]: [QP-Rel]: @@ -153,6 +172,7 @@ If you like this project, please give it a star (in the upper-right corner of yo [HSM]: [Lic]: [Cust]: + [Sup]: [AN]: [Tutorial]: [Video]: diff --git a/cmakeSupport.md b/cmakeSupport.md index 3c1639ef..601b2ecc 100644 --- a/cmakeSupport.md +++ b/cmakeSupport.md @@ -38,6 +38,10 @@ set(QPC_PROJECT qpcPrj) set(QPC_CFG_KERNEL QV) set(QPC_CFG_GUI TRUE) set(QPC_CFG_PORT win32) +# QP/C 8.0.0: to include a local 'qp_config.h' add the related include path +# to the qpc build settings. Replace "${CMAKE_CURRENT_LIST_DIR}/include" by +# your project specific path! +set(QPC_CFG_QPCONFIG_H_INCLUDE_PATH ${CMAKE_CURRENT_LIST_DIR}/include) qpc_sdk_init() target_link_libraries(qpcApp PRIVATE qpc) @@ -78,6 +82,8 @@ This file is situated in the root directory of qpc. It performs a pre-initializa * `QPC-CFG-GUI` - BOOL: set this boolean variable to ON/TRUE, if GUI support (win32) shall be compiled in. Default: OFF * `QPC_CFG_UNIT_TEST` - BOOL: set this to ON/TRUE to support qutest, if build configuration `Spy` is active. Default: OFF * `QPC_CFG_VERBOSE` - BOOL: set this to enable more verbosity in message output. Default: OFF +* `QPC_CFG_QPCONFIG_H_INCLUDE_PATH`: - STRING (PATH): (`QP/C 8.0.0`) set this to have the build of QP/C use your project specific `qp_config.h`. + Default: `${QPC_SDK_PATH}/ports/config` ### General usage hints 1. Set `QPC_SDK_PATH` or `QPC_FETCH_FROM_GIT` either in your `CMakeLists.txt` file or as an environment variable. @@ -111,43 +117,13 @@ Many `qpc` examples provide 3 build configurations: These configurations are also supported by qpc with cmake. Different possibilities exist to activate those. ### `qp_config.h` support -Some build configurations require the inclusion of `qp_config.h`. To achieve this, the QPC macro `QP_CONFIG` should be set, when compiling the -`qpc` source files. The include search paths also needs to be set accordingly in order for the preprocessor to be able to find the correct include -file. +With the release of QP/C V8.0.0 the inclusion of `qp_config.h` is mandatory. +The `cmake` build system of qpc addresses this by providing the configuration variable `QPC_CFG_QPCONFIG_H_INCLUDE_PATH`. Set this to the path of your local project's `qp_config.h` and this will automatically be found by the build system. Do this in your main `CMakeLists.txt` file __before__ calling `qpc_sdk_init()`. -As `qp_config.h` is a project related file, which - in most cases - resides outside the `qpc` source code tree, the decision is to handle the -above mentioned topic within the root project's `CMakeLists.txt` file instead of integrating this topic into a rather complicated configuration -of `qpc` itself. +You do not need to set this variable, should the qpc default settings be sufficient for your project. In this case the build system uses the `qp_config.h` file, as it can be found in the directory `${QPC_SDK_PATH}/src/ports/config`. -An example can be found in the [cmake dpp example](https://github.com/QuantumLeaps/qpc-examples/tree/main/posix-win32-cmake/dpp). Have a look into -the example's [CMakeLists.txt](https://github.com/QuantumLeaps/qpc-examples/blob/main/posix-win32-cmake/dpp/CMakeLists.txt). - -You will find the reference to the `qpc` library, followed by the project's specific setup for `qp_config.h` like this: -``` -# set up qpc library -target_link_libraries(dpp - PRIVATE - qpc -) -# should a 'qp_config.h' configuration file be used and is it available -# edit the HINTS in the 'find_file()' call according to your project settings -if(USE_QP_CONFIG) - find_file(QP_CONFIG qp_config.h HINTS ${CMAKE_CURRENT_SOURCE_DIR}) # try to identify 'qp_config.h' - if(QP_CONFIG) # found 'qp_config.h' - cmake_path(GET QP_CONFIG PARENT_PATH QP_CONFIG_DIR) # extract the path from the FQFN - target_compile_definitions(qpc # add -DQP_CONFIG to the qpc build - PUBLIC - QP_CONFIG - ) - target_include_directories(qpc # add the path to 'qp_config.h' to the list of include paths for qpc - PUBLIC - ${QP_CONFIG_DIR} - ) - else() # 'qp_config.h' requested but not find - try to configure and build anyways - message(WARNING "File 'qp_config.h' not found!") - endif() -endif() -``` +An example can be found in the [cmake dpp example](https://github.com/QuantumLeaps/qpcpp-examples/tree/main/posix-win32-cmake/dpp). Have a look into +the example's [CMakeLists.txt](https://github.com/QuantumLeaps/qpcpp-examples/blob/main/posix-win32-cmake/dpp/CMakeLists.txt). ### Multi configuration generators The most easy way to make use of the different configurations is to use a multi config generator like `Ninja Multi-Config` or `MS Visual Studio`. diff --git a/examples b/examples index 16ea07cc..f505eec1 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 16ea07cc4dbcbde83431a9962cf4ec157b951dcf +Subproject commit f505eec147a61e8a10f725bf343f914b5cedb57c diff --git a/include/README.md b/include/README.md new file mode 100644 index 00000000..2c26380d --- /dev/null +++ b/include/README.md @@ -0,0 +1,45 @@ +# Files Missing from the QP/C GPL Distribution +Due to the widespread non-compliance with the GPL, as well as infringement +on the [dual-licensing model of QP frameworks][Lic], the following files +have been **removed from the open-source GPL distribution**: + +``` +qpc +| ++---include +| qs.h +| qs_pkg.h +| qxk.h +| +\---src + | + +---qs + | qs.c + | qs_64bit.c + | qs_fp.c + | qs_rx.c + | qutest.c + | + \---qxk + qxk.c + qxk_mutex.c + qxk_sema.c + qxk_xthr.c +``` + +> NOTE: These files are available to the [commercial licensees][Cust] with +the active Support Term. Please contact [Quantum Leaps technical support][Sup] +to get the complete QP/C framework distribution. + +# QP/C Framework Evaluation +To request **evaluation** of the complete QP/C framework, please contact +Quantum Leaps at: +- https://www.state-machine.com/contact + +# Quantum Leaps Licensing: +To learn more about the open source and commercial licensing options: +- https://www.state-machine.com/licensing + + [Lic]: + [Cust]: + [Sup]: diff --git a/include/qequeue.h b/include/qequeue.h index 70aa1325..cece51b3 100644 --- a/include/qequeue.h +++ b/include/qequeue.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qequeue.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -51,13 +43,11 @@ typedef uint8_t QEQueueCtr; #elif (QF_EQUEUE_CTR_SIZE == 2U) typedef uint16_t QEQueueCtr; -#elif (QF_EQUEUE_CTR_SIZE == 4U) - typedef uint32_t QEQueueCtr; #else - #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" + #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U" #endif -struct QEvt; // forward declaration +struct QEvt; // forward declartion //$declare${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv @@ -70,7 +60,7 @@ typedef struct QEQueue { struct QEvt const * volatile frontEvt; //! @private @memberof QEQueue - struct QEvt const ** ring; + struct QEvt const * * ring; //! @private @memberof QEQueue QEQueueCtr end; @@ -84,18 +74,42 @@ typedef struct QEQueue { //! @private @memberof QEQueue QEQueueCtr volatile nFree; +#ifndef Q_UNSAFE + //! @private @memberof QEQueue + uintptr_t frontEvt_dis; +#endif // ndef Q_UNSAFE + +#ifndef Q_UNSAFE + //! @private @memberof QEQueue + QEQueueCtr head_dis; +#endif // ndef Q_UNSAFE + +#ifndef Q_UNSAFE + //! @private @memberof QEQueue + QEQueueCtr tail_dis; +#endif // ndef Q_UNSAFE + +#ifndef Q_UNSAFE + //! @private @memberof QEQueue + QEQueueCtr nFree_dis; +#endif // ndef Q_UNSAFE + +#ifndef Q_UNSAFE //! @private @memberof QEQueue QEQueueCtr nMin; +#endif // ndef Q_UNSAFE -// public: +// type: } QEQueue; -extern QEQueue QEQueue_dummy; + +// dummy static member to force generating 'struct QEQueue {...}' +extern QEQueue * QEQueue_dummy; // public: //! @public @memberof QEQueue void QEQueue_init(QEQueue * const me, - struct QEvt const ** const qSto, + struct QEvt const * * const qSto, uint_fast16_t const qLen); //! @public @memberof QEQueue @@ -120,7 +134,11 @@ static inline QEQueueCtr QEQueue_getNFree(QEQueue const * const me) { //! @public @memberof QEQueue static inline QEQueueCtr QEQueue_getNMin(QEQueue const * const me) { + #ifndef Q_UNSAFE return me->nMin; + #else + return 0U; + #endif } //! @public @memberof QEQueue diff --git a/include/qk.h b/include/qk.h index 4d916519..e563da80 100644 --- a/include/qk.h +++ b/include/qk.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qk.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -162,8 +154,7 @@ void QK_activate_(void); } while (false) //${QK-impl::QACTIVE_EQUEUE_WAIT_} ........................................... -#define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(320, (me_)->eQueue.frontEvt != (QEvt *)0) +#define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) //${QK-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... #ifndef Q_UNSAFE diff --git a/include/qmpool.h b/include/qmpool.h index 59adf5c0..0bae35d2 100644 --- a/include/qmpool.h +++ b/include/qmpool.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qmpool.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -71,8 +63,8 @@ #endif #define QF_MPOOL_EL(evType_) struct { \ - QFreeBlock sto_[((sizeof(evType_) - 1U) \ - / sizeof(QFreeBlock)) + 1U]; } + QFreeBlock sto_[((sizeof(evType_) - 1U) / (2U * sizeof(void *))) + 1U]; \ +} //$declare${QF::QFreeBlock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv @@ -116,8 +108,20 @@ typedef struct { //! @private @memberof QMPool QMPoolCtr volatile nFree; +#ifndef Q_UNSAFE //! @private @memberof QMPool QMPoolCtr nMin; +#endif // ndef Q_UNSAFE + +#ifndef Q_UNSAFE + //! @private @memberof QMPool + uintptr_t free_head_dis; +#endif // ndef Q_UNSAFE + +#ifndef Q_UNSAFE + //! @private @memberof QMPool + QMPoolCtr nFree_dis; +#endif // ndef Q_UNSAFE } QMPool; // public: diff --git a/include/qp.h b/include/qp.h index b0b5f371..bb878de7 100644 --- a/include/qp.h +++ b/include/qp.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qp.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -44,9 +36,9 @@ #define QP_H_ //============================================================================ -#define QP_VERSION_STR "7.4.0-rc.3" -#define QP_VERSION 740U -#define QP_RELEASE 0x7092C3BBU +#define QP_VERSION_STR "8.0.0" +#define QP_VERSION 800U +#define QP_RELEASE 0x7055936FU //============================================================================ //! @cond INTERNAL @@ -134,12 +126,6 @@ typedef uint16_t QSignal; typedef uint32_t QSignal; #endif // (Q_SIGNAL_SIZE == 4U) -//${QEP::QEVT_MARKER} ........................................................ -#define QEVT_MARKER 0xE0U - -//${QEP::QEVT_DYNAMIC} ....................................................... -#define QEVT_DYNAMIC 0U - //${QEP::QEvt} ............................................................... //! @class QEvt typedef struct QEvt { @@ -151,10 +137,10 @@ typedef struct QEvt { // private: //! @private @memberof QEvt - uint8_t volatile refCtr_; + uint8_t evtTag_; //! @private @memberof QEvt - uint8_t evtTag_; + uint8_t volatile refCtr_; } QEvt; extern QEvt const QEvt_reserved_[4]; @@ -166,8 +152,8 @@ static inline void QEvt_ctor(QEvt * const me, enum_t const sig) { me->sig = (QSignal)sig; + me->evtTag_ = 0x0FU; me->refCtr_ = 0U; - me->evtTag_ = QEVT_MARKER; } //! @public @memberof QEvt @@ -180,15 +166,18 @@ static inline QEvt * QEvt_init(QEvt * const me, // private: +#ifndef Q_UNSAFE //! @private @memberof QEvt static inline bool QEvt_verify_(QEvt const * const me) { - return (me != (QEvt const *)0) - && ((me->evtTag_ & 0xF0U) == QEVT_MARKER); + uint8_t rc = me->refCtr_; + return (rc <= 2U*QF_MAX_ACTIVE) + && (((me->evtTag_ ^ rc) & 0x0FU) == 0x0FU); } +#endif // ndef Q_UNSAFE //! @private @memberof QEvt static inline uint_fast8_t QEvt_getPoolNum_(QEvt const * const me) { - return (uint_fast8_t)me->evtTag_ & 0x0FU; + return (uint_fast8_t)(me->evtTag_ >> 4U); } //${QEP::QStateRet} .......................................................... @@ -198,7 +187,6 @@ static inline uint_fast8_t QEvt_getPoolNum_(QEvt const * const me) { enum QStateRet { // unhandled and need to "bubble up" Q_RET_SUPER, //!< event passed to superstate to handle - Q_RET_SUPER_SUB, //!< event passed to submachine superstate Q_RET_UNHANDLED, //!< event unhandled due to guard // handled and do not need to "bubble up" @@ -214,12 +202,10 @@ enum QStateRet { // transitions need to execute transition-action table in ::QMsm Q_RET_TRAN, //!< regular transition - Q_RET_TRAN_INIT, //!< initial transition in a state or submachine - Q_RET_TRAN_EP, //!< entry-point transition into a submachine + Q_RET_TRAN_INIT, //!< initial transition in a state // transitions that additionally clobber me->state Q_RET_TRAN_HIST, //!< transition to history of a given state - Q_RET_TRAN_XP //!< exit-point transition out of a submachine }; //${QEP::QState} ............................................................. @@ -253,16 +239,6 @@ typedef struct QMTranActTable { QActionHandler const act[1]; //!< @private @memberof QMTranActTable } QMTranActTable; -//${QEP::QReservedSig} ....................................................... -//! Reserved signals by the QHsm-style state machine implementation -enum QReservedSig { - Q_EMPTY_SIG, //!< signal to execute the default case - Q_ENTRY_SIG, //!< signal for coding entry actions - Q_EXIT_SIG, //!< signal for coding exit actions - Q_INIT_SIG, //!< signal for coding initial transitions - Q_USER_SIG //!< offset for the user signals (QP Application) -}; - //${QEP::QAsmAttr} ........................................................... union QAsmAttr { QStateHandler fun; //!< @private @memberof QAsmAttr @@ -451,7 +427,10 @@ QState QMsm_enterHistory_( //$declare${QEP-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QEP-macros::QEVT_INITIALIZER} ............................................ -#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0U, QEVT_MARKER } +#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0x01U, 0x0EU } + +//${QEP-macros::QEVT_DYNAMIC} ................................................ +#define QEVT_DYNAMIC ((uint8_t)0) //${QEP-macros::QASM_INIT} ................................................... #ifdef Q_SPY @@ -494,6 +473,21 @@ QState QMsm_enterHistory_( //${QEP-macros::Q_MSM_UPCAST} ................................................ #define Q_MSM_UPCAST(ptr_) ((QMsm *)(ptr_)) +//${QEP-macros::Q_EMPTY_SIG} ................................................. +#define Q_EMPTY_SIG ((QSignal)0) + +//${QEP-macros::Q_ENTRY_SIG} ................................................. +#define Q_ENTRY_SIG ((QSignal)1) + +//${QEP-macros::Q_EXIT_SIG} .................................................. +#define Q_EXIT_SIG ((QSignal)2) + +//${QEP-macros::Q_INIT_SIG} .................................................. +#define Q_INIT_SIG ((QSignal)3) + +//${QEP-macros::Q_USER_SIG} .................................................. +#define Q_USER_SIG ((enum_t)4) + //${QEP-macros::Q_TRAN} ...................................................... #define Q_TRAN(target_) \ ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \ @@ -582,18 +576,6 @@ QState QMsm_enterHistory_( (struct QMTranActTable const *)(tatbl_))), \ (QState)Q_RET_TRAN_HIST) -//${QEP-macros::QM_TRAN_EP} .................................................. -#define QM_TRAN_EP(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), \ - (QState)Q_RET_TRAN_EP) - -//${QEP-macros::QM_TRAN_XP} .................................................. -#define QM_TRAN_XP(xp_, tatbl_) \ - ((((Q_ASM_UPCAST(me))->state.act = (xp_)), \ - ((Q_ASM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - (QState)Q_RET_TRAN_XP) - //${QEP-macros::QM_HANDLED} .................................................. #define QM_HANDLED() ((QState)Q_RET_HANDLED) @@ -603,11 +585,6 @@ QState QMsm_enterHistory_( //${QEP-macros::QM_SUPER} .................................................... #define QM_SUPER() ((QState)Q_RET_SUPER) -//${QEP-macros::QM_SUPER_SUB} ................................................ -#define QM_SUPER_SUB(host_) \ - ((Q_ASM_UPCAST(me))->temp.obj = (host_), \ - (QState)Q_RET_SUPER_SUB) - //${QEP-macros::QM_STATE_NULL} ............................................... #define QM_STATE_NULL ((QMState *)0) //$enddecl${QEP-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -774,7 +751,7 @@ static inline bool QPSet_verify_(QPSet const * const me, #endif // ndef Q_UNSAFE //${QF::types::QSubscrList} .................................................. -// @struct QSubscrList +//! @struct QSubscrList typedef struct { // private: @@ -787,6 +764,9 @@ typedef struct { #endif // ndef Q_UNSAFE } QSubscrList; +//${QF::types::QEvtPtr} ...................................................... +typedef QEvt const * QEvtPtr; + //${QF::types::QEQueue} ...................................................... struct QEQueue; //$enddecl${QF::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -859,7 +839,7 @@ void QActive_setAttr(QActive * const me, //! @public @memberof QActive void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, @@ -972,19 +952,40 @@ typedef struct QTimeEvt { //! @private @memberof QTimeEvt struct QTimeEvt * volatile next; +#ifndef Q_UNSAFE //! @private @memberof QTimeEvt - void * volatile act; + uintptr_t next_dis; +#endif // ndef Q_UNSAFE + + //! @private @memberof QTimeEvt + void * act; //! @private @memberof QTimeEvt QTimeEvtCtr volatile ctr; +#ifndef Q_UNSAFE + //! @private @memberof QTimeEvt + QTimeEvtCtr ctr_dis; +#endif // ndef Q_UNSAFE + //! @private @memberof QTimeEvt QTimeEvtCtr interval; + + //! @private @memberof QTimeEvt + uint8_t tickRate; + + //! @private @memberof QTimeEvt + uint8_t flags; } QTimeEvt; //! @static @private @memberof QTimeEvt extern QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; +#ifndef Q_UNSAFE +//! @static @private @memberof QTimeEvt +extern uintptr_t QTimeEvt_timeEvtHead_dis_[QF_MAX_TICK_RATE]; +#endif // ndef Q_UNSAFE + // public: //! @public @memberof QTimeEvt @@ -995,15 +996,15 @@ void QTimeEvt_ctorX(QTimeEvt * const me, //! @public @memberof QTimeEvt void QTimeEvt_armX(QTimeEvt * const me, - QTimeEvtCtr const nTicks, - QTimeEvtCtr const interval); + uint32_t const nTicks, + uint32_t const interval); //! @public @memberof QTimeEvt bool QTimeEvt_disarm(QTimeEvt * const me); //! @public @memberof QTimeEvt bool QTimeEvt_rearm(QTimeEvt * const me, - QTimeEvtCtr const nTicks); + uint32_t const nTicks); //! @public @memberof QTimeEvt bool QTimeEvt_wasDisarmed(QTimeEvt * const me); @@ -1011,6 +1012,9 @@ bool QTimeEvt_wasDisarmed(QTimeEvt * const me); //! @public @memberof QTimeEvt QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me); +//! @static @private @memberof QTimeEvt +void QTimeEvt_init(void); + //! @static @private @memberof QTimeEvt void QTimeEvt_tick_( uint_fast8_t const tickRate, diff --git a/include/qp_pkg.h b/include/qp_pkg.h index 81cc001b..6e36f6fe 100644 --- a/include/qp_pkg.h +++ b/include/qp_pkg.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qp_pkg.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -77,23 +69,29 @@ void QF_bzero_( uint_fast16_t const len); //$enddecl${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// Bitmasks are for the QTimeEvt::refCtr_ attribute (inherited from ::QEvt). -// In ::QTimeEvt this attribute is NOT used for reference counting. -#define QTE_IS_LINKED (1U << 7U) -#define QTE_WAS_DISARMED (1U << 6U) -#define QTE_TICK_RATE 0x0FU +// Bitmasks are for the QTimeEvt::flags attribute +#define QTE_FLAG_IS_LINKED (1U << 7U) +#define QTE_FLAG_WAS_DISARMED (1U << 6U) //! @private @memberof QEvt static inline void QEvt_refCtr_inc_(QEvt const *me) { - ++((QEvt *)me)->refCtr_; + uint8_t rc = me->refCtr_ + 1U; + ((QEvt *)me)->refCtr_ = rc; // cast away 'const' +#ifndef Q_UNSAFE + ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); +#endif // ndef Q_UNSAFE } //! @private @memberof QEvt static inline void QEvt_refCtr_dec_(QEvt const *me) { - --((QEvt *)me)->refCtr_; + uint8_t rc = me->refCtr_ - 1U; + ((QEvt *)me)->refCtr_ = rc; // cast away 'const' +#ifndef Q_UNSAFE + ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); +#endif // ndef Q_UNSAFE } -#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) -#define Q_UINTPTR_CAST_(ptr_) ((uintptr_t)(ptr_)) +#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) +#define Q_PTR2UINT_CAST_(ptr_) ((uintptr_t)(ptr_)) #endif // QP_PKG_H_ diff --git a/include/qpc.h b/include/qpc.h index c02c08a4..8a4816ef 100644 --- a/include/qpc.h +++ b/include/qpc.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qpc.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -43,26 +35,25 @@ #ifndef QPC_H_ #define QPC_H_ -//============================================================================ #include "qp_port.h" // QP port from the port directory #include "qsafe.h" // QP Functional Safety (FuSa) Subsystem #ifdef Q_SPY // software tracing enabled? #include "qs_port.h" // QS/C port from the port directory #else - #include "qs_dummy.h" // QS/C dummy (inactive) interface + #include "qs_dummy.h" // QS/C dummy interface (inactive) #endif -//============================================================================ #ifndef QP_API_VERSION - -#define QP_API_VERSION 0 - + #define QP_API_VERSION 0 #endif // #ifndef QP_API_VERSION -//============================================================================ // QP API compatibility layer... +//============================================================================ +#if (QP_API_VERSION < 800) -#if (QP_API_VERSION < 740) +#define QM_SUPER_SUB(host_) error "submachines no longer supported" +#define QM_TRAN_EP(tatbl_) error "submachines no longer supported" +#define QM_TRAN_XP(xp_, tatbl_) error "submachines no longer supported" #ifdef QEVT_DYN_CTOR //! @deprecated #QEVT_DYN_CTOR, please use #QEVT_PAR_INIT @@ -98,6 +89,12 @@ typedef char char_t; //! number that **always** evaluates the `expr_` expression. #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) +#elif defined Q_UNSAFE + + //! @deprecated general purpose assertion with user-specified ID + //! number that **always** evaluates the `expr_` expression. + #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) + #else // QP FuSa Subsystem enabled //! @deprecated general purpose assertion with user-specified ID @@ -144,78 +141,6 @@ static inline void QF_psInit( //! @deprecated instead use: QASM_IS_IN() #define QHsm_isIn(me_, state_) QASM_IS_IN((QAsm *)(me_), (state_)) -//============================================================================ -#if (QP_API_VERSION < 691) - -//! @deprecated enable the QS global filter -#define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_)) - -//! @deprecated disable the QS global filter -#define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_)) - -//! @deprecated enable the QS local filter for SM (state machine) object -#define QS_FILTER_SM_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for AO (active objects) -#define QS_FILTER_AO_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for MP (memory pool) object -#define QS_FILTER_MP_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for EQ (event queue) object -#define QS_FILTER_EQ_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for TE (time event) object -#define QS_FILTER_TE_OBJ(obj_) ((void)0) - -#ifdef Q_SPY - -//! @deprecated local Filter for a generic application object `obj_`. -#define QS_FILTER_AP_OBJ(obj_) (QS_filt_.loc_AP = (obj_)) - -//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID() -#define QS_BEGIN(rec_, obj_) \ - if (((QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ - & (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \ - && ((QS_priv_.locFilter_AP == (void *)0) \ - || (QS_priv_.locFilter_AP == (obj_)))) \ - { \ - QS_CRIT_STAT \ - QS_CRIT_ENTRY(); \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - -//! @deprecated Output formatted uint32_t to the QS record -#define QS_U32_HEX(width_, data_) \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | QS_HEX_FMT, (data_))) - -#else - -#define QS_FILTER_AP_OBJ(obj_) ((void)0) -#define QS_BEGIN(rec_, obj_) if (false) { -#define QS_U32_HEX(width_, data_) ((void)0) - -#endif - -//============================================================================ -#if (QP_API_VERSION < 660) - -//! @deprecated casting to QXThreadHandler -//! instead use: the new signature of QXThreadHandler and don't cast -#define Q_XTHREAD_CAST(handler_) ((QXThreadHandler)(handler_)) - -//============================================================================ -#if (QP_API_VERSION < 580) - -//! @deprecated instead use: QASM_INIT() -#define QMSM_INIT(me_, par_, qsId_) QASM_INIT((me_), (par_), (qsId_)) - -//! @deprecated instead use: QASM_DISPATCH() -#define QMSM_DISPATCH(me_, e_, qsId_) QASM_DISPATCH((me_), (e_), (qsId_)) - -#endif // QP_API_VERSION < 580 -#endif // QP_API_VERSION < 660 -#endif // QP_API_VERSION < 691 -#endif // QP_API_VERSION < 700 +#endif // QP_API_VERSION < 800 #endif // QPC_H_ diff --git a/include/qs.h b/include/qs.h deleted file mode 100644 index cd11684a..00000000 --- a/include/qs.h +++ /dev/null @@ -1,1033 +0,0 @@ -//$file${include::qs.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qs.h} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${include::qs.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#ifndef QS_H_ -#define QS_H_ - -#ifndef Q_SPY -#error "Q_SPY must be defined to include qs.h" -#endif - -//============================================================================ -//! @cond INTERNAL - -#ifndef QS_CTR_SIZE -#define QS_CTR_SIZE 2U -#endif - -#ifndef QS_TIME_SIZE -#define QS_TIME_SIZE 4U -#endif - -//! @endcond -//============================================================================ - -//$declare${QS::types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::types::QS} ........................................................... -//! @class QS -typedef struct QS { - //! @cond INTERNAL - uint8_t dummy; - //! @endcond -} QS; - -//${QS::types::QSpyPre} ...................................................... -//! @static @public @memberof QS -//! pre-defined QS record IDs -enum QSpyPre { - // [0] QS session (not maskable) - QS_EMPTY, //!< QS record for cleanly starting a session - - // [1] SM records - QS_QEP_STATE_ENTRY, //!< a state was entered - QS_QEP_STATE_EXIT, //!< a state was exited - QS_QEP_STATE_INIT, //!< an initial transition was taken in a state - QS_QEP_INIT_TRAN, //!< the top-most initial transition was taken - QS_QEP_INTERN_TRAN, //!< an internal transition was taken - QS_QEP_TRAN, //!< a regular transition was taken - QS_QEP_IGNORED, //!< an event was ignored (silently discarded) - QS_QEP_DISPATCH, //!< an event was dispatched (begin of RTC step) - QS_QEP_UNHANDLED, //!< an event was un-handled due to a guard - - // [10] Active Object (AO) records - QS_QF_ACTIVE_DEFER, //!< AO deferred an event - QS_QF_ACTIVE_RECALL, //!< AO recalled an event - QS_QF_ACTIVE_SUBSCRIBE, //!< an AO subscribed to an event - QS_QF_ACTIVE_UNSUBSCRIBE, //!< an AO unsubscribed to an event - QS_QF_ACTIVE_POST, //!< an event was posted (FIFO) directly to AO - QS_QF_ACTIVE_POST_LIFO, //!< an event was posted (LIFO) directly to AO - QS_QF_ACTIVE_GET, //!< AO got an event and its queue is not empty - QS_QF_ACTIVE_GET_LAST,//!< AO got an event and its queue is empty - QS_QF_ACTIVE_RECALL_ATTEMPT, //!< AO attempted to recall an event - - // [19] Event Queue (EQ) records - QS_QF_EQUEUE_POST, //!< an event was posted (FIFO) to a raw queue - QS_QF_EQUEUE_POST_LIFO, //!< an event was posted (LIFO) to a raw queue - QS_QF_EQUEUE_GET, //!< get an event and queue still not empty - QS_QF_EQUEUE_GET_LAST,//!< get the last event from the queue - - // [23] Framework (QF) records - QS_QF_NEW_ATTEMPT, //!< an attempt to allocate an event failed - - // [24] Memory Pool (MP) records - QS_QF_MPOOL_GET, //!< a memory block was removed from memory pool - QS_QF_MPOOL_PUT, //!< a memory block was returned to memory pool - - // [26] Additional Framework (QF) records - QS_QF_PUBLISH, //!< an event was published to active objects - QS_QF_NEW_REF, //!< new event reference was created - QS_QF_NEW, //!< new event was created - QS_QF_GC_ATTEMPT, //!< garbage collection attempt - QS_QF_GC, //!< garbage collection - QS_QF_TICK, //!< QTimeEvt tick was called - - // [32] Time Event (TE) records - QS_QF_TIMEEVT_ARM, //!< a time event was armed - QS_QF_TIMEEVT_AUTO_DISARM, //!< a time event expired and was disarmed - QS_QF_TIMEEVT_DISARM_ATTEMPT,//!< attempt to disarm a disarmed QTimeEvt - QS_QF_TIMEEVT_DISARM, //!< true disarming of an armed time event - QS_QF_TIMEEVT_REARM, //!< rearming of a time event - QS_QF_TIMEEVT_POST, //!< a time event posted itself directly to an AO - - // [38] Additional Framework (QF) records - QS_QF_DELETE_REF, //!< an event reference is about to be deleted - QS_QF_CRIT_ENTRY, //!< critical section was entered - QS_QF_CRIT_EXIT, //!< critical section was exited - QS_QF_ISR_ENTRY, //!< an ISR was entered - QS_QF_ISR_EXIT, //!< an ISR was exited - QS_QF_INT_DISABLE, //!< interrupts were disabled - QS_QF_INT_ENABLE, //!< interrupts were enabled - - // [45] Additional Active Object (AO) records - QS_QF_ACTIVE_POST_ATTEMPT,//!< attempt to post an evt to AO failed - - // [46] Additional Event Queue (EQ) records - QS_QF_EQUEUE_POST_ATTEMPT,//!< attempt to post evt to QEQueue failed - - // [47] Additional Memory Pool (MP) records - QS_QF_MPOOL_GET_ATTEMPT, //!< attempt to get a memory block failed - - // [48] Scheduler (SC) records - QS_SCHED_PREEMPT, //!< scheduler asynchronously preempted a task - QS_SCHED_RESTORE, //!< scheduler restored preempted task - QS_SCHED_LOCK, //!< scheduler was locked - QS_SCHED_UNLOCK, //!< scheduler was unlocked - QS_SCHED_NEXT, //!< scheduler started next task - QS_SCHED_IDLE, //!< scheduler restored the idle task - - // [54] Miscellaneous QS records (not maskable) - QS_ENUM_DICT, //!< enumeration dictionary entry - - // [55] Additional QEP records - QS_QEP_TRAN_HIST, //!< a tran. to history was taken - QS_QEP_TRAN_EP, //!< a tran. to entry point into a submachine - QS_QEP_TRAN_XP, //!< a tran. to exit point out of a submachine - - // [58] Miscellaneous QS records (not maskable) - QS_TEST_PAUSED, //!< test has been paused - QS_TEST_PROBE_GET, //!< reports that Test-Probe has been used - QS_SIG_DICT, //!< signal dictionary entry - QS_OBJ_DICT, //!< object dictionary entry - QS_FUN_DICT, //!< function dictionary entry - QS_USR_DICT, //!< user QS record dictionary entry - QS_TARGET_INFO, //!< reports the Target information - QS_TARGET_DONE, //!< reports completion of a user callback - QS_RX_STATUS, //!< reports QS data receive status - QS_QUERY_DATA, //!< reports the data from "current object" query - QS_PEEK_DATA, //!< reports the data from the PEEK query - QS_ASSERT_FAIL, //!< assertion failed in the code - QS_QF_RUN, //!< QF_run() was entered - - // [71] Semaphore (SEM) records - QS_SEM_TAKE, //!< a semaphore was taken by a thread - QS_SEM_BLOCK, //!< a semaphore blocked a thread - QS_SEM_SIGNAL, //!< a semaphore was signaled - QS_SEM_BLOCK_ATTEMPT, //!< a semaphore blocked was attempted - - // [75] Mutex (MTX) records - QS_MTX_LOCK, //!< a mutex was locked - QS_MTX_BLOCK, //!< a mutex blocked a thread - QS_MTX_UNLOCK, //!< a mutex was unlocked - QS_MTX_LOCK_ATTEMPT, //!< a mutex lock was attempted - QS_MTX_BLOCK_ATTEMPT, //!< a mutex blocking was attempted - QS_MTX_UNLOCK_ATTEMPT,//!< a mutex unlock was attempted - - // [81] - QS_PRE_MAX //!< the # predefined signals -}; - -//${QS::types::QSpyGroups} ................................................... -//! @static @public @memberof QS -//! QS-TX record groups for QS_GLB_FILTER() -enum QSpyGroups { - QS_ALL_RECORDS = 0xF0,//!< all maskable QS records - QS_SM_RECORDS, //!< State Machine QS records - QS_AO_RECORDS, //!< Active Object QS records - QS_EQ_RECORDS, //!< Event Queues QS records - QS_MP_RECORDS, //!< Memory Pools QS records - QS_TE_RECORDS, //!< Time Events QS records - QS_QF_RECORDS, //!< QF QS records - QS_SC_RECORDS, //!< Scheduler QS records - QS_SEM_RECORDS, //!< Semaphore QS records - QS_MTX_RECORDS, //!< Mutex QS records - QS_U0_RECORDS, //!< User Group 100-104 records - QS_U1_RECORDS, //!< User Group 105-109 records - QS_U2_RECORDS, //!< User Group 110-114 records - QS_U3_RECORDS, //!< User Group 115-119 records - QS_U4_RECORDS, //!< User Group 120-124 records - QS_UA_RECORDS //!< All User records -}; - -//${QS::types::QSpyUserOffsets} .............................................. -//! @static @public @memberof QS -//! QS user record group offsets for QS_GLB_FILTER() -enum QSpyUserOffsets { - QS_USER = 100, //!< the first record available to QS users - QS_USER0 = QS_USER, //!< offset for User Group 0 - QS_USER1 = (enum_t)QS_USER0 + 5, //!< offset for User Group 1 - QS_USER2 = (enum_t)QS_USER1 + 5, //!< offset for User Group 2 - QS_USER3 = (enum_t)QS_USER2 + 5, //!< offset for User Group 3 - QS_USER4 = (enum_t)QS_USER3 + 5 //!< offset for User Group 4 -}; - -//${QS::types::QSpyIdOffsets} ................................................ -//! @static @public @memberof QS -//! QS ID offsets for QS_LOC_FILTER() -enum QSpyIdOffsets { - QS_AO_ID = 0, //!< offset for AO priorities - QS_EP_ID = 64, //!< offset for event-pool IDs - QS_EQ_ID = 80, //!< offset for event-queue IDs - QS_AP_ID = 96 //!< offset for Application-specific IDs -}; - -//${QS::types::QSpyIdGroups} ................................................. -//! @static @public @memberof QS -//! QS ID groups for QS_LOC_FILTER() -enum QSpyIdGroups { - QS_ALL_IDS = 0xF0, //!< all QS IDs - QS_AO_IDS = 0x80 + (enum_t)QS_AO_ID, //!< AO IDs (priorities) - QS_EP_IDS = 0x80 + (enum_t)QS_EP_ID, //!< event-pool IDs - QS_EQ_IDS = 0x80 + (enum_t)QS_EQ_ID, //!< event-queue IDs - QS_AP_IDS = 0x80 + (enum_t)QS_AP_ID //!< Application-specific IDs -}; - -//${QS::types::QSpyId} ....................................................... -//! @struct QSpyId -typedef struct { uint8_t prio; } QSpyId; - -//${QS::types::QSObj} ........................................................ -#if (QS_OBJ_PTR_SIZE == 2U) -typedef uint16_t QSObj; -#endif // (QS_OBJ_PTR_SIZE == 2U) - -//${QS::types::QSObj} ........................................................ -#if (QS_OBJ_PTR_SIZE == 4U) -typedef uint32_t QSObj; -#endif // (QS_OBJ_PTR_SIZE == 4U) - -//${QS::types::QSObj} ........................................................ -#if (QS_OBJ_PTR_SIZE == 8U) -typedef uint64_t QSObj; -#endif // (QS_OBJ_PTR_SIZE == 8U) - -//${QS::types::QSFun} ........................................................ -#if (QS_FUN_PTR_SIZE == 2U) -typedef uint16_t QSFun; -#endif // (QS_FUN_PTR_SIZE == 2U) - -//${QS::types::QSFun} ........................................................ -#if (QS_FUN_PTR_SIZE == 4U) -typedef uint32_t QSFun; -#endif // (QS_FUN_PTR_SIZE == 4U) - -//${QS::types::QSFun} ........................................................ -#if (QS_FUN_PTR_SIZE == 8U) -typedef uint64_t QSFun; -#endif // (QS_FUN_PTR_SIZE == 8U) - -//${QS::types::QSpyFunPtr} ................................................... -//! @static @private @memberof QS -typedef void (* QSpyFunPtr )(void); - -//${QS::types::QSCtr} ........................................................ -#if (QS_CTR_SIZE == 2U) -typedef uint16_t QSCtr; -#endif // (QS_CTR_SIZE == 2U) - -//${QS::types::QSCtr} ........................................................ -#if (QS_CTR_SIZE == 4U) -typedef uint32_t QSCtr; -#endif // (QS_CTR_SIZE == 4U) - -//${QS::types::QSTimeCtr} .................................................... -#if (QS_TIME_SIZE == 2U) -typedef uint16_t QSTimeCtr; -#endif // (QS_TIME_SIZE == 2U) - -//${QS::types::QSTimeCtr} .................................................... -#if (QS_TIME_SIZE == 4U) -typedef uint32_t QSTimeCtr; -#endif // (QS_TIME_SIZE == 4U) -//$enddecl${QS::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::filters::Filter} ..................................................... -//! @struct QS_Filter -typedef struct { -// public: - uint8_t glb[16]; - uint8_t loc[16]; -} QS_Filter; - -//${QS::filters::filt_} ...................................................... -//! @static @private @memberof QS -extern QS_Filter QS_filt_; -//$enddecl${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QS-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS-macros::QS_INIT} ...................................................... -#define QS_INIT(arg_) (QS_onStartup(arg_)) - -//${QS-macros::QS_EXIT} ...................................................... -#define QS_EXIT() (QS_onCleanup()) - -//${QS-macros::QS_OUTPUT} .................................................... -#define QS_OUTPUT() (QS_output()) - -//${QS-macros::QS_RX_INPUT} .................................................. -#define QS_RX_INPUT() (QS_rx_input()) - -//${QS-macros::QS_GLB_FILTER} ................................................ -#define QS_GLB_FILTER(rec_) (QS_glbFilter_((int_fast16_t)(rec_))) - -//${QS-macros::QS_LOC_FILTER} ................................................ -#define QS_LOC_FILTER(qsId_) (QS_locFilter_((int_fast16_t)(qsId_))) - -//${QS-macros::QS_BEGIN_ID} .................................................. -#define QS_BEGIN_ID(rec_, qsId_) \ -if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \ - QS_CRIT_STAT \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - -//${QS-macros::QS_END} ....................................................... -#define QS_END() } \ - QS_endRec_(); \ - QS_MEM_APP(); \ - QS_CRIT_EXIT(); \ -} - -//${QS-macros::QS_FLUSH} ..................................................... -#define QS_FLUSH() (QS_onFlush()) - -//${QS-macros::QS_BEGIN_INCRIT} .............................................. -#define QS_BEGIN_INCRIT(rec_, qsId_) \ -if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - -//${QS-macros::QS_END_INCRIT} ................................................ -#define QS_END_INCRIT() } \ - QS_endRec_(); \ -} - -//${QS-macros::QS_GLB_CHECK_} ................................................ -#define QS_GLB_CHECK_(rec_) \ - (((uint_fast8_t)QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ - & ((uint_fast8_t)1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) - -//${QS-macros::QS_LOC_CHECK_} ................................................ -#define QS_LOC_CHECK_(qsId_) \ - (((uint_fast8_t)QS_filt_.loc[(uint_fast8_t)(qsId_) >> 3U] \ - & ((uint_fast8_t)1U << ((uint_fast8_t)(qsId_) & 7U))) != 0U) - -//${QS-macros::QS_REC_DONE} .................................................. -#ifndef QS_REC_DONE -#define QS_REC_DONE() ((void)0) -#endif // ndef QS_REC_DONE - -//${QS-macros::QS_I8} ........................................................ -#define QS_I8(width_, data_) \ - (QS_u8_fmt_((uint8_t)(((width_) << 4U) & 0x7U) | (uint8_t)QS_I8_ENUM_T, \ - (data_))) - -//${QS-macros::QS_U8} ........................................................ -#define QS_U8(width_, data_) \ - (QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_))) - -//${QS-macros::QS_I16} ....................................................... -#define QS_I16(width_, data_) \ - (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_))) - -//${QS-macros::QS_U16} ....................................................... -#define QS_U16(width_, data_) \ - (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_))) - -//${QS-macros::QS_I32} ....................................................... -#define QS_I32(width_, data_) \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_))) - -//${QS-macros::QS_U32} ....................................................... -#define QS_U32(width_, data_) \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_))) - -//${QS-macros::QS_I64} ....................................................... -#define QS_I64(width_, data_) \ - (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_))) - -//${QS-macros::QS_U64} ....................................................... -#define QS_U64(width_, data_) \ - (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_))) - -//${QS-macros::QS_F32} ....................................................... -#define QS_F32(width_, data_) \ - (QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_))) - -//${QS-macros::QS_F64} ....................................................... -#define QS_F64(width_, data_) \ - (QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_))) - -//${QS-macros::QS_STR} ....................................................... -#define QS_STR(str_) (QS_str_fmt_((str_))) - -//${QS-macros::QS_MEM} ....................................................... -#define QS_MEM(mem_, size_) (QS_mem_fmt_((mem_), (size_))) - -//${QS-macros::QS_ENUM} ...................................................... -#define QS_ENUM(group_, value_) \ - (QS_u8_fmt_((uint8_t)(0x80U | ((group_) << 4U)) | (uint8_t)QS_I8_ENUM_T,\ - (uint8_t)(value_))) - -//${QS-macros::QS_TIME_PRE_} ................................................. -#if (QS_TIME_SIZE == 2U) -#define QS_TIME_PRE_() (QS_u16_raw_(QS_onGetTime())) -#endif // (QS_TIME_SIZE == 2U) - -//${QS-macros::QS_TIME_PRE_} ................................................. -#if (QS_TIME_SIZE == 4U) -#define QS_TIME_PRE_() (QS_u32_raw_(QS_onGetTime())) -#endif // (QS_TIME_SIZE == 4U) - -//${QS-macros::QS_OBJ} ....................................................... -#if (QS_OBJ_PTR_SIZE == 2U) -#define QS_OBJ(obj_) (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_))) -#endif // (QS_OBJ_PTR_SIZE == 2U) - -//${QS-macros::QS_OBJ} ....................................................... -#if (QS_OBJ_PTR_SIZE == 4U) -#define QS_OBJ(obj_) (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) -#endif // (QS_OBJ_PTR_SIZE == 4U) - -//${QS-macros::QS_OBJ} ....................................................... -#if (QS_OBJ_PTR_SIZE == 8U) -#define QS_OBJ(obj_) (QS_u64_fmt_(QS_OBJ_T, (uint64_t)(obj_))) -#endif // (QS_OBJ_PTR_SIZE == 8U) - -//${QS-macros::QS_FUN} ....................................................... -#if (QS_FUN_PTR_SIZE == 2U) -#define QS_FUN(fun_) (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_))) -#endif // (QS_FUN_PTR_SIZE == 2U) - -//${QS-macros::QS_FUN} ....................................................... -#if (QS_FUN_PTR_SIZE == 4U) -#define QS_FUN(fun_) (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) -#endif // (QS_FUN_PTR_SIZE == 4U) - -//${QS-macros::QS_FUN} ....................................................... -#if (QS_FUN_PTR_SIZE == 8U) -#define QS_FUN(fun_) (QS_u64_fmt_(QS_FUN_T, (uint64_t)(fun_))) -#endif // (QS_FUN_PTR_SIZE == 8U) - -//${QS-macros::QS_SIG} ....................................................... -#if (Q_SIGNAL_SIZE == 1U) -#define QS_SIG(sig_, obj_) \ - QS_u8_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) -#endif // (Q_SIGNAL_SIZE == 1U) - -//${QS-macros::QS_SIG} ....................................................... -#if (Q_SIGNAL_SIZE == 2U) -#define QS_SIG(sig_, obj_) \ - QS_u16_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) -#endif // (Q_SIGNAL_SIZE == 2U) - -//${QS-macros::QS_SIG} ....................................................... -#if (Q_SIGNAL_SIZE == 4U) -#define QS_SIG(sig_, obj_) \ - QS_u32_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) -#endif // (Q_SIGNAL_SIZE == 4U) - -//${QS-macros::QS_SIG_DICTIONARY} ............................................ -#define QS_SIG_DICTIONARY(sig_, obj_) \ - (QS_sig_dict_pre_((QSignal)(sig_), (obj_), #sig_)) - -//${QS-macros::QS_OBJ_DICTIONARY} ............................................ -#define QS_OBJ_DICTIONARY(obj_) \ - (QS_obj_dict_pre_((obj_), #obj_)) - -//${QS-macros::QS_OBJ_ARR_DICTIONARY} ........................................ -#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \ - (QS_obj_arr_dict_pre_((obj_), (idx_), #obj_)) - -//${QS-macros::QS_FUN_DICTIONARY} ............................................ -#define QS_FUN_DICTIONARY(fun_) \ - (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_)) - -//${QS-macros::QS_USR_DICTIONARY} ............................................ -#define QS_USR_DICTIONARY(rec_) \ - (QS_usr_dict_pre_((rec_), #rec_)) - -//${QS-macros::QS_ENUM_DICTIONARY} ........................................... -#define QS_ENUM_DICTIONARY(value_, group_) \ - (QS_enum_dict_pre_((value_), (group_), #value_)) - -//${QS-macros::QS_RX_PUT} .................................................... -#define QS_RX_PUT(b_) (QS_rxPut((b_))) - -//${QS-macros::QS_TR_CRIT_ENTRY} ............................................. -#define QS_TR_CRIT_ENTRY() - -//${QS-macros::QS_TR_CRIT_EXIT} .............................................. -#define QS_TR_CRIT_EXIT() - -//${QS-macros::QS_TR_ISR_ENTRY} .............................................. -#define QS_TR_ISR_ENTRY(isrnest, prio) do { \ - QS_BEGIN_PRE_(QS_QF_ISR_ENTRY, 0U) \ - QS_TIME_PRE_(); \ - QS_2u8_raw_(isrnest, prio); \ - QS_END_PRE_() \ -} - -//${QS-macros::QS_TR_ISR_EXIT} ............................................... -void QS_TR_ISR_EXIT( - uint_fast8_t isrnest, - uint_fast8_t prio); - -//${QS-macros::QS_ONLY} ...................................................... -#define QS_ONLY(code_) (code_) - -//${QS-macros::QS_ASSERTION} ................................................. -#define QS_ASSERTION(module_, id_, delay_) \ - (QS_assertion_pre_((module_), (id_), (delay_))) - -//${QS-macros::QS_EOD} ....................................................... -#define QS_EOD ((uint16_t)0xFFFFU) - -//${QS-macros::QS_CMD} ....................................................... -#define QS_CMD ((uint8_t)7U) - -//${QS-macros::QS_HEX_FMT} ................................................... -#define QS_HEX_FMT ((uint8_t)0x0FU) - -//${QS-macros::QS_CRIT_STAT} ................................................. -#ifndef QS_CRIT_STAT -#define QS_CRIT_STAT QF_CRIT_STAT -#endif // ndef QS_CRIT_STAT - -//${QS-macros::QS_CRIT_ENTRY} ................................................ -#ifndef QS_CRIT_ENTRY -#define QS_CRIT_ENTRY() QF_CRIT_ENTRY() -#endif // ndef QS_CRIT_ENTRY - -//${QS-macros::QS_CRIT_EXIT} ................................................. -#ifndef QS_CRIT_EXIT -#define QS_CRIT_EXIT() QF_CRIT_EXIT() -#endif // ndef QS_CRIT_EXIT - -//${QS-macros::QS_MEM_SYS} ................................................... -#ifndef QS_MEM_SYS -#define QS_MEM_SYS() QF_MEM_SYS() -#endif // ndef QS_MEM_SYS - -//${QS-macros::QS_MEM_APP} ................................................... -#ifndef QS_MEM_APP -#define QS_MEM_APP() QF_MEM_APP() -#endif // ndef QS_MEM_APP -//$enddecl${QS-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//============================================================================ -//! @cond INTERNAL - -typedef struct { - void const * locFilter_AP; //!< @deprecated - uint8_t * buf; - QSCtr end; - QSCtr volatile head; - QSCtr volatile tail; - QSCtr volatile used; - uint8_t volatile seq; - uint8_t volatile chksum; - uint8_t volatile critNest; - uint8_t flags; -} QS_Attr; - -extern QS_Attr QS_priv_; - -void QS_glbFilter_(int_fast16_t const filter); -void QS_locFilter_(int_fast16_t const filter); - -void QS_beginRec_(uint_fast8_t const rec); -void QS_endRec_(void); - -void QS_u8_raw_(uint8_t const d); -void QS_2u8_raw_(uint8_t const d1, uint8_t const d2); -void QS_u16_raw_(uint16_t const d); -void QS_u32_raw_(uint32_t const d); -void QS_u64_raw_(uint64_t const d); -void QS_obj_raw_(void const * const obj); -void QS_str_raw_(char const * const str); - -void QS_u8_fmt_(uint8_t const format, uint8_t const d); -void QS_u16_fmt_(uint8_t const format, uint16_t const d); -void QS_u32_fmt_(uint8_t const format, uint32_t const d); -void QS_u64_fmt_(uint8_t const format, uint64_t const d); -void QS_f32_fmt_(uint8_t const format, float32_t const f); -void QS_f64_fmt_(uint8_t const format, float64_t const d); -void QS_str_fmt_(char const * const str); -void QS_mem_fmt_(uint8_t const * const blk, uint8_t const size); - -void QS_sig_dict_pre_(QSignal const sig, void const * const obj, - char const * const name); -void QS_obj_dict_pre_(void const * const obj, char const * const name); -void QS_obj_arr_dict_pre_(void const * const obj, uint_fast16_t const idx, - char const * const name); -void QS_fun_dict_pre_(QSpyFunPtr const fun, char const * const name); -void QS_usr_dict_pre_(enum_t const rec, char const * const name); -void QS_enum_dict_pre_(enum_t const value, uint8_t const group, - char const * const name); - -void QS_assertion_pre_(char const * const module, int_t const id, - uint32_t const delay); - -void QS_target_info_pre_(uint8_t const isReset); - -//! @endcond -//============================================================================ - -//$declare${QS::QS-TX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QS-TX::preType} ...................................................... -//! Enumerates data elements for app-specific trace records -enum QS_preType { - QS_I8_ENUM_T, //!< signed 8-bit integer or enum format - QS_U8_T, //!< unsigned 8-bit integer format - QS_I16_T, //!< signed 16-bit integer format - QS_U16_T, //!< unsigned 16-bit integer format - QS_I32_T, //!< signed 32-bit integer format - QS_U32_T, //!< unsigned 32-bit integer format - QS_F32_T, //!< 32-bit floating point format - QS_F64_T, //!< 64-bit floating point format - QS_STR_T, //!< zero-terminated ASCII string format - QS_MEM_T, //!< up to 255-bytes memory block format - QS_SIG_T, //!< event signal format - QS_OBJ_T, //!< object pointer format - QS_FUN_T, //!< function pointer format - QS_I64_T, //!< signed 64-bit integer format - QS_U64_T //!< unsigned 64-bit integer format -}; - -//${QS::QS-TX::initBuf} ...................................................... -//! @static @public @memberof QS -void QS_initBuf( - uint8_t * const sto, - uint_fast32_t const stoSize); - -//${QS::QS-TX::getByte} ...................................................... -//! @static @public @memberof QS -uint16_t QS_getByte(void); - -//${QS::QS-TX::getBlock} ..................................................... -//! @static @public @memberof QS -uint8_t const * QS_getBlock(uint16_t * const pNbytes); - -//${QS::QS-TX::doOutput} ..................................................... -//! @static @public @memberof QS -void QS_doOutput(void); - -//${QS::QS-TX::onStartup} .................................................... -//! @static @public @memberof QS -uint8_t QS_onStartup(void const * arg); - -//${QS::QS-TX::onCleanup} .................................................... -//! @static @public @memberof QS -void QS_onCleanup(void); - -//${QS::QS-TX::onFlush} ...................................................... -//! @static @public @memberof QS -void QS_onFlush(void); - -//${QS::QS-TX::onGetTime} .................................................... -//! @static @public @memberof QS -QSTimeCtr QS_onGetTime(void); -//$enddecl${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//============================================================================ -#ifdef Q_UTEST - -//$declare${QS::QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QUTest::TProbe} ...................................................... -// @struct TProbe -struct QS_TProbe { - QSFun addr; - uint32_t data; - uint8_t idx; -}; - -//${QS::QUTest::onTestSetup} ................................................. -//! @static @public @memberof QS -void QS_onTestSetup(void); - -//${QS::QUTest::onTestTeardown} .............................................. -//! @static @public @memberof QS -void QS_onTestTeardown(void); - -//${QS::QUTest::onTestEvt} ................................................... -//! @static @public @memberof QS -void QS_onTestEvt(QEvt * e); - -//${QS::QUTest::onTestPost} .................................................. -//! @static @public @memberof QS -void QS_onTestPost( - void const * sender, - QActive * recipient, - QEvt const * e, - bool status); - -//${QS::QUTest::onTestLoop} .................................................. -//! @static @public @memberof QS -void QS_onTestLoop(void); -//$enddecl${QS::QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -#define QUTEST_ON_POST 124 - -//============================================================================ -//! @cond INTERNAL - -typedef struct { - struct QS_TProbe tpBuf[16]; - uint8_t tpNum; - QSTimeCtr testTime; - QPSet readySet; - QPSet readySet_dis; - uint_fast8_t intLock; -} QSTestAttr; - -extern QSTestAttr QS_tstPriv_; - -void QS_test_pause_(void); -uint32_t QS_getTestProbe_(QSpyFunPtr const api); - -//! @endcond -//============================================================================ - -// QP-stub for QUTest -// NOTE: The QP-stub is needed for unit testing QP applications, -// but might NOT be needed for testing QP itself. -#if (Q_UTEST != 0) - -//$declare${QS::QUTest-stub::QHsmDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QUTest-stub::QHsmDummy} .............................................. -//! @class QHsmDummy -//! @extends QAsm -typedef struct { -// protected: - QAsm super; -} QHsmDummy; - -// public: - -//! @public @memberof QHsmDummy -void QHsmDummy_ctor(QHsmDummy * const me); - -//! @private @memberof QHsmDummy -void QHsmDummy_init_( - QAsm * const me, - void const * const par, - uint_fast8_t const qsId); - -// private: - -//! @private @memberof QHsmDummy -void QHsmDummy_dispatch_( - QAsm * const me, - QEvt const * const e, - uint_fast8_t const qsId); -//$enddecl${QS::QUTest-stub::QHsmDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QS::QUTest-stub::QActiveDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QUTest-stub::QActiveDummy} ........................................... -//! @class QActiveDummy -//! @extends QActive -typedef struct { -// protected: - QActive super; -} QActiveDummy; - -// public: - -//! @public @memberof QActiveDummy -void QActiveDummy_ctor(QActiveDummy * const me); - -// private: - -//! @private @memberof QActiveDummy -void QActiveDummy_init_( - QAsm * const me, - void const * const par, - uint_fast8_t const qsId); - -//! @private @memberof QActiveDummy -void QActiveDummy_dispatch_( - QAsm * const me, - QEvt const * const e, - uint_fast8_t const qsId); - -//! @private @memberof QActiveDummy -bool QActiveDummy_fakePost_( - QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, - void const * const sender); - -//! @private @memberof QActiveDummy -void QActiveDummy_fakePostLIFO_( - QActive * const me, - QEvt const * const e); -//$enddecl${QS::QUTest-stub::QActiveDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -#endif // Q_UTEST != 0 - -#define QS_TEST_PROBE_DEF(fun_) \ - uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_)); - -#define QS_TEST_PROBE(code_) \ - if (qs_tp_ != 0U) { code_ } - -#define QS_TEST_PROBE_ID(id_, code_) \ - if (qs_tp_ == (uint32_t)(id_)) { code_ } - -#define QS_TEST_PAUSE() (QS_test_pause_()) - -#else // Q_UTEST not defined - -// dummy definitions when not building for QUTEST -#define QS_TEST_PROBE_DEF(fun_) -#define QS_TEST_PROBE(code_) -#define QS_TEST_PROBE_ID(id_, code_) -#define QS_TEST_PAUSE() ((void)0) - -#endif // Q_UTEST - -//============================================================================ -//! @cond INTERNAL - -typedef struct { - uint32_t param1; - uint32_t param2; - uint32_t param3; - uint8_t idx; - uint8_t cmdId; -} CmdVar; - -typedef struct { - uint_fast8_t rate; -} TickVar; - -typedef struct { - uint16_t offs; - uint8_t size; - uint8_t num; - uint8_t idx; -} PeekVar; - -typedef struct { - uint32_t data; - uint16_t offs; - uint8_t size; - uint8_t num; - uint8_t idx; - uint8_t fill; -} PokeVar; - -typedef struct { - uint8_t data[16]; - uint8_t idx; - int8_t recId; // global/local -} FltVar; - -typedef struct { - QSObj addr; - uint8_t idx; - uint8_t kind; // see qs.h, enum QSpyObjKind - int8_t recId; -} ObjVar; - -typedef struct { - QEvt *e; - uint8_t *p; - QSignal sig; - uint16_t len; - uint8_t prio; - uint8_t idx; -} EvtVar; - -typedef struct { - void * currObj[8]; - uint8_t * buf; - QSCtr end; - QSCtr volatile head; - QSCtr volatile tail; - uint8_t state; - uint8_t esc; - uint8_t seq; - uint8_t chksum; -#ifdef Q_UTEST - bool inTestLoop; -#endif - union Variant { - CmdVar cmd; - TickVar tick; - PeekVar peek; - PokeVar poke; - FltVar flt; - ObjVar obj; - EvtVar evt; -#ifdef Q_UTEST - struct QS_TProbe tp; -#endif // Q_UTEST - } var; -} QS_RxAttr; - -//! @endcond - -//! @static @private @memberof QS -extern QS_RxAttr QS_rxPriv_; - -//============================================================================ - -//$declare${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QS-RX::QSpyObjKind} .................................................. -//! @static @public @memberof QS -//! Kinds of objects used in QS-RX -enum QS_QSpyObjKind { - SM_OBJ, //!< state machine object - AO_OBJ, //!< active object - MP_OBJ, //!< event pool object - EQ_OBJ, //!< raw queue object - TE_OBJ, //!< time event object - AP_OBJ, //!< generic Application-specific object - MAX_OBJ -}; - -//${QS::QS-RX::OSpyObjComb} .................................................. -//! @static @public @memberof QS -//! Object combinations for QS-RX -enum QS_OSpyObjComb { - SM_AO_OBJ = (enum_t)MAX_OBJ //!< combination of SM and AO -}; - -//${QS::QS-RX::rxInitBuf} .................................................... -//! @static @public @memberof QS -void QS_rxInitBuf( - uint8_t * const sto, - uint16_t const stoSize); - -//${QS::QS-RX::rxPut} ........................................................ -//! @static @public @memberof QS -static inline bool QS_rxPut(uint8_t const b) { - // NOTE: does not need critical section - // But requires system-level memory access (QF_MEM_SYS()). - - QSCtr head = QS_rxPriv_.head + 1U; - if (head == QS_rxPriv_.end) { - head = 0U; - } - if (head != QS_rxPriv_.tail) { // buffer NOT full? - QS_rxPriv_.buf[QS_rxPriv_.head] = b; - QS_rxPriv_.head = head; // update the head to a *valid* index - return true; // byte placed in the buffer - } - else { - return false; // byte NOT placed in the buffer - } -} - -//${QS::QS-RX::rxParse} ...................................................... -//! @static @public @memberof QS -void QS_rxParse(void); - -//${QS::QS-RX::setCurrObj} ................................................... -//! @static @public @memberof QS -void QS_setCurrObj( - uint8_t const obj_kind, - void * const obj_ptr); - -//${QS::QS-RX::rxGetNfree} ................................................... -//! @static @public @memberof QS -uint16_t QS_rxGetNfree(void); - -//${QS::QS-RX::doInput} ...................................................... -//! @static @public @memberof QS -void QS_doInput(void); - -//${QS::QS-RX::onReset} ...................................................... -//! @static @public @memberof QS -void QS_onReset(void); - -//${QS::QS-RX::onCommand} .................................................... -//! @static @public @memberof QS -void QS_onCommand( - uint8_t cmdId, - uint32_t param1, - uint32_t param2, - uint32_t param3); -//$enddecl${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -#endif // QS_H_ diff --git a/include/qs_dummy.h b/include/qs_dummy.h index 1e4b82f1..b0c3bad3 100644 --- a/include/qs_dummy.h +++ b/include/qs_dummy.h @@ -1,45 +1,32 @@ -//$file${include::qs_dummy.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//============================================================================ +// QP/C-Spy software tracing target-resident component // -// Model: qpc.qm -// File: ${include::qs_dummy.h} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // +// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // -// -//$endhead${include::qs_dummy.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QS_DUMMY_H_ #define QS_DUMMY_H_ @@ -55,14 +42,11 @@ #define QS_EXIT() ((void)0) #define QS_DUMP() ((void)0) #define QS_GLB_FILTER(rec_) ((void)0) -#define QS_LOC_FILTER(qsId_) ((void)0) +#define QS_LOC_FILTER(qsId_) ((void)0) -#define QS_GET_BYTE(pByte_) ((uint16_t)0xFFFFU) -#define QS_GET_BLOCK(pSize_) ((uint8_t *)0) - -#define QS_BEGIN_ID(rec_, qsId_) if (false) { +#define QS_BEGIN_ID(rec_, qsId_) if (false) { #define QS_END() } -#define QS_BEGIN_INCRIT(rec_, qsId_) if (false) { +#define QS_BEGIN_INCRIT(rec_, qsId_) if (false) { #define QS_END_INCRIT() } #define QS_I8(width_, data_) ((void)0) @@ -98,37 +82,87 @@ #define QS_OUTPUT() ((void)0) #define QS_RX_INPUT() ((void)0) +#define QS_RX_PUT(b_) ((void)0) #define QS_ONLY(code_) ((void)0) +//============================================================================ +// QS API used inside applications +#ifndef QS_TIME_SIZE + typedef uint32_t QSTimeCtr; +#elif (QS_TIME_SIZE == 2U) + typedef uint16_t QSTimeCtr; +#else + typedef uint32_t QSTimeCtr; +#endif + +void QS_initBuf(uint8_t * const sto, uint_fast32_t const stoSize); +uint16_t QS_getByte(void); +uint8_t const *QS_getBlock(uint16_t* const pNbytes); +void QS_doOutput(void); +uint8_t QS_onStartup(void const* arg); +void QS_onCleanup(void); +void QS_onFlush(void); +QSTimeCtr QS_onGetTime(void); + +void QS_rxInitBuf(uint8_t * const sto, uint16_t const stoSize); +void QS_rxParse(void); + +//============================================================================ +// QS API used inside test fixtures +#ifdef Q_UTEST + +#if (QS_FUN_PTR_SIZE == 2U) + typedef uint16_t QSFun; +#elif (QS_FUN_PTR_SIZE == 4U) + typedef uint32_t QSFun; +#elif (QS_FUN_PTR_SIZE == 8U) + typedef uint64_t QSFun; +#endif + +struct QS_TProbe { + QSFun addr; + uint32_t data; + uint8_t idx; +}; + +void QS_onTestSetup(void); +void QS_onTestTeardown(void); +void QS_onTestEvt(QEvt *e); +void QS_onTestPost(void const *sender, QActive *recipient, + QEvt const *e, bool status); +void QS_onTestLoop(void); + +#endif // def Q_UTEST + //============================================================================ // interface used only for internal implementation, but not in applications #ifdef QP_IMPL // predefined QS trace records - #define QS_BEGIN_PRE_(rec_, qsId_) if (false) { - #define QS_END_PRE_() } - #define QS_U8_PRE_(data_) ((void)0) - #define QS_2U8_PRE_(data1_, data2_) ((void)0) - #define QS_U16_PRE_(data_) ((void)0) - #define QS_U32_PRE_(data_) ((void)0) - #define QS_TIME_PRE_() ((void)0) - #define QS_SIG_PRE_(sig_) ((void)0) - #define QS_EVS_PRE_(size_) ((void)0) - #define QS_OBJ_PRE_(obj_) ((void)0) - #define QS_FUN_PRE_(fun_) ((void)0) - #define QS_EQC_PRE_(ctr_) ((void)0) - #define QS_MPC_PRE_(ctr_) ((void)0) - #define QS_MPS_PRE_(size_) ((void)0) - #define QS_TEC_PRE_(ctr_) ((void)0) + #define QS_BEGIN_PRE(rec_, qsId_) if (false) { + #define QS_END_PRE() } + #define QS_U8_PRE(data_) ((void)0) + #define QS_2U8_PRE(data1_, data2_) ((void)0) + #define QS_U16_PRE(data_) ((void)0) + #define QS_U32_PRE(data_) ((void)0) + #define QS_TIME_PRE() ((void)0) + #define QS_SIG_PRE(sig_) ((void)0) + #define QS_EVS_PRE(size_) ((void)0) + #define QS_OBJ_PRE(obj_) ((void)0) + #define QS_FUN_PRE(fun_) ((void)0) + #define QS_EQC_PRE(ctr_) ((void)0) + #define QS_MPC_PRE(ctr_) ((void)0) + #define QS_MPS_PRE(size_) ((void)0) + #define QS_TEC_PRE(ctr_) ((void)0) #define QS_CRIT_STAT - #define QS_CRIT_ENTRY() ((void)0) - #define QS_CRIT_EXIT() ((void)0) + #define QS_CRIT_ENTRY() ((void)0) + #define QS_CRIT_EXIT() ((void)0) - #define QS_MEM_SYS() ((void)0) - #define QS_MEM_APP() ((void)0) + #define QS_MEM_SYS() ((void)0) + #define QS_MEM_APP() ((void)0) - #define QS_TR_CRIT_ENTRY() ((void)0) - #define QS_TR_CRIT_EXIT() ((void)0) + #define QS_TR_CRIT_ENTRY() ((void)0) + #define QS_TR_CRIT_EXIT() ((void)0) #define QS_TR_ISR_ENTRY(isrnest_, prio_) ((void)0) #define QS_TR_ISR_EXIT(isrnest_, prio_) ((void)0) #endif // QP_IMPL diff --git a/include/qs_pkg.h b/include/qs_pkg.h deleted file mode 100644 index 988a2c8c..00000000 --- a/include/qs_pkg.h +++ /dev/null @@ -1,176 +0,0 @@ -//$file${include::qs_pkg.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qs_pkg.h} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${include::qs_pkg.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#ifndef QS_PKG_H_ -#define QS_PKG_H_ - -//============================================================================ -//! @cond INTERNAL - -//! QS received record types (RX channel) -enum QSpyRxRecords { - QS_RX_INFO, //!< query Target info (ver, config, tstamp) - QS_RX_COMMAND, //!< execute a user-defined command in the Target - QS_RX_RESET, //!< reset the Target - QS_RX_TICK, //!< call system clock tick in the Target - QS_RX_PEEK, //!< peek Target memory - QS_RX_POKE, //!< poke Target memory - QS_RX_FILL, //!< fill Target memory - QS_RX_TEST_SETUP, //!< test setup - QS_RX_TEST_TEARDOWN, //!< test teardown - QS_RX_TEST_PROBE, //!< set a Test-Probe in the Target - QS_RX_GLB_FILTER, //!< set global filters in the Target - QS_RX_LOC_FILTER, //!< set local filters in the Target - QS_RX_AO_FILTER, //!< set local AO filter in the Target - QS_RX_CURR_OBJ, //!< set the "current-object" in the Target - QS_RX_TEST_CONTINUE, //!< continue a test after QS_TEST_PAUSE() - QS_RX_QUERY_CURR, //!< query the "current object" in the Target - QS_RX_EVENT //!< inject an event to the Target -}; - -//---------------------------------------------------------------------------- -#define QS_FRAME 0x7EU -#define QS_ESC 0x7DU -#define QS_ESC_XOR 0x20U -#define QS_GOOD_CHKSUM 0xFFU - -//---------------------------------------------------------------------------- -#define QS_BEGIN_PRE_(rec_, qsId_) \ - if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \ - QS_beginRec_((uint_fast8_t)(rec_)); -#define QS_END_PRE_() QS_endRec_(); } - -#define QS_U8_PRE_(data_) (QS_u8_raw_((uint8_t)(data_))) -#define QS_2U8_PRE_(data1_, data2_) \ - (QS_2u8_raw_((uint8_t)(data1_), (uint8_t)(data2_))) -#define QS_U16_PRE_(data_) (QS_u16_raw_((uint16_t)(data_))) -#define QS_U32_PRE_(data_) (QS_u32_raw_((uint32_t)(data_))) -#define QS_STR_PRE_(msg_) (QS_str_raw_((msg_))) -#define QS_OBJ_PRE_(obj_) (QS_obj_raw_(obj_)) - -#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U)) - #define QS_SIG_PRE_(sig_) (QS_u8_raw_((uint8_t)sig_)) -#elif (Q_SIGNAL_SIZE == 2U) - #define QS_SIG_PRE_(sig_) (QS_u16_raw_((uint16_t)sig_)) -#elif (Q_SIGNAL_SIZE == 4U) - #define QS_SIG_PRE_(sig_) (QS_u32_raw_((uint32_t)sig_)) -#endif - -#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 2U)) - #define QS_FUN_PRE_(fun_) (QS_u16_raw_((uint16_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 4U) - #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 8U) - #define QS_FUN_PRE_(fun_) (QS_u64_raw_((uint64_t)(fun_))) -#else - #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) -#endif - -//---------------------------------------------------------------------------- -#if (!defined QF_EQUEUE_CTR_SIZE || (QF_EQUEUE_CTR_SIZE == 1U)) - #define QS_EQC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_EQUEUE_CTR_SIZE == 2U) - #define QS_EQC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_EQUEUE_CTR_SIZE == 4U) - #define QS_EQC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) -#endif - -#if (!defined QF_EVENT_SIZ_SIZE || (QF_EVENT_SIZ_SIZE == 1U)) - #define QS_EVS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) -#elif (QF_EVENT_SIZ_SIZE == 2U) - #define QS_EVS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) -#elif (QF_EVENT_SIZ_SIZE == 4U) - #define QS_EVS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) -#endif - -#if (!defined QF_MPOOL_SIZ_SIZE || (QF_MPOOL_SIZ_SIZE == 1U)) - #define QS_MPS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) -#elif (QF_MPOOL_SIZ_SIZE == 2U) - #define QS_MPS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) -#elif (QF_MPOOL_SIZ_SIZE == 4U) - #define QS_MPS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) -#endif - -#if (!defined QF_MPOOL_CTR_SIZE || (QF_MPOOL_CTR_SIZE == 1U)) - #define QS_MPC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_MPOOL_CTR_SIZE == 2U) - #define QS_MPC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_MPOOL_CTR_SIZE == 4U) - #define QS_MPC_PRE_(ctr_) QS_u32_raw_((uint16_t)(ctr_)) -#endif - -#if (!defined QF_TIMEEVT_CTR_SIZE || (QF_TIMEEVT_CTR_SIZE == 1U)) - #define QS_TEC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_TIMEEVT_CTR_SIZE == 2U) - #define QS_TEC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_TIMEEVT_CTR_SIZE == 4U) - #define QS_TEC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) -#endif - -//---------------------------------------------------------------------------- -#define QS_INSERT_BYTE_(b_) \ - buf[head] = (b_); \ - ++head; \ - if (head == end) { \ - head = 0U; \ - } - -#define QS_INSERT_ESC_BYTE_(b_) \ - chksum = (uint8_t)(chksum + (b_)); \ - if (((b_) != QS_FRAME) && ((b_) != QS_ESC)) { \ - QS_INSERT_BYTE_(b_) \ - } \ - else { \ - QS_INSERT_BYTE_(QS_ESC) \ - QS_INSERT_BYTE_((uint8_t)((b_) ^ QS_ESC_XOR))\ - ++QS_priv_.used; \ - } - -//---------------------------------------------------------------------------- -#if (defined Q_UTEST) && (Q_UTEST != 0) -void QS_processTestEvts_(void); -#endif // Q_UTEST != 0 - -//! @endcond -//============================================================================ - -#endif // QS_PKG_H_ diff --git a/include/qsafe.h b/include/qsafe.h index 33892ba0..f1938364 100644 --- a/include/qsafe.h +++ b/include/qsafe.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qsafe.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // diff --git a/include/qstamp.h b/include/qstamp.h index 1eea570c..97ebf016 100644 --- a/include/qstamp.h +++ b/include/qstamp.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qstamp.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // diff --git a/include/qv.h b/include/qv.h index 90307f5d..bd308d1d 100644 --- a/include/qv.h +++ b/include/qv.h @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${include::qv.h} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -111,8 +103,7 @@ void QV_onIdle(void); #define QF_SCHED_UNLOCK_() ((void)0) //${QV-impl::QACTIVE_EQUEUE_WAIT_} ........................................... -#define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) +#define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) //${QV-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... #ifndef Q_UNSAFE diff --git a/include/qxk.h b/include/qxk.h deleted file mode 100644 index ba8287e7..00000000 --- a/include/qxk.h +++ /dev/null @@ -1,405 +0,0 @@ -//$file${include::qxk.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qxk.h} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${include::qxk.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#ifndef QXK_H_ -#define QXK_H_ - -//$declare${QXK::QXK} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXK} ................................................................ -//! @class QXK -typedef struct QXK { - //! @cond INTERNAL - uint8_t dummy; - //! @endcond -} QXK; -//$enddecl${QXK::QXK} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QXK::QSchedStatus} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QSchedStatus} ....................................................... -typedef uint_fast16_t QSchedStatus; -//$enddecl${QXK::QSchedStatus} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QXK::QXTHREAD_NO_TIMEOUT} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXTHREAD_NO_TIMEOUT} ................................................ -#define QXTHREAD_NO_TIMEOUT ((QTimeEvtCtr)0) -//$enddecl${QXK::QXTHREAD_NO_TIMEOUT} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXK-base::Attr} ..................................................... -//! @class QXK_Attr -typedef struct { -// private: - - //! @memberof QXK_Attr - struct QActive * volatile curr; - - //! @memberof QXK_Attr - struct QActive * volatile next; - - //! @memberof QXK_Attr - struct QActive * volatile prev; - - //! @memberof QXK_Attr - uint_fast8_t volatile actPrio; - - //! @memberof QXK_Attr - uint_fast8_t volatile lockCeil; - - //! @memberof QXK_Attr - uint_fast8_t volatile lockHolder; - - //! @memberof QXK_Attr - QPSet readySet; - -#ifndef Q_UNSAFE - //! @memberof QXK_Attr - QPSet readySet_dis; -#endif // ndef Q_UNSAFE -} QXK_Attr; - -//${QXK::QXK-base::priv_} .................................................... -//! @static @private @memberof QXK -extern QXK_Attr QXK_priv_; - -//${QXK::QXK-base::onIdle} ................................................... -//! @static @public @memberof QXK -void QXK_onIdle(void); - -//${QXK::QXK-base::schedLock} ................................................ -//! @static @public @memberof QXK -QSchedStatus QXK_schedLock(uint_fast8_t const ceiling); - -//${QXK::QXK-base::schedUnlock} .............................................. -//! @static @public @memberof QXK -void QXK_schedUnlock(QSchedStatus const stat); - -//${QXK::QXK-base::current} .................................................. -//! @static @public @memberof QXK -QActive * QXK_current(void); - -//${QXK::QXK-base::sched_} ................................................... -//! @static @private @memberof QXK -uint_fast8_t QXK_sched_(void); - -//${QXK::QXK-base::activate_} ................................................ -//! @static @private @memberof QXK -void QXK_activate_(void); - -//${QXK::QXK-base::contextSw_} ............................................... -//! @static @public @memberof QXK -void QXK_contextSw_(QActive * const next); - -//${QXK::QXK-base::threadExit_} .............................................. -//! @static @private @memberof QXK -void QXK_threadExit_(void); -//$enddecl${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXThread} ........................................................... -//! @class QXThread -//! @extends QActive -typedef struct QXThread { -// protected: - QActive super; - -// private: - - //! @private @memberof QXThread - QTimeEvt timeEvt; -} QXThread; - -//! @static @private @memberof QXThread -//! dummy static member to force QM to generate 'struct QXThread' -extern QXThread const * QXThread_dummy; - -// public: - -//! @public @memberof QXThread -void QXThread_ctor(QXThread * const me, - QXThreadHandler const handler, - uint_fast8_t const tickRate); - -//! @public @memberof QXThread -static inline void QXThread_start(QXThread * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par) -{ - QActive_start(&me->super, prioSpec, qSto, qLen, stkSto, stkSize, par); -} - -//! @public @memberof QXThread -bool QXThread_delay(QTimeEvtCtr const nTicks); - -//! @public @memberof QXThread -bool QXThread_delayCancel(QXThread * const me); - -//! @static @public @memberof QXThread -QEvt const * QXThread_queueGet(QTimeEvtCtr const nTicks); - -// private: - -//! @private @memberof QXThread -void QXThread_block_(QXThread const * const me); - -//! @private @memberof QXThread -void QXThread_unblock_(QXThread const * const me); - -//! @private @memberof QXThread -void QXThread_timeout_(QActive * const act); - -//! @private @memberof QXThread -void QXThread_teArm_(QXThread * const me, - enum_t const sig, - QTimeEvtCtr const nTicks); - -//! @private @memberof QXThread -bool QXThread_teDisarm_(QXThread * const me); - -// public: - -//! @private @memberof QXThread -void QXThread_stackInit_( - QActive * const me, - QXThreadHandler const handler, - void * const stkSto, - uint_fast16_t const stkSize); -//$enddecl${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXSemaphore} ........................................................ -//! @class QXSemaphore -typedef struct { -// private: - - //! @private @memberof QXSemaphore - QPSet waitSet; - - //! @private @memberof QXSemaphore - uint8_t volatile count; - - //! @private @memberof QXSemaphore - uint8_t max_count; -} QXSemaphore; - -// public: - -//! @public @memberof QXSemaphore -void QXSemaphore_init(QXSemaphore * const me, - uint_fast8_t const count, - uint_fast8_t const max_count); - -//! @public @memberof QXSemaphore -bool QXSemaphore_wait(QXSemaphore * const me, - QTimeEvtCtr const nTicks); - -//! @public @memberof QXSemaphore -bool QXSemaphore_tryWait(QXSemaphore * const me); - -//! @public @memberof QXSemaphore -bool QXSemaphore_signal(QXSemaphore * const me); -//$enddecl${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXMutex} ............................................................ -//! @class QXMutex -typedef struct { -// private: - - //! @private @memberof QXMutex - QActive ao; - - //! @private @memberof QXMutex - QPSet waitSet; -} QXMutex; - -// public: - -//! @public @memberof QXMutex -void QXMutex_init(QXMutex * const me, - QPrioSpec const prioSpec); - -//! @public @memberof QXMutex -bool QXMutex_lock(QXMutex * const me, - QTimeEvtCtr const nTicks); - -//! @public @memberof QXMutex -bool QXMutex_tryLock(QXMutex * const me); - -//! @public @memberof QXMutex -void QXMutex_unlock(QXMutex * const me); -//$enddecl${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QXK-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK-macros::QXTHREAD_POST_X} ............................................. -#define QXTHREAD_POST_X(me_, e_, margin_, sender_) \ - QACTIVE_POST_X(&(me_)->super, (e_), (margin_), (sender_)) -//$enddecl${QXK-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//============================================================================ -// interface used only for internal implementation, but not in applications -#ifdef QP_IMPL - -//$declare${QXK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK-impl::QF_SCHED_STAT_} ................................................ -#define QF_SCHED_STAT_ QSchedStatus lockStat_; - -//${QXK-impl::QF_SCHED_LOCK_} ................................................ -#define QF_SCHED_LOCK_(ceil_) do { \ - if (QXK_ISR_CONTEXT_()) { \ - lockStat_ = 0xFFU; \ - } else { \ - lockStat_ = QXK_schedLock((ceil_)); \ - } \ -} while (false) - -//${QXK-impl::QF_SCHED_UNLOCK_} .............................................. -#define QF_SCHED_UNLOCK_() do { \ - if (lockStat_ != 0xFFU) { \ - QXK_schedUnlock(lockStat_); \ - } \ -} while (false) - -//${QXK-impl::QACTIVE_EQUEUE_WAIT_} .......................................... -#define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) - -//${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................ -#ifndef Q_UNSAFE -#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ - if (!QXK_ISR_CONTEXT_()) { \ - if (QXK_sched_() != 0U) { \ - QXK_activate_(); \ - } \ - } \ -} while (false) -#endif // ndef Q_UNSAFE - -//${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................ -#ifdef Q_UNSAFE -#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - if (!QXK_ISR_CONTEXT_()) { \ - if (QXK_sched_() != 0U) { \ - QXK_activate_(); \ - } \ - } \ -} while (false) -#endif // def Q_UNSAFE - -//${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} ....................................... -#ifndef Q_UNSAFE -#define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \ - if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ - (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ - if (!QXK_ISR_CONTEXT_()) { \ - (void)QXK_sched_(); \ - } \ - } \ -} while (false) -#endif // ndef Q_UNSAFE - -//${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} ....................................... -#ifdef Q_UNSAFE -#define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \ - if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ - (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ - if (!QXK_ISR_CONTEXT_()) { \ - (void)QXK_sched_(); \ - } \ - } \ -} while (false) -#endif // def Q_UNSAFE - -//${QXK-impl::QXK_PTR_CAST_} ................................................. -#define QXK_PTR_CAST_(type_, ptr_) ((type_)(ptr_)) - -//${QXK-impl::QXTHREAD_CAST_} ................................................ -#define QXTHREAD_CAST_(ptr_) ((QXThread *)(ptr_)) -//$enddecl${QXK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF_EPOOL-impl::QF_EPOOL_TYPE_} ........................................... -#define QF_EPOOL_TYPE_ QMPool - -//${QF_EPOOL-impl::QF_EPOOL_INIT_} ........................................... -#define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - -//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} ..................................... -#define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - -//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................ -#define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - -//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................ -#define QF_EPOOL_PUT_(p_, e_, qsId_) \ - (QMPool_put(&(p_), (e_), (qsId_))) -//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -enum QXK_TimeoutSigs { - QXK_DELAY_SIG = 1, - QXK_TIMEOUT_SIG -}; - -#endif // QP_IMPL - -#endif // QXK_H_ diff --git a/ports/CMakeLists.txt b/ports/CMakeLists.txt index 2c33dc6b..9274eeb5 100644 --- a/ports/CMakeLists.txt +++ b/ports/CMakeLists.txt @@ -14,3 +14,7 @@ else() endif() add_subdirectory(${PORT_DIR}) +if(NOT QPC_CFG_QPCONFIG_H_INCLUDE_PATH) + set(QPC_CFG_QPCONFIG_H_INCLUDE_PATH config) +endif() +target_include_directories(qpc PUBLIC ${QPC_CFG_QPCONFIG_H_INCLUDE_PATH}) diff --git a/ports/README.md b/ports/README.md new file mode 100644 index 00000000..73e88f8d --- /dev/null +++ b/ports/README.md @@ -0,0 +1,63 @@ +# Files Missing from the QP/C GPL Distribution +Due to the growing non-compliance with the GPL as well as infringement +on the dual-licensing model of QP frameworks, the following files have +been **removed from the open-source GPL distribution**: + +``` +qpc +| +\---ports + +---arm-cm + | +---qxk + | | +---armclang + | | | qxk_port.c + | | | qp_port.h + | | | qs_port.h + | | | + | | +---config + | | | qp_config.h + | | | + | | +---gnu + | | | qxk_port.c + | | | qp_port.h + | | | qs_port.h + | | | + | | \---iar + | | qxk_port.c + | | qp_port.h + | | qs_port.h + | | + | \---qutest + | qp_port.h + | qs_port.h + | + +---posix-qutest + | qp_port.h + | qs_port.h + | qutest_port.c + | safe_std.h + | + \---win32-qutest + qp_port.h + qs_port.h + qutest_port.c + safe_std.h +``` + +> NOTE: These files are available to the [commercial licensees][com] with +current Support Term. Please contact [Quantum Leaps technical support][sup] +to get the complete QP/C framework distribution. + +# QP/C Framework Evaluation +To request **evaluation** of the complete QP/C framework, please contact +Quantum Leaps at: + +- https://www.state-machine.com/contact +- mailto:info@state-machine.com + +# Quantum Leaps Licensing: +To learn more about the open source and commercial licensing options: +- https://www.state-machine.com/licensing + + [com]: + [sup]: diff --git a/ports/arm-cm/qk/armclang/qk_port.c b/ports/arm-cm/qk/armclang/qk_port.c index 04302874..67715269 100644 --- a/ports/arm-cm/qk/armclang/qk_port.c +++ b/ports/arm-cm/qk/armclang/qk_port.c @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QK/C port to ARM Cortex-M, ARM-CLANG @@ -76,14 +75,17 @@ char const QF_port_module_[] = "qk_port"; //............................................................................ // Unconditionally disable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are disabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are disabled *selectively* with the // BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_disable_(void) { +// NOT disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_disable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -105,13 +107,16 @@ __asm volatile ( } //............................................................................ // Unconditionally enable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are enabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_enable_(void) { +// disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_enable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -136,6 +141,7 @@ __asm volatile ( } //............................................................................ // Enter QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is entered by disabling interrupts @@ -143,11 +149,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is entered by disabling // interrupts *selectively* with the BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_entry_(void) { +// NOT disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_entry_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -169,6 +174,7 @@ __asm volatile ( } //............................................................................ // Exit QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is exited by enabling interrupts @@ -176,11 +182,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is exited by enabling // interrupts with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_exit_(void) { +// disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_exit_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -217,8 +222,8 @@ __asm volatile ( // application programmer forgets to explicitly set priorities of all // "kernel aware" interrupts. // -// The interrupt priorities established in QK_init() can be later -// changed by the application-level code. +// NOTE: The IRQ priorities established in QK_init() can be later changed +// by the application-level code. void QK_init(void) { #if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... @@ -240,7 +245,11 @@ void QK_init(void) { #ifdef QK_USE_IRQ_NUM //--------- QK IRQ specified? // The QK port is configured to use a given ARM Cortex-M IRQ # // to return to thread mode (default is to use the NMI exception) - NVIC_IP[QK_USE_IRQ_NUM] = 0U; // priority 0 (highest) + + // clear the IRQ priority to 0 (highest) + NVIC_IP[QK_USE_IRQ_NUM >> 2U] &= ~(0xFFU << (8U*(QK_USE_IRQ_NUM & 3U))); + + // enable the IRQ NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU)); #endif //--------- QK IRQ specified @@ -253,17 +262,14 @@ void QK_init(void) { #endif //--------- VFP available } -//............................................................................ -// The PendSV_Handler exception is used for handling the asynchronous -// preemption in QK. The use of the PendSV exception is the recommended and -// the most efficient method for performing context switches with ARM Cortex-M. +//============================================================================ +// The PendSV exception is used for handling asynchronous preemption in QK. +// The use of the PendSV exception is the recommended and most efficient +// method for performing context switches in ARM Cortex-M. // // The PendSV exception should have the lowest priority in the whole system // (0xFF, see QK_init). All other exceptions and interrupts should have higher -// priority. For example, for NVIC with 2 priority bits all interrupts and -// exceptions must have numerical value of priority lower than 0xC0. In this -// case the interrupt priority levels available to your applications are (in -// the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. +// priority. // // Also, *all* "kernel aware" ISRs in the QK application must call the // QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for @@ -324,84 +330,132 @@ __asm volatile ( //============================================================================ // QK_thread_ret is a helper function executed when the QXK activator returns. // -// NOTE: QK_thread_ret does not execute in the PendSV context! +// After the QK activator returns, we need to resume the preempted +// thread. However, this must be accomplished by a return-from-exception, +// while we are still in the *thread* context. The switching to the +// exception context is accomplished by triggering the NMI exception or +// the selected IRQ (if macro #QK_USE_IRQ_NUM is defined). +// // NOTE: QK_thread_ret is entered with interrupts DISABLED. +// NOTE: any function calls made from this code corrupt lr, but it is +// NOT used to return from QK_thread_ret(). Instead QK_thread_ret() +// "returns" by entering an exception (either NMI or IRQ). +// __attribute__ ((naked, used)) void QK_thread_ret(void) { -__asm volatile ( + __asm volatile ( +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() +#endif - // After the QK activator returns, we need to resume the preempted - // thread. However, this must be accomplished by a return-from-exception, - // while we are still in the thread context. The switch to the exception - // context is accomplished by triggering the NMI exception or the selected - // IRQ (if macro #QK_USE_IRQ_NUM is defined). +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ + " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" + " MOVS r1,#1 \n" + " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ + + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with PRIMASK + // This code stops here and continues in the IRQ handler + +#else //--------- use the NMI (default) + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOVS r1,#1 \n" + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) + // This code stops here and continues in the NMI handler + // NOTE: interrupts remain *disabled*. + +#endif //--------- use the NMI + +#else //--------- ARMv7-M and higher... + " CPSID i \n" // disable interrupts with PRIMASK + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with BASEPRI + // NOTE: interrupts remain disabled with PRIMASK - // before triggering the NMI/IRQ, make sure that the VFP stack frame - // will NOT be used... #ifdef __ARM_FP //--------- if VFP available... - // make sure that the VFP stack frame will NOT be used + // make sure that the following IRQ/NMI will NOT use the VFP stack frame " MRS r0,CONTROL \n" // r0 := CONTROL " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) #endif //--------- VFP available -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemApp \n" - " BLX r0 \n" // call QF_onMemApp() -#endif - -#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) - " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) - -#else //--------- use the selected IRQ +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOVS r1,#1 \n" " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit " STR r1,[r0] \n" // pend the IRQ + " CPSIE i \n" // enable interrupts with PRIMASK + // This code stops here and continues in the IRQ handler - // now enable interrupts so that pended IRQ can be entered - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#endif //--------- use IRQ +#else //--------- use the NMI (default) + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOVS r1,#1 \n" + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) + // NOTE: this code stops here and continues in the NMI handler + // NOTE: PRIMASK remains *disabled*. - // NOTE! interrupts are still disabled when NMI is used - " B . \n" // wait for preemption by NMI/IRQ +#endif //--------- use the NMI + +#endif //--------- ARMv7-M and higher + + // execution should *never* reach here, so the following code + // enters the Q_onError() error handler + " LDR r0,=QF_int_disable_ \n" + " BLX r0 \n" // call QF_int_disable_() + " LDR r0,=QF_port_module_ \n" + " MOVS r1,#121 \n" + " LDR r2,=Q_onError \n" + " BX r2 \n" ); } //============================================================================ -// This exception handler is used for returning back to the preempted thread. -// The exception handler simply removes its own interrupt stack frame from -// the stack (MSP) and returns to the preempted task using the interrupt -// stack frame that must be at the top of the stack. -__attribute__ ((naked)) -#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default +// The following exception handlers are used for returning back to the +// preempted *thread* context. -// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! -void NMI_Handler(void) { -__asm volatile ( - // enable interrupts - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -); - -#else //--------- use the selected IRQ +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ // NOTE: The IRQ Handler is entered with interrupts already ENABLED +__attribute__ ((naked)) void QK_USE_IRQ_HANDLER(void) { -#endif //--------- use IRQ - - // ...continue here from either NMI_Handler() or IRQ_Handler() __asm volatile ( " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame " POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc + // NOTE: this causes exception-return to the preempted *thread* context ); } +#else //--------- IRQ NOT defined, use the NMI (default) + +// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! +__attribute__ ((naked)) +void NMI_Handler(void) { +__asm volatile ( + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame + +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with PRIMASK + + // NOTE: calling QF_int_enable_() corrupted the lr (EXC_RETURN), but + // it is NOT used to used to return from the exception. (See POP {r0,pc}) +#else //--------- ARMv7-M and higher... + " CPSIE i \n" // enable interrupts with PRIMASK +#endif //--------- ARMv7-M and higher + " POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc + ); + // NOTE: this causes exception-return to the preempted *thread* context +} + +#endif //--------- use the NMI + //============================================================================ #if (__ARM_ARCH == 6) // if ARMv6-M... diff --git a/ports/arm-cm/qk/armclang/qp_port.h b/ports/arm-cm/qk/armclang/qp_port.h index a5f68dcd..c3b2196e 100644 --- a/ports/arm-cm/qk/armclang/qp_port.h +++ b/ports/arm-cm/qk/armclang/qp_port.h @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-02 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-M, preemptive QK kernel, ARM-CLANG @@ -36,12 +35,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -157,7 +153,7 @@ static inline uint32_t QK_get_IPSR(void) { #endif // ARMv6-M // initialization of the QK kernel -#define QK_INIT() QK_init() +#define QK_INIT() QK_init() void QK_init(void); void QK_thread_ret(void); diff --git a/ports/arm-cm/qk/armclang/qs_port.h b/ports/arm-cm/qk/armclang/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cm/qk/armclang/qs_port.h +++ b/ports/arm-cm/qk/armclang/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cm/qk/config/qp_config.h b/ports/arm-cm/qk/config/qp_config.h index 17334c77..ac58c0ef 100644 --- a/ports/arm-cm/qk/config/qp_config.h +++ b/ports/arm-cm/qk/config/qp_config.h @@ -1,32 +1,30 @@ //============================================================================ // QP configuration file (QK on ARM Cortex-M) -// Last updated for version: 7.4.0 -// Last updated on: 2024-06-06 +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ #ifndef QP_CONFIG_H_ @@ -34,17 +32,10 @@ //-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// NOTE: Requires command-line macro: QP_CONFIG -// This qp_config.h header file is activated only when the macro -// QP_CONFIG is defined on the command-line to the compiler -// ------------------------------------------- - // QP API compatibility version (QP_API_VERSION) // <0=> 0 (Maximum compatibility) -// <580=>580 (QP 5.8.0 or newer) -// <660=>660 (QP 6.6.0 or newer) // <691=>691 (QP 6.9.1 or newer) -// <700=>700 (QP 7.0.0 or newer) +// <734=>7.3.4 (QP 7.3.4 or newer) // <9999=>9999 (Latest only) // QP API backwards compatibility with the QP/C API version. // Lower QP_API_VERSION values enable backwards compatibility @@ -158,7 +149,6 @@ // Event queue counter size (QF_EQUEUE_CTR_SIZE) // <1U=>1 (default) // <2U=>2 -// <4U=>4 // Size of event queue counter [bytes] // Default: 1 (255 events maximum in a queue) #define QF_EQUEUE_CTR_SIZE 1U @@ -244,8 +234,8 @@ // If enabled, provide the otherwise unused IRQ number (QK_USE_IRQ_NUM) // and the corresponding IRQ handler name (QK_USE_IRQ_HANDLER) // in the "Text Editor" mode. -//#define QK_USE_IRQ_NUM 31 -//#define QK_USE_IRQ_HANDLER Reserved31_IRQHandler +//#define QK_USE_IRQ_NUM +//#define QK_USE_IRQ_HANDLER // // diff --git a/ports/arm-cm/qk/gnu/qk_port.c b/ports/arm-cm/qk/gnu/qk_port.c index b2873b86..a350e873 100644 --- a/ports/arm-cm/qk/gnu/qk_port.c +++ b/ports/arm-cm/qk/gnu/qk_port.c @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-01-30 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QK/C port to ARM Cortex-M, GNU-ARM @@ -76,14 +75,17 @@ char const QF_port_module_[] = "qk_port"; //............................................................................ // Unconditionally disable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are disabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are disabled *selectively* with the // BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_disable_(void) { +// NOT disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_disable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -105,13 +107,16 @@ __asm volatile ( } //............................................................................ // Unconditionally enable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are enabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_enable_(void) { +// disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_enable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -136,6 +141,7 @@ __asm volatile ( } //............................................................................ // Enter QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is entered by disabling interrupts @@ -143,11 +149,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is entered by disabling // interrupts *selectively* with the BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_entry_(void) { +// NOT disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_entry_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -169,6 +174,7 @@ __asm volatile ( } //............................................................................ // Exit QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is exited by enabling interrupts @@ -176,11 +182,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is exited by enabling // interrupts with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_exit_(void) { +// disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_exit_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -217,8 +222,8 @@ __asm volatile ( // application programmer forgets to explicitly set priorities of all // "kernel aware" interrupts. // -// The interrupt priorities established in QK_init() can be later -// changed by the application-level code. +// NOTE: The IRQ priorities established in QK_init() can be later changed +// by the application-level code. void QK_init(void) { #if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... @@ -240,7 +245,11 @@ void QK_init(void) { #ifdef QK_USE_IRQ_NUM //--------- QK IRQ specified? // The QK port is configured to use a given ARM Cortex-M IRQ # // to return to thread mode (default is to use the NMI exception) - NVIC_IP[QK_USE_IRQ_NUM] = 0U; // priority 0 (highest) + + // clear the IRQ priority to 0 (highest) + NVIC_IP[QK_USE_IRQ_NUM >> 2U] &= ~(0xFFU << (8U*(QK_USE_IRQ_NUM & 3U))); + + // enable the IRQ NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU)); #endif //--------- QK IRQ specified @@ -253,17 +262,14 @@ void QK_init(void) { #endif //--------- VFP available } -//............................................................................ -// The PendSV_Handler exception is used for handling the asynchronous -// preemption in QK. The use of the PendSV exception is the recommended and -// the most efficient method for performing context switches with ARM Cortex-M. +//============================================================================ +// The PendSV exception is used for handling asynchronous preemption in QK. +// The use of the PendSV exception is the recommended and most efficient +// method for performing context switches in ARM Cortex-M. // // The PendSV exception should have the lowest priority in the whole system // (0xFF, see QK_init). All other exceptions and interrupts should have higher -// priority. For example, for NVIC with 2 priority bits all interrupts and -// exceptions must have numerical value of priority lower than 0xC0. In this -// case the interrupt priority levels available to your applications are (in -// the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. +// priority. // // Also, *all* "kernel aware" ISRs in the QK application must call the // QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for @@ -281,7 +287,7 @@ void QK_init(void) { __attribute__ ((naked, optimize("-fno-stack-protector"))) void PendSV_Handler(void) { __asm volatile ( - " PUSH {r0,lr} \n" // save EXC_RETURN + stack-aligner + " PUSH {r0,lr} \n" // save stack-aligner + EXC_RETURN //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< " LDR r0,=QF_int_disable_ \n" @@ -329,84 +335,136 @@ __asm volatile ( //============================================================================ // QK_thread_ret is a helper function executed when the QXK activator returns. // -// NOTE: QK_thread_ret does not execute in the PendSV context! +// After the QK activator returns, we need to resume the preempted +// thread. However, this must be accomplished by a return-from-exception, +// while we are still in the *thread* context. The switching to the +// exception context is accomplished by triggering the NMI exception or +// the selected IRQ (if macro #QK_USE_IRQ_NUM is defined). +// // NOTE: QK_thread_ret is entered with interrupts DISABLED. -__attribute__ ((naked, used, optimize("-fno-stack-protector"))) +// NOTE: any function calls made from this code corrupt lr, but it is +// NOT used to return from QK_thread_ret(). Instead QK_thread_ret() +// "returns" by entering an exception (either NMI or IRQ). +// +// NOTE: +// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, +// but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition +// flags in the PSR. +__attribute__ ((naked, used)) void QK_thread_ret(void) { -__asm volatile ( + __asm volatile ( +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() +#endif - // After the QK activator returns, we need to resume the preempted - // thread. However, this must be accomplished by a return-from-exception, - // while we are still in the thread context. The switch to the exception - // context is accomplished by triggering the NMI exception or the selected - // IRQ (if macro #QK_USE_IRQ_NUM is defined). +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ + " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" + " MOV r1,#1 \n" + " LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ + + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with PRIMASK + // This code stops here and continues in the IRQ handler + +#else //--------- use the NMI (default) + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOV r1,#1 \n" + " LSL r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) + // This code stops here and continues in the NMI handler + // NOTE: interrupts remain *disabled*. + +#endif //--------- use the NMI + +#else //--------- ARMv7-M and higher... + " CPSID i \n" // disable interrupts with PRIMASK + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with BASEPRI + // NOTE: interrupts remain disabled with PRIMASK - // before triggering the NMI/IRQ, make sure that the VFP stack frame - // will NOT be used... #ifdef __ARM_FP //--------- if VFP available... - // make sure that the VFP stack frame will NOT be used + // make sure that the following IRQ/NMI will NOT use the VFP stack frame " MRS r0,CONTROL \n" // r0 := CONTROL " BIC r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) #endif //--------- VFP available -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemApp \n" - " BLX r0 \n" // call QF_onMemApp() -#endif - -#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " MOV r1,#1 \n" - " LSL r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) - " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) - -#else //--------- use the selected IRQ +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOV r1,#1 \n" " LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit " STR r1,[r0] \n" // pend the IRQ + " CPSIE i \n" // enable interrupts with PRIMASK + // This code stops here and continues in the IRQ handler - // now enable interrupts so that pended IRQ can be entered - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#endif //--------- use IRQ +#else //--------- use the NMI (default) + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOV r1,#1 \n" + " LSL r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) + // NOTE: this code stops here and continues in the NMI handler + // NOTE: PRIMASK remains *disabled*. - // NOTE! interrupts are still disabled when NMI is used - " B . \n" // wait for preemption by NMI/IRQ +#endif //--------- use the NMI + +#endif //--------- ARMv7-M and higher + + // execution should *never* reach here, so the following code + // enters the Q_onError() error handler + " LDR r0,=QF_int_disable_ \n" + " BLX r0 \n" // call QF_int_disable_() + " LDR r0,=QF_port_module_ \n" + " MOV r1,#121 \n" + " LDR r2,=Q_onError \n" + " BX r2 \n" ); } //============================================================================ -// This exception handler is used for returning back to the preempted thread. -// The exception handler simply removes its own interrupt stack frame from -// the stack (MSP) and returns to the preempted task using the interrupt -// stack frame that must be at the top of the stack. -__attribute__ ((naked, optimize("-fno-stack-protector"))) -#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default +// The following exception handlers are used for returning back to the +// preempted *thread* context. -// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! -void NMI_Handler(void) { -__asm volatile ( - // enable interrupts - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -); - -#else //--------- use the selected IRQ +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ // NOTE: The IRQ Handler is entered with interrupts already ENABLED +__attribute__ ((naked)) void QK_USE_IRQ_HANDLER(void) { -#endif //--------- use IRQ - - // ...continue here from either NMI_Handler() or IRQ_Handler() __asm volatile ( " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame " POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc + // NOTE: this causes exception-return to the preempted *thread* context ); } +#else //--------- IRQ NOT defined, use the NMI (default) + +// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! +__attribute__ ((naked)) +void NMI_Handler(void) { +__asm volatile ( + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame + +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with PRIMASK + + // NOTE: calling QF_int_enable_() corrupted the lr (EXC_RETURN), but + // it is NOT used to used to return from the exception. (See POP {r0,pc}) +#else //--------- ARMv7-M and higher... + " CPSIE i \n" // enable interrupts with PRIMASK +#endif //--------- ARMv7-M and higher + " POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc + ); + // NOTE: this causes exception-return to the preempted *thread* context +} + +#endif //--------- use the NMI + //============================================================================ #if (__ARM_ARCH == 6) // if ARMv6-M... diff --git a/ports/arm-cm/qk/gnu/qp_port.h b/ports/arm-cm/qk/gnu/qp_port.h index 0b519f58..519527a2 100644 --- a/ports/arm-cm/qk/gnu/qp_port.h +++ b/ports/arm-cm/qk/gnu/qp_port.h @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-M, preemptive QK kernel, GNU-ARM @@ -36,12 +35,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -222,8 +218,6 @@ extern int32_t volatile QF_int_lock_nest_; // is intended only for applications and is not used inside the QF port, which // remains generic and not dependent on the number of implemented priority bits // implemented in the NVIC. -// -// #endif // QP_PORT_H_ diff --git a/ports/arm-cm/qk/gnu/qs_port.h b/ports/arm-cm/qk/gnu/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cm/qk/gnu/qs_port.h +++ b/ports/arm-cm/qk/gnu/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cm/qk/iar/qk_port.c b/ports/arm-cm/qk/iar/qk_port.c index b6ab1e80..360be31a 100644 --- a/ports/arm-cm/qk/iar/qk_port.c +++ b/ports/arm-cm/qk/iar/qk_port.c @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QK/C port to ARM Cortex-M, IAR-ARM @@ -80,13 +79,16 @@ char const QF_port_module_[] = "qk_port"; //............................................................................ // Unconditionally disable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are disabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are disabled *selectively* with the // BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. +// NOT disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__stackless void QF_int_disable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -109,12 +111,15 @@ __asm volatile ( } //............................................................................ // Unconditionally enable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are enabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. +// disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__stackless void QF_int_enable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -140,6 +145,7 @@ __asm volatile ( } //............................................................................ // Enter QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is entered by disabling interrupts @@ -147,10 +153,9 @@ __asm volatile ( // On ARMv7-M and higher, critical section is entered by disabling // interrupts *selectively* with the BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. +// NOT disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__stackless void QF_crit_entry_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -173,6 +178,7 @@ __asm volatile ( } //............................................................................ // Exit QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is exited by enabling interrupts @@ -180,10 +186,9 @@ __asm volatile ( // On ARMv7-M and higher, critical section is exited by enabling // interrupts with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. +// disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__stackless void QF_crit_exit_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -221,8 +226,8 @@ __asm volatile ( // application programmer forgets to explicitly set priorities of all // "kernel aware" interrupts. // -// The interrupt priorities established in QK_init() can be later -// changed by the application-level code. +// NOTE: The IRQ priorities established in QK_init() can be later changed +// by the application-level code. void QK_init(void) { #if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... @@ -244,7 +249,11 @@ void QK_init(void) { #ifdef QK_USE_IRQ_NUM //--------- QK IRQ specified? // The QK port is configured to use a given ARM Cortex-M IRQ # // to return to thread mode (default is to use the NMI exception) - NVIC_IP[QK_USE_IRQ_NUM] = 0U; // priority 0 (highest) + + // clear the IRQ priority to 0 (highest) + NVIC_IP[QK_USE_IRQ_NUM >> 2U] &= ~(0xFFU << (8U*(QK_USE_IRQ_NUM & 3U))); + + // enable the IRQ NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU)); #endif //--------- QK IRQ specified @@ -257,17 +266,14 @@ void QK_init(void) { #endif //--------- VFP available } -//............................................................................ -// The PendSV_Handler exception is used for handling the asynchronous -// preemption in QK. The use of the PendSV exception is the recommended and -// the most efficient method for performing context switches with ARM Cortex-M. +//============================================================================ +// The PendSV exception is used for handling asynchronous preemption in QK. +// The use of the PendSV exception is the recommended and most efficient +// method for performing context switches in ARM Cortex-M. // // The PendSV exception should have the lowest priority in the whole system // (0xFF, see QK_init). All other exceptions and interrupts should have higher -// priority. For example, for NVIC with 2 priority bits all interrupts and -// exceptions must have numerical value of priority lower than 0xC0. In this -// case the interrupt priority levels available to your applications are (in -// the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. +// priority. // // Also, *all* "kernel aware" ISRs in the QK application must call the // QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for @@ -328,88 +334,137 @@ __asm volatile ( //============================================================================ // QK_thread_ret is a helper function executed when the QXK activator returns. // -// NOTE: QK_thread_ret does not execute in the PendSV context! +// After the QK activator returns, we need to resume the preempted +// thread. However, this must be accomplished by a return-from-exception, +// while we are still in the *thread* context. The switching to the +// exception context is accomplished by triggering the NMI exception or +// the selected IRQ (if macro #QK_USE_IRQ_NUM is defined). +// // NOTE: QK_thread_ret is entered with interrupts DISABLED. +// NOTE: any function calls made from this code corrupt lr, but it is +// NOT used to return from QK_thread_ret(). Instead QK_thread_ret() +// "returns" by entering an exception (either NMI or IRQ). +// __stackless void QK_thread_ret(void) { -__asm volatile ( + __asm volatile ( +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() +#endif - // After the QK activator returns, we need to resume the preempted - // thread. However, this must be accomplished by a return-from-exception, - // while we are still in the thread context. The switch to the exception - // context is accomplished by triggering the NMI exception or the selected - // IRQ (if macro #QK_USE_IRQ_NUM is defined). +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ + " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" + " MOVS r1,#1 \n" + " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ + + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with PRIMASK + // This code stops here and continues in the IRQ handler + +#else //--------- use the NMI (default) + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOVS r1,#1 \n" + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) + // This code stops here and continues in the NMI handler + // NOTE: interrupts remain *disabled*. + +#endif //--------- use the NMI + +#else //--------- ARMv7-M and higher... + " CPSID i \n" // disable interrupts with PRIMASK + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with BASEPRI + // NOTE: interrupts remain disabled with PRIMASK - // before triggering the NMI/IRQ, make sure that the VFP stack frame - // will NOT be used... #ifdef __ARM_FP //--------- if VFP available... - // make sure that the VFP stack frame will NOT be used + // make sure that the following IRQ/NMI will NOT use the VFP stack frame " MRS r0,CONTROL \n" // r0 := CONTROL " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) #endif //--------- VFP available -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemApp \n" - " BLX r0 \n" // call QF_onMemApp() -#endif - -#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) - " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) - -#else //--------- use the selected IRQ +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOVS r1,#1 \n" " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit " STR r1,[r0] \n" // pend the IRQ + " CPSIE i \n" // enable interrupts with PRIMASK + // This code stops here and continues in the IRQ handler - // now enable interrupts so that pended IRQ can be entered - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#endif //--------- use IRQ +#else //--------- use the NMI (default) + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOVS r1,#1 \n" + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) + // NOTE: this code stops here and continues in the NMI handler + // NOTE: PRIMASK remains *disabled*. - // NOTE! interrupts are still disabled when NMI is used - " B . \n" // wait for preemption by NMI/IRQ +#endif //--------- use the NMI + +#endif //--------- ARMv7-M and higher + + // execution should *never* reach here, so the following code + // enters the Q_onError() error handler + " LDR r0,=QF_int_disable_ \n" + " BLX r0 \n" // call QF_int_disable_() + " LDR r0,=QF_port_module_ \n" + " MOVS r1,#121 \n" + " LDR r2,=Q_onError \n" + " BX r2 \n" ); } //============================================================================ -// This exception handler is used for returning back to the preempted thread. -// The exception handler simply removes its own interrupt stack frame from -// the stack (MSP) and returns to the preempted task using the interrupt -// stack frame that must be at the top of the stack. -__stackless -#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default +// The following exception handlers are used for returning back to the +// preempted *thread* context. -// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! -void NMI_Handler(void) { -__asm volatile ( - // enable interrupts - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -); - -#else //--------- use the selected IRQ +#ifdef QK_USE_IRQ_NUM //--------- IRQ defined, use the specified IRQ // NOTE: The IRQ Handler is entered with interrupts already ENABLED +__stackless void QK_USE_IRQ_HANDLER(void) { -#endif //--------- use IRQ - - // ...continue here from either NMI_Handler() or IRQ_Handler() __asm volatile ( " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame " POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc + // NOTE: this causes exception-return to the preempted *thread* context ); } +#else //--------- IRQ NOT defined, use the NMI (default) + +// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! +__stackless +void NMI_Handler(void) { +__asm volatile ( + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame + +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " LDR r0,=QF_int_enable_ \n" + " BLX r0 \n" // enable interrupts with PRIMASK + + // NOTE: calling QF_int_enable_() corrupted the lr (EXC_RETURN), but + // it is NOT used to used to return from the exception. (See POP {r0,pc}) +#else //--------- ARMv7-M and higher... + " CPSIE i \n" // enable interrupts with PRIMASK +#endif //--------- ARMv7-M and higher + " POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc + ); + // NOTE: this causes exception-return to the preempted *thread* context +} + +#endif //--------- use the NMI + //============================================================================ #if (__ARM_ARCH == 6) // if ARMv6-M... // hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) +__stackless uint_fast8_t QF_qlog2(uint32_t x) { static uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, @@ -418,7 +473,7 @@ uint_fast8_t QF_qlog2(uint32_t x) { uint_fast8_t n; __asm volatile ( - " MOVS %[n],#0 \n" + " MOVS %[n],#0 \n" #if (QF_MAX_ACTIVE > 16U) " LSRS r2,r0,#16 \n" " BEQ QF_qlog2_1 \n" @@ -438,7 +493,7 @@ __asm volatile ( " ADDS %[n],%[n],#4 \n" " MOVS r0,r2 \n" "QF_qlog2_3:" : [n]"=r"(n) -); + ); return n + log2LUT[x]; } diff --git a/ports/arm-cm/qk/iar/qp_port.h b/ports/arm-cm/qk/iar/qp_port.h index 3d7bb79f..5dc7c297 100644 --- a/ports/arm-cm/qk/iar/qp_port.h +++ b/ports/arm-cm/qk/iar/qp_port.h @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-M, preemptive QK kernel, IAR-ARM @@ -36,13 +35,10 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard #include // IAR intrinsic functions - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -216,8 +212,6 @@ extern int32_t volatile QF_int_lock_nest_; // is intended only for applications and is not used inside the QF port, which // remains generic and not dependent on the number of implemented priority bits // implemented in the NVIC. -// -// #endif // QP_PORT_H_ diff --git a/ports/arm-cm/qk/iar/qs_port.h b/ports/arm-cm/qk/iar/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cm/qk/iar/qs_port.h +++ b/ports/arm-cm/qk/iar/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cm/qutest/qp_port.h b/ports/arm-cm/qutest/qp_port.h deleted file mode 100644 index 7f496141..00000000 --- a/ports/arm-cm/qutest/qp_port.h +++ /dev/null @@ -1,100 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QP/C "port" for QUTEST unit test harness, generic C99 - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QUTest event queue and thread types -#define QACTIVE_EQUEUE_TYPE QEQueue -// QACTIVE_OS_OBJ_TYPE not used in this port -// QACTIVE_THREAD_TYPE not used in this port - -// QF interrupt disable/enable -#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) -#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) - -// QF critical section -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() QF_INT_DISABLE() -#define QF_CRIT_EXIT() QF_INT_ENABLE() - -// QF_LOG2 not defined -- use the internal LOG2() implementation - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QUTest port uses QEQueue event-queue -#include "qmpool.h" // QUTest port uses QMPool memory-pool -#include "qp.h" // QP platform-independent public interface - -//============================================================================ -// interface used only inside QF implementation, but not in applications -#ifdef QP_IMPL - - // QUTest scheduler locking (not used) - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - // native event queue operations - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) - -#ifndef Q_UNSAFE - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) -#else - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) -#endif - - // native QF event pool operations - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - #define QF_EPOOL_PUT_(p_, e_, qsId_) \ - (QMPool_put(&(p_), (e_), (qsId_))) - -#endif // QP_IMPL - -#endif // QP_PORT_H_ - diff --git a/ports/arm-cm/qutest/qs_port.h b/ports/arm-cm/qutest/qs_port.h deleted file mode 100644 index 7895e109..00000000 --- a/ports/arm-cm/qutest/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 4U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 4U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/arm-cm/qv/armclang/qp_port.h b/ports/arm-cm/qv/armclang/qp_port.h index 5d5a127a..07d6d0aa 100644 --- a/ports/arm-cm/qv/armclang/qp_port.h +++ b/ports/arm-cm/qv/armclang/qp_port.h @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-M, cooperative QV kernel, ARM-CLANG @@ -36,12 +35,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -114,10 +110,9 @@ #if (__ARM_ARCH == 6) // ARMv6-M? // macro to put the CPU to sleep inside QV_onIdle() - #define QV_CPU_SLEEP() do { \ + #define QV_CPU_SLEEP() do { \ __asm volatile ("wfi"::: "memory"); \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ + QF_INT_ENABLE(); \ } while (false) #define QV_ARM_ERRATUM_838869() ((void)0) @@ -125,11 +120,10 @@ #else // ARMv7-M or higher // macro to put the CPU to sleep inside QV_onIdle() - #define QV_CPU_SLEEP() do { \ + #define QV_CPU_SLEEP() do { \ __asm volatile ("cpsid i" ::: "memory"); \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ - __asm volatile ("wfi" ::: "memory"); \ + QF_INT_ENABLE(); \ + __asm volatile ("wfi" ::: "memory"); \ __asm volatile ("cpsie i" ::: "memory"); \ } while (false) @@ -206,8 +200,6 @@ extern int32_t volatile QF_int_lock_nest_; // is intended only for applications and is not used inside the QF port, which // remains generic and not dependent on the number of implemented priority bits // implemented in the NVIC. -// -// #endif // QP_PORT_H_ diff --git a/ports/arm-cm/qv/armclang/qs_port.h b/ports/arm-cm/qv/armclang/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cm/qv/armclang/qs_port.h +++ b/ports/arm-cm/qv/armclang/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cm/qv/armclang/qv_port.c b/ports/arm-cm/qv/armclang/qv_port.c index 5df26371..8644d433 100644 --- a/ports/arm-cm/qv/armclang/qv_port.c +++ b/ports/arm-cm/qv/armclang/qv_port.c @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QV/C port to ARM Cortex-M, ARM-CLANG @@ -58,20 +57,24 @@ // For best performance, these functions are implemented in assembly, // but they can be implemented in C as well. + //int32_t volatile QF_int_lock_nest_; // not used extern char const QF_port_module_[]; char const QF_port_module_[] = "qv_port"; //............................................................................ // Unconditionally disable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are disabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are disabled *selectively* with the // BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_disable_(void) { +// NOT disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_disable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -93,13 +96,16 @@ __asm volatile ( } //............................................................................ // Unconditionally enable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are enabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_enable_(void) { +// disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_enable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -124,6 +130,7 @@ __asm volatile ( } //............................................................................ // Enter QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is entered by disabling interrupts @@ -131,11 +138,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is entered by disabling // interrupts *selectively* with the BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_entry_(void) { +// NOT disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_entry_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -157,6 +163,7 @@ __asm volatile ( } //............................................................................ // Exit QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is exited by enabling interrupts @@ -164,11 +171,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is exited by enabling // interrupts with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_exit_(void) { +// disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_exit_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -205,8 +211,8 @@ __asm volatile ( // application programmer forgets to explicitly set priorities of all // "kernel aware" interrupts. // -// The interrupt priorities established in QV_init() can be later -// changed by the application-level code. +// NOTE: The IRQ priorities established in QV_init() can be later changed +// by the application-level code. void QV_init(void) { #if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... diff --git a/ports/arm-cm/qv/config/qp_config.h b/ports/arm-cm/qv/config/qp_config.h index 0e9ffda3..14ed0755 100644 --- a/ports/arm-cm/qv/config/qp_config.h +++ b/ports/arm-cm/qv/config/qp_config.h @@ -1,32 +1,30 @@ //============================================================================ // QP configuration file (QV on ARM Cortex-M) -// Last updated for version: 7.4.0 -// Last updated on: 2024-06-06 +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ #ifndef QP_CONFIG_H_ @@ -34,17 +32,10 @@ //-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// NOTE: Requires command-line macro: QP_CONFIG -// This qp_config.h header file is activated only when the macro -// QP_CONFIG is defined on the command-line to the compiler -// ------------------------------------------- - // QP API compatibility version (QP_API_VERSION) // <0=> 0 (Maximum compatibility) -// <580=>580 (QP 5.8.0 or newer) -// <660=>660 (QP 6.6.0 or newer) // <691=>691 (QP 6.9.1 or newer) -// <700=>700 (QP 7.0.0 or newer) +// <734=>7.3.4 (QP 7.3.4 or newer) // <9999=>9999 (Latest only) // QP API backwards compatibility with the QP/C API version. // Lower QP_API_VERSION values enable backwards compatibility @@ -158,7 +149,6 @@ // Event queue counter size (QF_EQUEUE_CTR_SIZE) // <1U=>1 (default) // <2U=>2 -// <4U=>4 // Size of event queue counter [bytes] // Default: 1 (255 events maximum in a queue) #define QF_EQUEUE_CTR_SIZE 1U diff --git a/ports/arm-cm/qv/gnu/qp_port.h b/ports/arm-cm/qv/gnu/qp_port.h index da2ad579..7ad61011 100644 --- a/ports/arm-cm/qv/gnu/qp_port.h +++ b/ports/arm-cm/qv/gnu/qp_port.h @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-02 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-M, cooperative QV kernel, GNU-ARM @@ -36,12 +35,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -114,10 +110,9 @@ #if (__ARM_ARCH == 6) // ARMv6-M? // macro to put the CPU to sleep inside QV_onIdle() - #define QV_CPU_SLEEP() do { \ + #define QV_CPU_SLEEP() do { \ __asm volatile ("wfi"::: "memory"); \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ + QF_INT_ENABLE(); \ } while (false) #define QV_ARM_ERRATUM_838869() ((void)0) @@ -125,11 +120,10 @@ #else // ARMv7-M or higher // macro to put the CPU to sleep inside QV_onIdle() - #define QV_CPU_SLEEP() do { \ + #define QV_CPU_SLEEP() do { \ __asm volatile ("cpsid i" ::: "memory"); \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ - __asm volatile ("wfi" ::: "memory"); \ + QF_INT_ENABLE(); \ + __asm volatile ("wfi" ::: "memory"); \ __asm volatile ("cpsie i" ::: "memory"); \ } while (false) @@ -206,8 +200,6 @@ extern int32_t volatile QF_int_lock_nest_; // is intended only for applications and is not used inside the QF port, which // remains generic and not dependent on the number of implemented priority bits // implemented in the NVIC. -// -// #endif // QP_PORT_H_ diff --git a/ports/arm-cm/qv/gnu/qs_port.h b/ports/arm-cm/qv/gnu/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cm/qv/gnu/qs_port.h +++ b/ports/arm-cm/qv/gnu/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cm/qv/gnu/qv_port.c b/ports/arm-cm/qv/gnu/qv_port.c index f58549b1..ff0e83df 100644 --- a/ports/arm-cm/qv/gnu/qv_port.c +++ b/ports/arm-cm/qv/gnu/qv_port.c @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QV/C port to ARM Cortex-M, GNU-ARM @@ -58,20 +57,24 @@ // For best performance, these functions are implemented in assembly, // but they can be implemented in C as well. + //int32_t volatile QF_int_lock_nest_; // not used extern char const QF_port_module_[]; char const QF_port_module_[] = "qv_port"; //............................................................................ // Unconditionally disable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are disabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are disabled *selectively* with the // BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_disable_(void) { +// NOT disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_disable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -93,13 +96,16 @@ __asm volatile ( } //............................................................................ // Unconditionally enable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are enabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_enable_(void) { +// disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__attribute__ ((naked, weak)) +void QF_int_enable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -124,6 +130,7 @@ __asm volatile ( } //............................................................................ // Enter QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is entered by disabling interrupts @@ -131,11 +138,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is entered by disabling // interrupts *selectively* with the BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_entry_(void) { +// NOT disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_entry_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -157,6 +163,7 @@ __asm volatile ( } //............................................................................ // Exit QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is exited by enabling interrupts @@ -164,11 +171,10 @@ __asm volatile ( // On ARMv7-M and higher, critical section is exited by enabling // interrupts with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_exit_(void) { +// disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__attribute__ ((naked, weak)) +void QF_crit_exit_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK @@ -205,8 +211,8 @@ __asm volatile ( // application programmer forgets to explicitly set priorities of all // "kernel aware" interrupts. // -// The interrupt priorities established in QV_init() can be later -// changed by the application-level code. +// NOTE: The IRQ priorities established in QV_init() can be later changed +// by the application-level code. void QV_init(void) { #if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... diff --git a/ports/arm-cm/qv/iar/qp_port.h b/ports/arm-cm/qv/iar/qp_port.h index e3adb58d..4f749ac8 100644 --- a/ports/arm-cm/qv/iar/qp_port.h +++ b/ports/arm-cm/qv/iar/qp_port.h @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-02 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-M, cooperative QV kernel, IAR-ARM @@ -36,13 +35,10 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard #include // IAR intrinsic functions - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -116,9 +112,8 @@ // macro to put the CPU to sleep inside QV_onIdle() #define QV_CPU_SLEEP() do { \ - __WFI(); \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ + __WFI(); \ + QF_INT_ENABLE(); \ } while (false) #define QV_ARM_ERRATUM_838869() ((void)0) @@ -128,7 +123,6 @@ // macro to put the CPU to sleep inside QV_onIdle() #define QV_CPU_SLEEP() do { \ __disable_interrupt(); \ - QF_MEM_APP(); \ QF_INT_ENABLE(); \ __WFI(); \ __enable_interrupt(); \ @@ -207,8 +201,6 @@ extern int32_t volatile QF_int_lock_nest_; // is intended only for applications and is not used inside the QF port, which // remains generic and not dependent on the number of implemented priority bits // implemented in the NVIC. -// -// #endif // QP_PORT_H_ diff --git a/ports/arm-cm/qv/iar/qs_port.h b/ports/arm-cm/qv/iar/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cm/qv/iar/qs_port.h +++ b/ports/arm-cm/qv/iar/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cm/qv/iar/qv_port.c b/ports/arm-cm/qv/iar/qv_port.c index ea61168e..8ec7af61 100644 --- a/ports/arm-cm/qv/iar/qv_port.c +++ b/ports/arm-cm/qv/iar/qv_port.c @@ -1,34 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-12-03 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QV/C port to ARM Cortex-M, IAR-ARM @@ -69,13 +68,16 @@ char const QF_port_module_[] = "qv_port"; //............................................................................ // Unconditionally disable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are disabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are disabled *selectively* with the // BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. +// NOT disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__stackless void QF_int_disable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -98,12 +100,15 @@ __asm volatile ( } //............................................................................ // Unconditionally enable interrupts. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, interrupts are enabled with the PRIMASK register. // On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. +// disabled upon the entry to the function, which means that +// this interrupt management policy CANNOT nest. +__stackless void QF_int_enable_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -129,6 +134,7 @@ __asm volatile ( } //............................................................................ // Enter QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is entered by disabling interrupts @@ -136,10 +142,9 @@ __asm volatile ( // On ARMv7-M and higher, critical section is entered by disabling // interrupts *selectively* with the BASEPRI register. // Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. +// NOT disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__stackless void QF_crit_entry_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -162,6 +167,7 @@ __asm volatile ( } //............................................................................ // Exit QF critical section. +// NOTE: this function must NOT use the stack. // // description: // On ARMv6-M, critical section is exited by enabling interrupts @@ -169,10 +175,9 @@ __asm volatile ( // On ARMv7-M and higher, critical section is exited by enabling // interrupts with the BASEPRI register. // Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. +// disabled upon the entry to the function, which means that +// this critical section CANNOT nest. +__stackless void QF_crit_exit_(void) { __asm volatile ( #if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? @@ -210,8 +215,8 @@ __asm volatile ( // application programmer forgets to explicitly set priorities of all // "kernel aware" interrupts. // -// The interrupt priorities established in QV_init() can be later -// changed by the application-level code. +// NOTE: The IRQ priorities established in QV_init() can be later changed +// by the application-level code. void QV_init(void) { #if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... @@ -240,6 +245,7 @@ void QV_init(void) { #if (__ARM_ARCH == 6) // if ARMv6-M... // hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) +__stackless uint_fast8_t QF_qlog2(uint32_t x) { static uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, @@ -248,7 +254,7 @@ uint_fast8_t QF_qlog2(uint32_t x) { uint_fast8_t n; __asm volatile ( - " MOVS %[n],#0 \n" + " MOVS %[n],#0 \n" #if (QF_MAX_ACTIVE > 16U) " LSRS r2,r0,#16 \n" " BEQ QF_qlog2_1 \n" @@ -268,7 +274,7 @@ __asm volatile ( " ADDS %[n],%[n],#4 \n" " MOVS r0,r2 \n" "QF_qlog2_3:" : [n]"=r"(n) -); + ); return n + log2LUT[x]; } diff --git a/ports/arm-cm/qxk/armclang/qp_port.h b/ports/arm-cm/qxk/armclang/qp_port.h deleted file mode 100644 index 80588a82..00000000 --- a/ports/arm-cm/qxk/armclang/qp_port.h +++ /dev/null @@ -1,234 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-12-02 -//! @version Last updated for: @ref qpc_7_3_1 -//! -//! @file -//! @brief QP/C port to ARM Cortex-M, dual-mode QXK kernel, ARM-CLANG - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QF configuration for QXK -- data members of the QActive class... - -// QActive event-queue type used for AOs and eXtended threads. -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QActive OS-Object type used for the private stack pointer for eXtended threads. -// (The private stack pointer is NULL for basic-threads). -#define QACTIVE_OS_OBJ_TYPE void* - -// QActive "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// QF interrupt disable/enable and log2()... -#if (__ARM_ARCH == 6) // ARMv6-M? - - // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 - #define QF_AWARE_ISR_CMSIS_PRI 0 - - // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else // ARMv7-M or higher - - // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 - #define QF_BASEPRI 0x3F - - // CMSIS threshold for "QF-aware" interrupts, see NOTE4 - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - // ARMv7-M or higher provide the CLZ instruction for fast LOG2 - #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) - -#endif - -// interrupt disabling policy, see NOTE2 and NOTE3 -#define QF_INT_DISABLE() (QF_int_disable_()) -#define QF_INT_ENABLE() (QF_int_enable_()) - -// QF critical section, see NOTE1, NOTE2, and NOTE3 -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() (QF_crit_entry_()) -#define QF_CRIT_EXIT() (QF_crit_exit_()) - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") - -#if (__ARM_ARCH == 6) // ARMv6-M? - // hand-optimized quick LOG2 in assembly - uint_fast8_t QF_qlog2(uint32_t x); -#endif // ARMv7-M or higher - -// Memory isolation ---------------------------------------------------------- -#ifdef QF_MEM_ISOLATE - - // Memory isolation requires the context-switch - #define QF_ON_CONTEXT_SW 1U - - // Memory System setting - #define QF_MEM_SYS() QF_onMemSys() - - // Memory Application setting - #define QF_MEM_APP() QF_onMemApp() - - // callback functions for memory settings (provided by applications) - void QF_onMemSys(void); - void QF_onMemApp(void); - -#endif // def QF_MEM_ISOLATE - -// determination if the code executes in the ISR context -#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) - -__attribute__((always_inline)) -static inline uint32_t QXK_get_IPSR(void) { - uint32_t regIPSR; - __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); - return regIPSR; -} - -// trigger the PendSV exception to perform the context switch -#define QXK_CONTEXT_SWITCH_() \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) - -// QXK ISR entry and exit -#define QXK_ISR_ENTRY() ((void)0) - -#ifdef QF_MEM_ISOLATE - #define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - QF_MEM_SYS(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ - } while (false) -#else - #define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ - } while (false) -#endif - -#if (__ARM_ARCH == 6) // ARMv6-M? - #define QXK_ARM_ERRATUM_838869() ((void)0) -#else // ARMv7-M or higher - // The following macro implements the recommended workaround for the - // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - // (memory barrier) instruction needs to be added before exiting an ISR. - #define QXK_ARM_ERRATUM_838869() __asm volatile ("dsb" ::: "memory") - -#endif // ARMv6-M - -// initialization of the QXK kernel -#define QXK_INIT() QXK_init() -void QXK_init(void); -void QXK_thread_ret(void); - -#ifdef __ARM_FP //--------- if VFP available... -// When the FPU is configured, clear the FPCA bit in the CONTROL register -// to prevent wasting the stack space for the FPU context. -#define QXK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QXK kernel uses the native QP event queue -#include "qmpool.h" // QXK kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qxk.h" // QXK kernel - -// prototypes -void QF_int_disable_(void); -void QF_int_enable_(void); -void QF_crit_entry_(void); -void QF_crit_exit_(void); - -extern int32_t volatile QF_int_lock_nest_; - -//============================================================================ -// NOTE1: -// The critical section policy does not use the "saving and restoring" -// interrupt status policy (macro QF_CRIT_STAT is defined to nothing). -// However, this the QF critical sections might still be able to nest, -// depending on the implementation of the QF_crit_entry_()/QF_crit_exit_() -// functions. They are defined as "weak" in the qv_port.c module, -// so the application can provide a different implementation. -// Please see the definitions of the interrupt and critical-section -// funcctions in the qv_port.c module for details. -// -// NOTE2: -// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt -// disabling policy uses the PRIMASK register to disable interrupts globally. -// The QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts -// are "kernel-aware". -// -// NOTE3: -// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI -// register (which is not implemented in ARMv6-M) to disable interrupts only -// with priority lower than the threshold specified by the QF_BASEPRI macro. -// The interrupts with priorities above QF_BASEPRI (i.e., with numerical -// priority values lower than QF_BASEPRI) are NOT disabled in this method. -// These free-running interrupts have very low ("zero") latency, but they -// are NOT allowed to call any QF services, because QF is unaware of them -// ("kernel-unaware" interrupts). Consequently, only interrupts with -// numerical values of priorities equal to or higher than QF_BASEPRI -// ("kernel-aware" interrupts ), can call QF services. -// -// NOTE4: -// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -// the "QF-aware" interrupt priorities in the applications, whereas the -// numerical values of the "QF-aware" interrupts must be greater or equal to -// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -// passed directly to the CMSIS function NVIC_SetPriority(), which shifts -// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -// is intended only for applications and is not used inside the QF port, which -// remains generic and not dependent on the number of implemented priority bits -// implemented in the NVIC. - -#endif // QP_PORT_H_ - diff --git a/ports/arm-cm/qxk/armclang/qs_port.h b/ports/arm-cm/qxk/armclang/qs_port.h deleted file mode 100644 index 7895e109..00000000 --- a/ports/arm-cm/qxk/armclang/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 4U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 4U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/arm-cm/qxk/armclang/qxk_port.c b/ports/arm-cm/qxk/armclang/qxk_port.c deleted file mode 100644 index 4c605235..00000000 --- a/ports/arm-cm/qxk/armclang/qxk_port.c +++ /dev/null @@ -1,798 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-28 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QXK/C port to ARM Cortex-M, ARM-CLANG - -#define QP_IMPL 1U -#include "qp_port.h" -#include "qp_pkg.h" -#include "qsafe.h" // QP Functional Safety (FuSa) System - -#include // for offsetof() - -//============================================================================ -// NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! -#define QXK_CURR 0 -#define QXK_NEXT 4 -#define QXK_ACT_PRIO 12 - -// make sure that the offsets match the QXK declaration in "qxk.h" -_Static_assert(QXK_CURR == offsetof(QXK_Attr, curr), - "QXK_Attr.curr at unexpected offset"); -_Static_assert(QXK_NEXT == offsetof(QXK_Attr, next), - "QXK_Attr.next at unexpected offset"); -_Static_assert(QXK_ACT_PRIO == offsetof(QXK_Attr, actPrio), - "QXK_Attr.actPrio at unexpected offset"); - -// offsets within struct QActive; NOTE: keep in synch with "qp.h" !!! -#define QACTIVE_PRIO 12 -#define QACTIVE_OSOBJ 20 - -// make sure that the offsets match the QActvie declaration in "qp.h" -_Static_assert(QACTIVE_OSOBJ == offsetof(QActive, osObject), - "QActive.osObject at unexpected offset"); -_Static_assert(QACTIVE_PRIO == offsetof(QActive, prio), - "QActive.prio at unexpected offset"); - -//============================================================================ -// Initialize the private stack of an extended QXK thread. -// -// NOTE -// The function aligns the stack to the 8-byte boundary for compatibility -// with the AAPCS. Additionally, the function pre-fills the stack with the -// known bit pattern (0xDEADBEEF). -// -// NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware -// of this thread. In that case the kernel cannot use the thread yet, so no -// critical section is needed. -void QXThread_stackInit_(QActive *me, QXThreadHandler const handler, - void * const stkSto, uint_fast16_t const stkSize) -{ - // round down the stack top to the 8-byte boundary - // NOTE: ARM Cortex-M stack grows down from hi -> low memory - uint32_t *sp = - (uint32_t *)((((uint32_t)stkSto + stkSize) >> 3U) << 3U); - uint32_t *sp_limit; - - // synthesize the ARM Cortex-M exception stack frame... - *(--sp) = (1U << 24); // xPSR (just the THUMB bit) - *(--sp) = (uint32_t)handler; // PC (the thread handler) - *(--sp) = (uint32_t)&QXK_threadExit_; // LR (exit from thread) - *(--sp) = 0x0000000CU; // R12 - *(--sp) = 0x00000003U; // R3 - *(--sp) = 0x00000002U; // R2 - *(--sp) = 0x00000001U; // R1 - *(--sp) = (uint32_t)me; // R0 parameter to handler (thread object) - *(--sp) = 0x0000000BU; // R11 - *(--sp) = 0x0000000AU; // R10 - *(--sp) = 0x00000009U; // R9 - *(--sp) = 0x00000008U; // R8 - *(--sp) = 0x00000007U; // R7 - *(--sp) = 0x00000006U; // R6 - *(--sp) = 0x00000005U; // R5 - *(--sp) = 0x00000004U; // R4 - -#ifdef __ARM_FP //--------- if VFP available... - *(--sp) = 0xFFFFFFFDU; // exception return with VFP state - *(--sp) = 0xAAAAAAAAU; // stack "aligner" -#endif // VFP available - - // save the top of the stack in the thread's attribute - me->osObject = sp; - - // pre-fill the unused part of the stack with 0xDEADBEEF - sp_limit = (uint32_t *)(((((uint32_t)stkSto - 1U) >> 3U) + 1U) << 3U); - for (; sp >= sp_limit; --sp) { - *sp = 0xDEADBEEFU; - } -} - -// prototypes ---------------------------------------------------------------- -void PendSV_Handler(void); -#ifdef QXK_USE_IRQ_HANDLER // if use IRQ... -void QXK_USE_IRQ_HANDLER(void); -#else // use default (NMI) -void NMI_Handler(void); -#endif - -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) -#define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint32_t volatile *)0xE000E400U) -#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) -#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -#define NVIC_PEND 0xE000E200 -#define SCB_ICSR 0xE000ED04 - -// helper macros to "stringify" values -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) - -//============================================================================ -// interrupts and critical section... -// -// NOTE: -// The following interrupt disabling/enabling as well as critical section -// entry/exit functions are defined as "weak" so that they can be -// re-implemented differently at the application level. -// -// NOTE: -// For best performance, these functions are implemented in assembly, -// but they can be implemented in C as well. - - -//int32_t volatile QF_int_lock_nest_; // not used -extern char const QF_port_module_[]; -char const QF_port_module_[] = "qxk_port"; - -//............................................................................ -// Unconditionally disable interrupts. -// -// description: -// On ARMv6-M, interrupts are disabled with the PRIMASK register. -// On ARMv7-M and higher, interrupts are disabled *selectively* with the -// BASEPRI register. -// Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_disable_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK - " CPSID i \n" // set PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI - " MOVS r1,#" STRINGIFY(QF_BASEPRI) "\n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0) - " BNE QF_int_disable_error\n" - " BX lr \n" - "QF_int_disable_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#100 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Unconditionally enable interrupts. -// -// description: -// On ARMv6-M, interrupts are enabled with the PRIMASK register. -// On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. -// Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// QF_int_enable_() is NOT allowed to push anything on the stack -// (see NOTE-1 at the end of QXK_thread_ret(). -__attribute__ ((naked, weak)) void QF_int_enable_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI != 0) - " BEQ QF_int_enable_error\n" -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " CPSIE i \n" // clear PRIMASK -#else //--------- ARMv7-M or higher - " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " BX lr \n" - "QF_int_enable_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#101 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Enter QF critical section. -// -// description: -// On ARMv6-M, critical section is entered by disabling interrupts -// with the PRIMASK register. -// On ARMv7-M and higher, critical section is entered by disabling -// interrupts *selectively* with the BASEPRI register. -// Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_entry_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK - " CPSID i \n" // set PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI - " MOVS r1,#" STRINGIFY(QF_BASEPRI) "\n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0) - " BNE QF_crit_entry_error\n" - " BX lr \n" - "QF_crit_entry_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#110 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Exit QF critical section. -// -// description: -// On ARMv6-M, critical section is exited by enabling interrupts -// with the PRIMASK register. -// On ARMv7-M and higher, critical section is exited by enabling -// interrupts with the BASEPRI register. -// Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_exit_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI != 0) - " BEQ QF_crit_exit_error\n" -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " CPSIE i \n" // clear PRIMASK -#else //--------- ARMv7-M or higher - " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " BX lr \n" - "QF_crit_exit_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#111 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} - -//============================================================================ -// Initialize the exception priorities and IRQ priorities to safe values. -// -// description: -// On ARMv7-M or higher, this QF port disables interrupts by means of the -// BASEPRI register. However, this method cannot disable interrupt -// priority zero, which is the default for all interrupts out of reset. -// The following code changes the SysTick priority and all IRQ priorities -// to the safe value QF_BASEPRI, which the QF critical section can disable. -// This avoids breaching of the QF critical sections in case the -// application programmer forgets to explicitly set priorities of all -// "kernel aware" interrupts. -// -// The interrupt priorities established in QXK_init() can be later -// changed by the application-level code. -void QXK_init(void) { - -#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - - // SCB_SYSPRI[2]: SysTick - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - - // set all 240 possible IRQ priories to QF_BASEPRI... - for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { - NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) - | (QF_BASEPRI << 8U) | QF_BASEPRI; - } - -#endif //--------- ARMv7-M or higher - - // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); - -#ifdef QXK_USE_IRQ_NUM //--------- QXK IRQ specified? - // The QXK port is configured to use a given ARM Cortex-M IRQ # - // to return to thread mode (default is to use the NMI exception) - NVIC_IP[QXK_USE_IRQ_NUM] = 0U; // priority 0 (highest) - NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); -#endif //--------- QXK IRQ specified - -#ifdef __ARM_FP //--------- if VFP available... - // make sure that the FPU is enabled by setting CP10 & CP11 Full Access - SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); - - // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) - FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); -#endif //--------- VFP available -} - -//============================================================================ -// The PendSV exception is used for performing asynchronous preemption in QXK. -// The use of the PendSV exception is the recommended and most efficient -// method for performing context switches in ARM Cortex-M. -// -// The PendSV exception should have the lowest interrupt priority in the system -// (0xFF, see QXK_init()). All other exceptions and interrupts should have -// higher interrupt priority. -// -// Also, *all* "kernel aware" ISRs in the QXK application must call the -// QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -// asynchronous preemption. -// -// Due to tail-chaining and its lowest priority, the PendSV exception will be -// entered immediately after the exit from the *last* nested interrupt (or -// exception). In QXK, this is exactly the time when the QXK activator needs to -// handle the asynchronous preemption. -__attribute__ ((naked)) -void PendSV_Handler(void) { -__asm volatile ( - - //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< - " PUSH {r0,lr} \n" // save stack-aligner + EXC_RETURN - " LDR r0,=QF_int_disable_ \n" - " BLX r0 \n" // call QF_int_disable_() - -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemSys \n" - " BLX r0 \n" // call QF_onMemSys() -#endif - " POP {r0,r1} \n" // restore the aligner + EXC_RETURN in r1 - " MOV lr,r1 \n" // restore EXC_RETURN into lr - - // The PendSV exception handler can be preempted by an interrupt, - // which might pend PendSV exception again. The following write to - // ICSR[27] un-pends any such spurious instance of PendSV. - " MOVS r1,#1 \n" - " LSLS r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit) - " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " STR r1,[r2] \n" // ICSR[27] := 1 (un-pend PendSV) - - // Check QXK_priv_.next, which contains the pointer to the next thread - // to run, which is set in QXK_ISR_EXIT(). Return if QXK_priv_.next == 0 - " LDR r3,=QXK_priv_ \n" - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next - " CMP r0,#0 \n" // is (QXK_priv_.next == 0)? - " BEQ PendSV_return \n" // branch if (QXK_priv_.next == 0) - - // Load pointers into registers... - " MOV r12,r0 \n" // save QXK_priv_.next in r12 - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // r2 := QXK_priv_.next->osObject - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr - - " CMP r1,#0 \n" // (QXK_priv_.curr != 0)? - " BNE PendSV_save_ex \n" // branch if (current thread is extended) - - " CMP r2,#0 \n" // (QXK_priv_.next->osObject != 0)? - " BNE PendSV_save_ao \n" // branch if (next thread is extended) - - "PendSV_activate: \n" -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 - " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available - // The QXK activator must be called in a Thread mode, while this code - // executes in the Handler mode of the PendSV exception. The switch - // to the Thread mode is accomplished by returning from PendSV using - // a fabricated exception stack frame, where the return address is - // QXK_activate_(). - // - // NOTE: the QXK activator is called with interrupts DISABLED and also - // returns with interrupts DISABLED. - " MOVS r3,#1 \n" - " LSLS r3,r3,#24 \n" // r3 := (1 << 24), set T bit (new xpsr) - " LDR r2,=QXK_activate_\n" // address of QXK_activate_ - " SUBS r2,r2,#1 \n" // align Thumb-address at halfword (new pc) - " LDR r1,=QXK_thread_ret\n" // return address after the call (new lr) - - " SUB sp,sp,#(8*4) \n" // reserve space for exception stack frame - " ADD r0,sp,#(5*4) \n" // r0 := 5 registers below the SP - " STM r0!,{r1-r3} \n" // save xpsr,pc,lr - - " MOVS r0,#6 \n" - " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 -#if (__ARM_ARCH != 6) // ARMv7-M or higher - " DSB \n" // ARM Erratum 838869 -#endif // ARMv7-M or higher - " BX r0 \n" // exception-return to the QXK activator - - //======================================================================== - // Saving AO-thread before crossing to eXtended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_save_ao: \n" -#if (__ARM_ARCH == 6) // if ARMv6-M... - " SUB sp,sp,#(8*4) \n" // make room for 8 registers r4-r11 - " MOV r0,sp \n" // r0 := temporary stack pointer - " STMIA r0!,{r4-r7} \n" // save the low registers - " MOV r4,r8 \n" // move the high registers to low registers... - " MOV r5,r9 \n" - " MOV r6,r10 \n" - " MOV r7,r11 \n" - " STMIA r0!,{r4-r7} \n" // save the high registers - " MOV r0,r12 \n" // restore QXK_priv_.next in r0 -#else // ARMv7-M or higher - " PUSH {r4-r11} \n" // save r4-r11 on top of the exception frame -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 - " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available -#endif // ARMv7-M or higher - - " CMP r2,#0 \n" - " BNE PendSV_restore_ex\n" // branch if (QXK_priv_.next->osObject != 0) - // otherwise continue to restoring next AO-thread... - - //------------------------------------------------------------------------ - // Restoring AO-thread after crossing from eXtended-thread - // expected register contents: - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_restore_ao: \n" - // don NOT clear QXK_priv_.curr or QXK_priv_.next, - // as they might be needed for AO activation - -#if (__ARM_ARCH == 6) // if ARMv6-M... - " MOV r0,sp \n" // r0 := top of stack - " MOV r2,r0 \n" - " ADDS r2,r2,#(4*4) \n" // point r2 to the 4 high registers r7-r11 - " LDMIA r2!,{r4-r7} \n" // pop the 4 high registers into low registers - " MOV r8,r4 \n" // move low registers into high registers - " MOV r9,r5 \n" - " MOV r10,r6 \n" - " MOV r11,r7 \n" - " LDMIA r0!,{r4-r7} \n" // pop the low registers - " ADD sp,sp,#(8*4) \n" // remove 8 registers from the stack - - " MOVS r2,#6 \n" - " MVNS r2,r2 \n" // r2 := ~6 == 0xFFFFFFF9 - " MOV lr,r2 \n" // make sure MSP is used -#else // ARMv7-M or higher -#ifdef __ARM_FP //--------- if VFP available... - " POP {r0,lr} \n" // restore aligner and EXC_RETURN into lr - " DSB \n" // ARM Erratum 838869 - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if EXC_RETURN[4] is zero... - " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#else - " BIC lr,lr,#(1 << 2) \n" // make sure MSP is used -#endif // VFP available - " POP {r4-r11} \n" // restore r4-r11 from the next thread's stack -#endif // ARMv7-M or higher - - " MOV r0,r12 \n" // r0 := QXK_priv_.next - " MOVS r2,#" STRINGIFY(QACTIVE_PRIO) "\n" // r2 := offset of .prio - " LDRB r0,[r0,r2] \n" // r0 := QXK_priv_.next->prio - " LDR r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" // r2 := QXK_priv_.actPrio - " CMP r2,r0 \n" - " BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO - - // otherwise no activation needed... - " MOVS r2,#0 \n" - " STR r2,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0 - " STR r2,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - - " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " CMP r0,#0 \n" // r0 == QXK_priv_.next->prio - " BEQ PendSV_idle \n" // if (QXK_priv_.next->prio != 0) - " MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_() - "PendSV_idle: \n" - " LDR r3,=QXK_contextSw_ \n" - " BLX r3 \n" // call QXK_contextSw_() -#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " B PendSV_return1 \n" // skip over saving aligner + EXC_RETURN - - // re-enable interrupts and return from PendSV - "PendSV_return: \n" - " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN - - "PendSV_return1: \n" -#ifdef QF_MEM_ISOLATE - " LDR r3,=QF_onMemApp \n" - " BLX r3 \n" // call QF_onMemApp() -#endif - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() - //>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>> - - " POP {r0,pc} \n" // return to the preempted AO-thread - - //------------------------------------------------------------------------ - // Saving extended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_save_ex: \n" - " MRS r0,PSP \n" // r0 := Process Stack Pointer -#if (__ARM_ARCH == 6) // if ARMv6-M... - " SUBS r0,r0,#(8*4) \n" // make room for 8 registers r4-r11 - " MOVS r1,r0 \n" // r1 := temporary PSP (do not clobber r0!) - " STMIA r1!,{r4-r7} \n" // save the low registers - " MOV r4,r8 \n" // move the high registers to low registers... - " MOV r5,r9 \n" - " MOV r6,r10 \n" - " MOV r7,r11 \n" - " STMIA r1!,{r4-r7} \n" // save the high registers - // NOTE: at this point r0 holds the top of stack - - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr (restore value) -#else // ARMv7-M or higher - " ISB \n" // reset pipeline after fetching PSP - " STMDB r0!,{r4-r11} \n" // save r4-r11 on top of the exception frame -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ r0!,{s16-s31} \n" // ... save VFP registers s16..s31 - " STMDB r0!,{r1,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available -#endif // ARMv7-M or higher - - // store the SP of the current extended-thread - " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // QXK_priv_.curr->osObject := r0 - " MOV r0,r12 \n" // QXK_priv_.next (restore value) - - " CMP r2,#0 \n" - " BEQ PendSV_restore_ao\n" // branch if (QXK_priv_.next->osObject == 0) - // otherwise continue to restoring next extended-thread... - - //------------------------------------------------------------------------ - // Restoring extended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_restore_ex: \n" - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := r0 (QXK_priv_.next) - " MOVS r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - - " PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_() - " LDR r3,=QXK_contextSw_ \n" - " BLX r3 \n" // call QXK_contextSw_() -#ifdef QF_MEM_ISOLATE - " LDR r3,=QF_onMemApp \n" - " BLX r3 \n" // call QF_onMemApp() -#endif -#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - - - // exit the critical section - " LDR r3,=QF_int_enable_ \n" - " BLX r3 \n" // call QF_int_enable_() - " POP {r0-r3} \n" // restore next, osObject, EXC_RETURN - " MOV lr,r3 \n" // restore the EXC_RETURN into lr - -#if (__ARM_ARCH == 6) // if ARMv6-M... - " MOVS r0,r2 \n" // r2 := top of stack - " ADDS r0,r0,#(4*4) \n" // point r0 to the 4 high registers r7-r11 - " LDMIA r0!,{r4-r7} \n" // pop the 4 high registers into low registers - " MOV r8,r4 \n" // move low registers into high registers - " MOV r9,r5 \n" - " MOV r10,r6 \n" - " MOV r11,r7 \n" - " LDMIA r2!,{r4-r7} \n" // pop the low registers - " MOVS r2,r0 \n" // r2 := holds the new top of stack - - " MOVS r1,#2 \n" - " MVNS r1,r1 \n" // r1 := ~2 == 0xFFFFFFFD - " MOV lr,r1 \n" // make sure PSP is used -#else // ARMv7-M or higher -#ifdef __ARM_FP //--------- if VFP available... - " LDMIA r2!,{r1,lr} \n" // restore aligner and EXC_RETURN into lr - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VLDMIAEQ r2!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#else - " ORR lr,lr,#(1 << 2) \n" // make sure PSP is used -#endif // VFP available - " LDMIA r2!,{r4-r11} \n" // restore r4-r11 from the next thread's stack -#endif // ARMv7-M or higher - - // set the PSP to the next thread's SP - " MSR PSP,r2 \n" // Process Stack Pointer := r2 - -#if (__ARM_ARCH != 6) // if ARMv7-M or higher... - " DSB \n" // ARM Erratum 838869 -#endif // ARMv7-M or higher - " BX lr \n" // return to the next extended-thread - ); -} - -//============================================================================ -// QXK_thread_ret is a helper function executed when the QXK activator returns. -// -// NOTE: QXK_thread_ret() does not execute in the PendSV context! -// NOTE: QXK_thread_ret() is entered with interrupts DISABLED. -__attribute__ ((naked, used)) -void QXK_thread_ret(void) { -__asm volatile ( - - // After the QXK activator returns, we need to resume the preempted - // thread. However, this must be accomplished by a return-from-exception, - // while we are still in the thread context. The switch to the exception - // context is accomplished by triggering the NMI exception or the selected - // IRQ (if macro #QXK_USE_IRQ_NUM is defined). - - // before triggering the NMI/IRQ, make sure that the VFP stack frame - // will NOT be used... -#ifdef __ARM_FP //--------- if VFP available... - // make sure that the VFP stack frame will NOT be used - " MRS r0,CONTROL \n" // r0 := CONTROL - " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) - " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) - " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) -#endif //--------- VFP available - - // NOTE: the following function calls corrupt lr, but it is NOT - // used to return from QXK_thread_ret(). Instead QXK_thread_ret() - // "returns" by entering an exception (either NMI or IRQ). -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemApp \n" - " BLX r0 \n" // call QF_onMemApp() -#endif - -#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) - " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) - // NOTE! interrupts are still disabled when NMI is entered - -#else //--------- use the selected IRQ - " LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n" - " MOVS r1,#1 \n" - " LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit - " STR r1,[r0] \n" // pend the IRQ - - // now enable interrupts so that pended IRQ can be entered - // - // NOTE-1: - // The IRQ preempts immediately after interrupts are enabled, - // without cleanly returning from QF_int_enable_(). Therefore - // QF_int_enable_() is NOT allowed to push anything on the stack - // because the stack is NOT restored when the IRQ preempts. - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#endif //--------- use IRQ - - " B . \n" // wait for preemption by NMI/IRQ - ); -} - -//============================================================================ -// This exception handler is used for returning back to the preempted thread. -// The exception handler simply removes its own interrupt stack frame from -// the stack (MSP) and returns to the preempted task using the interrupt -// stack frame that must be at the top of the stack. -__attribute__ ((naked)) -#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - -// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! -void NMI_Handler(void) { -__asm volatile ( - // call QF_int_enable_(), NOTE: corrupts lr (EXC_RETURN) - // but see code after "BLX r0" - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#ifdef __ARM_FP //--------- if VFP available... - // When VFP is available, lr (EXC_RETURN) is restored from the stack - // before returning from exception, so the value in lr doesn't matter -#else //--------- VFP NOT available - // lr (EXC_RETURN) can be synthesized because it is known (0xFFFFFFF9): - // - return to Thread mode; - // - exception return uses non-floating-point state from MSP; - // - execution uses MSP after return. - " MOVS r0,#6 \n" - " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 - " MOV lr,r0 \n" // lr := 0xFFFFFFF9 (EXC_RETURN) -#endif //--------- VFP NOT available -); - -#else //--------- IRQ defined, use the selected IRQ - -// NOTE: The IRQ Handler is entered with interrupts already ENABLED -void QXK_USE_IRQ_HANDLER(void) { -#endif //--------- IRQ defined - - // ...continue here from either NMI or IRQ -__asm volatile ( - " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame - -#ifdef __ARM_FP //--------- if VFP available... - " POP {r0,lr} \n" // restore aligher and EXC_RETURN into lr - " DSB \n" // ARM Erratum 838869 - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if EXC_RETURN[4] is zero... - " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#endif //--------- VFP available - " BX lr \n" // return to the preempted task - ); -} - -//============================================================================ -#if (__ARM_ARCH == 6) // if ARMv6-M... - -// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) -__attribute__ ((naked)) -uint_fast8_t QF_qlog2(uint32_t x) { -__asm volatile ( - " MOVS r1,#0 \n" -#if (QF_MAX_ACTIVE > 16U) - " LSRS r2,r0,#16 \n" - " BEQ QF_qlog2_1 \n" - " MOVS r1,#16 \n" - " MOVS r0,r2 \n" - "QF_qlog2_1: \n" -#endif -#if (QF_MAX_ACTIVE > 8U) - " LSRS r2,r0,#8 \n" - " BEQ QF_qlog2_2 \n" - " ADDS r1, r1,#8 \n" - " MOVS r0, r2 \n" - "QF_qlog2_2: \n" -#endif - " LSRS r2,r0,#4 \n" - " BEQ QF_qlog2_3 \n" - " ADDS r1,r1,#4 \n" - " MOV r0,r2 \n" - "QF_qlog2_3: \n" - " LDR r2,=QF_qlog2_LUT \n" - " LDRB r0,[r2,r0] \n" - " ADDS r0,r1,r0 \n" - " BX lr \n" - " .align \n" - "QF_qlog2_LUT: \n" - " .byte 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4" - ); -} - -#endif // ARMv6-M - diff --git a/ports/arm-cm/qxk/config/qp_config.h b/ports/arm-cm/qxk/config/qp_config.h deleted file mode 100644 index 191770f4..00000000 --- a/ports/arm-cm/qxk/config/qp_config.h +++ /dev/null @@ -1,255 +0,0 @@ -//============================================================================ -// QP configuration file (QXK on ARM Cortex-M) -// Last updated for version: 7.4.0 -// Last updated on: 2024-06-06 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -#ifndef QP_CONFIG_H_ -#define QP_CONFIG_H_ - -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- - -// NOTE: Requires command-line macro: QP_CONFIG -// This qp_config.h header file is activated only when the macro -// QP_CONFIG is defined on the command-line to the compiler -// ------------------------------------------- - -// QP API compatibility version (QP_API_VERSION) -// <0=> 0 (Maximum compatibility) -// <580=>580 (QP 5.8.0 or newer) -// <660=>660 (QP 6.6.0 or newer) -// <691=>691 (QP 6.9.1 or newer) -// <700=>700 (QP 7.0.0 or newer) -// <9999=>9999 (Latest only) -// QP API backwards compatibility with the QP/C API version. -// Lower QP_API_VERSION values enable backwards compatibility -// with lower (older) QP API versions. -// For example, QP_API_VERSION==691 will enable the compatibility -// layer with QP version 6.9.1 and newer, but not older than 6.9.1. -// QP_API_VERSION==0 enables the maximum currently supported -// backwards compatibility. Conversely, QP_API_VERSION==9999 means -// that no backwards compatibility layer should be enabled. -// Default: 0 (All supported) -#define QP_API_VERSION 0 - -//.......................................................................... -// QP Functional Safety (FuSa) Subsystem (Q_UNSAFE) -// The QP FuSa Subsystem consists of the following facilities: -// - Software assertions as a recommended technique -// (called Failure Assertion Programming (FAP) in IEC 61508) -// - Software Self-Monitoring (SSM), which encompasses such techniques: -// * Duplicate Inverse Storage for critical variables -// * Memory Markers for critical objects (e.g., events) -// * Hard-limits for all loops -// * Memory Isolation by means of Memory Protection Unit (MPU) - -// Disable QP FuSa in development -// Disable assertions and other self monitoring features -// in development build configurations (NDEBUG undefined). -// VIOLATES functional safety standards. NOT recommended !!! -//#ifndef NDEBUG -//#define Q_UNSAFE -//#endif -// - -// Disable QP FuSa in production release -// Disable assertions and other self monitoring features -// in the release build configurations (NDEBUG defined). -// VIOLATES functional safety standards. NOT recommended !!! -//#ifdef NDEBUG -//#define Q_UNSAFE -//#endif -// - -// - -//.......................................................................... -// QEP Event Processor -// Events and state machines. - -// Event signal size (Q_SIGNAL_SIZE) -// <1U=>1 -// <2U=>2 (default) -// <4U=>4 -// Size of the QEvt signal for QEP/QF [bytes] -// Default: 2 -#define Q_SIGNAL_SIZE 2U - -// - -//.......................................................................... -// QF Framework -// Active Object framework - -// Maximum # Active Objects (QF_MAX_ACTIVE) <1-64> -// Maximum # Active Objects in the system <1..64> -// Default: 32 -#define QF_MAX_ACTIVE 32U - -// Maximum # event pools (QF_MAX_EPOOL) -// <0=>0 no event pools -// <1=>1 <2=>2 <3=>3 (default) <4=>4 <5=>5 -// <6=>6 <7=>7 <8=>8 <9=>9 <10=>10 <11=>11 -// <12=>12 <13=>13 <14=>14 <15=>15 -// Maximum # Event Pools <1..15> -// Default: 3 -#define QF_MAX_EPOOL 3U - -// Maximum # clock tick rates (QF_MAX_TICK_RATE) -// <0=>0 no time events -// <1=>1 (default) <2=>2 <3=>3 <4=>4 <5=>5 -// <6=>6 <7=>7 <8=>8 <9=>9 <10=>10 <11=>11 -// <12=>12 <13=>13 <14=>14 <15=>15 -// Maximum # clock tick rates for time events <1..15> -// Default: 1 -#define QF_MAX_TICK_RATE 1U - -// Event parameter initialization (QEVT_PAR_INIT) -// Resource Acquisition Is Initialization (RAII) for dynamic events -//#define QEVT_PAR_INIT -// - -// Active Object stop API (QACTIVE_CAN_STOP) -// Enable Active Object stop API (Not recommended) -//#define QACTIVE_CAN_STOP -// - -// Event size (QF_EVENT_SIZ_SIZE) -// <1U=>1 -// <2U=>2 (default) -// <4U=>4 -// Size of the dynamic events for QF [bytes] -// Default: 2 (64K bytes maximum event size) -#define QF_EVENT_SIZ_SIZE 2U - -// Time event counter size (QF_TIMEEVT_CTR_SIZE) -// <1U=>1 -// <2U=>2 -// <4U=>4 (default) -// Size of the QTimeEvt counter [bytes] -// Default: 4 (2^32 dynamic range) -#define QF_TIMEEVT_CTR_SIZE 4U - -// Event queue counter size (QF_EQUEUE_CTR_SIZE) -// <1U=>1 (default) -// <2U=>2 -// <4U=>4 -// Size of event queue counter [bytes] -// Default: 1 (255 events maximum in a queue) -#define QF_EQUEUE_CTR_SIZE 1U - -// Memory pool counter size (QF_MPOOL_CTR_SIZE) -// <1U=>1 -// <2U=>2 (default) -// <4U=>4 -// Size of memory pool counter [bytes] -// Default: 2 (64K blocks maximum in a pool) -#define QF_MPOOL_CTR_SIZE 2U - -// Memory block size (QF_MPOOL_SIZ_SIZE) -// <1U=>1 -// <2U=>2 (default) -// <4U=>4 -// Size of memory pool block [bytes] -// Default: 2 (64K bytes maximum block size) -#define QF_MPOOL_SIZ_SIZE 2U - -// - -//.......................................................................... -// QS Software Tracing -// Target-resident component of QP/Spy software tracing system -// (tracing instrumentation and command-input). - -// NOTE: Requires command-line macro: Q_SPY -// The QS software tracing instrumentation is activated only when -// the macro Q_SPY is defined on the command-line to the compiler. -// Typically, Q_SPY is defined only in the "spy" build configuration. - -// QS timestamp size (QS_TIME_SIZE) -// <1U=>1 -// <2U=>2 -// <4U=>4 (default) -// Size of the timestamp in QS [bytes] -// Default: 4 (2^32 dynamic range) -#define QS_TIME_SIZE 4U - -// QS buffer counter size (QS_CTR_SIZE) -// <1U=>1 -// <2U=>2 (default) -// <4U=>4 -// Size of the counter in the internal QS buffer [bytes] -// Default: 2 (64K bytes in QS buffer) -#define QS_CTR_SIZE 2U - -// - -//.......................................................................... -// QXK Preemptive Dual-Mode Kernel -// Preemptive non-blocking/blocking RTOS kernel. - -// Context switch callback (QF_ON_CONTEXT_SW) - -// Context switch callback WITHOUT QS -// Enable context switch callback QF_onContextSw() -// When Q_SPY is undefined. -//#ifndef Q_SPY -//#define QF_ON_CONTEXT_SW -//#endif -// - -// Context switch callback WITH QS -// Enable context switch callback QF_onContextSw() -// When Q_SPY is defined. -//#ifdef Q_SPY -//#define QF_ON_CONTEXT_SW -//#endif -// - -// - -// MPU memory isolation (QF_MEM_ISOLATE) -// Enable memory isolation (requires MPU) -// NOTE: implies QF_ON_CONTEXT_SW. -//#define QF_MEM_ISOLATE -// - -// Use IRQ handler for QXK return-from-preemption -// Enable this option only if the NMI handler is used in the project. -// If enabled, provide the otherwise unused IRQ number (QXK_USE_IRQ_NUM) -// and the corresponding IRQ handler name (QXK_USE_IRQ_HANDLER) -// in the "Text Editor" mode. -//#define QXK_USE_IRQ_NUM 31 -//#define QXK_USE_IRQ_HANDLER Reserved31_IRQHandler -// - -// - -//------------- <<< end of configuration section >>> ----------------------- - -#endif // QP_CONFIG_H_ diff --git a/ports/arm-cm/qxk/gnu/qp_port.h b/ports/arm-cm/qxk/gnu/qp_port.h deleted file mode 100644 index 4c15708b..00000000 --- a/ports/arm-cm/qxk/gnu/qp_port.h +++ /dev/null @@ -1,235 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-12-02 -//! @version Last updated for: @ref qpc_7_3_1 -//! -//! @file -//! @brief QP/C port to ARM Cortex-M, dual-mode QXK kernel, GNU-ARM - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QF configuration for QXK -- data members of the QActive class... - -// QActive event-queue type used for AOs and eXtended threads. -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QActive OS-Object type used for the private stack pointer for eXtended threads. -// (The private stack pointer is NULL for basic-threads). -#define QACTIVE_OS_OBJ_TYPE void* - -// QActive "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// QF interrupt disable/enable and log2()... -#if (__ARM_ARCH == 6) // ARMv6-M? - - // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 - #define QF_AWARE_ISR_CMSIS_PRI 0 - - // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else // ARMv7-M or higher - - // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 - #define QF_BASEPRI 0x3F - - // CMSIS threshold for "QF-aware" interrupts, see NOTE4 - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - // ARMv7-M or higher provide the CLZ instruction for fast LOG2 - #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) - -#endif - -// interrupt disabling policy, see NOTE2 and NOTE3 -#define QF_INT_DISABLE() (QF_int_disable_()) -#define QF_INT_ENABLE() (QF_int_enable_()) - -// QF critical section, see NOTE1, NOTE2, and NOTE3 -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() (QF_crit_entry_()) -#define QF_CRIT_EXIT() (QF_crit_exit_()) - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") - -#if (__ARM_ARCH == 6) // ARMv6-M? - // hand-optimized quick LOG2 in assembly - uint_fast8_t QF_qlog2(uint32_t x); -#endif // ARMv7-M or higher - -// Memory isolation ---------------------------------------------------------- -#ifdef QF_MEM_ISOLATE - - // Memory isolation requires the context-switch - #define QF_ON_CONTEXT_SW 1U - - // Memory System setting - #define QF_MEM_SYS() QF_onMemSys() - - // Memory Application setting - #define QF_MEM_APP() QF_onMemApp() - - // callback functions for memory settings (provided by applications) - void QF_onMemSys(void); - void QF_onMemApp(void); - -#endif // def QF_MEM_ISOLATE - -// determination if the code executes in the ISR context -#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) - -__attribute__((always_inline)) -static inline uint32_t QXK_get_IPSR(void) { - uint32_t regIPSR; - __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); - return regIPSR; -} - -// trigger the PendSV exception to perform the context switch -#define QXK_CONTEXT_SWITCH_() \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) - -// QXK ISR entry and exit -#define QXK_ISR_ENTRY() ((void)0) - -#ifdef QF_MEM_ISOLATE - #define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - QF_MEM_SYS(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ - } while (false) -#else - #define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ - } while (false) -#endif - -#if (__ARM_ARCH == 6) // ARMv6-M? - #define QXK_ARM_ERRATUM_838869() ((void)0) -#else // ARMv7-M or higher - // The following macro implements the recommended workaround for the - // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - // (memory barrier) instruction needs to be added before exiting an ISR. - #define QXK_ARM_ERRATUM_838869() \ - __asm volatile ("dsb" ::: "memory") - -#endif // ARMv6-M - -// initialization of the QXK kernel -#define QXK_INIT() QXK_init() -void QXK_init(void); -void QXK_thread_ret(void); - -#ifdef __ARM_FP //--------- if VFP available... -// When the FPU is configured, clear the FPCA bit in the CONTROL register -// to prevent wasting the stack space for the FPU context. -#define QXK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QXK kernel uses the native QP event queue -#include "qmpool.h" // QXK kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qxk.h" // QXK kernel - -// prototypes -void QF_int_disable_(void); -void QF_int_enable_(void); -void QF_crit_entry_(void); -void QF_crit_exit_(void); - -extern int32_t volatile QF_int_lock_nest_; - -//============================================================================ -// NOTE1: -// The critical section policy does not use the "saving and restoring" -// interrupt status policy (macro QF_CRIT_STAT is defined to nothing). -// However, this the QF critical sections might still be able to nest, -// depending on the implementation of the QF_crit_entry_()/QF_crit_exit_() -// functions. They are defined as "weak" in the qv_port.c module, -// so the application can provide a different implementation. -// Please see the definitions of the interrupt and critical-section -// funcctions in the qv_port.c module for details. -// -// NOTE2: -// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt -// disabling policy uses the PRIMASK register to disable interrupts globally. -// The QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts -// are "kernel-aware". -// -// NOTE3: -// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI -// register (which is not implemented in ARMv6-M) to disable interrupts only -// with priority lower than the threshold specified by the QF_BASEPRI macro. -// The interrupts with priorities above QF_BASEPRI (i.e., with numerical -// priority values lower than QF_BASEPRI) are NOT disabled in this method. -// These free-running interrupts have very low ("zero") latency, but they -// are NOT allowed to call any QF services, because QF is unaware of them -// ("kernel-unaware" interrupts). Consequently, only interrupts with -// numerical values of priorities equal to or higher than QF_BASEPRI -// ("kernel-aware" interrupts ), can call QF services. -// -// NOTE4: -// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -// the "QF-aware" interrupt priorities in the applications, whereas the -// numerical values of the "QF-aware" interrupts must be greater or equal to -// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -// passed directly to the CMSIS function NVIC_SetPriority(), which shifts -// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -// is intended only for applications and is not used inside the QF port, which -// remains generic and not dependent on the number of implemented priority bits -// implemented in the NVIC. - -#endif // QP_PORT_H_ - diff --git a/ports/arm-cm/qxk/gnu/qs_port.h b/ports/arm-cm/qxk/gnu/qs_port.h deleted file mode 100644 index 7895e109..00000000 --- a/ports/arm-cm/qxk/gnu/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 4U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 4U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/arm-cm/qxk/gnu/qxk_port.c b/ports/arm-cm/qxk/gnu/qxk_port.c deleted file mode 100644 index 4eb91756..00000000 --- a/ports/arm-cm/qxk/gnu/qxk_port.c +++ /dev/null @@ -1,808 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-28 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QXK/C port to ARM Cortex-M, GNU-ARM - -#define QP_IMPL 1U -#include "qp_port.h" -#include "qp_pkg.h" -#include "qsafe.h" // QP Functional Safety (FuSa) System - -#include // for offsetof() - -//============================================================================ -// NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! -#define QXK_CURR 0 -#define QXK_NEXT 4 -#define QXK_ACT_PRIO 12 - -// make sure that the offsets match the QXK declaration in "qxk.h" -_Static_assert(QXK_CURR == offsetof(QXK_Attr, curr), - "QXK_Attr.curr at unexpected offset"); -_Static_assert(QXK_NEXT == offsetof(QXK_Attr, next), - "QXK_Attr.next at unexpected offset"); -_Static_assert(QXK_ACT_PRIO == offsetof(QXK_Attr, actPrio), - "QXK_Attr.actPrio at unexpected offset"); - -// offsets within struct QActive; NOTE: keep in synch with "qp.h" !!! -#define QACTIVE_PRIO 12 -#define QACTIVE_OSOBJ 20 - -// make sure that the offsets match the QActvie declaration in "qp.h" -_Static_assert(QACTIVE_OSOBJ == offsetof(QActive, osObject), - "QActive.osObject at unexpected offset"); -_Static_assert(QACTIVE_PRIO == offsetof(QActive, prio), - "QActive.prio at unexpected offset"); - -//============================================================================ -// Initialize the private stack of an extended QXK thread. -// -// NOTE -// The function aligns the stack to the 8-byte boundary for compatibility -// with the AAPCS. Additionally, the function pre-fills the stack with the -// known bit pattern (0xDEADBEEF). -// -// NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware -// of this thread. In that case the kernel cannot use the thread yet, so no -// critical section is needed. -void QXThread_stackInit_(QActive *me, QXThreadHandler const handler, - void * const stkSto, uint_fast16_t const stkSize) -{ - // round down the stack top to the 8-byte boundary - // NOTE: ARM Cortex-M stack grows down from hi -> low memory - uint32_t *sp = - (uint32_t *)((((uint32_t)stkSto + stkSize) >> 3U) << 3U); - uint32_t *sp_limit; - - // synthesize the ARM Cortex-M exception stack frame... - *(--sp) = (1U << 24); // xPSR (just the THUMB bit) - *(--sp) = (uint32_t)handler; // PC (the thread handler) - *(--sp) = (uint32_t)&QXK_threadExit_; // LR (exit from thread) - *(--sp) = 0x0000000CU; // R12 - *(--sp) = 0x00000003U; // R3 - *(--sp) = 0x00000002U; // R2 - *(--sp) = 0x00000001U; // R1 - *(--sp) = (uint32_t)me; // R0 parameter to handler (thread object) - *(--sp) = 0x0000000BU; // R11 - *(--sp) = 0x0000000AU; // R10 - *(--sp) = 0x00000009U; // R9 - *(--sp) = 0x00000008U; // R8 - *(--sp) = 0x00000007U; // R7 - *(--sp) = 0x00000006U; // R6 - *(--sp) = 0x00000005U; // R5 - *(--sp) = 0x00000004U; // R4 - -#ifdef __ARM_FP //--------- if VFP available... - *(--sp) = 0xFFFFFFFDU; // exception return with VFP state - *(--sp) = 0xAAAAAAAAU; // stack "aligner" -#endif // VFP available - - // save the top of the stack in the thread's attribute - me->osObject = sp; - - // pre-fill the unused part of the stack with 0xDEADBEEF - sp_limit = (uint32_t *)(((((uint32_t)stkSto - 1U) >> 3U) + 1U) << 3U); - for (; sp >= sp_limit; --sp) { - *sp = 0xDEADBEEFU; - } -} - -// prototypes ---------------------------------------------------------------- -void PendSV_Handler(void); -#ifdef QXK_USE_IRQ_HANDLER // if use IRQ... -void QXK_USE_IRQ_HANDLER(void); -#else // use default (NMI) -void NMI_Handler(void); -#endif - -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) -#define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint32_t volatile *)0xE000E400U) -#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) -#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -#define NVIC_PEND 0xE000E200 -#define SCB_ICSR 0xE000ED04 - -// helper macros to "stringify" values -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) - -//============================================================================ -// interrupts and critical section... -// -// NOTE: -// The following interrupt disabling/enabling as well as critical section -// entry/exit functions are defined as "weak" so that they can be -// re-implemented differently at the application level. -// -// NOTE: -// For best performance, these functions are implemented in assembly, -// but they can be implemented in C as well. - - -//int32_t volatile QF_int_lock_nest_; // not used -extern char const QF_port_module_[]; -char const QF_port_module_[] = "qxk_port"; - -//............................................................................ -// Unconditionally disable interrupts. -// -// description: -// On ARMv6-M, interrupts are disabled with the PRIMASK register. -// On ARMv7-M and higher, interrupts are disabled *selectively* with the -// BASEPRI register. -// Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -__attribute__ ((naked, weak)) void QF_int_disable_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK - " CPSID i \n" // set PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI - " MOVS r1,#" STRINGIFY(QF_BASEPRI) "\n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0) - " BNE QF_int_disable_error\n" - " BX lr \n" - "QF_int_disable_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#100 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Unconditionally enable interrupts. -// -// description: -// On ARMv6-M, interrupts are enabled with the PRIMASK register. -// On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. -// Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// QF_int_enable_() is NOT allowed to push anything on the stack -// (see NOTE-1 at the end of QXK_thread_ret(). -__attribute__ ((naked, weak)) void QF_int_enable_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI != 0) - " BEQ QF_int_enable_error\n" -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " CPSIE i \n" // clear PRIMASK -#else //--------- ARMv7-M or higher - " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " BX lr \n" - "QF_int_enable_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#101 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Enter QF critical section. -// -// description: -// On ARMv6-M, critical section is entered by disabling interrupts -// with the PRIMASK register. -// On ARMv7-M and higher, critical section is entered by disabling -// interrupts *selectively* with the BASEPRI register. -// Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_entry_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK - " CPSID i \n" // set PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI - " MOVS r1,#" STRINGIFY(QF_BASEPRI) "\n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0) - " BNE QF_crit_entry_error\n" - " BX lr \n" - "QF_crit_entry_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#110 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Exit QF critical section. -// -// description: -// On ARMv6-M, critical section is exited by enabling interrupts -// with the PRIMASK register. -// On ARMv7-M and higher, critical section is exited by enabling -// interrupts with the BASEPRI register. -// Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -__attribute__ ((naked, weak)) void QF_crit_exit_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI != 0) - " BEQ QF_crit_exit_error\n" -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " CPSIE i \n" // clear PRIMASK -#else //--------- ARMv7-M or higher - " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " BX lr \n" - "QF_crit_exit_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#111 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} - -//============================================================================ -// Initialize the exception priorities and IRQ priorities to safe values. -// -// description: -// On ARMv7-M or higher, this QF port disables interrupts by means of the -// BASEPRI register. However, this method cannot disable interrupt -// priority zero, which is the default for all interrupts out of reset. -// The following code changes the SysTick priority and all IRQ priorities -// to the safe value QF_BASEPRI, which the QF critical section can disable. -// This avoids breaching of the QF critical sections in case the -// application programmer forgets to explicitly set priorities of all -// "kernel aware" interrupts. -// -// The interrupt priorities established in QXK_init() can be later -// changed by the application-level code. -void QXK_init(void) { - -#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - - // SCB_SYSPRI[2]: SysTick - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - - // set all 240 possible IRQ priories to QF_BASEPRI... - for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { - NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) - | (QF_BASEPRI << 8U) | QF_BASEPRI; - } - -#endif //--------- ARMv7-M or higher - - // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); - -#ifdef QXK_USE_IRQ_NUM //--------- QXK IRQ specified? - // The QXK port is configured to use a given ARM Cortex-M IRQ # - // to return to thread mode (default is to use the NMI exception) - NVIC_IP[QXK_USE_IRQ_NUM] = 0U; // priority 0 (highest) - NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); -#endif //--------- QXK IRQ specified - -#ifdef __ARM_FP //--------- if VFP available... - // make sure that the FPU is enabled by setting CP10 & CP11 Full Access - SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); - - // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) - FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); -#endif //--------- VFP available -} - -//============================================================================ -// The PendSV exception is used for performing asynchronous preemption in QXK. -// The use of the PendSV exception is the recommended and most efficient -// method for performing context switches in ARM Cortex-M. -// -// The PendSV exception should have the lowest interrupt priority in the system -// (0xFF, see QXK_init()). All other exceptions and interrupts should have -// higher interrupt priority. -// -// Also, *all* "kernel aware" ISRs in the QXK application must call the -// QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -// asynchronous preemption. -// -// Due to tail-chaining and its lowest priority, the PendSV exception will be -// entered immediately after the exit from the *last* nested interrupt (or -// exception). In QXK, this is exactly the time when the QXK activator needs to -// handle the asynchronous preemption. -// -// NOTE: -// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, -// but for Cortex-M0/M0+/M1 the mnemonics MOV, LSR and ADD always set the -// condition flags in the PSR. -__attribute__ ((naked, optimize("-fno-stack-protector"))) -void PendSV_Handler(void) { -__asm volatile ( - - //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< - " PUSH {r0,lr} \n" // save stack-aligner + EXC_RETURN - " LDR r0,=QF_int_disable_ \n" - " BLX r0 \n" // call QF_int_disable_() - -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemSys \n" - " BLX r0 \n" // call QF_onMemSys() -#endif - " POP {r0,r1} \n" // restore the aligner + EXC_RETURN in r1 - " MOV lr,r1 \n" // restore EXC_RETURN into lr - - // The PendSV exception handler can be preempted by an interrupt, - // which might pend PendSV exception again. The following write to - // ICSR[27] un-pends any such spurious instance of PendSV. - " MOV r1,#1 \n" - " LSL r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit) - " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " STR r1,[r2] \n" // ICSR[27] := 1 (un-pend PendSV) - - // Check QXK_priv_.next, which contains the pointer to the next thread - // to run, which is set in QXK_ISR_EXIT(). Return if QXK_priv_.next == 0 - " LDR r3,=QXK_priv_ \n" - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next - " CMP r0,#0 \n" // is (QXK_priv_.next == 0)? - " BEQ PendSV_return \n" // branch if (QXK_priv_.next == 0) - - // Load pointers into registers... - " MOV r12,r0 \n" // save QXK_priv_.next in r12 - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // r2 := QXK_priv_.next->osObject - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr - - " CMP r1,#0 \n" // (QXK_priv_.curr != 0)? - " BNE PendSV_save_ex \n" // branch if (current thread is extended) - - " CMP r2,#0 \n" // (QXK_priv_.next->osObject != 0)? - " BNE PendSV_save_ao \n" // branch if (next thread is extended) - - "PendSV_activate: \n" -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 - " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available - // The QXK activator must be called in a Thread mode, while this code - // executes in the Handler mode of the PendSV exception. The switch - // to the Thread mode is accomplished by returning from PendSV using - // a fabricated exception stack frame, where the return address is - // QXK_activate_(). - // - // NOTE: the QXK activator is called with interrupts DISABLED and also - // returns with interrupts DISABLED. - " MOV r3,#1 \n" - " LSL r3,r3,#24 \n" // r3 := (1 << 24), set T bit (new xpsr) - " LDR r2,=QXK_activate_\n" // address of QXK_activate_ - " SUB r2,r2,#1 \n" // align Thumb-address at halfword (new pc) - " LDR r1,=QXK_thread_ret\n" // return address after the call (new lr) - - " SUB sp,sp,#(8*4) \n" // reserve space for exception stack frame - " ADD r0,sp,#(5*4) \n" // r0 := 5 registers below the SP - " STM r0!,{r1-r3} \n" // save xpsr,pc,lr - - " MOV r0,#6 \n" - " MVN r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 -#if (__ARM_ARCH != 6) // ARMv7-M or higher - " DSB \n" // ARM Erratum 838869 -#endif // ARMv7-M or higher - " BX r0 \n" // exception-return to the QXK activator - - //======================================================================== - // Saving AO-thread before crossing to eXtended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_save_ao: \n" -#if (__ARM_ARCH == 6) // if ARMv6-M... - " SUB sp,sp,#(8*4) \n" // make room for 8 registers r4-r11 - " MOV r0,sp \n" // r0 := temporary stack pointer - " STMIA r0!,{r4-r7} \n" // save the low registers - " MOV r4,r8 \n" // move the high registers to low registers... - " MOV r5,r9 \n" - " MOV r6,r10 \n" - " MOV r7,r11 \n" - " STMIA r0!,{r4-r7} \n" // save the high registers - " MOV r0,r12 \n" // restore QXK_priv_.next in r0 -#else // ARMv7-M or higher - " PUSH {r4-r11} \n" // save r4-r11 on top of the exception frame -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 - " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available -#endif // ARMv7-M or higher - - " CMP r2,#0 \n" - " BNE PendSV_restore_ex\n" // branch if (QXK_priv_.next->osObject != 0) - // otherwise continue to restoring next AO-thread... - - //------------------------------------------------------------------------ - // Restoring AO-thread after crossing from eXtended-thread - // expected register contents: - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_restore_ao: \n" - // don NOT clear QXK_priv_.curr or QXK_priv_.next, - // as they might be needed for AO activation - -#if (__ARM_ARCH == 6) // if ARMv6-M... - " MOV r0,sp \n" // r0 := top of stack - " MOV r2,r0 \n" - " ADD r2,r2,#(4*4) \n" // point r2 to the 4 high registers r7-r11 - " LDMIA r2!,{r4-r7} \n" // pop the 4 high registers into low registers - " MOV r8,r4 \n" // move low registers into high registers - " MOV r9,r5 \n" - " MOV r10,r6 \n" - " MOV r11,r7 \n" - " LDMIA r0!,{r4-r7} \n" // pop the low registers - " ADD sp,sp,#(8*4) \n" // remove 8 registers from the stack - - " MOV r2,#6 \n" - " MVN r2,r2 \n" // r2 := ~6 == 0xFFFFFFF9 - " MOV lr,r2 \n" // make sure MSP is used -#else // ARMv7-M or higher -#ifdef __ARM_FP //--------- if VFP available... - " POP {r0,lr} \n" // restore aligner and EXC_RETURN into lr - " DSB \n" // ARM Erratum 838869 - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if EXC_RETURN[4] is zero... - " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#else - " BIC lr,lr,#(1 << 2) \n" // make sure MSP is used -#endif // VFP available - " POP {r4-r11} \n" // restore r4-r11 from the next thread's stack -#endif // ARMv7-M or higher - - " MOV r0,r12 \n" // r0 := QXK_priv_.next - " MOV r2,#" STRINGIFY(QACTIVE_PRIO) "\n" // r2 := offset of .prio - " LDRB r0,[r0,r2] \n" // r0 := QXK_priv_.next->prio - " LDR r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" // r2 := QXK_priv_.actPrio - " CMP r2,r0 \n" - " BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO - - // otherwise no activation needed... - " MOV r2,#0 \n" - " STR r2,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0 - " STR r2,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - - " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " CMP r0,#0 \n" // r0 == QXK_priv_.next->prio - " BEQ PendSV_idle \n" // if (QXK_priv_.next->prio != 0) - " MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_() - "PendSV_idle: \n" - " LDR r3,=QXK_contextSw_ \n" - " BLX r3 \n" // call QXK_contextSw_() -#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " B PendSV_return1 \n" // skip over saving aligner + EXC_RETURN - - // re-enable interrupts and return from PendSV - "PendSV_return: \n" - " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN - - "PendSV_return1: \n" -#ifdef QF_MEM_ISOLATE - " LDR r3,=QF_onMemApp \n" - " BLX r3 \n" // call QF_onMemApp() -#endif - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() - //>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>> - - " POP {r0,pc} \n" // return to the preempted AO-thread - - //------------------------------------------------------------------------ - // Saving extended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_save_ex: \n" - " MRS r0,PSP \n" // r0 := Process Stack Pointer -#if (__ARM_ARCH == 6) // if ARMv6-M... - " SUB r0,r0,#(8*4) \n" // make room for 8 registers r4-r11 - " MOV r1,r0 \n" // r1 := temporary PSP (do not clobber r0!) - " STMIA r1!,{r4-r7} \n" // save the low registers - " MOV r4,r8 \n" // move the high registers to low registers... - " MOV r5,r9 \n" - " MOV r6,r10 \n" - " MOV r7,r11 \n" - " STMIA r1!,{r4-r7} \n" // save the high registers - // NOTE: at this point r0 holds the top of stack - - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr (restore value) -#else // ARMv7-M or higher - " ISB \n" // reset pipeline after fetching PSP - " STMDB r0!,{r4-r11} \n" // save r4-r11 on top of the exception frame -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ r0!,{s16-s31} \n" // ... save VFP registers s16..s31 - " STMDB r0!,{r1,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available -#endif // ARMv7-M or higher - - // store the SP of the current extended-thread - " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // QXK_priv_.curr->osObject := r0 - " MOV r0,r12 \n" // QXK_priv_.next (restore value) - - " CMP r2,#0 \n" - " BEQ PendSV_restore_ao\n" // branch if (QXK_priv_.next->osObject == 0) - // otherwise continue to restoring next extended-thread... - - //------------------------------------------------------------------------ - // Restoring extended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_restore_ex: \n" - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := r0 (QXK_priv_.next) - " MOV r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - - " PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_() - " LDR r3,=QXK_contextSw_ \n" - " BLX r3 \n" // call QXK_contextSw_() -#ifdef QF_MEM_ISOLATE - " LDR r3,=QF_onMemApp \n" - " BLX r3 \n" // call QF_onMemApp() -#endif -#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - - - // exit the critical section - " LDR r3,=QF_int_enable_ \n" - " BLX r3 \n" // call QF_int_enable_() - " POP {r0-r3} \n" // restore next, osObject, EXC_RETURN - " MOV lr,r3 \n" // restore the EXC_RETURN into lr - -#if (__ARM_ARCH == 6) // if ARMv6-M... - " MOV r0,r2 \n" // r2 := top of stack - " ADD r0,r0,#(4*4) \n" // point r0 to the 4 high registers r7-r11 - " LDMIA r0!,{r4-r7} \n" // pop the 4 high registers into low registers - " MOV r8,r4 \n" // move low registers into high registers - " MOV r9,r5 \n" - " MOV r10,r6 \n" - " MOV r11,r7 \n" - " LDMIA r2!,{r4-r7} \n" // pop the low registers - " MOV r2,r0 \n" // r2 := holds the new top of stack - - " MOV r1,#2 \n" - " MVN r1,r1 \n" // r1 := ~2 == 0xFFFFFFFD - " MOV lr,r1 \n" // make sure PSP is used -#else // ARMv7-M or higher -#ifdef __ARM_FP //--------- if VFP available... - " LDMIA r2!,{r1,lr} \n" // restore aligner and EXC_RETURN into lr - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VLDMIAEQ r2!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#else - " ORR lr,lr,#(1 << 2) \n" // make sure PSP is used -#endif // VFP available - " LDMIA r2!,{r4-r11} \n" // restore r4-r11 from the next thread's stack -#endif // ARMv7-M or higher - - // set the PSP to the next thread's SP - " MSR PSP,r2 \n" // Process Stack Pointer := r2 - -#if (__ARM_ARCH != 6) // if ARMv7-M or higher... - " DSB \n" // ARM Erratum 838869 -#endif // ARMv7-M or higher - " BX lr \n" // return to the next extended-thread - ); -} - -//============================================================================ -// QXK_thread_ret is a helper function executed when the QXK activator returns. -// -// NOTE: QXK_thread_ret() does not execute in the PendSV context! -// NOTE: QXK_thread_ret() is entered with interrupts DISABLED. -__attribute__ ((naked, used)) -void QXK_thread_ret(void) { -__asm volatile ( - - // After the QXK activator returns, we need to resume the preempted - // thread. However, this must be accomplished by a return-from-exception, - // while we are still in the thread context. The switch to the exception - // context is accomplished by triggering the NMI exception or the selected - // IRQ (if macro #QXK_USE_IRQ_NUM is defined). - - // before triggering the NMI/IRQ, make sure that the VFP stack frame - // will NOT be used... -#ifdef __ARM_FP //--------- if VFP available... - // make sure that the VFP stack frame will NOT be used - " MRS r0,CONTROL \n" // r0 := CONTROL - " BIC r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) - " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) - " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) -#endif //--------- VFP available - - // NOTE: the following function calls corrupt lr, but it is NOT - // used to return from QXK_thread_ret(). Instead QXK_thread_ret() - // "returns" by entering an exception (either NMI or IRQ). -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemApp \n" - " BLX r0 \n" // call QF_onMemApp() -#endif - -#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " MOV r1,#1 \n" - " LSL r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) - " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) - // NOTE! interrupts are still disabled when NMI is entered - -#else //--------- use the selected IRQ - " LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n" - " MOV r1,#1 \n" - " LSL r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit - " STR r1,[r0] \n" // pend the IRQ - - // now enable interrupts so that pended IRQ can be entered - // - // NOTE-1: - // The IRQ preempts immediately after interrupts are enabled, - // without cleanly returning from QF_int_enable_(). Therefore - // QF_int_enable_() is NOT allowed to push anything on the stack - // because the stack is NOT restored when the IRQ preempts. - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#endif //--------- use IRQ - - " B . \n" // wait for preemption by NMI/IRQ - ); -} - -//============================================================================ -// This exception handler is used for returning back to the preempted thread. -// The exception handler simply removes its own interrupt stack frame from -// the stack (MSP) and returns to the preempted task using the interrupt -// stack frame that must be at the top of the stack. -__attribute__ ((naked, optimize("-fno-stack-protector"))) -#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - -// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! -void NMI_Handler(void) { -__asm volatile ( - // call QF_int_enable_(), NOTE: corrupts lr (EXC_RETURN) - // but see code after "BLX r0" - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#ifdef __ARM_FP //--------- if VFP available... - // When VFP is available, lr (EXC_RETURN) is restored from the stack - // before returning from exception, so the value in lr doesn't matter -#else //--------- VFP NOT available - // lr (EXC_RETURN) can be synthesized because it is known (0xFFFFFFF9): - // - return to Thread mode; - // - exception return uses non-floating-point state from MSP; - // - execution uses MSP after return. - " MOV r0,#6 \n" - " MVN r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 - " MOV lr,r0 \n" // lr := 0xFFFFFFF9 (EXC_RETURN) -#endif //--------- VFP NOT available -); - -#else //--------- IRQ defined, use the selected IRQ - -// NOTE: The IRQ Handler is entered with interrupts already ENABLED -void QXK_USE_IRQ_HANDLER(void) { -#endif //--------- IRQ defined - - // ...continue here from either NMI or IRQ -__asm volatile ( - " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame - -#ifdef __ARM_FP //--------- if VFP available... - " POP {r0,lr} \n" // restore aligher and EXC_RETURN into lr - " DSB \n" // ARM Erratum 838869 - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if EXC_RETURN[4] is zero... - " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#endif //--------- VFP available - " BX lr \n" // return to the preempted task - ); -} - -//============================================================================ -#if (__ARM_ARCH == 6) // if ARMv6-M... - -// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) -// NOTE: -// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, -// but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition -// flags in the PSR. -__attribute__ ((naked, optimize("-fno-stack-protector"))) -uint_fast8_t QF_qlog2(uint32_t x) { - Q_UNUSED_PAR(x); -__asm volatile ( - " MOV r1,#0 \n" -#if (QF_MAX_ACTIVE > 16U) - " LSR r2,r0,#16 \n" - " BEQ QF_qlog2_1 \n" - " MOV r1,#16 \n" - " MOV r0,r2 \n" - "QF_qlog2_1: \n" -#endif -#if (QF_MAX_ACTIVE > 8U) - " LSR r2,r0,#8 \n" - " BEQ QF_qlog2_2 \n" - " ADD r1, r1,#8 \n" - " MOV r0, r2 \n" - "QF_qlog2_2: \n" -#endif - " LSR r2,r0,#4 \n" - " BEQ QF_qlog2_3 \n" - " ADD r1,r1,#4 \n" - " MOV r0,r2 \n" - "QF_qlog2_3: \n" - " LDR r2,=QF_qlog2_LUT \n" - " LDRB r0,[r2,r0] \n" - " ADD r0,r1,r0 \n" - " BX lr \n" - " .align \n" - "QF_qlog2_LUT: \n" - " .byte 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4" - ); -} - -#endif // ARMv6-M - diff --git a/ports/arm-cm/qxk/iar/qp_port.h b/ports/arm-cm/qxk/iar/qp_port.h deleted file mode 100644 index d81f9d63..00000000 --- a/ports/arm-cm/qxk/iar/qp_port.h +++ /dev/null @@ -1,228 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-12-02 -//! @version Last updated for: @ref qpc_7_3_1 -//! -//! @file -//! @brief QP/C port to ARM Cortex-M, dual-mode QXK kernel, IAR-ARM - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard -#include // IAR intrinsic functions - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QF configuration for QXK -- data members of the QActive class... - -// QActive event-queue type used for AOs and eXtended threads. -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QActive OS-Object type used for the private stack pointer for eXtended threads. -// (The private stack pointer is NULL for basic-threads). -#define QACTIVE_OS_OBJ_TYPE void* - -// QActive "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// QF interrupt disable/enable and log2()... -#if (__ARM_ARCH == 6) // ARMv6-M? - - // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 - #define QF_AWARE_ISR_CMSIS_PRI 0 - - // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else // ARMv7-M or higher - - // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 - #define QF_BASEPRI 0x3F - - // CMSIS threshold for "QF-aware" interrupts, see NOTE4 - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - // ARMv7-M or higher provide the CLZ instruction for fast LOG2 - #define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(n_)))) - -#endif - -// interrupt disabling policy, see NOTE2 and NOTE3 -#define QF_INT_DISABLE() (QF_int_disable_()) -#define QF_INT_ENABLE() (QF_int_enable_()) - -// QF critical section, see NOTE1, NOTE2, and NOTE3 -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() (QF_crit_entry_()) -#define QF_CRIT_EXIT() (QF_crit_exit_()) - -#define QF_CRIT_EXIT_NOP() __ISB() - -#if (__ARM_ARCH == 6) // ARMv6-M? - // hand-optimized quick LOG2 in assembly - uint_fast8_t QF_qlog2(uint32_t x); -#endif // ARMv7-M or higher - -// Memory isolation ---------------------------------------------------------- -#ifdef QF_MEM_ISOLATE - - // Memory isolation requires the context-switch - #define QF_ON_CONTEXT_SW 1U - - // Memory System setting - #define QF_MEM_SYS() QF_onMemSys() - - // Memory Application setting - #define QF_MEM_APP() QF_onMemApp() - - // callback functions for memory settings (provided by applications) - void QF_onMemSys(void); - void QF_onMemApp(void); - -#endif // def QF_MEM_ISOLATE - -// determination if the code executes in the ISR context -#define QXK_ISR_CONTEXT_() (__get_IPSR() != 0U) - -// trigger the PendSV exception to perform the context switch -#define QXK_CONTEXT_SWITCH_() \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) - -// QXK ISR entry and exit -#define QXK_ISR_ENTRY() ((void)0) - -#ifdef QF_MEM_ISOLATE - #define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - QF_MEM_SYS(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_MEM_APP(); \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ - } while (false) -#else - #define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ - } while (false) -#endif - -#if (__ARM_ARCH == 6) // ARMv6-M? - #define QXK_ARM_ERRATUM_838869() ((void)0) -#else // ARMv7-M or higher - // The following macro implements the recommended workaround for the - // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - // (memory barrier) instruction needs to be added before exiting an ISR. - #define QXK_ARM_ERRATUM_838869() __DSB() - -#endif // ARMv6-M - -// initialization of the QXK kernel -#define QXK_INIT() QXK_init() -void QXK_init(void); -void QXK_thread_ret(void); - -#ifdef __ARM_FP //--------- if VFP available... -// When the FPU is configured, clear the FPCA bit in the CONTROL register -// to prevent wasting the stack space for the FPU context. -#define QXK_START() __set_CONTROL(0U) -#endif - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QXK kernel uses the native QP event queue -#include "qmpool.h" // QXK kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qxk.h" // QXK kernel - -// prototypes -void QF_int_disable_(void); -void QF_int_enable_(void); -void QF_crit_entry_(void); -void QF_crit_exit_(void); - -extern int32_t volatile QF_int_lock_nest_; - -//============================================================================ -// NOTE1: -// The critical section policy does not use the "saving and restoring" -// interrupt status policy (macro QF_CRIT_STAT is defined to nothing). -// However, this the QF critical sections might still be able to nest, -// depending on the implementation of the QF_crit_entry_()/QF_crit_exit_() -// functions. They are defined as "weak" in the qv_port.c module, -// so the application can provide a different implementation. -// Please see the definitions of the interrupt and critical-section -// funcctions in the qv_port.c module for details. -// -// NOTE2: -// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt -// disabling policy uses the PRIMASK register to disable interrupts globally. -// The QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts -// are "kernel-aware". -// -// NOTE3: -// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI -// register (which is not implemented in ARMv6-M) to disable interrupts only -// with priority lower than the threshold specified by the QF_BASEPRI macro. -// The interrupts with priorities above QF_BASEPRI (i.e., with numerical -// priority values lower than QF_BASEPRI) are NOT disabled in this method. -// These free-running interrupts have very low ("zero") latency, but they -// are NOT allowed to call any QF services, because QF is unaware of them -// ("kernel-unaware" interrupts). Consequently, only interrupts with -// numerical values of priorities equal to or higher than QF_BASEPRI -// ("kernel-aware" interrupts ), can call QF services. -// -// NOTE4: -// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -// the "QF-aware" interrupt priorities in the applications, whereas the -// numerical values of the "QF-aware" interrupts must be greater or equal to -// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -// passed directly to the CMSIS function NVIC_SetPriority(), which shifts -// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -// is intended only for applications and is not used inside the QF port, which -// remains generic and not dependent on the number of implemented priority bits -// implemented in the NVIC. - -#endif // QP_PORT_H_ - diff --git a/ports/arm-cm/qxk/iar/qs_port.h b/ports/arm-cm/qxk/iar/qs_port.h deleted file mode 100644 index 7895e109..00000000 --- a/ports/arm-cm/qxk/iar/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 4U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 4U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/arm-cm/qxk/iar/qxk_port.c b/ports/arm-cm/qxk/iar/qxk_port.c deleted file mode 100644 index 32041d61..00000000 --- a/ports/arm-cm/qxk/iar/qxk_port.c +++ /dev/null @@ -1,801 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-28 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QXK/C port to ARM Cortex-M, IAR-ARM - -#define QP_IMPL 1U -#include "qp_port.h" -#include "qp_pkg.h" -#include "qsafe.h" // QP Functional Safety (FuSa) System - -#include // for offsetof() - -//============================================================================ -// NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! -#define QXK_CURR 0 -#define QXK_NEXT 4 -#define QXK_ACT_PRIO 12 - -// make sure that the offsets match the QXK declaration in "qxk.h" -_Static_assert(QXK_CURR == offsetof(QXK_Attr, curr), - "QXK_Attr.curr at unexpected offset"); -_Static_assert(QXK_NEXT == offsetof(QXK_Attr, next), - "QXK_Attr.next at unexpected offset"); -_Static_assert(QXK_ACT_PRIO == offsetof(QXK_Attr, actPrio), - "QXK_Attr.actPrio at unexpected offset"); - -// offsets within struct QActive; NOTE: keep in synch with "qp.h" !!! -#define QACTIVE_PRIO 12 -#define QACTIVE_OSOBJ 20 - -// make sure that the offsets match the QActvie declaration in "qp.h" -_Static_assert(QACTIVE_OSOBJ == offsetof(QActive, osObject), - "QActive.osObject at unexpected offset"); -_Static_assert(QACTIVE_PRIO == offsetof(QActive, prio), - "QActive.prio at unexpected offset"); - -//============================================================================ -// Initialize the private stack of an extended QXK thread. -// -// NOTE -// The function aligns the stack to the 8-byte boundary for compatibility -// with the AAPCS. Additionally, the function pre-fills the stack with the -// known bit pattern (0xDEADBEEF). -// -// NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware -// of this thread. In that case the kernel cannot use the thread yet, so no -// critical section is needed. -void QXThread_stackInit_(QActive *me, QXThreadHandler const handler, - void * const stkSto, uint_fast16_t const stkSize) -{ - // round down the stack top to the 8-byte boundary - // NOTE: ARM Cortex-M stack grows down from hi -> low memory - uint32_t *sp = - (uint32_t *)((((uint32_t)stkSto + stkSize) >> 3U) << 3U); - uint32_t *sp_limit; - - // synthesize the ARM Cortex-M exception stack frame... - *(--sp) = (1U << 24); // xPSR (just the THUMB bit) - *(--sp) = (uint32_t)handler; // PC (the thread handler) - *(--sp) = (uint32_t)&QXK_threadExit_; // LR (exit from thread) - *(--sp) = 0x0000000CU; // R12 - *(--sp) = 0x00000003U; // R3 - *(--sp) = 0x00000002U; // R2 - *(--sp) = 0x00000001U; // R1 - *(--sp) = (uint32_t)me; // R0 parameter to handler (thread object) - *(--sp) = 0x0000000BU; // R11 - *(--sp) = 0x0000000AU; // R10 - *(--sp) = 0x00000009U; // R9 - *(--sp) = 0x00000008U; // R8 - *(--sp) = 0x00000007U; // R7 - *(--sp) = 0x00000006U; // R6 - *(--sp) = 0x00000005U; // R5 - *(--sp) = 0x00000004U; // R4 - -#ifdef __ARM_FP //--------- if VFP available... - *(--sp) = 0xFFFFFFFDU; // exception return with VFP state - *(--sp) = 0xAAAAAAAAU; // stack "aligner" -#endif // VFP available - - // save the top of the stack in the thread's attribute - me->osObject = sp; - - // pre-fill the unused part of the stack with 0xDEADBEEF - sp_limit = (uint32_t *)(((((uint32_t)stkSto - 1U) >> 3U) + 1U) << 3U); - for (; sp >= sp_limit; --sp) { - *sp = 0xDEADBEEFU; - } -} - -// prototypes ---------------------------------------------------------------- -void PendSV_Handler(void); -#ifdef QXK_USE_IRQ_HANDLER // if use IRQ... -void QXK_USE_IRQ_HANDLER(void); -#else // use default (NMI) -void NMI_Handler(void); -#endif - -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) -#define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint32_t volatile *)0xE000E400U) -#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) -#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -#define NVIC_PEND 0xE000E200 -#define SCB_ICSR 0xE000ED04 - -// helper macros to "stringify" values -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) - -//============================================================================ -// interrupts and critical section... -// -// NOTE: -// The following interrupt disabling/enabling as well as critical section -// entry/exit functions are defined as "weak" so that they can be -// re-implemented differently at the application level. -// -// NOTE: -// For best performance, these functions are implemented in assembly, -// but they can be implemented in C as well. - -#pragma weak QF_int_disable_ -#pragma weak QF_int_enable_ -#pragma weak QF_crit_entry_ -#pragma weak QF_crit_exit_ - -//int32_t volatile QF_int_lock_nest_; // not used -extern char const QF_port_module_[]; -char const QF_port_module_[] = "qxk_port"; - -//............................................................................ -// Unconditionally disable interrupts. -// -// description: -// On ARMv6-M, interrupts are disabled with the PRIMASK register. -// On ARMv7-M and higher, interrupts are disabled *selectively* with the -// BASEPRI register. -// Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -void QF_int_disable_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK - " CPSID i \n" // set PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI - " MOVS r1,#" STRINGIFY(QF_BASEPRI) "\n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0) - " BNE QF_int_disable_error\n" - " BX lr \n" - "QF_int_disable_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#100 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Unconditionally enable interrupts. -// -// description: -// On ARMv6-M, interrupts are enabled with the PRIMASK register. -// On ARMv7-M and higher, interrupts are enabled with the BASEPRI register. -// Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// QF_int_enable_() is NOT allowed to push anything on the stack -// (see NOTE-1 at the end of QXK_thread_ret(). -void QF_int_enable_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI != 0) - " BEQ QF_int_enable_error\n" -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " CPSIE i \n" // clear PRIMASK -#else //--------- ARMv7-M or higher - " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " BX lr \n" - "QF_int_enable_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#101 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Enter QF critical section. -// -// description: -// On ARMv6-M, critical section is entered by disabling interrupts -// with the PRIMASK register. -// On ARMv7-M and higher, critical section is entered by disabling -// interrupts *selectively* with the BASEPRI register. -// Additionally, the function also asserts that the interrupts are -// NOT disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -void QF_crit_entry_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK - " CPSID i \n" // set PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI - " MOVS r1,#" STRINGIFY(QF_BASEPRI) "\n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0) - " BNE QF_crit_entry_error\n" - " BX lr \n" - "QF_crit_entry_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#110 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} -//............................................................................ -// Exit QF critical section. -// -// description: -// On ARMv6-M, critical section is exited by enabling interrupts -// with the PRIMASK register. -// On ARMv7-M and higher, critical section is exited by enabling -// interrupts with the BASEPRI register. -// Additionally, the function also asserts that the interrupts ARE -// disabled upon the entry to the function. -// -// NOTE: -// The assertion means that this critical section CANNOT nest. -void QF_crit_exit_(void) { -__asm volatile ( -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " MRS r0,PRIMASK \n" // r0 <- previous PRIMASK -#else //--------- ARMv7-M or higher - " MRS r0,BASEPRI \n" // r0 <- previous BASEPRI -#endif //--------- ARMv7-M or higher - " CMP r0,#0 \n" // assert(PRIMASK/BASEPRI != 0) - " BEQ QF_crit_exit_error\n" -#if (__ARM_ARCH == 6) //--------- ARMv6-M architecture? - " CPSIE i \n" // clear PRIMASK -#else //--------- ARMv7-M or higher - " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK -#endif //--------- ARMv7-M or higher - " BX lr \n" - "QF_crit_exit_error: \n" - " LDR r0,=QF_port_module_ \n" - " MOVS r1,#111 \n" - " LDR r2,=Q_onError \n" - " BX r2 \n" - ); -} - -//============================================================================ -// Initialize the exception priorities and IRQ priorities to safe values. -// -// description: -// On ARMv7-M or higher, this QF port disables interrupts by means of the -// BASEPRI register. However, this method cannot disable interrupt -// priority zero, which is the default for all interrupts out of reset. -// The following code changes the SysTick priority and all IRQ priorities -// to the safe value QF_BASEPRI, which the QF critical section can disable. -// This avoids breaching of the QF critical sections in case the -// application programmer forgets to explicitly set priorities of all -// "kernel aware" interrupts. -// -// The interrupt priorities established in QXK_init() can be later -// changed by the application-level code. -void QXK_init(void) { - -#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - - // SCB_SYSPRI[2]: SysTick - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - - // set all 240 possible IRQ priories to QF_BASEPRI... - for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { - NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) - | (QF_BASEPRI << 8U) | QF_BASEPRI; - } - -#endif //--------- ARMv7-M or higher - - // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); - -#ifdef QXK_USE_IRQ_NUM //--------- QXK IRQ specified? - // The QXK port is configured to use a given ARM Cortex-M IRQ # - // to return to thread mode (default is to use the NMI exception) - NVIC_IP[QXK_USE_IRQ_NUM] = 0U; // priority 0 (highest) - NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); -#endif //--------- QXK IRQ specified - -#ifdef __ARM_FP //--------- if VFP available... - // make sure that the FPU is enabled by setting CP10 & CP11 Full Access - SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); - - // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) - FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); -#endif //--------- VFP available -} - -//============================================================================ -// The PendSV exception is used for performing asynchronous preemption in QXK. -// The use of the PendSV exception is the recommended and most efficient -// method for performing context switches in ARM Cortex-M. -// -// The PendSV exception should have the lowest interrupt priority in the system -// (0xFF, see QXK_init()). All other exceptions and interrupts should have -// higher interrupt priority. -// -// Also, *all* "kernel aware" ISRs in the QXK application must call the -// QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -// asynchronous preemption. -// -// Due to tail-chaining and its lowest priority, the PendSV exception will be -// entered immediately after the exit from the *last* nested interrupt (or -// exception). In QXK, this is exactly the time when the QXK activator needs to -// handle the asynchronous preemption. -__stackless -void PendSV_Handler(void) { -__asm volatile ( - - //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< - " PUSH {r0,lr} \n" // save stack-aligner + EXC_RETURN - " LDR r0,=QF_int_disable_ \n" - " BLX r0 \n" // call QF_int_disable_() - -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemSys \n" - " BLX r0 \n" // call QF_onMemSys() -#endif - " POP {r0,r1} \n" // restore the aligner + EXC_RETURN in r1 - " MOV lr,r1 \n" // restore EXC_RETURN into lr - - // The PendSV exception handler can be preempted by an interrupt, - // which might pend PendSV exception again. The following write to - // ICSR[27] un-pends any such spurious instance of PendSV. - " MOVS r1,#1 \n" - " LSLS r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit) - " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " STR r1,[r2] \n" // ICSR[27] := 1 (un-pend PendSV) - - // Check QXK_priv_.next, which contains the pointer to the next thread - // to run, which is set in QXK_ISR_EXIT(). Return if QXK_priv_.next == 0 - " LDR r3,=QXK_priv_ \n" - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next - " CMP r0,#0 \n" // is (QXK_priv_.next == 0)? - " BEQ PendSV_return \n" // branch if (QXK_priv_.next == 0) - - // Load pointers into registers... - " MOV r12,r0 \n" // save QXK_priv_.next in r12 - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // r2 := QXK_priv_.next->osObject - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr - - " CMP r1,#0 \n" // (QXK_priv_.curr != 0)? - " BNE PendSV_save_ex \n" // branch if (current thread is extended) - - " CMP r2,#0 \n" // (QXK_priv_.next->osObject != 0)? - " BNE PendSV_save_ao \n" // branch if (next thread is extended) - - "PendSV_activate: \n" -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 - " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available - // The QXK activator must be called in a Thread mode, while this code - // executes in the Handler mode of the PendSV exception. The switch - // to the Thread mode is accomplished by returning from PendSV using - // a fabricated exception stack frame, where the return address is - // QXK_activate_(). - // - // NOTE: the QXK activator is called with interrupts DISABLED and also - // returns with interrupts DISABLED. - " MOVS r3,#1 \n" - " LSLS r3,r3,#24 \n" // r3 := (1 << 24), set T bit (new xpsr) - " LDR r2,=QXK_activate_\n" // address of QXK_activate_ - " SUBS r2,r2,#1 \n" // align Thumb-address at halfword (new pc) - " LDR r1,=QXK_thread_ret\n" // return address after the call (new lr) - - " SUB sp,sp,#(8*4) \n" // reserve space for exception stack frame - " ADD r0,sp,#(5*4) \n" // r0 := 5 registers below the SP - " STM r0!,{r1-r3} \n" // save xpsr,pc,lr - - " MOVS r0,#6 \n" - " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 -#if (__ARM_ARCH != 6) // ARMv7-M or higher - " DSB \n" // ARM Erratum 838869 -#endif // ARMv7-M or higher - " BX r0 \n" // exception-return to the QXK activator - - //======================================================================== - // Saving AO-thread before crossing to eXtended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_save_ao: \n" -#if (__ARM_ARCH == 6) // if ARMv6-M... - " SUB sp,sp,#(8*4) \n" // make room for 8 registers r4-r11 - " MOV r0,sp \n" // r0 := temporary stack pointer - " STMIA r0!,{r4-r7} \n" // save the low registers - " MOV r4,r8 \n" // move the high registers to low registers... - " MOV r5,r9 \n" - " MOV r6,r10 \n" - " MOV r7,r11 \n" - " STMIA r0!,{r4-r7} \n" // save the high registers - " MOV r0,r12 \n" // restore QXK_priv_.next in r0 -#else // ARMv7-M or higher - " PUSH {r4-r11} \n" // save r4-r11 on top of the exception frame -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 - " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available -#endif // ARMv7-M or higher - - " CMP r2,#0 \n" - " BNE PendSV_restore_ex\n" // branch if (QXK_priv_.next->osObject != 0) - // otherwise continue to restoring next AO-thread... - - //------------------------------------------------------------------------ - // Restoring AO-thread after crossing from eXtended-thread - // expected register contents: - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_restore_ao: \n" - // don NOT clear QXK_priv_.curr or QXK_priv_.next, - // as they might be needed for AO activation - -#if (__ARM_ARCH == 6) // if ARMv6-M... - " MOV r0,sp \n" // r0 := top of stack - " MOV r2,r0 \n" - " ADDS r2,r2,#(4*4) \n" // point r2 to the 4 high registers r7-r11 - " LDMIA r2!,{r4-r7} \n" // pop the 4 high registers into low registers - " MOV r8,r4 \n" // move low registers into high registers - " MOV r9,r5 \n" - " MOV r10,r6 \n" - " MOV r11,r7 \n" - " LDMIA r0!,{r4-r7} \n" // pop the low registers - " ADD sp,sp,#(8*4) \n" // remove 8 registers from the stack - - " MOVS r2,#6 \n" - " MVNS r2,r2 \n" // r2 := ~6 == 0xFFFFFFF9 - " MOV lr,r2 \n" // make sure MSP is used -#else // ARMv7-M or higher -#ifdef __ARM_FP //--------- if VFP available... - " POP {r0,lr} \n" // restore aligner and EXC_RETURN into lr - " DSB \n" // ARM Erratum 838869 - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if EXC_RETURN[4] is zero... - " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#else - " BIC lr,lr,#(1 << 2) \n" // make sure MSP is used -#endif // VFP available - " POP {r4-r11} \n" // restore r4-r11 from the next thread's stack -#endif // ARMv7-M or higher - - " MOV r0,r12 \n" // r0 := QXK_priv_.next - " MOVS r2,#" STRINGIFY(QACTIVE_PRIO) "\n" // r2 := offset of .prio - " LDRB r0,[r0,r2] \n" // r0 := QXK_priv_.next->prio - " LDR r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" // r2 := QXK_priv_.actPrio - " CMP r2,r0 \n" - " BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO - - // otherwise no activation needed... - " MOVS r2,#0 \n" - " STR r2,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0 - " STR r2,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - - " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " CMP r0,#0 \n" // r0 == QXK_priv_.next->prio - " BEQ PendSV_idle \n" // if (QXK_priv_.next->prio != 0) - " MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_() - "PendSV_idle: \n" - " LDR r3,=QXK_contextSw_ \n" - " BLX r3 \n" // call QXK_contextSw_() -#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " B PendSV_return1 \n" // skip over saving aligner + EXC_RETURN - - // re-enable interrupts and return from PendSV - "PendSV_return: \n" - " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN - - "PendSV_return1: \n" -#ifdef QF_MEM_ISOLATE - " LDR r3,=QF_onMemApp \n" - " BLX r3 \n" // call QF_onMemApp() -#endif - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() - //>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>> - - " POP {r0,pc} \n" // return to the preempted AO-thread - - //------------------------------------------------------------------------ - // Saving extended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_save_ex: \n" - " MRS r0,PSP \n" // r0 := Process Stack Pointer -#if (__ARM_ARCH == 6) // if ARMv6-M... - " SUBS r0,r0,#(8*4) \n" // make room for 8 registers r4-r11 - " MOVS r1,r0 \n" // r1 := temporary PSP (do not clobber r0!) - " STMIA r1!,{r4-r7} \n" // save the low registers - " MOV r4,r8 \n" // move the high registers to low registers... - " MOV r5,r9 \n" - " MOV r6,r10 \n" - " MOV r7,r11 \n" - " STMIA r1!,{r4-r7} \n" // save the high registers - // NOTE: at this point r0 holds the top of stack - - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr (restore value) -#else // ARMv7-M or higher - " ISB \n" // reset pipeline after fetching PSP - " STMDB r0!,{r4-r11} \n" // save r4-r11 on top of the exception frame -#ifdef __ARM_FP //--------- if VFP available... - " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VSTMDBEQ r0!,{s16-s31} \n" // ... save VFP registers s16..s31 - " STMDB r0!,{r1,lr} \n" // save the "aligner" and the EXC_RETURN value -#endif // VFP available -#endif // ARMv7-M or higher - - // store the SP of the current extended-thread - " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // QXK_priv_.curr->osObject := r0 - " MOV r0,r12 \n" // QXK_priv_.next (restore value) - - " CMP r2,#0 \n" - " BEQ PendSV_restore_ao\n" // branch if (QXK_priv_.next->osObject == 0) - // otherwise continue to restoring next extended-thread... - - //------------------------------------------------------------------------ - // Restoring extended-thread - // expected register contents: - // r0 -> QXK_priv_.next / basic-thread - // r1 -> QXK_priv_.curr / basic-thread - // r2 -> QXK_priv_.next->osObject (SP) - // r3 -> &QXK_priv_ - // r12 -> QXK_priv_.next / basic-thread - "PendSV_restore_ex: \n" - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := r0 (QXK_priv_.next) - " MOVS r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - - " PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_() - " LDR r3,=QXK_contextSw_ \n" - " BLX r3 \n" // call QXK_contextSw_() -#ifdef QF_MEM_ISOLATE - " LDR r3,=QF_onMemApp \n" - " BLX r3 \n" // call QF_onMemApp() -#endif -#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - - - // exit the critical section - " LDR r3,=QF_int_enable_ \n" - " BLX r3 \n" // call QF_int_enable_() - " POP {r0-r3} \n" // restore next, osObject, EXC_RETURN - " MOV lr,r3 \n" // restore the EXC_RETURN into lr - -#if (__ARM_ARCH == 6) // if ARMv6-M... - " MOVS r0,r2 \n" // r2 := top of stack - " ADDS r0,r0,#(4*4) \n" // point r0 to the 4 high registers r7-r11 - " LDMIA r0!,{r4-r7} \n" // pop the 4 high registers into low registers - " MOV r8,r4 \n" // move low registers into high registers - " MOV r9,r5 \n" - " MOV r10,r6 \n" - " MOV r11,r7 \n" - " LDMIA r2!,{r4-r7} \n" // pop the low registers - " MOVS r2,r0 \n" // r2 := holds the new top of stack - - " MOVS r1,#2 \n" - " MVNS r1,r1 \n" // r1 := ~2 == 0xFFFFFFFD - " MOV lr,r1 \n" // make sure PSP is used -#else // ARMv7-M or higher -#ifdef __ARM_FP //--------- if VFP available... - " LDMIA r2!,{r1,lr} \n" // restore aligner and EXC_RETURN into lr - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if lr[4] is zero... - " VLDMIAEQ r2!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#else - " ORR lr,lr,#(1 << 2) \n" // make sure PSP is used -#endif // VFP available - " LDMIA r2!,{r4-r11} \n" // restore r4-r11 from the next thread's stack -#endif // ARMv7-M or higher - - // set the PSP to the next thread's SP - " MSR PSP,r2 \n" // Process Stack Pointer := r2 - -#if (__ARM_ARCH != 6) // if ARMv7-M or higher... - " DSB \n" // ARM Erratum 838869 -#endif // ARMv7-M or higher - " BX lr \n" // return to the next extended-thread - ); -} - -//============================================================================ -// QXK_thread_ret is a helper function executed when the QXK activator returns. -// -// NOTE: QXK_thread_ret() does not execute in the PendSV context! -// NOTE: QXK_thread_ret() is entered with interrupts DISABLED. -__stackless -void QXK_thread_ret(void) { -__asm volatile ( - - // After the QXK activator returns, we need to resume the preempted - // thread. However, this must be accomplished by a return-from-exception, - // while we are still in the thread context. The switch to the exception - // context is accomplished by triggering the NMI exception or the selected - // IRQ (if macro #QXK_USE_IRQ_NUM is defined). - - // before triggering the NMI/IRQ, make sure that the VFP stack frame - // will NOT be used... -#ifdef __ARM_FP //--------- if VFP available... - // make sure that the VFP stack frame will NOT be used - " MRS r0,CONTROL \n" // r0 := CONTROL - " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) - " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) - " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) -#endif //--------- VFP available - - // NOTE: the following function calls corrupt lr, but it is NOT - // used to return from QXK_thread_ret(). Instead QXK_thread_ret() - // "returns" by entering an exception (either NMI or IRQ). -#ifdef QF_MEM_ISOLATE - " LDR r0,=QF_onMemApp \n" - " BLX r0 \n" // call QF_onMemApp() -#endif - -#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State - " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) - " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) - // NOTE! interrupts are still disabled when NMI is entered - -#else //--------- use the selected IRQ - " LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n" - " MOVS r1,#1 \n" - " LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit - " STR r1,[r0] \n" // pend the IRQ - - // now enable interrupts so that pended IRQ can be entered - // - // NOTE-1: - // The IRQ preempts immediately after interrupts are enabled, - // without cleanly returning from QF_int_enable_(). Therefore - // QF_int_enable_() is NOT allowed to push anything on the stack - // because the stack is NOT restored when the IRQ preempts. - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#endif //--------- use IRQ - - " B . \n" // wait for preemption by NMI/IRQ - ); -} - -//============================================================================ -// This exception handler is used for returning back to the preempted thread. -// The exception handler simply removes its own interrupt stack frame from -// the stack (MSP) and returns to the preempted task using the interrupt -// stack frame that must be at the top of the stack. -__stackless -#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default - -// NOTE: The NMI_Handler() is entered with interrupts still DISABLED! -void NMI_Handler(void) { -__asm volatile ( - // call QF_int_enable_(), NOTE: corrupts lr (EXC_RETURN) - // but see code after "BLX r0" - " LDR r0,=QF_int_enable_ \n" - " BLX r0 \n" // call QF_int_enable_() -#ifdef __ARM_FP //--------- if VFP available... - // When VFP is available, lr (EXC_RETURN) is restored from the stack - // before returning from exception, so the value in lr doesn't matter -#else //--------- VFP NOT available - // lr (EXC_RETURN) can be synthesized because it is known (0xFFFFFFF9): - // - return to Thread mode; - // - exception return uses non-floating-point state from MSP; - // - execution uses MSP after return. - " MOVS r0,#6 \n" - " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 - " MOV lr,r0 \n" // lr := 0xFFFFFFF9 (EXC_RETURN) -#endif //--------- VFP NOT available -); - -#else //--------- IRQ defined, use the selected IRQ - -// NOTE: The IRQ Handler is entered with interrupts already ENABLED -void QXK_USE_IRQ_HANDLER(void) { -#endif //--------- IRQ defined - - // ...continue here from either NMI or IRQ -__asm volatile ( - " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame - -#ifdef __ARM_FP //--------- if VFP available... - " POP {r0,lr} \n" // restore aligher and EXC_RETURN into lr - " DSB \n" // ARM Erratum 838869 - " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? - " IT EQ \n" // if EXC_RETURN[4] is zero... - " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 -#endif //--------- VFP available - " BX lr \n" // return to the preempted task - ); -} - -//============================================================================ -#if (__ARM_ARCH == 6) // if ARMv6-M... - -// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) -uint_fast8_t QF_qlog2(uint32_t x) { - static uint8_t const log2LUT[16] = { - 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, - 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U - }; - uint_fast8_t n; - -__asm volatile ( - " MOVS %[n],#0 \n" -#if (QF_MAX_ACTIVE > 16U) - " LSRS r2,r0,#16 \n" - " BEQ QF_qlog2_1 \n" - " MOVS %[n],#16 \n" - " MOVS r0,r2 \n" - "QF_qlog2_1: \n" -#endif -#if (QF_MAX_ACTIVE > 8U) - " LSRS r2,r0,#8 \n" - " BEQ QF_qlog2_2 \n" - " ADDS %[n],%[n],#8 \n" - " MOVS r0,r2 \n" - "QF_qlog2_2: \n" -#endif - " LSRS r2,r0,#4 \n" - " BEQ.N QF_qlog2_3 \n" - " ADDS %[n],%[n],#4 \n" - " MOVS r0,r2 \n" - "QF_qlog2_3:" : [n]"=r"(n) -); - return n + log2LUT[x]; -} - -#endif // ARMv6-M - diff --git a/ports/arm-cm/qxk/llvm/README.txt b/ports/arm-cm/qxk/llvm/README.txt deleted file mode 100644 index 9cd332f7..00000000 --- a/ports/arm-cm/qxk/llvm/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -The port to ARM-LLVM toolchain is identical to ARM-CLANG -and is located in ports/arm-cm/armclang/ sub-directory \ No newline at end of file diff --git a/ports/arm-cr/qk/config/qp_config.h b/ports/arm-cr/qk/config/qp_config.h index 9f1f3034..b5299776 100644 --- a/ports/arm-cr/qk/config/qp_config.h +++ b/ports/arm-cr/qk/config/qp_config.h @@ -1,32 +1,30 @@ //============================================================================ // QP configuration file (QK on ARM Cortex-R) -// Last updated for version: 7.4.0 -// Last updated on: 2024-06-06 +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ #ifndef QP_CONFIG_H_ @@ -34,17 +32,10 @@ //-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// NOTE: Requires command-line macro: QP_CONFIG -// This qp_config.h header file is activated only when the macro -// QP_CONFIG is defined on the command-line to the compiler -// ------------------------------------------- - // QP API compatibility version (QP_API_VERSION) // <0=> 0 (Maximum compatibility) -// <580=>580 (QP 5.8.0 or newer) -// <660=>660 (QP 6.6.0 or newer) // <691=>691 (QP 6.9.1 or newer) -// <700=>700 (QP 7.0.0 or newer) +// <734=>7.3.4 (QP 7.3.4 or newer) // <9999=>9999 (Latest only) // QP API backwards compatibility with the QP/C API version. // Lower QP_API_VERSION values enable backwards compatibility @@ -158,7 +149,6 @@ // Event queue counter size (QF_EQUEUE_CTR_SIZE) // <1U=>1 (default) // <2U=>2 -// <4U=>4 // Size of event queue counter [bytes] // Default: 1 (255 events maximum in a queue) #define QF_EQUEUE_CTR_SIZE 1U diff --git a/ports/arm-cr/qk/gnu/qp_port.h b/ports/arm-cr/qk/gnu/qp_port.h index d1f5ad44..7ed13cd4 100644 --- a/ports/arm-cr/qk/gnu/qp_port.h +++ b/ports/arm-cr/qk/gnu/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, GNU-ARM @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void diff --git a/ports/arm-cr/qk/gnu/qs_port.h b/ports/arm-cr/qk/gnu/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cr/qk/gnu/qs_port.h +++ b/ports/arm-cr/qk/gnu/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cr/qk/iar/qp_port.h b/ports/arm-cr/qk/iar/qp_port.h index 4edfd0e9..929621ff 100644 --- a/ports/arm-cr/qk/iar/qp_port.h +++ b/ports/arm-cr/qk/iar/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, IAR-ARM @@ -36,13 +36,10 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard #include // IAR intrinsic functions - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void diff --git a/ports/arm-cr/qk/iar/qs_port.h b/ports/arm-cr/qk/iar/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cr/qk/iar/qs_port.h +++ b/ports/arm-cr/qk/iar/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cr/qk/ti/qp_port.h b/ports/arm-cr/qk/ti/qp_port.h index b6906f41..22349b1f 100644 --- a/ports/arm-cr/qk/ti/qp_port.h +++ b/ports/arm-cr/qk/ti/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, TI-ARM @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void diff --git a/ports/arm-cr/qk/ti/qs_port.h b/ports/arm-cr/qk/ti/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cr/qk/ti/qs_port.h +++ b/ports/arm-cr/qk/ti/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cr/qv/config/qp_config.h b/ports/arm-cr/qv/config/qp_config.h index 3ae8c32c..1f549be1 100644 --- a/ports/arm-cr/qv/config/qp_config.h +++ b/ports/arm-cr/qv/config/qp_config.h @@ -1,32 +1,30 @@ //============================================================================ // QP configuration file (QV on ARM Cortex-R) -// Last updated for version: 7.4.0 -// Last updated on: 2024-06-06 +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ #ifndef QP_CONFIG_H_ @@ -34,17 +32,10 @@ //-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// NOTE: Requires command-line macro: QP_CONFIG -// This qp_config.h header file is activated only when the macro -// QP_CONFIG is defined on the command-line to the compiler -// ------------------------------------------- - // QP API compatibility version (QP_API_VERSION) // <0=> 0 (Maximum compatibility) -// <580=>580 (QP 5.8.0 or newer) -// <660=>660 (QP 6.6.0 or newer) // <691=>691 (QP 6.9.1 or newer) -// <700=>700 (QP 7.0.0 or newer) +// <734=>7.3.4 (QP 7.3.4 or newer) // <9999=>9999 (Latest only) // QP API backwards compatibility with the QP/C API version. // Lower QP_API_VERSION values enable backwards compatibility @@ -158,7 +149,6 @@ // Event queue counter size (QF_EQUEUE_CTR_SIZE) // <1U=>1 (default) // <2U=>2 -// <4U=>4 // Size of event queue counter [bytes] // Default: 1 (255 events maximum in a queue) #define QF_EQUEUE_CTR_SIZE 1U @@ -233,6 +223,7 @@ // + //------------- <<< end of configuration section >>> ----------------------- #endif // QP_CONFIG_H_ diff --git a/ports/arm-cr/qv/gnu/qp_port.h b/ports/arm-cr/qv/gnu/qp_port.h index 89ac11de..21bbd1e1 100644 --- a/ports/arm-cr/qv/gnu/qp_port.h +++ b/ports/arm-cr/qv/gnu/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-R, cooperative QV kernel, GNU-ARM @@ -36,15 +36,12 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (GNU-ARM compiler) -#define Q_NORETURN __attribute__ ((noreturn)) void +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void // QF configuration for QV -- data members of the QActive class... diff --git a/ports/arm-cr/qv/gnu/qs_port.h b/ports/arm-cr/qv/gnu/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cr/qv/gnu/qs_port.h +++ b/ports/arm-cr/qv/gnu/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cr/qv/iar/qp_port.h b/ports/arm-cr/qv/iar/qp_port.h index 81c1365b..5ae2b458 100644 --- a/ports/arm-cr/qv/iar/qp_port.h +++ b/ports/arm-cr/qv/iar/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to Cortex-R, cooperative QV kernel, IAR-ARM @@ -36,16 +36,13 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard #include // IAR intrinsic functions +#include "qp_config.h" // QP configuration from the application -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (IAR-ARM compiler) -#define Q_NORETURN __noreturn void +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void // QF configuration for QV -- data members of the QActive class... diff --git a/ports/arm-cr/qv/iar/qs_port.h b/ports/arm-cr/qv/iar/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cr/qv/iar/qs_port.h +++ b/ports/arm-cr/qv/iar/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/arm-cr/qv/ti/qp_port.h b/ports/arm-cr/qv/ti/qp_port.h index b8bb588f..aa9156e8 100644 --- a/ports/arm-cr/qv/ti/qp_port.h +++ b/ports/arm-cr/qv/ti/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to ARM Cortex-R, cooperative QV kernel, TI-ARM @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void diff --git a/ports/arm-cr/qv/ti/qs_port.h b/ports/arm-cr/qv/ti/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/arm-cr/qv/ti/qs_port.h +++ b/ports/arm-cr/qv/ti/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/config/qp_config.h b/ports/config/qp_config.h index 953c58cc..9e503a9e 100644 --- a/ports/config/qp_config.h +++ b/ports/config/qp_config.h @@ -1,32 +1,30 @@ //============================================================================ // QP configuration file (generic) -// Last updated for version: 7.4.0 -// Last updated on: 2024-06-06 +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ #ifndef QP_CONFIG_H_ @@ -34,17 +32,10 @@ //-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// NOTE: Requires command-line macro: QP_CONFIG -// This qp_config.h header file is activated only when the macro -// QP_CONFIG is defined on the command-line to the compiler -// ------------------------------------------- - // QP API compatibility version (QP_API_VERSION) // <0=> 0 (Maximum compatibility) -// <580=>580 (QP 5.8.0 or newer) -// <660=>660 (QP 6.6.0 or newer) // <691=>691 (QP 6.9.1 or newer) -// <700=>700 (QP 7.0.0 or newer) +// <734=>7.3.4 (QP 7.3.4 or newer) // <9999=>9999 (Latest only) // QP API backwards compatibility with the QP/C API version. // Lower QP_API_VERSION values enable backwards compatibility @@ -158,7 +149,6 @@ // Event queue counter size (QF_EQUEUE_CTR_SIZE) // <1U=>1 (default) // <2U=>2 -// <4U=>4 // Size of event queue counter [bytes] // Default: 1 (255 events maximum in a queue) #define QF_EQUEUE_CTR_SIZE 1U diff --git a/ports/embos/qf_port.c b/ports/embos/qf_port.c index 604e0d32..56faafdd 100644 --- a/ports/embos/qf_port.c +++ b/ports/embos/qf_port.c @@ -1,40 +1,43 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-26 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C port to embOS RTOS kernel, generic C11 compiler //! #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-level interface -#include "qsafe.h" // QP Functional Safety (FuSa) subsystem +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem #ifdef Q_SPY // QS software tracing enabled? #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS package-scope internal interface + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else #include "qs_dummy.h" // disable the QS software tracing #endif // Q_SPY @@ -77,8 +80,11 @@ static void thread_function(void *pVoid) { // embOS signature } //............................................................................ void QF_init(void) { - OS_InitKern(); // initialize embOS - OS_InitHW(); // initialize the hardware used by embOS + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + QTimeEvt_init(); // initialize QTimeEvts + OS_InitKern(); // initialize embOS + OS_InitHW(); // initialize the hardware used by embOS } //............................................................................ int QF_run(void) { @@ -87,29 +93,29 @@ int QF_run(void) { // produce the QS_QF_RUN trace record QS_CRIT_STAT QS_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() QS_CRIT_EXIT(); OS_Start(); // start embOS multitasking - return 0; // dummy return to make the compiler happy + return 0; // this unreachable return keeps the compiler happy } //............................................................................ void QF_stop(void) { - QF_onCleanup(); // cleanup callback + QF_onCleanup(); // cleanup callback } //............................................................................ void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { // create the embOS message box for the AO OS_MAILBOX_Create(&me->eQueue, - (OS_U16)sizeof(QEvt *), + (OS_U16)sizeof(QEvtPtr), // item size (OS_UINT)qLen, (void *)&qSto[0]); @@ -183,9 +189,20 @@ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { +#ifndef Q_SPY + Q_UNUSED_PAR(sender); +#endif + QF_CRIT_STAT QF_CRIT_ENTRY(); - uint_fast16_t nFree = + + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + + // the number of free slots available in the queue + uint_fast16_t const nFree = (uint_fast16_t)(me->eQueue.maxMsg - me->eQueue.nofMsg); bool status; @@ -195,7 +212,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e, } else { status = false; // cannot post - Q_ERROR_INCRIT(510); // must be able to post the event + Q_ERROR_INCRIT(210); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { @@ -207,15 +224,15 @@ bool QActive_post_(QActive * const me, QEvt const * const e, if (status) { // can post the event? - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE((QEQueueCtr)nFree); // # free entries + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter @@ -226,20 +243,19 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_ENTRY(); // posting to the embOS mailbox must succeed, see NOTE3 - Q_ASSERT_INCRIT(520, err == '\0'); + Q_ASSERT_INCRIT(220, err == '\0'); } - else { - - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() + else { // cannot post the event + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE(nFree); // # free entries + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() } QF_CRIT_EXIT(); @@ -250,14 +266,19 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(me->eQueue.maxMsg - me->eQueue.nofMsg); // # free - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + Q_REQUIRE_INCRIT(300, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(me->eQueue.maxMsg - me->eQueue.nofMsg); // # free + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter @@ -268,24 +289,26 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_ENTRY(); // posting to the embOS mailbox must succeed, see NOTE3 - Q_ASSERT_INCRIT(610, err == '\0'); + Q_ASSERT_INCRIT(320, err == '\0'); QF_CRIT_EXIT(); } //............................................................................ QEvt const *QActive_get_(QActive * const me) { - QEvt const *e; + QEvtPtr e; OS_MAILBOX_GetBlocked(&me->eQueue, (void *)&e); - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(me->eQueue.maxMsg - me->eQueue.nofMsg);// # free - QS_END_PRE_() - QS_CRIT_EXIT(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + + QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE((QEQueueCtr)(me->eQueue.maxMsg - me->eQueue.nofMsg)); + QS_END_PRE() + + QF_CRIT_EXIT(); return e; } @@ -298,8 +321,8 @@ QEvt const *QActive_get_(QActive * const me) { // FPU. In this QP-embOS port, an active object task that uses the FPU is // designated by the QF_TASK_USES_FPU attribute, which can be set with the // QF_setEmbOsTaskAttr() function. The task attributes must be set *before* -// calling QActive_start(). The task attributes are saved in QActive.osObject -// member. +// calling QActive_start(). The task attributes are saved in the +// QActive.osObject member. // // NOTE3: // The event posting to embOS mailbox occurs OUTSIDE critical section, diff --git a/ports/embos/qp_port.h b/ports/embos/qp_port.h index f3113223..d07ded2b 100644 --- a/ports/embos/qp_port.h +++ b/ports/embos/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to embOS RTOS (v5), generic C11 compiler @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void diff --git a/ports/embos/qs_port.h b/ports/embos/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/embos/qs_port.h +++ b/ports/embos/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/freertos/qf_port.c b/ports/freertos/qf_port.c index 22a378fc..9352f59c 100644 --- a/ports/freertos/qf_port.c +++ b/ports/freertos/qf_port.c @@ -1,29 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-10-29 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C port to FreeRTOS 10.x, generic C11 compiler @@ -75,18 +78,22 @@ static void task_function(void *pvParameters); // FreeRTOS task signature //============================================================================ void QF_init(void) { - // empty for FreeRTOS + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + QTimeEvt_init(); // initialize QTimeEvts } //............................................................................ int_t QF_run(void) { QF_onStartup(); // the startup callback (configure/enable interrupts) // produce the QS_QF_RUN trace record +#ifdef Q_SPY QF_CRIT_STAT QF_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() QF_CRIT_EXIT(); +#endif vTaskStartScheduler(); // start the FreeRTOS scheduler @@ -124,7 +131,7 @@ static void task_function(void *pvParameters) { // FreeRTOS task signature //............................................................................ void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, @@ -137,28 +144,28 @@ void QActive_start(QActive * const me, // - queue size must be provided // - stack storage must be provided // - stack size must be provided - Q_REQUIRE_INCRIT(200, - (qSto != (QEvt const **)0) && (qLen > 0U) + Q_REQUIRE_INCRIT(100, + (qSto != (QEvtPtr *)0) && (qLen > 0U) && (stkSto != (void *)0) && (stkSize > 0U)); QF_CRIT_EXIT(); // create FreeRTOS message queue me->eQueue = xQueueCreateStatic( (UBaseType_t)qLen, // length of the queue - (UBaseType_t)sizeof(QEvt *), // element size + (UBaseType_t)sizeof(QEvtPtr), // item size (uint8_t *)qSto, // storage buffer &me->osObject); // static queue buffer QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(210, me->eQueue != (QueueHandle_t)0); + Q_ASSERT_INCRIT(110, me->eQueue != (QueueHandle_t)0); QF_CRIT_EXIT(); me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO me->pthre = 0U; // preemption-threshold (not used for AO registration) - QActive_register_(me); // register this AO + QActive_register_(me); // make QF aware of this AO // top-most initial tran. (virtual call) (*me->super.vptr->init)(&me->super, par, me->prio); - QS_FLUSH(); // flush the QS trace buffer to the host + QS_FLUSH(); // flush the trace buffer to the host // task name provided by the user in QActive_setAttr() or default name char const *taskName = (me->thread.pxDummy1 != (void *)0) @@ -200,14 +207,18 @@ void QActive_start(QActive * const me, &me->thread); // task buffer QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(220, task != (TaskHandle_t)0); + Q_ASSERT_INCRIT(120, task != (TaskHandle_t)0); QF_CRIT_EXIT(); + +#ifdef Q_UNSAFE + Q_UNUSED_PAR(task); +#endif } //............................................................................ #ifdef QACTIVE_CAN_STOP void QActive_stop(QActive * const me) { QActive_unsubscribeAll(me); // unsubscribe from all events - me->eQueue = (QueueHandle_t)0; // stop the thread (see task_function()) + me->eQueue = (QueueHandle_t)0; // stop thread (see task_function()) } #endif //............................................................................ @@ -216,13 +227,15 @@ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { QF_CRIT_ENTRY(); // this function must be called before QActive_start(), // which implies that me->thread.pxDummy1 must not be used yet; - Q_REQUIRE_INCRIT(300, me->thread.pxDummy1 == (void *)0); + Q_REQUIRE_INCRIT(150, me->thread.pxDummy1 == (void *)0); switch (attr1) { case TASK_NAME_ATTR: // temporarily store the name, cast 'const' away me->thread.pxDummy1 = (void *)attr2; break; // ... + default: + break; } QF_CRIT_EXIT(); } @@ -238,6 +251,145 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_STAT QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + + // the number of free slots available in the queue + uint_fast16_t const nFree = + (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); + + bool status; + if (margin == QF_NO_MARGIN) { + if (nFree > 0U) { + status = true; // can post + } + else { + status = false; // cannot post + Q_ERROR_INCRIT(210); // must be able to post the event + } + } + else if (nFree > (QEQueueCtr)margin) { + status = true; // can post + } + else { + status = false; // cannot post + } + + if (status) { // can post the event? + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE((QEQueueCtr)nFree); // # free entries + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() + + if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter + } + QF_CRIT_EXIT(); + + BaseType_t err = xQueueSendToBack( + me->eQueue, (void const *)&e, (TickType_t)0); + + QF_CRIT_ENTRY(); + // posting to the FreeRTOS message queue must succeed, see NOTE3 + Q_ASSERT_INCRIT(220, err == pdPASS); + +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif + } + else { // cannot post the event + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(nFree); // # free entries + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() + } + QF_CRIT_EXIT(); + + return status; +} +//............................................................................ +void QActive_postLIFO_(QActive * const me, QEvt const * const e) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + + Q_REQUIRE_INCRIT(300, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() + + if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter + } + QF_CRIT_EXIT(); + + BaseType_t err = xQueueSendToFront( + me->eQueue, (void const *)&e, (TickType_t)0); + + QF_CRIT_ENTRY(); + // LIFO posting to the FreeRTOS queue must succeed, see NOTE3 + Q_ASSERT_INCRIT(320, err == pdPASS); + QF_CRIT_EXIT(); + +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif +} +//............................................................................ +QEvt const *QActive_get_(QActive * const me) { + QEvtPtr e; + xQueueReceive(me->eQueue, (void *)&e, portMAX_DELAY); + + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free + QS_END_PRE() + QS_CRIT_EXIT(); + + return e; +} + +//============================================================================ +// The "FromISR" QP APIs for the FreeRTOS port... +bool QActive_postFromISR_(QActive * const me, QEvt const * const e, + uint_fast16_t const margin, + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender) +{ + UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + + Q_REQUIRE_INCRIT(500, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(501, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + // find the number of free slots available in the queue uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); @@ -260,130 +412,15 @@ bool QActive_post_(QActive * const me, QEvt const * const e, if (status) { // can post the event? - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() - - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? - QEvt_refCtr_inc_(e); // increment the reference counter - } - QF_CRIT_EXIT(); - - BaseType_t err = xQueueSendToBack( - me->eQueue, (void const *)&e, (TickType_t)0); - - // posting to the FreeRTOS message queue must succeed, see NOTE3 - QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(520, err == pdPASS); - } - else { - - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() - } - QF_CRIT_EXIT(); - - return status; -} -//............................................................................ -void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() - - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? - QEvt_refCtr_inc_(e); // increment the reference counter - } - QF_CRIT_EXIT(); - - BaseType_t err = xQueueSendToFront( - me->eQueue, (void const *)&e, (TickType_t)0); - - // LIFO posting to the FreeRTOS queue must succeed, see NOTE3 - QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(610, err == pdPASS); - QF_CRIT_EXIT(); -} -//............................................................................ -QEvt const *QActive_get_(QActive * const me) { - QEvt const *e; - xQueueReceive(me->eQueue, (void *)&e, portMAX_DELAY); - - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free - QS_END_PRE_() - QS_CRIT_EXIT(); - - return e; -} - -//============================================================================ -// The "FromISR" QP APIs for the FreeRTOS port... -bool QActive_postFromISR_(QActive * const me, QEvt const * const e, - uint_fast16_t const margin, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender) -{ - UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - - // find the number of free slots available in the queue - uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); - - bool status; - if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { - status = true; // can post - } - else { - status = false; // cannot post - Q_ERROR_INCRIT(810); // must be able to post the event - } - } - else if (nFree > margin) { - status = true; // can post - } - else { - status = false; // cannot post - } - - if (status) { // can post the event? - - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries available - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr + QS_EQC_PRE(nFree); // # free entries available + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter @@ -396,20 +433,24 @@ bool QActive_postFromISR_(QActive * const me, QEvt const * const e, // posting to the FreeRTOS message queue must succeed uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_ASSERT_INCRIT(820, err == pdPASS); + Q_ASSERT_INCRIT(520, err == pdPASS); portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif } else { - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries available - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr + QS_EQC_PRE(nFree); // # free entries available + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); QF_gcFromISR(e); // recycle the event to avoid a leak @@ -422,22 +463,27 @@ void QActive_publishFromISR_(QEvt const * const e, BaseType_t * const pxHigherPriorityTaskWoken, void const * const sender) { + Q_REQUIRE_INCRIT(600, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(601, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + QSignal const sig = e->sig; UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - //! @pre the published signal must be within the configured range - Q_REQUIRE_INCRIT(500, sig < (QSignal)QActive_maxPubSignal_); - Q_REQUIRE_INCRIT(502, + // the published signal must be within the configured range + Q_REQUIRE_INCRIT(610, sig < (QSignal)QActive_maxPubSignal_); + Q_REQUIRE_INCRIT(611, QPSet_verify_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis)); - QS_BEGIN_PRE_(QS_QF_PUBLISH, 0U) - QS_TIME_PRE_(); // the timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_PUBLISH, 0U) + QS_TIME_PRE(); // the timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(sig); // the signal of the event + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count + QS_END_PRE() // is it a dynamic event? if (QEvt_getPoolNum_(e) != 0U) { @@ -462,7 +508,7 @@ void QActive_publishFromISR_(QEvt const * const e, do { // loop over all subscribers // the prio of the AO must be registered with the framework uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_ASSERT_INCRIT(510, QActive_registry_[p] != (QActive *)0); + Q_ASSERT_INCRIT(620, QActive_registry_[p] != (QActive *)0); portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); // QACTIVE_POST_FROM_ISR() asserts if the queue overflows @@ -490,311 +536,401 @@ void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, BaseType_t * const pxHigherPriorityTaskWoken, void const * const sender) { +#ifndef Q_SPY + Q_UNUSED_PAR(sender); +#endif + UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + Q_REQUIRE_INCRIT(700, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); + QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - QS_BEGIN_PRE_(QS_QF_TICK, 0U) + QS_BEGIN_PRE(QS_QF_TICK, 0U) ++prev->ctr; - QS_TEC_PRE_(prev->ctr); // tick ctr - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() + QS_TEC_PRE(prev->ctr); // tick ctr + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() // scan the linked-list of time events at this rate... - for (;;) { - QTimeEvt *t = prev->next; // advance down the time evt. list + uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound + for (; lbound > 0U; --lbound) { + Q_ASSERT_INCRIT(710, prev != (QTimeEvt *)0); // sanity check - // end of the list? - if (t == (QTimeEvt *)0) { + QTimeEvt *te = prev->next; // advance down the time evt. list +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(711, + Q_PTR2UINT_CAST_(te) == (uintptr_t)~prev->next_dis); +#endif // ndef Q_UNSAFE + + if (te == (QTimeEvt *)0) { // end of the list? // any new time events armed since the last QTimeEvt_tick_()? if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - - // sanity check - Q_ASSERT_INCRIT(610, prev != (QTimeEvt *)0); - prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(712, + Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) + == (uintptr_t)~QTimeEvt_timeEvtHead_dis_[tickRate]); +#endif // ndef Q_UNSAFE + prev->next = QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; // switch to the new list +#ifndef Q_UNSAFE + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(prev->next); + QTimeEvt_timeEvtHead_dis_[tickRate] = + (uintptr_t)~Q_PTR2UINT_CAST_((void *)0); +#endif // ndef Q_UNSAFE + + te = prev->next; // switch to the new list } - else { - break; // all currently armed time evts. processed + else { // all currently armed time events are processed + break; // terminate the for-loop } } - // time event scheduled for removal? - if (t->ctr == 0U) { - prev->next = t->next; - // mark time event 't' as NOT linked - t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED); + // the time event 'te' must be valid + Q_ASSERT_INCRIT(720, te != (QTimeEvt *)0); + + QTimeEvtCtr ctr = te->ctr; +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(721, QEvt_verify_(&te->super)); + Q_INVARIANT_INCRIT(722, ctr == (QTimeEvtCtr)~te->ctr_dis); +#endif // ndef Q_UNSAFE + + if (ctr == 0U) { // time event scheduled for removal? + prev->next = te->next; +#ifndef Q_UNSAFE + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); +#endif // ndef Q_UNSAFE + + // mark time event 'te' as NOT linked + te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer + // exit crit. section to reduce latency portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } - else { - --t->ctr; - - // is time evt about to expire? - if (t->ctr == 0U) { - QActive *act = (QActive *)t->act; // temp. for volatile - - // periodic time evt? - if (t->interval != 0U) { - t->ctr = t->interval; // rearm the time event - prev = t; // advance to this time event - } - // one-shot time event: automatically disarm - else { - prev->next = t->next; - // mark time event 't' as NOT linked - t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED); - // do NOT advance the prev pointer - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); // this time event object - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - } - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(t); // the time event object - QS_SIG_PRE_(t->super.sig); // signal of time event - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - - // exit critical section before posting - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - - // QACTIVE_POST_FROM_ISR() asserts if the queue overflows - QACTIVE_POST_FROM_ISR(act, &t->super, - pxHigherPriorityTaskWoken, - sender); + else if (ctr == 1U) { // is time event about to expire? + QActive * const act = (QActive *)te->act; + if (te->interval != 0U) { // periodic time evt? + te->ctr = te->interval; // rearm the time event +#ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~te->interval; +#endif // ndef Q_UNSAFE + prev = te; // advance to this time event } - else { - prev = t; // advance to this time event - // exit crit. section to reduce latency - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + else { // one-shot time event: automatically disarm + te->ctr = 0U; + prev->next = te->next; +#ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~0U; + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); +#endif // ndef Q_UNSAFE + + // mark time event 'e' as NOT linked + te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer + + QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE(te); // this time event object + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() } + + QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(te); // the time event object + QS_SIG_PRE(te->super.sig);// signal of this time event + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() + + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + + // QACTIVE_POST_FROM_ISR() asserts if the queue overflows + QACTIVE_POST_FROM_ISR(act, &te->super, + pxHigherPriorityTaskWoken, + sender); } - // re-enter crit. section to continue + else { // time event keeps timing out + --ctr; // decrement the tick counter + te->ctr = ctr; // update the original +#ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~ctr; +#endif // ndef Q_UNSAFE + + prev = te; // advance to this time event + + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + } + // re-enter crit. section to continue the loop uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); } + + Q_ENSURE_INCRIT(890, lbound > 0U); + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } //............................................................................ QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig) { - // find the poolNum that fits the requested event size ... - uint_fast8_t idx; - for (idx = 0U; idx < QF_priv_.maxPool_; ++idx) { - if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[idx])) { + // find the pool index that fits the requested event size... + uint_fast8_t poolNum = 0U; // zero-based poolNum initially + for (; poolNum < QF_priv_.maxPool_; ++poolNum) { + if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolNum])) { break; } } - // cannot run out of registered pools + UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_REQUIRE_INCRIT(700, idx < QF_priv_.maxPool_); + + // precondition: + // - cannot run out of registered pools + Q_REQUIRE_INCRIT(800, poolNum < QF_priv_.maxPool_); + + ++poolNum; // convert to 1-based poolNum + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - // get e -- platform-dependent + // get event e (port-dependent)... #ifdef Q_SPY - QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx], + QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[poolNum - 1U], ((margin != QF_NO_MARGIN) ? margin : 0U), - (uint_fast8_t)QS_EP_ID + idx + 1U); + (uint_fast8_t)QS_EP_ID + poolNum); #else - QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx], + QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[poolNum - 1U], ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); #endif - // was e allocated correctly? - if (e != (QEvt *)0) { + if (e != (QEvt *)0) { // was e allocated correctly? e->sig = (QSignal)sig; // set the signal e->refCtr_ = 0U; // initialize the reference counter to 0 - e->evtTag_ = (uint8_t)(QEVT_MARKER | (idx + 1U)); // pool ID + e->evtTag_ = (uint8_t)((poolNum << 4U) | 0x0FU); #ifdef Q_SPY uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - QS_BEGIN_PRE_(QS_QF_NEW, - (uint_fast8_t)QS_EP_ID + idx + 1U) - QS_TIME_PRE_(); // timestamp - QS_EVS_PRE_(evtSize); // the size of the event - QS_SIG_PRE_(sig); // the signal of the event - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_NEW, + (uint_fast8_t)QS_EP_ID + poolNum) + QS_TIME_PRE(); // timestamp + QS_EVS_PRE(evtSize); // the size of the event + QS_SIG_PRE(sig); // the signal of the event + QS_END_PRE() portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); -#endif // Q_SPY +#endif // def Q_SPY } - else { // event cannot be allocated - // must tolerate bad alloc. + else { // event was not allocated uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_ASSERT_INCRIT(720, margin != QF_NO_MARGIN); - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); -#ifdef Q_SPY - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, - (uint_fast8_t)QS_EP_ID + idx + 1U) - QS_TIME_PRE_(); // timestamp - QS_EVS_PRE_(evtSize); // the size of the event - QS_SIG_PRE_(sig); // the signal of the event - QS_END_PRE_() + // This assertion means that the event allocation failed, + // and this failure cannot be tolerated. The most frequent + // reason is an event leak in the application. + Q_ASSERT_INCRIT(820, margin != QF_NO_MARGIN); + + QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT, + (uint_fast8_t)QS_EP_ID + poolNum) + QS_TIME_PRE(); // timestamp + QS_EVS_PRE(evtSize); // the size of the event + QS_SIG_PRE(sig); // the signal of the event + QS_END_PRE() + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); -#endif // Q_SPY } - return e; // can't be NULL if we can't tolerate bad allocation + + // the returned event e is guaranteed to be valid (not NULL) + // if we can't tolerate failed allocation + return e; } //............................................................................ void QF_gcFromISR(QEvt const * const e) { - // is it a dynamic event? - if (QEvt_getPoolNum_(e) != 0U) { - UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + + Q_REQUIRE_INCRIT(700, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(701, QEvt_verify_(e)); +#endif + + uint_fast8_t const poolNum = QEvt_getPoolNum_(e); + + if (poolNum != 0U) { // is it a pool event (mutable)? + + if (e->refCtr_ > 1U) { // isn't this the last reference? + + QS_BEGIN_PRE(QS_QF_GC_ATTEMPT, + (uint_fast8_t)QS_EP_ID + poolNum) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() - // isn't this the last ref? - if (e->refCtr_ > 1U) { QEvt_refCtr_dec_(e); // decrement the ref counter - QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT, - (uint_fast8_t)QEvt_getPoolNum_(e)) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);//pool-Id&ref-Count - QS_END_PRE_() - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } - // this is the last reference to this event, recycle it - else { - uint_fast8_t idx = (uint_fast8_t)QEvt_getPoolNum_(e) - 1U; + else { // this is the last reference to this event, recycle it - QS_BEGIN_PRE_(QS_QF_GC, (uint_fast8_t)QEvt_getPoolNum_(e)) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);//pool-Id&ref-Count - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_GC, + (uint_fast8_t)QS_EP_ID + poolNum) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() - // pool ID must be in range - Q_ASSERT_INCRIT(810, idx < QF_priv_.maxPool_); + // pool number must be in range + Q_ASSERT_INCRIT(710, (poolNum <= QF_priv_.maxPool_) + && (poolNum <= QF_MAX_EPOOL)); portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); #ifdef Q_SPY // cast 'const' away in (QEvt *)e is OK because it's a pool event - QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e, + QMPool_putFromISR(&QF_priv_.ePool_[poolNum - 1U], (QEvt *)e, (uint_fast8_t)QS_EP_ID + QEvt_getPoolNum_(e)); #else - QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e, 0U); + QMPool_putFromISR(&QF_priv_.ePool_[poolNum - 1U], (QEvt *)e, 0U); #endif } } -} -//............................................................................ -void QMPool_putFromISR(QMPool * const me, void *block, - uint_fast8_t const qsId) -{ -#ifndef Q_SPY - Q_UNUSED_PAR(qsId); -#endif - - QFreeBlock * const fb = (QFreeBlock *)block; - - UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - - // precondition: - // - # free blocks cannot exceed the total # blocks and - // - the block pointer must be from this pool. - Q_REQUIRE_INCRIT(900, (me->nFree < me->nTot) - && (me->start <= fb) && (fb <= me->end)); - - fb->next = me->free_head; // link into list -#ifndef Q_UNSAFE - fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); -#endif - - me->free_head = fb; // set as new head of the free list - ++me->nFree; // one more free block in this pool - - QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // the number of free blocks in the pool - QS_END_PRE_() - - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + else { + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + } } //............................................................................ void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, uint_fast8_t const qsId) { -#ifndef Q_SPY + #ifndef Q_SPY Q_UNUSED_PAR(qsId); -#endif + #endif UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + // get volatile into temporaries + QFreeBlock *fb = me->free_head; + QMPoolCtr nFree = me->nFree; + + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(801, Q_PTR2UINT_CAST_(fb) + == (uintptr_t)~me->free_head_dis); + Q_INVARIANT_INCRIT(802, nFree == (QMPoolCtr)~me->nFree_dis); + #endif // ndef Q_UNSAFE + // have more free blocks than the requested margin? - QFreeBlock *fb; - if (me->nFree > (QMPoolCtr)margin) { - fb = me->free_head; // get a free block + if (nFree > (QMPoolCtr)margin) { + Q_ASSERT_INCRIT(810, fb != (QFreeBlock *)0); - // the pool has some free blocks, so a free block must be available - Q_ASSERT_INCRIT(900, fb != (QFreeBlock *)0); - - QFreeBlock * const fb_next = fb->next; // fast temporary to avoid UB + QFreeBlock * const fb_next = fb->next; // fast temporary + #ifndef Q_UNSAFE // the free block must have integrity (duplicate inverse storage) - Q_ASSERT_INCRIT(902, Q_UINTPTR_CAST_(fb_next) - == (uintptr_t)~fb->next_dis); + Q_INVARIANT_INCRIT(811, Q_PTR2UINT_CAST_(fb_next) + == (uintptr_t)~fb->next_dis); + #endif // ndef Q_UNSAFE - // is the pool becoming empty? - --me->nFree; // one less free block - if (me->nFree == 0U) { + --nFree; // one less free block + if (nFree == 0U) { // is the pool becoming empty? // pool is becoming empty, so the next free block must be NULL - Q_ASSERT_INCRIT(920, fb_next == (QFreeBlock *)0); + Q_ASSERT_INCRIT(820, fb_next == (QFreeBlock *)0); + me->nFree = 0U; + #ifndef Q_UNSAFE + me->nFree_dis = (QMPoolCtr)~0U; me->nMin = 0U; // remember that the pool got empty + #endif // ndef Q_UNSAFE } else { - // invariant - // The pool is not empty, so the next free-block pointer, - // so the next free block must be in range. - // - // NOTE: The next free block pointer can fall out of range - // when the client code writes past the memory block, thus - // corrupting the next block. - Q_ASSERT_INCRIT(930, + me->nFree = nFree; + #ifndef Q_UNSAFE + me->nFree_dis = (QMPoolCtr)~nFree; + + // The pool is not empty, so the next free-block pointer + // must be in range. + Q_INVARIANT_INCRIT(830, (me->start <= fb_next) && (fb_next <= me->end)); - // is the number of free blocks the new minimum so far? - if (me->nMin > me->nFree) { - me->nMin = me->nFree; // remember the new minimum + // is the # free blocks the new minimum so far? + if (me->nMin > nFree) { + me->nMin = nFree; // remember the minimum so far } + #endif // ndef Q_UNSAFE } me->free_head = fb_next; // set the head to the next free block + #ifndef Q_UNSAFE + me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb_next)); + #endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // # free blocks in the pool - QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // # of free blocks in the pool + #ifndef Q_UNSAFE + QS_MPC_PRE(me->nMin); // min # free blocks ever in the pool + #else + QS_MPC_PRE(0U); // min # free blocks (not available) + #endif // ndef Q_UNSAFE + QS_END_PRE() } else { // don't have enough free blocks at this point fb = (QFreeBlock *)0; - QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // # free blocks in the pool - QS_MPC_PRE_(margin); // the requested margin - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // # free blocks in the pool + QS_MPC_PRE(margin); // the requested margin + QS_END_PRE() } + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); return fb; // return the block or NULL pointer to the caller } +//............................................................................ +void QMPool_putFromISR(QMPool * const me, void *block, + uint_fast8_t const qsId) +{ + #ifndef Q_SPY + Q_UNUSED_PAR(qsId); + #endif + + QFreeBlock * const fb = (QFreeBlock *)block; + + UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + + // get volatile into temporaries + QFreeBlock *free_head = me->free_head; + QMPoolCtr nFree = me->nFree; + + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(901, Q_PTR2UINT_CAST_(free_head) + == (uintptr_t)~me->free_head_dis); + Q_INVARIANT_INCRIT(902, nFree == (QMPoolCtr)~me->nFree_dis); + #endif // ndef Q_UNSAFE + + Q_REQUIRE_INCRIT(910, nFree < me->nTot); + Q_REQUIRE_INCRIT(911, (me->start <= fb) && (fb <= me->end)); + + ++nFree; // one more free block in this pool + + me->free_head = fb; // set as new head of the free list + me->nFree = nFree; + fb->next = free_head; // link into list + #ifndef Q_UNSAFE + me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb)); + me->nFree_dis = (QMPoolCtr)~nFree; + fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(free_head)); + #endif + + QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // the # free blocks in the pool + QS_END_PRE() + + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); +} //============================================================================ // NOTE3: diff --git a/ports/freertos/qp_port.h b/ports/freertos/qp_port.h index 62abfac4..3dd43837 100644 --- a/ports/freertos/qp_port.h +++ b/ports/freertos/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to FreeRTOS 10.x, generic C11 compiler @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -206,7 +203,7 @@ enum FreeRTOS_TaskAttrs { #define QF_EPOOL_PUT_(p_, e_, qsId_) \ (QMPool_put(&(p_), (e_), (qsId_))) -#endif // QP_IMPL +#endif // def QP_IMPL //============================================================================ // NOTE2: diff --git a/ports/freertos/qs_port.h b/ports/freertos/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/freertos/qs_port.h +++ b/ports/freertos/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/lint-plus/16bit/cpu.lnt b/ports/lint-plus/16bit/cpu.lnt deleted file mode 100644 index d5cc76b1..00000000 --- a/ports/lint-plus/16bit/cpu.lnt +++ /dev/null @@ -1,6 +0,0 @@ -// Size Options for 16bit CPU (e.g., MSP430) --si2 -sl4 -sll8 -ss2 -sw2 -sp2 -sf4 -sd8 -sld8 - -// Alignment options for 16bit CPU --ai2 -al2 -all2 -as2 -af4 -ad8 -ald8 - diff --git a/ports/lint-plus/16bit/qs_port.h b/ports/lint-plus/16bit/qs_port.h deleted file mode 100644 index 65f5a327..00000000 --- a/ports/lint-plus/16bit/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 2U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 2U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/lint-plus/16bit/stdint.h b/ports/lint-plus/16bit/stdint.h deleted file mode 100644 index c1b99efc..00000000 --- a/ports/lint-plus/16bit/stdint.h +++ /dev/null @@ -1,47 +0,0 @@ -//! @file -//! @brief Selected exact-width and fast minimum-width integer types -//! for 16-bit CPU architecture (e.g., MSP430). -//! -//! @description -//! This header is part of the ANSI C99 standard library to define the -//! standard exact-width integer types (see C99 Section 7.18.1.1). -//! If the compiler does not provide the stdint.h header file, you can -//! either create one in the QP port directory, or you can typedef the -//! 8 exact-width integer types directly in the qep_port.h header file. -//! -//! @note The version included in the QP documentation contains only the 8 -//! exact-width types and 6 fast minimum-width types actually used in QP. -//! The actual definition of the integer types is platform dependent. -#ifndef STDINT_H_ -#define STDINT_H_ - -//lint -save -//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler -//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated - -// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 -typedef signed char int8_t; //!< exact-width 8-bit signed int -typedef signed int int16_t; //!< exact-width 16-bit signed int -typedef signed long int int32_t; //!< exact-width 32-bit signed int -typedef signed long long int64_t; //!< exact-width 64-bit signed int - -typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int -typedef unsigned int uint16_t; //!< exact-width 16-bit unsigned int -typedef unsigned long int uint32_t; //!< exact-width 32-bit unsigned int -typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int - -// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 -typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int -typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int -typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int -typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int -typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int -typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int - -// unsigned integer type capable of holding a pointer to void. -typedef unsigned uintptr_t; //!< unsigned int capable of holding void* - -//lint -restore - -#endif // STDINT_H_ - diff --git a/ports/lint-plus/32bit/cpu.lnt b/ports/lint-plus/32bit/cpu.lnt deleted file mode 100644 index 9281e892..00000000 --- a/ports/lint-plus/32bit/cpu.lnt +++ /dev/null @@ -1,3 +0,0 @@ -// Size Options for 32bit CPU (e.g., ARM Cortex-M) --si4 -sl4 -sll8 -ss2 -sw4 -sp4 -sf4 -sd8 -sld8 - diff --git a/ports/lint-plus/32bit/qs_port.h b/ports/lint-plus/32bit/qs_port.h deleted file mode 100644 index 7895e109..00000000 --- a/ports/lint-plus/32bit/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 4U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 4U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/lint-plus/32bit/stdint.h b/ports/lint-plus/32bit/stdint.h deleted file mode 100644 index 96e3af0c..00000000 --- a/ports/lint-plus/32bit/stdint.h +++ /dev/null @@ -1,47 +0,0 @@ -//! @file -//! @brief Selected exact-width and fast minimum-width integer types -//! for 32-bit CPU architecture (e.g., ARM Cortex-M). -//! -//! @description -//! This header is part of the ANSI C99 standard library to define the -//! standard exact-width integer types (see C99 Section 7.18.1.1). -//! If the compiler does not provide the stdint.h header file, you can -//! either create one in the QP port directory, or you can typedef the -//! 8 exact-width integer types directly in the qep_port.h header file. -//! -//! @note The version included in the QP documentation contains only the 8 -//! exact-width types and 6 fast minimum-width types actually used in QP. -//! The actual definition of the integer types is platform dependent. -#ifndef STDINT_H_ -#define STDINT_H_ - -//lint -save -//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler -//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated - -// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 -typedef signed char int8_t; //!< exact-width 8-bit signed int -typedef signed short int16_t; //!< exact-width 16-bit signed int -typedef signed int int32_t; //!< exact-width 32-bit signed int -typedef signed long long int64_t; //!< exact-width 64-bit signed int - -typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int -typedef unsigned short uint16_t; //!< exact-width 16-bit unsigned int -typedef unsigned int uint32_t; //!< exact-width 32-bit unsigned int -typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int - -// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 -typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int -typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int -typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int -typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int -typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int -typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int - -// unsigned integer type capable of holding a pointer to void. -typedef unsigned uintptr_t; //!< unsigned int capable of holding void* - -//lint -restore - -#endif // STDINT_H_ - diff --git a/ports/lint-plus/au-barr.lnt b/ports/lint-plus/au-barr.lnt deleted file mode 100644 index c1d3f84c..00000000 --- a/ports/lint-plus/au-barr.lnt +++ /dev/null @@ -1,696 +0,0 @@ -// --------------------------------------------------------------------------- -// Copyright Vector Informatik GmbH 2019. All rights reserved. -// -// This file is provided by Vector Informatik GmbH (https://www.vector.com) for -// use with PC-lint Plus. Redistribution is permitted but any redistribution -// must preserve this notice and, if the redistributed file has been modified, -// provide notice that the file has been modified from the original. -// --------------------------------------------------------------------------- - -// au-barr.lnt -- Author options - BARR-C:2018 -// -// This options file contains options to help enforce the -// checks advocated by the Embedded C Coding Standard BARR-C:2018. -// https://barrgroup.com/Embedded-Systems/Books/Embedded-C-Coding-Standard - -//========== GENERAL RULES ========== - -// 1.1 Which C? - - /* Enable C99 mode */ - -std=c99 - - /* 975 - unknown pragma will be ignored */ - +e975 - -append(975,[BARR-C:2018 Rule 1.1c]) - - /* 9051 - macro defined with the same name as a C keyword */ - +e9051 - -append(9051,[BARR-C:2018 Rule 1.1d]) - -// 1.2 Line Widths - - /* not currently supported */ - -// 1.3 Braces - - /* 9012 - body should be a compound statement */ - +e9012 - -append(9012,[BARR-C:2018 Rule 1.3a]) - -// 1.4 Parentheses - - /* 9050 - dependence placed on precedence */ - +e9050 - -append(9050,[BARR-C:2018 Rule 1.4a]) - - /* 9097 - unparenthesized argument to sizeof */ - +e9097 - -append(9097,[BARR-C:2018 Rule 1.4a]) - - /* 821 - right hand side of assignment not parenthesized */ - +e821 - -append(821,[BARR-C:2018 Rule 1.4a]) - - /* 834 - operator op1 followed by operator op2 could be confusing */ - +e834 - -append(834,[BARR-C:2018 Rule 1.4a]) - - /* 9240 - left/right side of logical operator is not a primary expression */ - +e9240 - -append(9240,[BARR-C:2018 Rule 1.4b]) - -// 1.5 Common Abbreviations - - /* not currently supported */ - -// 1.6 Casts - - /* not currently supported */ - -// 1.7 Keywords to Avoid - - /* 586 - keyword is deprecated */ - -deprecate(keyword, auto,[BARR-C:2018 Rule 1.7a]) - -deprecate(keyword, register,[BARR-C:2018 Rule 1.7b]) - -deprecate(keyword, continue,[BARR-C:2018 Rule 1.7d]) - - /* 801 - goto statement used */ - +e801 - -append(801,[BARR-C:2018 Rule 1.7c]) - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 1.7c]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 1.7c]) - -// 1.8 Keywords to Frequent - - /* 765 - external symbol could be made static */ - +e765 - -append(765,[BARR-C:2018 Rule 1.8a]) - - /* 818 - parameter of function could be pointer to const */ - +e818 - -append(818,[BARR-C:2018 Rule 1.8b]) - - /* 843 - static storage duration variable could be made const */ - +e843 - -append(843,[BARR-C:2018 Rule 1.8b]) - - /* 844 - static storage duration variable could be made pointer to const */ - +e844 - -append(844,[BARR-C:2018 Rule 1.8b]) - - /* 952 - parameter of function could be const */ - +e952 - -append(952,[BARR-C:2018 Rule 1.8b]) - - /* 953 - local variable could be const */ - +e953 - -append(953,[BARR-C:2018 Rule 1.8b]) - - /* 954 - local variable could be pointer to const */ - +e954 - -append(954,[BARR-C:2018 Rule 1.8b]) - - /* 2765 - reference to variable which is neither atomic nor volatile sig_atomic_t within signal handler */ - +e2765 - -append(2765,[BARR-C:2018 Rule 1.8c]) - -//========== COMMENTS ========== - -// 2.1 Acceptable Formats - - /* 427 - C++ comment continued via back-slash */ - +e427 - -append(427,[BARR-C:2018 Rule 2.1b]) - - /* 602 - nested block comment */ - +e602 - -append(602,[BARR-C:2018 Rule 2.1b]) - - /* 9059 - C comment contains C++ comment */ - +e9059 - -append(9059,[BARR-C:2018 Rule 2.1b]) - - // 9259 - C comment contains '://' sequence - +e9259 - -append(9259,[BARR-C:2018 Rule 2.1b]) - - /* 9066 - C++ comment contains C comment */ - +e9066 - -append(9066,[BARR-C:2018 Rule 2.1b]) - -// 2.2 Locations and Comments - - /* not statically checkable */ - -//========== WHITE SPACE RULES ========== - -// 3.1 Spaces - - /* not currently supported */ - -// 3.2 Alignment - - /* not currently supported */ - -// 3.3 Black Lines - - /* 783 - line does not end with a newline */ - +e783 - -append(783,[BARR-C:2018 Rule 3.3c]) - -// 3.4 Indentation - - /* 525 - unexpected negative indentation */ - +e525 - -append(525,[BARR-C:2018 Rule 3.4a]) - - /* 539 - unexpected positive indentation */ - +e539 - -append(539,[BARR-C:2018 Rule 3.4a]) - - /* 725 - unexpected lack of indentation */ - +e725 - -append(725,[BARR-C:2018 Rule 3.4a]) - -// 3.5 Tabs - - /* not currently supported */ - -// 3.6 Non-Printing Characters - - /* not currently supported */ - -//========== MODULE RULES ========== - -// 4.1 Naming Conventions - - /* 8516 - module name should contain only lowercase letters, numbers, and underscores */ - -hook(module_open, -cond(!('%[file_name]' ~ '^[[:lower:][:digit:]_./\\\\]+$'), - +message(8516, "module '%[file_name]' should contain only lowercase letters, numbers, and underscores"))) - +e8516 - -append(8516,[BARR-C:2018 Rule 4.1a]) - - /* 8517 - module does not end with '.c' */ - -hook(module_open, -cond(!('%[file_name]' ~ '[.]c$'), - +message(8517, "module '%[file_name]' should have '.c' extension"))) - +e8517 - -append(8517,[BARR-C:2018 Rule 4.1b]) - - /* 8518 - header does not end with '.h' */ - -hook(header_open, -cond(!('%[file_name]' ~ '[.]h$'), - +message(8517, "header '%[file_name]' should have '.h' extension"))) - +e8518 - -append(8518,[BARR-C:2018 Rule 4.1b]) - - /* 8519 - 'main' function defined in file that does not contain the word 'main' */ - -astquery(FunctionDecl : { - getQualifiedNameAsString() == "main" - isThisDeclarationADefinition() - not "main" in getLocation().getBufferName() - message(8519 "main function defined in file '" getLocation().getBufferName() "' which does not have the word 'main' in its name") - }) - +e8519 - -append(8519,[BARR-C:2018 Rule 4.1d]) - -// 4.2 Header Files - - /* 451 - header file repeatedly included but has no header guard */ - +e451 - -append(451,[BARR-C:2018 Rule 4.2b]) - - /* 967 - header file does not have a standard include guard */ - +e967 - -append(967,[BARR-C:2018 Rule 4.2b]) - - /* 9107 - header cannot be included in more than one translation unit because of the definition of symbol */ - +e9107 - -append(9107,[BARR-C:2018 Rule 4.2c]) - - /* 755 - global macro not referenced */ - +e755 - -append(755,[BARR-C:2018 Rule 4.2c]) - - /* 756 - global typedef not referenced */ - +e756 - -append(756,[BARR-C:2018 Rule 4.2c]) - - /* 757 - global declarator not referenced */ - +e757 - -append(757,[BARR-C:2018 Rule 4.2c]) - - /* 758 - global tag not referenced */ - +e758 - -append(758,[BARR-C:2018 Rule 4.2c]) - - /* 759 - header declaration for symbol could be moved from header to module */ - +e759 - -append(759,[BARR-C:2018 Rule 4.2c]) - - /* 768 - global field not referenced */ - +e768 - -append(768,[BARR-C:2018 Rule 4.2c]) - - /* 769 - global enumeration constant not referenced */ - +e769 - -append(769,[BARR-C:2018 Rule 4.2c]) - -// 4.3 Source Files - - /* 9019 - declaration of symbol before #include */ - -append(9019,[BARR-C:2018 Rule 4.3b]) - - /* 8520 - #include used with absolute path */ - -hook(header_open, -cond('%[file_name]' ~ '^([[:alpha:]]:)?[/\\\\]', - +message(8520, "#include directive uses absolute path to include file '%[file_name]'"))) - +e8520 - -append(8520,[BARR-C:2018 Rule 4.3d]) - - /* 8521 - #include used to include module file */ - -hook(header_open, -cond('%[file_name]' ~ '[.]c$', - +message(8521, "#include directive used to include module file '%[file_name]'"))) - +e8521 - -append(8521,[BARR-C:2018 Rule 4.3f]) - -// 4.4 File Templates - - /* not statically checkable */ - -//========== DATA TYPE RULES ========== - -// 5.1 Naming Conventions - - /* 8526 - typedef name should consist of lowercase letters and underscores */ - -astquery(TypedefDecl : { - $name = getNameAsString() - $name ~~ "[^[:lower:]_]" - message(8526 "typedef name '" $name "' should consist of lowercase letters and underscores") - }) - +e8526 - -append(8526,[BARR-C:2018 Rule 5.1a]) - - /* 8527 - typedef name should end with '_t' suffix */ - -astquery(TypedefDecl : { - $name = getNameAsString() - not $name ~~ "_t$" - message(8527 "typedef name '" $name " ' should end with '_t' suffix") - }) - +e8527 - -append(8527,[BARR-C:2018 Rule 5.1a]) - - /* 8528 - non-anonymous struct/union/enum declared outside of typedef */ - -astquery(RecordDecl : { - isFreeStanding() && not isAnonymousStructOrUnion() - message(8528 "non-anonymous struct/union declared outside of a typedef") - }) - -astquery(EnumDecl : { - isFreeStanding() && hasName() - message(8528 "non-anonymous enum declared outside of a typedef") - }) - +e8528 - -append(8528,[BARR-C:2018 Rule 5.1b]) - -// 5.2 Fixed-Width Integers - - /* 586 - keyword/type is deprecated */ - +e586 - - -deprecate(type,signed char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long long,[BARR-C:2018 Rule 5.2a]) - - -deprecate(keyword, short,[BARR-C:2018 Rule 5.2b]) - -deprecate(keyword, long,[BARR-C:2018 Rule 5.2b]) - - /* 9209 - plain character data used with prohibited operator */ - +e9209 - -append(9209,[BARR-C:2018 Rule 5.2c]) - -// 5.3 Signed and Unsigned Integers - - /* 9420 - bitfield does not have unsigned type */ - +e9420 - -append(9420,[BARR-C:2018 Rule 5.3a]) - - /* 9130 - bitwise operator applied to signed underlying type */ - +e9130 - -append(9130,[BARR-C:2018 Rule 5.3b]) - - /* 570 - negative value loses sign during implicit conversion */ - +e570 - -append(570,[BARR-C:2018 Rule 5.3c]) - - /* 713 - implicit conversion from unsigned to signed may lose precision */ - +e713 - -append(713,[BARR-C:2018 Rule 5.3c]) - - /* 8524 - combining signed and unsigned types with operator op1 */ - -astquery(BinaryOperator : { - getLHS().getType().isIntegerType() && getRHS().getType().isIntegerType() - $lhs_type = getLHS().ignoreParenImpCasts().getType() - $rhs_type = getRHS().ignoreParenImpCasts().getType() - ! $lhs_type.isEnumeralType() && ! $lhs_type.isBooleanType() - ! $rhs_type.isEnumeralType() && ! $rhs_type.isBooleanType() - $lhs_type.isUnsignedIntegerOrEnumerationType() != $rhs_type.isUnsignedIntegerOrEnumerationType() - message(8524 "combining signed and unsigned types with operator '" getOpcodeStr "'") - }) - +e8524 - -append(8524,[BARR-C:2018 Rule 5.3c]) - -// 5.4 Floating Point - - /* 586 - type is deprecated */ - -deprecate(type,float,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,double,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,long double,[BARR-C:2018 Rule 5.4b]) - - /* 777 - testing floating point values for equality */ - +e777 - -append(777,[BARR-C:2018 Rule 5.4b]) - - /* 9252 - testing floating point for equality using exact value */ - +e9252 - -append(9252,[BARR-C:2018 Rule 5.4b]) - -// 5.5 Structures and Unions - - /* not currently supported */ - -// 5.6 Booleans - - /* 8523 - cast to boolean */ - -astquery(CStyleCastExpr() : { - getType().isBooleanType() - message(8523 "cast to Boolean") - }) - +e8523 - -append(8523,[BARR-C:2018 Rule 5.6b]) - -//========== PROCEDURE RULES ========== - -// 6.1 Naming Conventions - - /* 8501 - function has name that matches a keyword in C or C++ */ - -astquery(FunctionDecl() : { - ("|" + getNameAsString() + "|") in "|alignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|" - message(8501 "function '" currentnode "'matches the name of a C/C++ keyword") - }) - +e8501 - -append(8501,[BARR-C:2018 Rule 6.1a]) - - /* 8502 - function has same name as standard library function */ - -astquery(FunctionDecl() : { - ("|" + getNameAsString() + "|") in "|abort|abs|acos|acosf|acosh|acoshf|acoshl|acosl|asctime|asin|asinf|asinh|asinhf|asinhl|asinl|assert|atan|atan2|atan2f|atan2l|atanf|atanh|atanhf|atanhl|atanl|atexit|atof|atoi|atol|atoll|bsearch|btowc|cabs|cabsf|cabsl|cacos|cacosf|cacosh|cacoshf|cacoshl|cacosl|calloc|carg|cargf|cargl|casin|casinf|casinh|casinhf|casinhl|casinl|catan|catanf|catanh|catanhf|catanhl|catanl|cbrt|cbrtf|cbrtl|ccos|ccosf|ccosh|ccoshf|ccoshl|ccosl|ceil|ceilf|ceill|cexp|cexpf|cexpl|cimag|cimagf|cimagl|clearerr|clock|clog|clogf|clogl|conj|conjf|conjl|copysign|copysignf|copysignl|cos|cosf|cosh|coshf|coshl|cosl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|creal|crealf|creall|csin|csinf|csinh|csinhf|csinhl|csinl|csqrt|csqrtf|csqrtl|ctan|ctanf|ctanh|ctanhf|ctanhl|ctanl|ctime|difftime|div|erf|erfc|erfcf|erfcl|erff|erfl|exit|_Exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|fabs|fabsf|fabsl|fclose|fdim|fdimf|fdiml|feclearexcept|fegetenv|fegetexceptflag|fegetround|feholdexcept|feof|feraiseexcept|ferror|fesetenv|fesetexceptflag|fesetround|fetestexcept|feupdateenv|fflush|fgetc|fgetpos|fgets|fgetwc|fgetws|floor|floorf|floorl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|fmin|fminf|fminl|fmod|fmodf|fmodl|fopen|fpclassify|fprintf|fputc|fputs|fputwc|fputws|fread|free|freopen|frexp|frexpf|frexpl|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|getc|getchar|getenv|gets|getwc|getwchar|gmtime|hypot|hypotf|hypotl|ilogb|ilogbf|ilogbl|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless|islessequal|islessgreater|islower|isnan|isnormal|isprint|ispunct|isspace|isunordered|isupper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|iswlower|iswprint|iswpunct|iswspace|iswupper|iswxdigit|isxdigit|labs|ldexp|ldexpf|ldexpl|ldiv|lgamma|lgammaf|lgammal|llabs|lldiv|llrint|llrintf|llrintl|llround|llroundf|llroundl|localeconv|localtime|log|log10|log10f|log10l|log1p|log1pf|log1pl|log2|log2f|log2l|logb|logbf|logbl|logf|logl|longjmp|lrint|lrintf|lrintl|lround|lroundf|lroundl|malloc|mblen|mbrlen|mbrtowc|mbsinit|mbsrtowcs|mbstowcs|mbtowc|memchr|memcmp|memcpy|memmove|memset|mktime|modf|modff|modfl|nan|nanf|nanl|nearbyint|nearbyintf|nearbyintl|nextafter|nextafterf|nextafterl|nexttoward|nexttowardf|nexttowardl|perror|pow|powf|powl|printf|putc|putchar|puts|putwc|putwchar|qsort|raise|rand|realloc|remainder|remainderf|remainderl|remove|remquo|remquof|remquol|rename|rewind|rint|rintf|rintl|round|roundf|roundl|scalbln|scalblnf|scalblnl|scalbn|scalbnf|scalbnl|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sin|sinf|sinh|sinhf|sinhl|sinl|snprintf|sprintf|sqrt|sqrtf|sqrtl|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strtod|strtof|strtoimax|strtok|strtol|strtold|strtoll|strtoul|strtoull|strtoumax|strxfrm|swprintf|swscanf|system|tan|tanf|tanh|tanhf|tanhl|tanl|tgamma|tgammaf|tgammal|time|tmpfile|tmpnam|tolower|toupper|towctrans|towlower|towupper|trunc|truncf|truncl|ungetc|ungetwc|va_arg|va_copy|va_end|va_start|vfprintf|vfscanf|vfwprintf|vfwscanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcstod|wcstof|wcstoimax|wcstok|wcstol|wcstold|wcstoll|wcstombs|wcstoul|wcstoull|wcstoumax|wcsxfrm|wctob|wctomb|wctrans|wctype|wmemchr|wmemcmp|wmemcpy|wmemmove|wmemset|wprintf|wscanf|" - message(8502 "function '" currentnode "' matches the name of a standard library function") - }) - +e8502 - -append(8502,[BARR-C:2018 Rule 6.1b]) - - /* 8503 - function has name that begins with an underscore */ - -astquery(FunctionDecl : { - getNameAsString().startsWith("_") - message(8503 "function '" currentnode "' begins with an underscore") - }) - +e8503 - -append(8503,[BARR-C:2018 Rule 6.1c]) - - /* 8504 - function name is longer than 31 characters */ - -astquery(FunctionDecl : { - getNameAsString().length() > 31 - message(8504 "function '" currentnode "' is longer than 31 characters") - }) - +e8504 - -append(8504,[BARR-C:2018 Rule 6.1d]) - - /* 8505 - function name contains upper case letter(s) */ - -astquery(FunctionDecl : { - getNameAsString() ~~ "[[:upper:]]" - message(8505 "function '" currentnode "' contains uppercase letters") - }) - +e8505 - -append(8505,[BARR-C:2018 Rule 6.1e]) - - /* 8506 - macro name contains lowercase letter(s) */ - -hook(macro_define, -cond(!%[is_builtin] && '%[name]' ~ '[[:lower:]]', +message(8506, "macro '%[name]' contains lowercase letters"))) - +e8506 - -append(8506,[BARR-C:2018 Rule 6.1f]) - -// 6.2 Functions - - /* 904 - return statement before end of function */ - +e904 - -append(904,[BARR-C:2018 Rule 6.2c]) - - /* 937 - old-style function declaration for function */ - +e937 - -append(937,[BARR-C:2018 Rule 6.2f]) - - /* 957 - function defined without a prototype in scope */ - +e957 - -append(957,[BARR-C:2018 Rule 6.2f]) - - /* 832 - parameter not explicitly declared, int assumed */ - +e832 - -append(832,[BARR-C:2018 Rule 6.2f]) - -// 6.3 Function-Like Macros - - /* 9026 - function-like macro defined */ - +e9026 - -append(9026,[BARR-C:2018 Rule 6.3a]) - - /* 665 - unparenthesized parameter in macro is passed an expression */ - +e665 - -append(665,[BARR-C:2018 Rule 6.3b]) - - /* 666 - expression with side effects passed to repeated parameter */ - +e666 - -append(666,[BARR-C:2018 Rule 6.3b]) - - /* 773 - expression-like macro not parenthesized */ - +e773 - -append(773,[BARR-C:2018 Rule 6.3b]) - - /* 9022 - unparenthesized macro parameter in definition of macro */ - +e9022 - -append(9022,[BARR-C:2018 Rule 6.3b]) - -// 6.4 Threads of Execution - - /* not currently supported */ - -// 6.5 Interrupt Service Routines - - /* not currently supported */ - -//========== VARIABLES ========== - -// 7.1 Naming Conventions - - /* 8507 - variable has name that matches a keyword in C or C++ */ - -astquery(VarDecl : { - ("|" + getNameAsString() + "|") in "|alignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|fortran|friend|goto|if|inline|int|interrupt|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|" - message(8507 "variable '" currentnode "' matches the name of a C/C++ keyword") - }) - +e8507 - -append(8507,[BARR-C:2018 Rule 7.1a]) - - /* 8525 - variable has same name as standard library variable */ - -astquery(VarDecl : { - ("|" + getNameAsString() + "|") in "|errno|stderr|stdin|stdout|" - message(8525 "variable '" currentnode "' matches the same name of a standard library variable") - }) - +e8525 - -append(8525,[BARR-C:2018 Rule 7.1b]) - - /* 8508 - variable has name that begins with an underscore */ - -astquery(VarDecl : { - getNameAsString().startsWith("_") - message(8508 "variable '" currentnode "' begins with an underscore") - }) - +e8508 - -append(8508,[BARR-C:2018 Rule 7.1c]) - - /* 8509 - variable name is longer than 31 characters */ - -astquery(VarDecl : { - getNameAsString().length() > 31 - message(8509 "variable '" currentnode "' is longer than 31 characters") - }) - +e8509 - -append(8509,[BARR-C:2018 Rule 7.1d]) - - /* 8510 - variable name contains less than 3 characters */ - -astquery(VarDecl : { - getNameAsString().length() < 3 - message(8510 "variable '" currentnode "' contains less than 3 characters") - }) - +e8510 - -append(8510,[BARR-C:2018 Rule 7.1e]) - - /* 8511 - variable name contains upper case letter(s) */ - -astquery(VarDecl : { - getNameAsString() ~~ "[[:upper:]]" - message(8511 "variable '" currentnode "' contains uppercase letters") - }) - +e8511 - -append(8511,[BARR-C:2018 Rule 7.1f]) - - /* 8512 - global variable must start with 'g' */ - -astquery(VarDecl() : { - hasExternalFormalLinkage() - not getNameAsString().startsWith("g") - message(8512 "global variable '" currentnode "' should have 'g' prefix") - }) - +e8512 - -append(8512,[BARR-C:2018 Rule 7.1j]) - - /* 8513 - variable of pointer type should have 'p' prefix */ - /* 8514 - variable of pointer type should have 'pp' prefix */ - -astquery(VarDecl() : { - getType().isPointerType() - if (getType().getPointeeType().isPointerType) { - not getNameAsString().startsWith("pp") - message(8514 "variable '" currentnode "' of type '" getType() "' should have 'pp' prefix") - } else { - not getNameAsString().startsWith("p") - message(8513 "variable '" currentnode "' of type '" getType() "' should have 'p' prefix") - } - }) - +e8513 - +e8514 - -append(8513,[BARR-C:2018 Rule 7.1k]) - -append(8514,[BARR-C:2018 Rule 7.1l]) - - /* 8515 - boolean variable should have 'b' prefix */ - -astquery(VarDecl: { - getType.isBooleanType() - not getNameAsString().startsWith("b") - message(8515 "boolean variable '" currentnode "' should have 'b' prefix") - }) - +e8515 - -append(8515,[BARR-C:2018 Rule 7.1m]) - -// 7.2 Initialization - - /* 530 - likely using an uninitialized value */ - +e530 - -append(530,[BARR-C:2018 Rule 7.2a]) - - /* 603 - argument to parameter of type pointer to const may be a pointer to uninitialized memory */ - +e603 - -append(603,[BARR-C:2018 Rule 7.2a]) - - /* 644 - potentially using an uninitialized value */ - +e644 - -append(644,[BARR-C:2018 Rule 7.2a]) - - /* 708 - union initialization */ - +e708 - -append(708,[BARR-C:2018 Rule 7.2a]) - - /* 727 - static local symbol not explicitly initialized */ - +e727 - -append(727,[BARR-C:2018 Rule 7.2a]) - - /* 728 - file scope static variable not explicitly initialized */ - +e728 - -append(728,[BARR-C:2018 Rule 7.2a]) - - /* 729 - external variable not explicitly initialized */ - +e729 - -append(729,[BARR-C:2018 Rule 7.2a]) - - /* 738 - address of static local symbol not explicitly initialized before passed to a function */ - +e738 - -append(738,[BARR-C:2018 Rule 7.2a]) - - /* 784 - nul character truncated from string */ - +e784 - -append(784,[BARR-C:2018 Rule 7.2a]) - - /* 785 - too few initializers for aggregate */ - +e785 - -append(785,[BARR-C:2018 Rule 7.2a]) - -//========== STATEMENT RULES ========== - -// 8.1 Variable Declarations - - /* 9146 - multiple declarators in a declaration */ - +e9146 - -append(9146,[BARR-C:2018 Rule 8.1a]) - -// 8.2 Conditional Statements - - /* 720 - boolean test of assignment */ - +e720 - -append(720,[BARR-C:2018 Rule 8.2c]) - - /* 820 - boolean test of parenthesized assignment */ - +e820 - -append(820,[BARR-C:2018 Rule 8.2c]) - - /* 9013 - no 'else' at end of 'if ... else if' chain */ - +e9013 - -append(9013,[BARR-C:2018 Rule 8.2d]) - -// 8.3 Switch Statements - - /* 9014 - switch without default */ - +e9014 - -append(9014,[BARR-C:2018 Rule 8.3b]) - - /* 616 - control flow falls through to next case without an intervening comment */ - +e616 - -append(616,[BARR-C:2018 Rule 8.3c]) - -// 8.4 Loops - - /* 850 - for statement index variable modified in body */ - +e850 - -append(850,[BARR-C:2018 Rule 8.4b]) - - /* 716 - infinite loop via while */ - +e716 - -append(716,[BARR-C:2018 Rule 8.4c]) - -// 8.5 Jumps - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 8.5a]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 8.5a]) - - /* 586 - function/macro is deprecated */ - -deprecate(function,abort,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,exit,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,longjmp,[BARR-C:2018 Rule 8.5b]) - -deprecate(macro,setjmp,[BARR-C:2018 Rule 8.5b]) - -// 8.6 Equivalence Test - - /* 8522 - variable should appear on RHS of '==' operator */ - -astquery(BinaryOperator() : { - getOpcodeStr() == "==" - $decl_ref = getLHS().ignoreParenCasts().DeclRefExpr() - $decl_ref && getRHS().isConstantExpr() - message(8522 "variable '" $decl_ref.getDecl() "' should appear on RHS of '==' operator") - }) - +e8522 - -append(8522,[BARR-C:2018 Rule 8.6a]) diff --git a/ports/lint-plus/au-ds.lnt b/ports/lint-plus/au-ds.lnt deleted file mode 100644 index 38fcd673..00000000 --- a/ports/lint-plus/au-ds.lnt +++ /dev/null @@ -1,21 +0,0 @@ -// au-ds.lnt -- Author options - Dan Saks - -/* - This options file can be used to explicitly activate those - checks advocated by Dan Saks in his series of presentations on - "C++ Gotchas". - - You can use this file directly when linting your programs as in: - - lin au-ds files - - */ - -+fsc // consider string constants as const char * -+e1933 // turn on "virtual call from member detection" - -// The rationale for the following two options are fully described -// in Dan Saks' article "const T vs. T const". Visit his web site -// at www.dansaks.com and click "Published Articles". -// --fqb +e963 // require T const rather than const T diff --git a/ports/lint-plus/au-misra4.lnt b/ports/lint-plus/au-misra4.lnt deleted file mode 100644 index a4567728..00000000 --- a/ports/lint-plus/au-misra4.lnt +++ /dev/null @@ -1,2764 +0,0 @@ -// --------------------------------------------------------------------------- -// Copyright Vector Informatik GmbH 2020. All rights reserved. -// -// This file is provided by Vector Informatik GmbH (https://www.vector.com) for -// use with PC-lint Plus. Redistribution is permitted but any redistribution -// must preserve this notice and, if the redistributed file has been modified, -// provide notice that the file has been modified from the original. -// --------------------------------------------------------------------------- - -// Modified by Quantum Leaps for MISRA C 2023 - -// au-misra4.lnt -- Author options - MISRA C 2023 - -/* - This options file can be used to explicitly activate those - checks advocated by the Motor Industry Software Reliability - Association. - - You can use this file directly when linting your programs as in: - - lint au-misra4.lnt hello.c - - "MISRA" is a registered trademark of MIRA Limited, held on - behalf of the MISRA Consortium. - -*/ - -/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 2 || %LINT_MINOR_VERSION% != 0), - +fatal_error(This configuration file is intended for PC-lint Plus 2.0. - You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. - It is recommended that you use configuration files intended - for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) -) - - -/**** Dir 1.1 (Req) ************/ - - /* not statically checkable */ - -/**** Dir 2.1 (Req) ************/ - - -std(c99) /* strict ISO C99 */ - /* Note: if you code to the C90 standard instead, you may - want to comment out the above option and uncomment the - following option. You will also want to do likewise for - other uses of the '-std(c99)' option throughout this file. */ - // -std(c90) - -/**** Dir 3.1 (Req) ************/ - - /* not statically checkable */ - -/**** Dir 4.1 (Req) ************/ - - /* not statically checkable */ - -/**** Dir 4.2 (Adv) ************/ - - /* not statically checkable */ - -/**** Dir 4.3 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - -deprecate(keyword,asm,[MISRA 2012 Directive 4.3, required]) - -/**** Dir 4.4 (Adv) ************/ - - /* This requirement (that there be no commented-out code) is, in - principle, not statically checkable. The reason given for the - requirement is that comments do not nest. Thus a commented - out section of code that happens to use slash-star commenting - could inadvertently introduce unwanted code. Rule 3.1, however, - addresses the nested comment issue and hence the major concern - that this requirement seeks to address is indeed checkable. - */ - -fnc /* flag nested comments */ - +e602 /* comment within comment */ - +elib(602) - -append(602,[MISRA 2012 Directive 4.4, advisory]) - -/**** Dir 4.5 (Adv) ************/ - - +fta /* enable typographical ambiguity checking */ - +e9046 /* typographical ambiguity */ - +elib(9046) - -append(9046,[MISRA 2012 Directive 4.5, advisory]) - -/**** Dir 4.6 (Adv) ************/ - - +e970 /* flag modifiers used outside of typedefs */ - +elib(970) - -append(970,[MISRA 2012 Directive 4.6, advisory]) - -estring(970,bool) - -estring(970,_Bool) - -estring(970,char) - -/**** Dir 4.7 (Req) ************/ - - +e534 /* ignoring return value of function */ - +elib(534) - -append(534,[MISRA 2012 Directive 4.7, required]) - -/**** Dir 4.8 (Adv) ************/ - - +e9045 /* non-hidden definition of type */ - +elib(9045) - -append(9045,[MISRA 2012 Directive 4.8, advisory]) - -/**** Dir 4.9 (Adv) ************/ - - +e9026 /* function-like macro defined */ - +elib(9026) - -append(9026,[MISRA 2012 Directive 4.9, advisory]) - -/**** Dir 4.10 (Req) ************/ - - +e451 /* Header repeatedly included without guard */ - +elib(451) - -append(451,[MISRA 2012 Directive 4.10, required]) - -/**** Dir 4.11 (Req) ************/ - - /* The arguments to over 100 calls to standard library functions - are monitored; users can specify additional constraints for - other functions. - */ - -/**** Dir 4.12 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,calloc,[MISRA 2012 Directive 4.12, required]) - -deprecate(function,malloc,[MISRA 2012 Directive 4.12, required]) - -deprecate(function,realloc,[MISRA 2012 Directive 4.12, required]) - -deprecate(function,free,[MISRA 2012 Directive 4.12, required]) - -/**** Dir 4.13 (Adv) ************/ - - /* Not currently supported */ - -/**** Rule 1.1 (Req) ************/ - - -std(c99) /* strict ISO C99 */ - /* Note: if you code to the C90 standard instead, you may - want to comment out the above option and uncomment the - following option. You will also want to do likewise for - other uses of the '-std(c99)' option throughout this file. */ - // -std(c90) - /* Note: appended citation text is not applied to errors - reporting violations of the C language. */ - - /* See the -lang_limit option. */ - +e793 /* language limit exceeded */ - +elib(793) - -append(793,[MISRA 2012 Rule 1.1, required]) - -/**** Rule 1.2 (Adv) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - -std(c99) /* strict ISO C99 */ - /* Note: if you code to the C90 standard instead, you may - want to comment out the above option and uncomment the - following option. You will also want to do likewise for - other uses of the '-std(c99)' option throughout this file. */ - // -std(c90) - -/**** Rule 1.3 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - - /* Avoid the use of undefined or unspecified behavior as described - in ISO C, Appendix A.6.1 and Appendix A.6.2 */ - - /* Source file not ending in a new-line character, ending in - new-line character immediately preceded by a backslash - character, or ending in a partial preprocessing token or - comment (ISO C, Appendix A.6.2, point 1). - */ - - /* Unclosed quotes (ISO C, Appendix A.6.2, point 4). - */ - +e2 /* unclosed quote */ - +elib(2) - -append(2,[MISRA 2012 Rule 1.3, required]) - - /* Repeated label within a function (ISO C, Appendix A.6.2, point - 5). - */ - +e31 /* symbol redefinition */ - +elib(31) - -append(31,[MISRA 2012 Rule 1.3, required]) - - /* Non-visible identifier used (ISO C, Appendix A.6.2, point 6). - */ - +e40 /* undeclared identifier */ - +elib(40) - -append(40,[MISRA 2012 Rule 1.3, required]) - - /* Identifiers for the same entity differ beyond the minimal - significant characters (ISO C, Appendix A.6.2, point 7). - See Rules 5.1, 5.2, 5.4, and 5.5. - */ - - /* The same identifier has both internal and external linkage in - the same translation unit (ISO C, Appendix A.6.2, point 8). - */ - +e401 /* symbol not previously declared static */ - +elib(401) - -append(401,[MISRA 2012 Rule 1.3, required]) - - /* Multiple definitions for the same externally linked identifier - (ISO C, Appendix A.6.2, point 9). - */ - +e31 /* symbol redefinition */ - +elib(31) - - /* Using automatic storage data via a pointer after the data's - lifetime (ISO C, Appendix A.6.2, point 10). - */ - +e604 /* returning address of auto variable */ - +elib(604) - -append(604,[MISRA 2012 Rule 1.3, required]) - - /* Incompatible redeclarations (ISO C, Appendix A.6.2, point 11). - See Rule 8.3 - */ - - /* Non-standard escape sequence (ISO C, Appendix A.6.2, point 12). - */ - +e606 /* non-ANSI escape sequence */ - +elib(606) - -append(606,[MISRA 2012 Rule 1.3, required]) - - /* Non-standard character in header name (ISO C, Appendix A.6.2, - point 15). - See Rule 20.2 - */ - +e9020 /* header name with non-standard character */ - +elib(9020) - -append(9020,[MISRA 2012 Rule 1.3, required]) - - /* No complete type available (ISO C, Appendix A.6.2, point 16). - */ - +e86 /* structure has no data elements */ - +elib(86) - -append(86,[MISRA 2012 Rule 1.3, required]) - - /* Modifying an object more than once or modifying and accessing - between two sequence points (ISO C, Appendix A.6.2, point 18). - See Rule 13.2 - */ - +e564 /* variable depends on order of evaluation */ - +elib(564) - -append(564,[MISRA 2012 Rule 1.3, required]) - - /* Invalid arithmetic operations or unrepresentable results - (ISO C, Appendix A.6.2, point 19). - */ - +e54 /* division by 0 */ - +elib(54) - -append(54,[MISRA 2012 Rule 1.3, required]) - +e414 /* possible division by 0 */ - +elib(414) - -append(414,[MISRA 2012 Rule 1.3, required]) - /* Also, see Rule 12.4 */ - - /* Passing a void argument to a function (ISO C, Appendix A.6.2, - point 20). - */ - - /* Incompatible function redeclaration (ISO C, Appendix A.6.2, - point 22). - See Rule 8.3 - */ - - /* An invalid array reference, null pointer reference, or - reference to an object declared with automatic storage duration in - a terminated block occurs (ISO C, Appendix A.6.2, point 24). - */ - +e413 /* likely use of null pointer */ - +elib(413) - -append(413,[MISRA 2012 Rule 1.3, required]) - +e415 /* out-of-bounds pointer */ - +elib(415) - -append(415,[MISRA 2012 Rule 1.3, required]) - +e416 /* out-of-bounds pointer */ - +elib(416) - -append(416,[MISRA 2012 Rule 1.3, required]) - +e428 /* negative subscript */ - +elib(428) - -append(428,[MISRA 2012 Rule 1.3, required]) - /* Also, see Rule 17.6 */ - - /* A pointer to a function is converted to a pointer to an object - or a pointer to an object is converted to a pointer to a function - (ISO C, Appendix A.6.2, point 26). - */ - +e2454 /* incompatible pointer types */ - +elib(2454) - -append(2454,[MISRA 2012 Rule 1.3, required]) - - /* An identifier for an object is declared with no linkage and the - type of the object is incomplete after its declarator, or after its - init-declarator if it has an initializer (ISO C, Appendix - A.6.2, point 33). - */ - +e86 /* structure has no data elements */ - +elib(86) - - /* Declaring a function at block scope with a storage-class - specifier other than extern (ISO C, Appendix A.6.2, point 34). - */ - +e629 /* static class for function */ - +elib(629) - -append(629,[MISRA 2012 Rule 1.3, required]) - - /* A bit-field is declared with a type other than int, signed int, - or unsigned int (ISO C, Appendix A.6.2, point 35). - See Rule 6.1. - */ - - /* Using the value of uninitialized automatic object (ISO C, - Appendix A.6.2, point 38). - See Rule 9.1 - */ - - /* An object with aggregate or union type with static storage - duration has a non-brace-enclosed initializer, or an object - with aggregate or union type with automatic storage duration - has either a single expression initializer with a type other - than that of the object or a non-brace-enclosed initializer - (ISO C, Appendix A.6.2, point 39). - Also, see Rule 9.2 - */ - - /* The value of a function is used, but no value was returned - (ISO C, Appendix A.6.2, point 40). - See Rule 17.4. - */ - - /* A function that accepts a variable number of arguments is - defined without a parameter type list that ends with the - ellipsis notation (ISO C, Appendix A.6.2, point 41). - */ - - /* An identifier for an object with internal linkage and an - incomplete type is declared with a tentative definition (ISO C, - Appendix A.6.2, point 42). - */ - +e86 /* structure has no data elements */ - +elib(86) - - /* Non-standard #include preprocessing directive (ISO C, Appendix - A.6.2, point 44). - See Rule 20.3. - */ - - /* Non-standard #line directive (ISO C, Appendix A.6.2, point 49). - */ - +"estring(10,a numeric constant)" /* expecting a numeric constant */ - - /* #defining or #undefing any of: defined, __LINE__, __FILE__, - __DATE__, __TIME__, or __STDC__ (ISO C, Appendix A.6.2, point 50). - */ - +e136 /* illegal macro name */ - +elib(136) - -append(136,[MISRA 2012 Rule 1.3, required]) - - /* Format-argument mismatch in an fprintf or fscanf type of - function (ISO C, Appendix A.6.2, point 75). - */ - +e558 /* too few arguments */ - +elib(558) - -append(558,[MISRA 2012 Rule 1.3, required]) - +e719 /* too many arguments */ - +elib(719) - -append(719,[MISRA 2012 Rule 1.3, required]) - - /* A %% conversion specification for the fprintf or fscanf - function contains characters between the pair of % characters - (ISO C, Appendix A.6.2, point 77). - */ - +e557 /* unrecognized format */ - +elib(557) - -append(557,[MISRA 2012 Rule 1.3, required]) - - /* An aggregate or union, or a pointer to an aggregate or union is - an argument to the fprintf function, except for the conversion - specifiers %s (for an array of character type) or %p (for a pointer - to void) (ISO C, Appendix A.6.2, point 81). - */ - +e437 /* passing struct to ellipsis */ - +elib(437) - -append(437,[MISRA 2012 Rule 1.3, required]) - - /* Referring to deallocated space (ISO C, Appendix A.6.2, point - 87). - */ - +e449 /* previously deallocated pointer */ - +elib(449) - -append(449,[MISRA 2012 Rule 1.3, required]) - - /* Misuse of free or realloc (ISO C, Appendix A.6.2, point 88). - */ - +esym(424,free) /* inappropriate deallocation */ - -append(424,[MISRA 2012 Rule 1.3, required]) - - /* An array written to by a copying or concatenation function is - too small (ISO C, Appendix A.6.2, point 91). - */ - +e419 /* data overrun */ - +elib(419) - -append(419,[MISRA 2012 Rule 1.3, required]) - - /* Order of evaluation (ISO C, Appendix A.6.1, point 7). - */ - +e564 /* variable depends on order of evaluation */ - +elib(564) - -append(564,[MISRA 2012 Rule 1.3, required]) - - /* Side effects order (ISO C, Appendix A.6.1, point 8). - */ - +e931 /* both sides of an expression have side-effects */ - +elib(931) - -append(931,[MISRA 2012 Rule 1.3, required]) - - /* Function argument evaluation (ISO C, Appendix A.6.1, point 9). - */ - +e564 /* variable depends on order of evaluation */ - +elib(564) - - /* The order in which # and ## operations are evaluated during - macro substitution (ISO C, Appendix A.6.1, point 12). - */ - +e9023 /* multiple '#/##' operators in macro definition */ - +elib(9023) - -append(9023,[MISRA 2012 Rule 1.3, required]) - - /* Whether setjmp is a macro or an external identifier (ISO C, - Appendix A.6.1, point 14). - See Rule 21.2. - */ - -/**** Rule 2.1 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e527 /* unreachable */ - +elib(527) - -append(527,[MISRA 2012 Rule 2.1, required]) - +e681 /* loop not entered */ - +elib(681) - -append(681,[MISRA 2012 Rule 2.1, required]) - +e827 /* loop not reachable */ - +elib(827) - -append(827,[MISRA 2012 Rule 2.1, required]) - -/**** Rule 2.2 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e438 /* value not used */ - +elib(438) - -append(438,[MISRA 2012 Rule 2.2, required]) - +e505 /* redundant argument to comma */ - +elib(505) - -append(505,[MISRA 2012 Rule 2.2, required]) - +e520 /* highest operator has no side effects */ - +elib(520) - -append(520,[MISRA 2012 Rule 2.2, required]) - +e521 /* highest operator has no side effects */ - +elib(521) - -append(521,[MISRA 2012 Rule 2.2, required]) - +e522 /* highest operator has no side effects */ - +elib(522) - -append(522,[MISRA 2012 Rule 2.2, required]) - +e774 /* condition always evaluates to true/false */ - +elib(774) - -append(774,[MISRA 2012 Rule 2.2, required]) - -/**** Rule 2.3 (Adv) ************/ - - +e751 /* local typedef not referenced */ - +elib(751) - -append(751,[MISRA 2012 Rule 2.3, advisory]) - +e756 /* global not referenced */ - +elib(756) - -append(756,[MISRA 2012 Rule 2.3, advisory]) - -/**** Rule 2.4 (Adv) ************/ - - +e753 /* local tag not referenced */ - +elib(753) - -append(753,[MISRA 2012 Rule 2.4, advisory]) - +e9058 - +elibsym(9058) - -append(9058,[MISRA 2012 Rule 2.4, advisory]) - -/**** Rule 2.5 (Adv) ************/ - - +e750 /* local macro not referenced */ - +elib(750) - -append(750,[MISRA 2012 Rule 2.5, advisory]) - +e755 /* global macro not referenced */ - +elib(755) - -append(755,[MISRA 2012 Rule 2.5, advisory]) - -/**** Rule 2.6 (Adv) ************/ - - +e563 /* label not referenced */ - +elib(563) - -append(563,[MISRA 2012 Rule 2.6, advisory]) - -/**** Rule 2.7 (Adv) ************/ - - +e715 /* not referenced */ - +elib(715) - -append(715,[MISRA 2012 Rule 2.7, advisory]) - -/**** Rule 3.1 (Req) ************/ - - -fnc /* flag nested comments */ - +e602 /* comment within comment */ - +elib(602) - -append(602,[MISRA 2012 Rule 3.1, required]) - +e9059 - +elib(9059) - -append(9059,[MISRA 2012 Rule 3.1, required]) - +e9066 - +elib(9066) - -append(9066,[MISRA 2012 Rule 3.1, required]) - +e9259 - +elib(9259) - -append(9259,[MISRA 2012 Rule 3.1, required]) - -/**** Rule 3.2 (Req) ************/ - - +e427 /* C++ comment ends in \\ */ - +elib(427) - -append(427,[MISRA 2012 Rule 3.2, required]) - -/**** Rule 4.1 (Req) ************/ - - +e9039 /* prohibited escape sequence */ - +elib(9039) - -append(9039,[MISRA 2012 Rule 4.1, required]) - -/**** Rule 4.2 (Adv) ************/ - - -ftg /* inhibit use of trigraphs */ - +e584 /* activate trigraph detected message */ - +elib(584) - -append(584,[MISRA 2012 Rule 4.2, advisory]) - +e739 /* activate trigraph in string message */ - +elib(739) - -append(739,[MISRA 2012 Rule 4.2, advisory]) - +e9060 /* trigraph in comment */ - +elib(9060) - -append(9060,[MISRA 2012 Rule 4.2, advisory]) - -/**** Rule 5.1 (Req) ************/ - - -idlen(31, x) /* Sets the number of significant characters in an external - identifier, update as appropriate for your target. Use - 'X' instead of 'x' if external identifiers are not case - sensitive. C90 guarantees 6 characters are significant, - C99 guarantees at least 31 characters are significant. */ - - +e621 /* identifier clash */ - +elib(621) - -append(621("external vs external"), [MISRA 2012 Rule 5.1, required]) - -/**** Rule 5.2 (Req) ************/ - - -idlen(63, c) /* Sets the number of significant characters in an internal - identifier, update as appropriate for your target. Use - 'C' instead of 'c' if internal identifiers are not case - sensitive. C90 guarantees 31 characters are significant, - C99 guarantees at least 63 characters are significant. */ - - +e621 /* identifier clash */ - +elib(621) - -append(621("tag vs tag"), [MISRA 2012 Rule 5.2, required]) - -append(621("field vs field"), [MISRA 2012 Rule 5.2, required]) - -append(621("label vs label"), [MISRA 2012 Rule 5.2, required]) - -append(621("internal vs internal, same scope"), [MISRA 2012 Rule 5.2, required]) - -append(621("internal vs external, same scope"), [MISRA 2012 Rule 5.2, required]) - -append(621("external vs internal, same scope"), [MISRA 2012 Rule 5.2, required]) - -/**** Rule 5.3 (Req) ************/ - - +e578 /* enable reports of name hiding */ - +elib(578) - -append(578,[MISRA 2012 Rule 5.3, required]) - - /* This rule uses the same -idlen option values as 5.2 */ - - +e621 /* identifier clash */ - +elib(621) - -append(621("internal vs internal, enclosing scope"), [MISRA 2012 Rule 5.3, required]) - -append(621("internal vs external, enclosing scope"), [MISRA 2012 Rule 5.3, required]) - -append(621("external vs internal, enclosing scope"), [MISRA 2012 Rule 5.3, required]) - -/**** Rule 5.4 (Req) ************/ - - -idlen(63, p) /* Sets the number of significant characters in a preprocessor - identifier, update as appropriate for your target. Use - 'P' instead of 'p' if preprocessor identifiers are not case - sensitive. C90 guarantees 31 characters are significant, - C99 guarantees at least 63 characters are significant. */ - - +e547 /* conflicting macro definition */ - +elib(547) - -append(547,[MISRA 2012 Rule 5.4, required]) - - +e760 /* macro redefined identically */ - +elib(760) - -append(760,[MISRA 2012 Rule 5.4, required]) - - +e621 /* identifier clash */ - +elib(621) - -append(621("macro vs macro"), [MISRA 2012 Rule 5.4, required]) - -append(621("macro vs macro parameter"), [MISRA 2012 Rule 5.4, required]) - -append(621("macro parameter vs macro parameter"), [MISRA 2012 Rule 5.4, required]) - -/**** Rule 5.5 (Req) ************/ - - /* 9095 - symbol has same name as previously defined macro */ - +e9095 - +elib(9095) - -append(9095,[MISRA 2012 Rule 5.5, required]) - - /* 9096 - symbol has same name as subsequently defined macro */ - +e9096 - +elib(9096) - -append(9096,[MISRA 2012 Rule 5.5, required]) - -/**** Rule 5.6 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 5.7 (Req) ************/ - - +e407 /* Inconsistent use of tag */ - +elib(407) - -append(407,[MISRA 2012 Rule 5.7, required]) - - +e631 /* Tag defined differently */ - +elib(631) - -append(631,[MISRA 2012 Rule 5.7, required]) - -/**** Rule 5.8 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 5.9 (Adv) ************/ - - /* Not currently supported */ - -/**** Rule 6.1 (Req) ************/ - - /* 9149 bit field must be explicitly signed integer, unsigned integer, - or bool */ - +e9149 - +elib(9149) - -append(9149,[MISRA 2012 Rule 6.1, required]) - -/**** Rule 6.2 (Req) ************/ - - +e9088 /* named signed single-bit bit-field */ - +elib(9088) - -append(9088,[MISRA 2012 Rule 6.2, required]) - -/**** Rule 7.1 (Req) ************/ - - +e9001 /* Octal constant used */ - +elib(9001) - -append(9001,[MISRA 2012 Rule 7.1, required]) - -/**** Rule 7.2 (Req) ************/ - - +e9048 /* unsigned literal without 'U' suffix */ - +elib(9048) - -append(9048,[MISRA 2012 Rule 7.2, required]) - -/**** Rule 7.3 (Req) ************/ - - +e620 /* suspicious constant */ - +elib(620) - -append(620,[MISRA 2012 Rule 7.3, required]) - +e9057 /* "l" after "u" in literal suffix */ - +elib(9057) - -append(9057,[MISRA 2012 Rule 7.3, required]) - -/**** Rule 7.4 (Req) ************/ - - +fsc - +e489 /* attempting to modify a string literal */ - +elib(489) - -append(489,[MISRA 2012 Rule 7.4, required]) - +e1776 /* string literal not const safe */ - +elib(1776) - -append(1776,[MISRA 2012 Rule 7.4, required]) - +e1778 /* assignment of string literal not const safe */ - +elib(1778) - -append(1778,[MISRA 2012 Rule 7.4, required]) - -/**** Rule 8.1 (Req) ************/ - - +e601 /* no explicit type */ - +elib(601) - -append(601,[MISRA 2012 Rule 8.1, required]) - +e808 /* no explicit type */ - +elib(808) - -append(808,[MISRA 2012 Rule 8.1, required]) - +e832 /* parameter has no explicit type */ - +elib(832) - -append(832,[MISRA 2012 Rule 8.1, required]) - -/**** Rule 8.2 (Req) ************/ - - +e937 /* old-style function declaration */ - +elib(937) - -append(937,[MISRA 2012 Rule 8.2, required]) - +e18 /* symbol redeclared */ - +elib(18) - -append(18,[MISRA 2012 Rule 8.2, required]) - - +e936 /* old-style function definition */ - +elib(936) - -append(936,[MISRA 2012 Rule 8.2, required]) - - +e955 /* param name missing from prototype */ - +elib(955) - -append(955,[MISRA 2012 Rule 8.2, required]) - -/**** Rule 8.3 (Req) ************/ - - +e18 /* symbol redeclared */ - +elib(18) - -append(18,[MISRA 2012 Rule 8.3, required]) - - /* 9072 parameter has different name than previous declaration */ - +e9072 - +elib(9072) - -append(9072,[MISRA 2012 Rule 8.3, required]) - - /* 9073 parameter has type alias name type difference with previous - declaration */ - +e9073 - +elib(9073) - -append(9073,[MISRA 2012 Rule 8.3, required]) - - /* 9094 return type has type alias name difference with previous - declaration */ - +e9094 - +elib(9094) - -append(9094,[MISRA 2012 Rule 8.3, required]) - -/**** Rule 8.4 (Req) ************/ - - +e15 /* symbol redeclared */ - +elib(15) - -append(15,[MISRA 2012 Rule 8.4, required]) - - /* 957 - function defined without prototype in scope */ - +e957 - +elib(957) - -append(957,[MISRA 2012 Rule 8.4, required]) - - /* 9075 external symbol defined without a prior declaration */ - +e9075 - +elib(9075) - -append(9075,[MISRA 2012 Rule 8.4, required]) - -/**** Rule 8.5 (Req) ************/ - - +e9004 /* object/function previously declared */ - +elib(9004) - -append(9004,[MISRA 2012 Rule 8.5, required]) - -/**** Rule 8.6 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 8.7 (Adv) ************/ - - +e765 /* could be made static */ - +elib(765) - -append(765,[MISRA 2012 Rule 8.7, advisory]) - -/**** Rule 8.8 (Req) ************/ - - +e839 /* storage class assumed static */ - +elib(839) - -append(839,[MISRA 2012 Rule 8.8, required]) - -/**** Rule 8.9 (Adv) ************/ - - +e9003 /* could define variable at block scope */ - +elib(9003) - -append(9003,[MISRA 2012 Rule 8.9, advisory]) - -/**** Rule 8.10 (Req) ************/ - - +e695 /* inline function without storage-class specifier */ - +elib(695) - -append(695,[MISRA 2012 Rule 8.10, required]) - +estring(9056,extern) /* inline function defined with extern */ - -append(9056,[MISRA 2012 Rule 8.10, required]) - -/**** Rule 8.11 (Adv) ************/ - - +e9067 /* array has no dimension or initializer */ - +elib(9067) - -append(9067,[MISRA 2012 Rule 8.11, advisory]) - -/**** Rule 8.12 (Req) ************/ - - +e488 /* duplicate enumerator values */ - +elib(488) - -append(488,[MISRA 2012 Rule 8.12, required]) - -/**** Rule 8.13 (Adv) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e818 /* pointer could be declared pointing to const */ - +elib(818) - -append(818,[MISRA 2012 Rule 8.13, advisory]) - +e844 /* pointer could be declared pointing to const */ - +elib(844) - -append(844,[MISRA 2012 Rule 8.13, advisory]) - +e954 /* pointer could be declared pointing to const */ - +elib(954) - -append(954,[MISRA 2012 Rule 8.13, advisory]) - - -fcv /* report parameters even if exclusively cast to void */ - -/**** Rule 8.14 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(keyword,restrict,[MISRA 2012 Rule 8.14, required]) - -/**** Rule 9.1 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e644 /* Symbol may not have been initialized */ - +elib(644) - -append(644,[MISRA 2012 Rule 9.1, mandatory]) - +e530 /* Symbol not initialized */ - +elib(530) - -append(530,[MISRA 2012 Rule 9.1, mandatory]) - - /* 603 - argument to parameter of type pointer to const may be a pointer to - uninitialized memory */ - +e603 - +elib(603) - -append(603,[MISRA 2012 Rule 9.1, mandatory]) - -/**** Rule 9.2 (Req) ************/ - - +e9069 /* aggregate initialize needs braces or designator */ - +elib(9069) - -append(9069,[MISRA 2012 Rule 9.2, required]) - -/**** Rule 9.3 (Req) ************/ - - +e9068 /* too few initializers */ - +elib(9068) - -append(9068,[MISRA 2012 Rule 9.3, required]) - -/**** Rule 9.4 (Req) ************/ - - +e485 /* duplicate initialization */ - +elib(485) - -append(485,[MISRA 2012 Rule 9.4, required]) - -/**** Rule 9.5 (Req) ************/ - - +e9054 /* designated initializer and dimensionless array */ - +elib(9054) - -append(9054,[MISRA 2012 Rule 9.5, required]) - -/**** Rule 10.1 (Req) ************/ - - +e48 /* bad type */ - +elib(48) - -append(48,[MISRA 2012 Rule 10.1, required]) - +e9027 /* unpermitted operand */ - +elib(9027) - -append(9027,[MISRA 2012 Rule 10.1, required]) - -/**** Rule 10.2 (Req) ************/ - - +e9028 /* unpermitted arithmetic */ - +elib(9028) - -append(9028,[MISRA 2012 Rule 10.2, required]) - -/**** Rule 10.3 (Req) ************/ - - +e9034 /* expression assigned to narrower or different essential type */ - +elib(9034) - -append(9034,[MISRA 2012 Rule 10.3, required]) - -/**** Rule 10.4 (Req) ************/ - - +e9029 /* mismatched essential type */ - +elib(9029) - -append(9029,[MISRA 2012 Rule 10.4, required]) - -/**** Rule 10.5 (Adv) ************/ - - +e9030 /* impermissible cast */ - +elib(9030) - -append(9030,[MISRA 2012 Rule 10.5, advisory]) - -/**** Rule 10.6 (Req) ************/ - - +e9031 /* composite expression assigned to wider essential type */ - +elib(9031) - -append(9031,[MISRA 2012 Rule 10.6, required]) - -/**** Rule 10.7 (Req) ************/ - - +e9032 /* composite expression with smaller essential type than other operand*/ - +elib(9032) - -append(9032,[MISRA 2012 Rule 10.7, required]) - -/**** Rule 10.8 (Req) ************/ - - +e9033 /* impermissible cast of composite expression */ - +elib(9033) - -append(9033,[MISRA 2012 Rule 10.8, required]) - -/**** Rule 11.1 (Req) ************/ - - /* 176 - cannot cast non-pointer non-integer to function pointer */ - +e176 - +elib(176) - -append(176,[MISRA 2012 Rule 11.1, required]) - - /* 178 - cannot cast function pointer to non-pointer non-integer */ - +e178 - +elib(178) - -append(178,[MISRA 2012 Rule 11.1, required]) - - +e9074 /* conversion between a pointer to function and another type */ - +elib(9074) - -append(9074,[MISRA 2012 Rule 11.1, required]) - -/**** Rule 11.2 (Req) ************/ - - +e9076 /* conversion between a pointer to incomplete type and another type */ - +elib(9076) - -append(9076,[MISRA 2012 Rule 11.2, required]) - -/**** Rule 11.3 (Req) ************/ - - +e9087 /* cast from pointer to pointer */ - +elib(9087) - -append(9087,[MISRA 2012 Rule 11.3, required]) - -/**** Rule 11.4 (Adv) ************/ - - +e9078 /* cast pointer/integer */ - +elib(9078) - -append(9078,[MISRA 2012 Rule 11.4, advisory]) - -/**** Rule 11.5 (Adv) ************/ - - +e9079 /* cast from pointer to pointer */ - +elib(9079) - -append(9079,[MISRA 2012 Rule 11.5, advisory]) - -/**** Rule 11.6 (Req) ************/ - - +elib(923) /* cast pointer/non-pointer */ - +etype(923, void *) - -append(923,[MISRA 2012 Rule 11.6, required]) - -/**** Rule 11.7 (Req) ************/ - - +e177 /* type cannot be cast to object pointer */ - +elib(177) - -append(177,[MISRA 2012 Rule 11.7, required]) - - +e179 /* object pointer cannot be cast to type */ - +elib(179) - -append(179,[MISRA 2012 Rule 11.7, required]) - - +e9295 /* cast between object pointer and forbidden essential type */ - +elib(9295) - -append(9295,[MISRA 2012 Rule 11.7, required]) - -/**** Rule 11.8 (Req) ************/ - - +e9005 /* attempt to cast away const/volatile from pointer or reference */ - +elib(9005) - -append(9005,[MISRA 2012 Rule 11.8, required]) - -/**** Rule 11.9 (Req) ************/ - - +e9080 /* integer null pointer constant */ - +elib(9080) - -append(9080,[MISRA 2012 Rule 11.9, required]) - -/**** Rule 12.1 (Adv) ************/ - - +e9050 /* dependence placed on precedence */ - +elib(9050) - -append(9050,[MISRA 2012 Rule 12.1, advisory]) - - +e9097 /* unparenthesized argument to sizeof */ - +elib(9097) - -append(9097,[MISRA 2012 Rule 12.1, advisory]) - -/**** Rule 12.2 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e598 /* excessive left shift */ - +elib(598) - -append(598,[MISRA 2012 Rule 12.2, required]) - +e9053 /* shift value exceeds size of LHS */ - +elib(9053) - -append(9053,[MISRA 2012 Rule 12.2, required]) - -/**** Rule 12.3 (Adv) ************/ - - +e9008 /* comma operator used */ - +elib(9008) - -append(9008,[MISRA 2012 Rule 12.3, advisory]) - -/**** Rule 12.4 (Adv) ************/ - - /* not currently supported */ - -/**** Rule 13.1 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e446 /* side effect in initializer */ - +elib(446) - -append(446,[MISRA 2012 Rule 13.1, required]) - -/**** Rule 13.2 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e564 /* variable depends on order of evaluation */ - +elib(564) - -append(564,[MISRA 2012 Rule 13.2, required]) - -/**** Rule 13.3 (Adv) ************/ - - +e9049 /* increment/decrement combined with other operations */ - +elib(9049) - -append(9049,[MISRA 2012 Rule 13.3, advisory]) - -/**** Rule 13.4 (Adv) ************/ - - +e720 /* Boolean test of assignment */ - +elib(720) - -append(720,[MISRA 2012 Rule 13.4, advisory]) - +e820 /* Boolean test of parenthesized assignment */ - +elib(820) - -append(820,[MISRA 2012 Rule 13.4, advisory]) - +e9084 /* assignment used inside larger - expression */ - +elib(9084) - -append(9084,[MISRA 2012 Rule 13.4, advisory]) - -/**** Rule 13.5 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e9007 /* side effects on right hand side of logical operator */ - +elib(9007) - -append(9007,[MISRA 2012 Rule 13.5, required]) - -/**** Rule 13.6 (Mand) ************/ - - +e9006 /* sizeof used with expression with side effect */ - +elib(9006) - -append(9006,[MISRA 2012 Rule 13.6, mandatory]) - -/**** Rule 14.1 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e9009 /* floating point variable used as loop counter */ - +elib(9009) - -append(9009,[MISRA 2012 Rule 14.1, required]) - -/**** Rule 14.2 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 14.3 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e685 /* relational always evaluates to true/false */ - +elib(685) - -append(685,[MISRA 2012 Rule 14.3, required]) - +e774 /* boolean always evaluates to true/false */ - +elib(774) - -append(774,[MISRA 2012 Rule 14.3, required]) - +e650 /* constant out of range for operator */ - +elib(650) - -append(650,[MISRA 2012 Rule 14.3, required]) - -/**** Rule 14.4 (Req) ************/ - - +e9036 /* condition should have essentially Boolean type */ - +elib(9036) - -append(9036,[MISRA 2012 Rule 14.4, required]) - -/**** Rule 15.1 (Adv) ************/ - - +e801 /* use of 'goto' is deprecated */ - +elib(801) - -append(801,[MISRA 2012 Rule 15.1, advisory]) - -/**** Rule 15.2 (Req) ************/ - - +e9064 /* goto references earlier label */ - +elib(9064) - -append(9064,[MISRA 2012 Rule 15.2, required]) - -/**** Rule 15.3 (Req) ************/ - - +e9041 /* goto not nested in the same block as label */ - +elib(9041) - -append(9041,[MISRA 2012 Rule 15.3, required]) - -/**** Rule 15.4 (Adv) ************/ - - +e9011 /* more than one 'break' terminates loop */ - +elib(9011) - -append(9011,[MISRA 2012 Rule 15.4, advisory]) - -/**** Rule 15.5 (Adv) ************/ - - +e904 /* return before function end */ - +elib(904) - -append(904,[MISRA 2012 Rule 15.5, advisory]) - -/**** Rule 15.6 (Req) ************/ - - +e9012 /* sub-statement should be a compound statement */ - +elib(9012) - -append(9012,[MISRA 2012 Rule 15.6, required]) - -/**** Rule 15.7 (Req) ************/ - - +e9013 /* no 'else' at end of 'if ... else if' chain */ - +elib(9013) - -append(9013,[MISRA 2012 Rule 15.7, required]) - +e9063 /* no comment or action in else-branch */ - +elib(9063) - -append(9063,[MISRA 2012 Rule 15.7, required]) - -/**** Rule 16.1 (Req) ************/ - - +e616 /* control flows into case/default */ - +elib(616) - -append(616,[MISRA 2012 Rule 16.1, required]) - +e744 /* switch statement has no default */ - +elib(744) - -append(744,[MISRA 2012 Rule 16.1, required]) - +e764 /* switch does not have a case */ - +elib(764) - -append(764,[MISRA 2012 Rule 16.1, required]) - +e825 /* control flows into case/default without -fallthrough comment */ - +elib(825) - -append(825,[MISRA 2012 Rule 16.1, required]) - +e9014 /* default missing from switch */ - +elib(9014) - -append(9014,[MISRA 2012 Rule 16.1, required]) - +e9042 /* departure from MISRA switch syntax */ - +elib(9042) - -append(9042,[MISRA 2012 Rule 16.1, required]) - +e9077 /* missing unconditional break */ - +elib(9077) - -append(9077,[MISRA 2012 Rule 16.1, required]) - +e9081 /* too few independent cases for switch */ - +elib(9081) - -append(9081,[MISRA 2012 Rule 16.1, required]) - +e9082 /* switch statement should either begin or end with default label */ - +elib(9082) - -append(9082,[MISRA 2012 Rule 16.1, required]) - +e9085 /* statement or comment should appear in default case */ - +elib(9085) - -append(9085,[MISRA 2012 Rule 16.1, required]) - -/**** Rule 16.2 (Req) ************/ - - +e44 /* Need a switch */ - +elib(44) - -append(44,[MISRA 2012 Rule 16.2, required]) - +e9055 /* enclosing statement is not a switch */ - +elib(9055) - -append(9055,[MISRA 2012 Rule 16.2, required]) - -/**** Rule 16.3 (Req) ************/ - - +e616 /* control flows into case/default */ - +elib(616) - -append(616,[MISRA 2012 Rule 16.3, required]) - +e825 /* control flows into case/default without -fallthrough comment */ - +elib(825) - -append(825,[MISRA 2012 Rule 16.3, required]) - +e9077 /* missing unconditional break */ - +elib(9077) - -append(9077,[MISRA 2012 Rule 16.3, required]) - +e9090 /* missing unconditional break */ - +elib(9090) - -append(9090,[MISRA 2012 Rule 16.3, required]) - -/**** Rule 16.4 (Req) ************/ - - +e744 /* switch statement has no default */ - +elib(744) - -append(744,[MISRA 2012 Rule 16.4, required]) - +e9014 /* switch statement has no default */ - +elib(9014) - -append(9014,[MISRA 2012 Rule 16.4, required]) - +e9085 /* default case has no statement nor comment */ - +elib(9085) - -append(9085,[MISRA 2012 Rule 16.4, required]) - -/**** Rule 16.5 (Req) ************/ - - +e9082 /* default should be first or last */ - +elib(9082) - -append(9082,[MISRA 2012 Rule 16.5, required]) - -/**** Rule 16.6 (Req) ************/ - - +e764 /* switch does not have a case */ - +elib(764) - -append(764,[MISRA 2012 Rule 16.6, required]) - +e9081 /* too few cases */ - +elib(9081) - -append(9081,[MISRA 2012 Rule 16.6, required]) - -/**** Rule 16.7 (Req) ************/ - - +e483 /* boolean value in switch expression */ - +elib(483) - -append(483,[MISRA 2012 Rule 16.7, required]) - -/**** Rule 17.1 (Req) ************/ - - +e829 /* warn on header usage */ - +elib(829) - +headerwarn(stdarg.h) - -append(829(stdarg.h),[MISRA 2012 Rule 17.1, required]) - -deprecate(macro,va_arg,[MISRA 2012 Rule 17.1, required]) - -deprecate(macro,va_start,[MISRA 2012 Rule 17.1, required]) - -deprecate(macro,va_end,[MISRA 2012 Rule 17.1, required]) - -deprecate(macro,va_copy,[MISRA 2012 Rule 17.1, required]) - -deprecate(type,va_list,[MISRA 2012 Rule 17.1, required]) - -/**** Rule 17.2 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e9070 - -append(9070,[MISRA 2012 Rule 17.2, required]) - -/**** Rule 17.3 (Mand) ************/ - - +e718 /* symbol undeclared, assumed to return int */ - +elib(718) - -append(718,[MISRA 2012 Rule 17.3, mandatory]) - -/**** Rule 17.4 (Mand) ************/ - - +e533 /* function should return a value */ - +elib(533) - -append(533,[MISRA 2012 Rule 17.4, mandatory]) - -/**** Rule 17.5 (Adv) ************/ - - /* MISRA has declared this rule to be "undecidable". */ - - +e473 /* argument to array parameter too small */ - +elib(473) - -append(473,[MISRA 2012 Rule 17.5, advisory]) - -/**** Rule 17.6 (Mand) ************/ - - +e9043 /* static between brackets of array declaration */ - +elib(9043) - -append(9043,[MISRA 2012 Rule 17.6, mandatory]) - -/**** Rule 17.7 (Req) ************/ - - +e534 /* ignoring return value of function */ - +elib(534) - -append(534,[MISRA 2012 Rule 17.7, required]) - -/**** Rule 17.8 (Adv) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e9044 /* function parameter modified */ - +elib(9044) - -append(9044,[MISRA 2012 Rule 17.8, advisory]) - -/**** Rule 18.1 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e415 /* out-of-bounds pointer */ - +elib(415) - -append(415,[MISRA 2012 Rule 18.1, required]) - +e416 /* out-of-bounds pointer */ - +elib(416) - -append(416,[MISRA 2012 Rule 18.1, required]) - +e428 /* out-of-bounds pointer */ - +elib(428) - -append(428,[MISRA 2012 Rule 18.1, required]) - +e661 /* out-of-bounds pointer */ - +elib(661) - -append(661,[MISRA 2012 Rule 18.1, required]) - +e662 /* out-of-bounds pointer */ - +elib(662) - -append(662,[MISRA 2012 Rule 18.1, required]) - +e676 /* out-of-bounds pointer */ - +elib(676) - -append(676,[MISRA 2012 Rule 18.1, required]) - -/**** Rule 18.2 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e947 /* pointer subtraction */ - +elib(947) - -append(947,[MISRA 2012 Rule 18.2, required]) - -/**** Rule 18.3 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e946 /* relational operator applied to pointers */ - +elib(946) - -append(946,[MISRA 2012 Rule 18.3, required]) - -/**** Rule 18.4 (Adv) ************/ - - +e9016 /* pointer arithmetic other than array indexing used */ - +elib(9016) - -append(9016,[MISRA 2012 Rule 18.4, advisory]) - -/**** Rule 18.5 (Adv) ************/ - - +e9025 /* more than two pointer indirection levels used */ - +elib(9025) - -append(9025,[MISRA 2012 Rule 18.5, advisory]) - -/**** Rule 18.6 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e733 /* assigning address of auto to outer scope symbol */ - +elib(733) - -append(733,[MISRA 2012 Rule 18.6, required]) - +e789 /* assigning address of auto to static */ - +elib(789) - -append(789,[MISRA 2012 Rule 18.6, required]) - +e604 /* returning address of auto variable */ - +elib(604) - -append(604,[MISRA 2012 Rule 18.6, required]) - -/**** Rule 18.7 (Req) ************/ - - +e9038 /* flexible array member declared */ - +elib(9038) - -append(9038,[MISRA 2012 Rule 18.7, required]) - -/**** Rule 18.8 (Req) ************/ - - +e9035 /* variable length array declared */ - +elib(9035) - -append(9035,[MISRA 2012 Rule 18.8, required]) - -/**** Rule 19.1 (Mand) ************/ - - /* MISRA has declared this rule to be "undecidable". */ - -/**** Rule 19.2 (Adv) ************/ - - +e9018 /* union type/object declared */ - +elib(9018) - -append(9018,[MISRA 2012 Rule 19.2, advisory]) - -/**** Rule 20.1 (Adv) ************/ - - +e9019 /* declaration before #include */ - +elib(9019) - -append(9019,[MISRA 2012 Rule 20.1, advisory]) - -/**** Rule 20.2 (Req) ************/ - - +e9020 /* header file name with non-standard character */ - +elib(9020) - -append(9020,[MISRA 2012 Rule 20.2, required]) - /* Note: If your system requires the '\' be used as a directory - separator, uncomment the following option. - */ - // -estring(9020,\) - -/**** Rule 20.3 (Req) ************/ - - +e12 /* Need < or " after #include */ - +elib(12) - -append(12,[MISRA 2012 Rule 20.3, required]) - - /* 544 directive not followed by EOL */ - +estring(544,include) - +elib(544) - -append(544(include),[MISRA 2012 Rule 20.3, required]) - -/**** Rule 20.4 (Req) ************/ - - +e9051 /* macro with same name as a keyword */ - +elib(9051) - -append(9051,[MISRA 2012 Rule 20.4, required]) - -/**** Rule 20.5 (Adv) ************/ - - +e9021 /* use of '#undef' is discouraged */ - +elib(9021) - -append(9021,[MISRA 2012 Rule 20.5, advisory]) - -/**** Rule 20.6 (Req) ************/ - - +e436 /* preprocessor directive in invocation of macro */ - +elib(436) - -append(436,[MISRA 2012 Rule 20.6, required]) - -/**** Rule 20.7 (Req) ************/ - - +e665 /* expression passed to unparenthesized macro */ - +elib(665) - -append(665,[MISRA 2012 Rule 20.7, required]) - -/**** Rule 20.8 (Req) ************/ - - +e9037 /* conditional of #if/#elif does not evaluate to 0 or 1 */ - +elib(9037) - -append(9037,[MISRA 2012 Rule 20.8, required]) - -/**** Rule 20.9 (Req) ************/ - - +e553 /* Undefined preprocessor variable, assumed 0 */ - +elib(553) - -append(553,[MISRA 2012 Rule 20.9, required]) - -/**** Rule 20.10 (Adv) ************/ - - +e9024 /* '#/##' operators used */ - +elib(9024) - -append(9024,[MISRA 2012 Rule 20.10, advisory]) - -/**** Rule 20.11 (Req) ************/ - - +e484 /* stringize operator followed by macro parameter followed by pasting operator */ - +elib(484) - -append(484,[MISRA 2012 Rule 20.11, required]) - -/**** Rule 20.12 (Req) ************/ - - +e9015 /* macro parameter used with and without '#/##' subject to further replacement */ - +elib(9015) - -append(9015,[MISRA 2012 Rule 20.12, required]) - -/**** Rule 20.13 (Req) ************/ - - /* 544 - directive not followed by EOL */ - +e544 - +elib(544) - -append(544,[MISRA 2012 Rule 20.13, required]) - - /* 16 - unknown preprocessor directive */ - +e16 - +elib(16) - -append(16,[MISRA 2012 Rule 20.13, required]) - - /* 9160 - unknown preprocessor directive in conditionally excluded - region */ - +e9160 - +elib(9160) - -append(9160,[MISRA 2012 Rule 20.13, required]) - -/**** Rule 20.14 (Req) ************/ - - +e8 /* unclosed #if */ - +elib(8) - -append(8,[MISRA 2012 Rule 20.14, required]) - -/**** Rule 21.1 (Req) ************/ - - +e136 /* Illegal macro name */ - +elib(136) - -append(136,[MISRA 2012 Rule 21.1, required]) - /* Undefining standard library macros is covered by rule 20.5. */ - /* Defining/redefining reserved/standard identifiers is covered - by rules 20.4 and 21.2. - */ - +e9071 /* defined macro reserved to the compiler */ - +elib(9071) - -append(9071,[MISRA 2012 Rule 21.1, required]) - // explicit exemptions - -estring(9071,* because *) - -estring(9071,cerf) - -estring(9071,cerfc) - -estring(9071,cexp2) - -estring(9071,cexpm1) - -estring(9071,clog10) - -estring(9071,clog1p) - -estring(9071,clog2) - -estring(9071,clgamma) - -estring(9071,ctgamma) - -estring(9071,cerff) - -estring(9071,cerfcf) - -estring(9071,cexp2f) - -estring(9071,cexpm1f) - -estring(9071,clog10f) - -estring(9071,clog1pf) - -estring(9071,clog2f) - -estring(9071,clgammaf) - -estring(9071,ctgammaf) - -estring(9071,cerfl) - -estring(9071,cerfcl) - -estring(9071,cexp2l) - -estring(9071,cexpm1l) - -estring(9071,clog10l) - -estring(9071,clog1pl) - -estring(9071,clog2l) - -estring(9071,clgammal) - -estring(9071,ctgammal) - -estring(9071,E0*) - -estring(9071,E1*) - -estring(9071,E2*) - -estring(9071,E3*) - -estring(9071,E4*) - -estring(9071,E5*) - -estring(9071,E6*) - -estring(9071,E7*) - -estring(9071,E8*) - -estring(9071,E9*) - -estring(9071,NDEBUG) - -estring(9071,PRIa*) - -estring(9071,PRIb*) - -estring(9071,PRIc*) - -estring(9071,PRId*) - -estring(9071,PRIe*) - -estring(9071,PRIf*) - -estring(9071,PRIg*) - -estring(9071,PRIh*) - -estring(9071,PRIi*) - -estring(9071,PRIj*) - -estring(9071,PRIk*) - -estring(9071,PRIl*) - -estring(9071,PRIm*) - -estring(9071,PRIn*) - -estring(9071,PRIo*) - -estring(9071,PRIp*) - -estring(9071,PRIq*) - -estring(9071,PRIr*) - -estring(9071,PRIs*) - -estring(9071,PRIt*) - -estring(9071,PRIu*) - -estring(9071,PRIv*) - -estring(9071,PRIw*) - -estring(9071,PRIx*) - -estring(9071,PRIy*) - -estring(9071,PRIz*) - -estring(9071,PRIX*) - -estring(9071,SCNa*) - -estring(9071,SCNb*) - -estring(9071,SCNc*) - -estring(9071,SCNd*) - -estring(9071,SCNe*) - -estring(9071,SCNf*) - -estring(9071,SCNg*) - -estring(9071,SCNh*) - -estring(9071,SCNi*) - -estring(9071,SCNj*) - -estring(9071,SCNk*) - -estring(9071,SCNl*) - -estring(9071,SCNm*) - -estring(9071,SCNn*) - -estring(9071,SCNo*) - -estring(9071,SCNp*) - -estring(9071,SCNq*) - -estring(9071,SCNr*) - -estring(9071,SCNs*) - -estring(9071,SCNt*) - -estring(9071,SCNu*) - -estring(9071,SCNv*) - -estring(9071,SCNw*) - -estring(9071,SCNx*) - -estring(9071,SCNy*) - -estring(9071,SCNz*) - -estring(9071,SCNX*) - +e9083 /* undefined macro reserved to the compiler */ - +elib(9083) - -append(9083,[MISRA 2012 Rule 21.1, required]) - // explicit exemptions - -estring(9083,* because *) - -estring(9083,cerf) - -estring(9083,cerfc) - -estring(9083,cexp2) - -estring(9083,cexpm1) - -estring(9083,clog10) - -estring(9083,clog1p) - -estring(9083,clog2) - -estring(9083,clgamma) - -estring(9083,ctgamma) - -estring(9083,cerff) - -estring(9083,cerfcf) - -estring(9083,cexp2f) - -estring(9083,cexpm1f) - -estring(9083,clog10f) - -estring(9083,clog1pf) - -estring(9083,clog2f) - -estring(9083,clgammaf) - -estring(9083,ctgammaf) - -estring(9083,cerfl) - -estring(9083,cerfcl) - -estring(9083,cexp2l) - -estring(9083,cexpm1l) - -estring(9083,clog10l) - -estring(9083,clog1pl) - -estring(9083,clog2l) - -estring(9083,clgammal) - -estring(9083,ctgammal) - -estring(9083,E0*) - -estring(9083,E1*) - -estring(9083,E2*) - -estring(9083,E3*) - -estring(9083,E4*) - -estring(9083,E5*) - -estring(9083,E6*) - -estring(9083,E7*) - -estring(9083,E8*) - -estring(9083,E9*) - -estring(9083,NDEBUG) - -estring(9083,PRIa*) - -estring(9083,PRIb*) - -estring(9083,PRIc*) - -estring(9083,PRId*) - -estring(9083,PRIe*) - -estring(9083,PRIf*) - -estring(9083,PRIg*) - -estring(9083,PRIh*) - -estring(9083,PRIi*) - -estring(9083,PRIj*) - -estring(9083,PRIk*) - -estring(9083,PRIl*) - -estring(9083,PRIm*) - -estring(9083,PRIn*) - -estring(9083,PRIo*) - -estring(9083,PRIp*) - -estring(9083,PRIq*) - -estring(9083,PRIr*) - -estring(9083,PRIs*) - -estring(9083,PRIt*) - -estring(9083,PRIu*) - -estring(9083,PRIv*) - -estring(9083,PRIw*) - -estring(9083,PRIx*) - -estring(9083,PRIy*) - -estring(9083,PRIz*) - -estring(9083,PRIX*) - -estring(9083,SCNa*) - -estring(9083,SCNb*) - -estring(9083,SCNc*) - -estring(9083,SCNd*) - -estring(9083,SCNe*) - -estring(9083,SCNf*) - -estring(9083,SCNg*) - -estring(9083,SCNh*) - -estring(9083,SCNi*) - -estring(9083,SCNj*) - -estring(9083,SCNk*) - -estring(9083,SCNl*) - -estring(9083,SCNm*) - -estring(9083,SCNn*) - -estring(9083,SCNo*) - -estring(9083,SCNp*) - -estring(9083,SCNq*) - -estring(9083,SCNr*) - -estring(9083,SCNs*) - -estring(9083,SCNt*) - -estring(9083,SCNu*) - -estring(9083,SCNv*) - -estring(9083,SCNw*) - -estring(9083,SCNx*) - -estring(9083,SCNy*) - -estring(9083,SCNz*) - -estring(9083,SCNX*) - -/**** Rule 21.2 (Req) ************/ - - +e9093 /* name is reserved to the compiler */ - +elib(9093) - -append(9093,[MISRA 2012 Rule 21.2, required]) - -/**** Rule 21.3 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,calloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(macro,calloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(function,malloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(macro,malloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(function,realloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(macro,realloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(function,free,[MISRA 2012 Rule 21.3, required]) - -deprecate(macro,free,[MISRA 2012 Rule 21.3, required]) - -/**** Rule 21.4 (Req) ************/ - - +e829 /* warn on header usage */ - +elib(829) - +headerwarn(setjmp.h) - -append(829(setjmp.h),[MISRA 2012 Rule 21.4, required]) - -deprecate(function,setjmp,[MISRA 2012 Rule 21.4, required]) - -deprecate(function,longjmp,[MISRA 2012 Rule 21.4, required]) - -deprecate(macro,setjmp,[MISRA 2012 Rule 21.4, required]) - -deprecate(macro,longjmp,[MISRA 2012 Rule 21.4, required]) - -deprecate(type,jmp_buf,[MISRA 2012 Rule 21.4, required]) - -/**** Rule 21.5 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,signal,[MISRA 2012 Rule 21.5, required]) - -deprecate(function,raise,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIGABRT,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIGFPE,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIGILL,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIGINT,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIGSEGV,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIGTERM,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIG_DFL,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIG_ERR,[MISRA 2012 Rule 21.5, required]) - -deprecate(macro,SIG_IGN,[MISRA 2012 Rule 21.5, required]) - -deprecate(type,sig_atomic_t,[MISRA 2012 Rule 21.5, required]) - +e829 /* warn on header usage */ - +elib(829) - +headerwarn(signal.h) - -append(829(signal.h),[MISRA 2012 Rule 21.5, required]) - -/**** Rule 21.6 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,clearerr,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fclose,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,feof,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,ferror,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fflush,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fgetc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fgetpos,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fgets,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fgetwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fgetws,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fopen,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fputc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fputs,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fputwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fputws,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fread,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fseek,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fsetpos,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,freopen,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,ftell,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fwide,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fwprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fwrite,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,fwscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,getc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,getchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,gets,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,getwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,getwchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,perror,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,printf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,putc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,putchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,puts,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,putwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,putwchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,remove,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,rename,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,rewind,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,scanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,setbuf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,setvbuf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,snprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,sprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,sscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,swprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,swscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,tmpfile,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,tmpnam,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,ungetc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,ungetwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vfprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vfscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vfwprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vfwscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vsnprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vsprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vsscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vswprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vswscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vwprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,vwscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,wprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(function,wscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,clearerr,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fclose,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,feof,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,ferror,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fflush,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fgetc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fgets,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fgetpos,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fgetwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fgetws,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fopen,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fputc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fputs,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fputwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fputws,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fread,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fseek,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fsetpos,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,freopen,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,ftell,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fwide,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fwprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fwrite,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,fwscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,getc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,getchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,gets,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,getwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,getwchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,perror,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,printf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,putc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,putchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,puts,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,putwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,putwchar,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,remove,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,rename,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,rewind,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,scanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,setbuf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,setvbuf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,snprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,sprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,sscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,swprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,swscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,tmpfile,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,tmpnam,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,ungetc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,ungetwc,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vfprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vfscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vfwprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vfwscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vsnprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vsprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vsscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vswprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vswscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vwprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,vwscanf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,wprintf,[MISRA 2012 Rule 21.6, required]) - -deprecate(macro,wscanf,[MISRA 2012 Rule 21.6, required]) - -/**** Rule 21.7 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,atof,[MISRA 2012 Rule 21.7, required]) - -deprecate(function,atoi,[MISRA 2012 Rule 21.7, required]) - -deprecate(function,atol,[MISRA 2012 Rule 21.7, required]) - -deprecate(function,atoll,[MISRA 2012 Rule 21.7, required]) - -deprecate(macro,atof,[MISRA 2012 Rule 21.7, required]) - -deprecate(macro,atoi,[MISRA 2012 Rule 21.7, required]) - -deprecate(macro,atol,[MISRA 2012 Rule 21.7, required]) - -deprecate(macro,atoll,[MISRA 2012 Rule 21.7, required]) - -/**** Rule 21.8 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,abort,[MISRA 2012 Rule 21.8, required]) - -deprecate(function,exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(function,getenv,[MISRA 2012 Rule 21.8, required]) - -deprecate(function,system,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,abort,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,getenv,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,system,[MISRA 2012 Rule 21.8, required]) - -/**** Rule 21.9 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,bsearch,[MISRA 2012 Rule 21.9, required]) - -deprecate(function,qsort,[MISRA 2012 Rule 21.9, required]) - -deprecate(macro,bsearch,[MISRA 2012 Rule 21.9, required]) - -deprecate(macro,qsort,[MISRA 2012 Rule 21.9, required]) - -/**** Rule 21.10 (Req) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(macro,wcsftime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,wcsftime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,clock,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,clock,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,difftime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,difftime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,mktime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,mktime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,time,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,time,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,asctime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,asctime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,ctime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,ctime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,gmtime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,gmtime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,localtime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,localtime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,strftime,[MISRA 2012 Rule 21.10, required]) - -deprecate(function,strftime,[MISRA 2012 Rule 21.10, required]) - -deprecate(macro,CLOCKS_PER_SEC,[MISRA 2012 Rule 21.10, required]) - -deprecate(type,clock_t,[MISRA 2012 Rule 21.10, required]) - -deprecate(type,time_t,[MISRA 2012 Rule 21.10, required]) - -deprecate(type,struct tm,[MISRA 2012 Rule 21.10, required]) - +e829 /* warn on header usage */ - +elib(829) - +headerwarn(time.h) - -append(829(time.h),[MISRA 2012 Rule 21.10, required]) - -/**** Rule 21.11 (Req) ************/ - - +e829 /* warn on header usage */ - +elib(829) - +headerwarn(tgmath.h) - -append(829(tgmath.h),[MISRA 2012 Rule 21.11, required]) - -/**** Rule 21.12 (Adv) ************/ - - +e586 /* Symbol is deprecated */ - +elib(586) - -deprecate(function,feclearexcept,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,feclearexcept,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(function,fegetexceptflag,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,fegetexceptflag,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(function,feraiseexcept,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,feraiseexcept,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(function,fesetexceptflag,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,fesetexceptflag,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(function,fetestexcept,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,fetestexcept,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,FE_INEXACT,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,FE_DIVBYZERO,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,FE_UNDERFLOW,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,FE_OVERFLOW,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,FE_INVALID,[MISRA 2012 Rule 21.12, advisory]) - -deprecate(macro,FE_ALL_EXCEPT,[MISRA 2012 Rule 21.12, advisory]) - -/**** Rule 22.1 (Req) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e429 /* custodial pointer neither free'd nor returned */ - +elib(429) - -append(429,[MISRA 2012 Rule 22.1, required]) - - /* 698 - in-place realloc could cause a memory leak */ - +e698 - +elib(698) - -append(698,[MISRA 2012 Rule 22.1, required]) - -/**** Rule 22.2 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e424 /* inappropriate deallocation */ - +elib(424) - -append(424,[MISRA 2012 Rule 22.2, mandatory]) - - +e449 /* pointer previously deallocated */ - +elib(449) - -append(449,[MISRA 2012 Rule 22.2, mandatory]) - -/**** Rule 22.3 (Req) ************/ - - /* MISRA has declared this rule to be "undecidable". */ - -/**** Rule 22.4 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - - +e2477 /* attempt to perform write operation on stream not opened for writing */ - +elib(2477) - -append(2477,[MISRA 2012 Rule 22.4, mandatory]) - -/**** Rule 22.5 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - +e9047 /* FILE pointer dereferenced */ - +elib(9047) - -append(9047,[MISRA 2012 Rule 22.5, mandatory]) - - -/**** Rule 22.6 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - - +e2471 /* operation on stream that has been closed */ - +elib(2471) - -append(2471,[MISRA 2012 Rule 22.6, mandatory]) - -// au-misra3-amd1.lnt -- Author options - MISRA C 2012 - -/* - This options file can be used to explicitly activate those - checks advocated by the Motor Industry Software Reliability - Association. - - You can use this file directly when linting your programs as in: - - lint au-misra3-amd1.lnt hello.c - - Note that this file does not enable checking for the base MISRA C 2012 - guidelines. Typical use will include au-misra3.lnt, e.g.: - - lint au-misra3.lnt au-misra3-amd1.lnt hello.c - - Vector Informatik GmbH relies on the document, "MISRA C:2012 Amendment 1 - Additional security guidelines for MISRA C:2012" - copyright 2016 by HORIBA MIRA Ltd, as the primary source for this - file. Vector Informatik GmbH makes no warranty as to the completeness - or applicability of this options file and reserves the right to - amend or alter the official contents of such at any time. - - "MISRA" is a registered trademark of HORIBA MIRA Ltd, held on - behalf of the MISRA Consortium. - - */ - -/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 2 || %LINT_MINOR_VERSION% != 0), - +fatal_error(This configuration file is intended for PC-lint Plus 2.0. - You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. - It is recommended that you use configuration files intended - for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) -) - - -/**** Dir 4.14 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 12.5 (Mand) ************/ - - +e682 /* sizeof applied to parameter whose type is sized array */ - +elib(682) - -append(682,[MISRA 2012 Rule 12.5, mandatory]) - - +e882 /* sizeof applied to parameter declared as incomplete array */ - +elib(882) - -append(882,[MISRA 2012 Rule 12.5, mandatory]) - -/**** Rule 21.13 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - - /* Define EOF until a proper definition is seen */ - -dEOF=-1 - - /* Define UCHAR_MIN and UCHAR_MAX if no definition available */ - -dUCHAR_MIN=0 - -dUCHAR_MAX=255 - - /* Ensure macro versions of ctype.h functions expand to function versions - to make use of the function semantics defined below */ - --uisalnum - --uisalpha - --uisblank - --uiscntrl - --uisdigit - --uisgraph - --uislower - --uisprint - --uispunct - --uisspace - --uisupper - --uisxdigit - --utolower - --utoupper - - /* Define semantics for ctype.h functions */ - -sem(isalnum, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isalpha, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isblank, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(iscntrl, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isdigit, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isgraph, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(islower, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isprint, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(ispunct, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isspace, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isupper, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isxdigit, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(tolower, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(toupper, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - - +esym(426, isalnum) - +esym(426, isalpha) - +esym(426, isblank) - +esym(426, iscntrl) - +esym(426, isdigit) - +esym(426, isgraph) - +esym(426, islower) - +esym(426, isprint) - +esym(426, ispunct) - +esym(426, isspace) - +esym(426, isupper) - +esym(426, isxdigit) - +esym(426, tolower) - +esym(426, toupper) - - -append(426(isalnum), value passed to isalnum is not representable as unsigned char and is not EOF) - -append(426(isalnum),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isalpha), value passed to isalpha is not representable as unsigned char and is not EOF) - -append(426(isalpha),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isblank), value passed to isblank is not representable as unsigned char and is not EOF) - -append(426(isblank),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(iscntrl), value passed to iscntrl is not representable as unsigned char and is not EOF) - -append(426(iscntrl),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isdigit), value passed to isdigit is not representable as unsigned char and is not EOF) - -append(426(isdigit),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isgraph), value passed to isgraph is not representable as unsigned char and is not EOF) - -append(426(isgraph),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(islower), value passed to islower is not representable as unsigned char and is not EOF) - -append(426(islower),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isprint), value passed to isprint is not representable as unsigned char and is not EOF) - -append(426(isprint),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(ispunct), value passed to ispunct is not representable as unsigned char and is not EOF) - -append(426(ispunct),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isspace), value passed to isspace is not representable as unsigned char and is not EOF) - -append(426(isspace),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isupper), value passed to isupper is not representable as unsigned char and is not EOF) - -append(426(isupper),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isxdigit), value passed to isxdigit is not representable as unsigned char and is not EOF) - -append(426(isxdigit),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(tolower), value passed to tolower is not representable as unsigned char and is not EOF) - -append(426(tolower),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(toupper), value passed to toupper is not representable as unsigned char and is not EOF) - -append(426(toupper),[MISRA 2012 Rule 21.13, mandatory]) - -/**** Rule 21.14 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 21.15 (Req) ************/ - - +e857 /* incompatible pointer arguments to memcpy/memmove/memcmp */ - +elib(857) - -append(857,[MISRA 2012 Rule 21.15, required]) - -/**** Rule 21.16 (Req) ************/ - - +e9098 /* pointer argument to memcmp does not point to a pointer type - or an essentially signed, unsigned, boolean, or enum type */ - +elib(9098) - -append(9098,[MISRA 2012 Rule 21.16, required]) - -/**** Rule 21.17 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - - /* 419 - apparent data overrun for function */ - /* 420 - apparent access beyond array for function */ - - +esym(419 420, strcat, strcpy) - -append(419(strcat),[MISRA 2012 Rule 21.17, mandatory]) - -append(420(strcat),[MISRA 2012 Rule 21.17, mandatory]) - -append(419(strcpy),[MISRA 2012 Rule 21.17, mandatory]) - -append(420(strcpy),[MISRA 2012 Rule 21.17, mandatory]) - -/**** Rule 21.18 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", the - * following options are provided to assist: - */ - - /* 419 - apparent data overrun for function */ - /* 420 - apparent access beyond array for function */ - /* 422 - function passed a negative value */ - - +esym(419 420 422, memchr, memcmp, memcpy, memmove, memset) - +esym(419 420 422, strncat, strncmp, strncpy, strxfrm) - - /* PC-lint Plus will issue 419 when it can determine that - * the size parameter of the below functions exceeds the - * size of the buffer that is being written to. - */ - - -append(419(memcpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(419(memmove),[MISRA 2012 Rule 21.18, mandatory]) - -append(419(strncat),[MISRA 2012 Rule 21.18, mandatory]) - -append(419(strncpy),[MISRA 2012 Rule 21.18, mandatory]) - - /* PC-lint Plus will issue 420 when it can determine that - * the size parameter of the below functions exceeds the - * size of the buffer that is being read from. - */ - - -append(420(memchr),[MISRA 2012 Rule 21.18, mandatory]) - -append(420(memcmp),[MISRA 2012 Rule 21.18, mandatory]) - -append(420(memcpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(420(memmove),[MISRA 2012 Rule 21.18, mandatory]) - - /* PC-lint Plus will issue 422 when it can determine that - * a negative value is being passed to the size parameter - * of the below functions. - */ - - -append(422(memchr),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memcmp),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memcpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memmove),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memset),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strncat),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strncmp),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strncpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strxfrm),[MISRA 2012 Rule 21.18, mandatory]) - -/**** Rule 21.19 (Mand) ************/ - - /* Not currently supported */ - -/**** Rule 21.20 (Mand) ************/ - - /* Not currently supported */ - -/**** Rule 22.7 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 22.8 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 22.9 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 22.10 (Req) ************/ - - /* Not currently supported */ - -// au-misra3-amd2.lnt -- Author options - MISRA C 2012 - -/* - This options file can be used to explicitly activate those - checks advocated by the Motor Industry Software Reliability - Association. - - You can use this file directly when linting your programs as in: - - lint au-misra3-amd2.lnt hello.c - - Note that this file does not enable checking for the base MISRA C 2012 - guidelines. Typical use will include au-misra3.lnt, e.g.: - - lint au-misra3.lnt au-misra3-amd2.lnt hello.c - - To include checking of rules introduced in both AMD-1 and AMD-2, use: - - lint au-misra3.lnt au-misra3-amd1.lnt au-misra3-amd2.lnt hello.c - - Vector Informatik GmbH relies on the document, "MISRA C:2012 Amendment 2 - Updates for ISO/IEC 9899:2011 Core functionality" - copyright 2020 by HORIBA MIRA Ltd, as the primary source for this - file. Vector Informatik GmbH makes no warranty as to the completeness - or applicability of this options file and reserves the right to - amend or alter the official contents of such at any time. - - "MISRA" is a registered trademark of HORIBA MIRA Ltd, held on - behalf of the MISRA Consortium. - - */ - -/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 2 || %LINT_MINOR_VERSION% != 0), - +fatal_error(This configuration file is intended for PC-lint Plus 2.0. - You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. - It is recommended that you use configuration files intended - for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) -) - - - -/**** Rule 1.4 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - /* C11 Keywords */ - -deprecate(keyword,_Alignas,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Alignof,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Atomic,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Generic,[MISRA 2012 Rule 1.4, required]) - //-deprecate(keyword,_Noreturn,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Thread_local,[MISRA 2012 Rule 1.4, required]) - - /* Facilities provided by the header file */ - -deprecate(macro,ATOMIC_BOOL_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_CHAR16_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_CHAR32_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_CHAR_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_FLAG_INIT,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_INT_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_LLONG_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_LONG_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_POINTER_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_SHORT_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_VAR_INIT,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_WCHAR_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,atomic_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_init,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,enum memory_order,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,memory_order,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,atomic_flag,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,struct atomic_flag,[MISRA 2012 Rule 1.4, required]) - - -deprecate(macro,kill_dependency,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,atomic_compare_exchange_strong,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_compare_exchange_strong_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_compare_exchange_weak,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_compare_exchange_weak_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_exchange,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_exchange_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_add,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_add_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_and,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_and_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_or,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_or_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_sub,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_sub_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_xor,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_xor_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_clear,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_clear_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_test_and_set,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_test_and_set_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_is_lock_free,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_load,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_load_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_signal_fence,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_store,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_store_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_thread_fence,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_strong,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_strong_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_weak,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_weak_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_exchange,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_exchange_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_add,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_add_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_and,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_and_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_or,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_or_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_sub,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_sub_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_xor,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_xor_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_clear,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_clear_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_test_and_set,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_test_and_set_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_is_lock_free,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_load,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_load_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_signal_fence,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_store,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_store_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_thread_fence,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,atomic_bool,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_char,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_char16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_char32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_intmax_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_intptr_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_llong,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_long,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ptrdiff_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_schar,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_short,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_size_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uchar,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uintmax_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uintptr_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ullong,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ulong,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ushort,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_wchar_t,[MISRA 2012 Rule 1.4, required]) - - /* Facilities provided by the header file */ - -deprecate(macro,ONCE_FLAG_INIT,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,TSS_DTOR_ITERATIONS,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thread_local,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,cnd_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,mtx_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,once_flag,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,thrd_start_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,thrd_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,tss_dtor_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,tss_t,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,call_once,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_broadcast,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_signal,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_timedwait,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_wait,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_lock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_timedlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_trylock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_unlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_current,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_detach,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_equal,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_exit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_join,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_sleep,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_yield,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_delete,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_get,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_set,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,call_once,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_broadcast,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_signal,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_timedwait,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_wait,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_lock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_timedlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_trylock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_unlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_current,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_detach,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_equal,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_exit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_join,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_sleep,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_yield,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_delete,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_get,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_set,[MISRA 2012 Rule 1.4, required]) - - /* The and header files */ - +e829 /* warn on header usage */ - +elib(829) - - +headerwarn(stdalign.h) - +headerwarn(stdnoreturn.h) - - -append(829(stdalign.h),[MISRA 2012 Rule 1.4, required]) - -append(829(stdnoreturn.h),[MISRA 2012 Rule 1.4, required]) - - /* Facilities of Annex K (Bounds-checking interfaces) */ - -deprecate(type,errno_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,rsize_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,constraint_handler_t,[MISRA 2012 Rule 1.4, required]) - - -deprecate(macro,RSIZE_MAX,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,L_tmpnam_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,TMP_MAX_S,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,abort_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,asctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,bsearch_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,ctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,freopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,getenv_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,gets_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,gmtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,ignore_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,localtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mbsrtowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mbstowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,memcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,memmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,memset_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,printf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,qsort_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,scanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,set_constraint_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,snprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,snwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,sprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,sscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strcat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strerror_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strerrorlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strtok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,swprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,swscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tmpfile_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tmpnam_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsnprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsnwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vswprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vswscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcrtomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcscat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcscpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsrtombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcstok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcstombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wctomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wmemcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wmemmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,abort_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,asctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,bsearch_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,freopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,getenv_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,gets_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,gmtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ignore_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,localtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mbsrtowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mbstowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,memcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,memmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,memset_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,printf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,qsort_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,scanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,set_constraint_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,snprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,snwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,sprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,sscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strcat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strerror_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strerrorlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strtok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,swprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,swscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tmpfile_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tmpnam_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsnprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsnwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vswprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vswscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcrtomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcscat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcscpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsrtombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcstok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcstombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wctomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wmemcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wmemmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wscanf_s,[MISRA 2012 Rule 1.4, required]) - -/**** Rule 21.3 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - /* The other functions covered by this rule are included in au-misra3.lnt */ - -deprecate(function,aligned_alloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(macro,aligned_alloc,[MISRA 2012 Rule 21.3, required]) - -/**** Rule 21.8 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - /* Deprecations for the abort and exit functions are included in au-misra3.lnt */ - -deprecate(function,_Exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(function,quick_exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,_Exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,quick_exit,[MISRA 2012 Rule 21.8, required]) - - /* Suppress deprecation messages targeting getenv for Rule 21.8 which is - marked as deprecated in au-misra3.lnt but no longer a violation. */ - -egrep(586,"function 'getenv' is deprecated. [[]MISRA 2012 Rule 21.8, required[]]$") - -egrep(586,"macro 'getenv' is deprecated. [[]MISRA 2012 Rule 21.8, required[]]$") - -/**** Rule 21.21 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - -deprecate(function,system,[MISRA 2012 Rule 21.21, required]) - -deprecate(macro,system,[MISRA 2012 Rule 21.21, required]) - diff --git a/ports/lint-plus/au-ql-c99.lnt b/ports/lint-plus/au-ql-c99.lnt deleted file mode 100644 index 520fe560..00000000 --- a/ports/lint-plus/au-ql-c99.lnt +++ /dev/null @@ -1,633 +0,0 @@ -// --------------------------------------------------------------------------- -// Copyright Gimpel Software LLC 2019. All rights reserved. -// -// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for -// use with PC-lint Plus. Redistribution is permitted but any redistribution -// must preserve this notice and, if the redistributed file has been modified, -// provide notice that the file has been modified from the original. -// --------------------------------------------------------------------------- - -// au-ql-c99.lnt -- Author options - QL-C99:2022 -// -// This options file contains options to help enforce the checks advocated -// by the Quantum Leaps Embedded C/C++ Coding Style (QL-C/C++:2022): -// https://github.com/QuantumLeaps/embedded-coding-style - -//========== GENERAL RULES ========== - -// 1.1 Which C? - - /* Enable C99 mode */ - -std=c99 - - /* 975 - unknown pragma will be ignored */ - +e975 - -append(975,[BARR-C:2018 Rule 1.1c]) - - /* 9051 - macro defined with the same name as a C keyword */ - +e9051 - -append(9051,[BARR-C:2018 Rule 1.1d]) - -// 1.2 Line Widths - - /* not currently supported */ - -// 1.3 Braces - - /* 9012 - body should be a compound statement */ - +e9012 - -append(9012,[BARR-C:2018 Rule 1.3a]) - -// 1.4 Parentheses - - /* 9050 - dependence placed on precedence */ - +e9050 - -append(9050,[BARR-C:2018 Rule 1.4a]) - - /* 9097 - unparenthesized argument to sizeof */ - +e9097 - -append(9097,[BARR-C:2018 Rule 1.4a]) - - /* 821 - right hand side of assignment not parenthesized */ - +e821 - -append(821,[BARR-C:2018 Rule 1.4a]) - - /* 834 - operator op1 followed by operator op2 could be confusing */ - +e834 - -append(834,[BARR-C:2018 Rule 1.4a]) - - /* 9240 - left/right side of logical operator is not a primary expression */ - +e9240 - -append(9240,[BARR-C:2018 Rule 1.4b]) - -// 1.5 Common Abbreviations - - /* not currently supported */ - -// 1.6 Casts - - /* not currently supported */ - -// 1.7 Keywords to Avoid - - /* 586 - keyword is deprecated */ - -deprecate(keyword, auto,[BARR-C:2018 Rule 1.7a]) - -deprecate(keyword, register,[BARR-C:2018 Rule 1.7b]) - -deprecate(keyword, continue,[BARR-C:2018 Rule 1.7d]) - - /* 801 - goto statement used */ - +e801 - -append(801,[BARR-C:2018 Rule 1.7c]) - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 1.7c]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 1.7c]) - -// 1.8 Keywords to Frequent - - /* 765 - external symbol could be made static */ - +e765 - -append(765,[BARR-C:2018 Rule 1.8a]) - - /* 818 - parameter of function could be pointer to const */ -//QL +e818 -//QL -append(818,[BARR-C:2018 Rule 1.8b]) - - /* 843 - static storage duration variable could be made const */ - +e843 - -append(843,[BARR-C:2018 Rule 1.8b]) - - /* 844 - static storage duration variable could be made pointer to const */ - +e844 - -append(844,[BARR-C:2018 Rule 1.8b]) - - /* 952 - parameter of function could be const */ -//QL +e952 -//QL -append(952,[BARR-C:2018 Rule 1.8b]) - - /* 953 - local variable could be const */ - +e953 - -append(953,[BARR-C:2018 Rule 1.8b]) - - /* 954 - local variable could be pointer to const */ - +e954 - -append(954,[BARR-C:2018 Rule 1.8b]) - - /* 2765 - reference to variable which is neither atomic nor volatile sig_atomic_t within signal handler */ - +e2765 - -append(2765,[BARR-C:2018 Rule 1.8c]) - -//========== COMMENTS ========== - -// 2.1 Acceptable Formats - - /* 427 - C++ comment continued via back-slash */ - +e427 - -append(427,[BARR-C:2018 Rule 2.1b]) - - /* 602 - nested block comment */ - +e602 - -append(602,[BARR-C:2018 Rule 2.1b]) - - /* 9059 - C comment contains C++ comment */ - +e9059 - -append(9059,[BARR-C:2018 Rule 2.1b]) - - // 9259 - C comment contains '://' sequence - +e9259 - -append(9259,[BARR-C:2018 Rule 2.1b]) - - /* 9066 - C++ comment contains C comment */ - +e9066 - -append(9066,[BARR-C:2018 Rule 2.1b]) - -// 2.2 Locations and Comments - - /* not statically checkable */ - -//========== WHITE SPACE RULES ========== - -// 3.1 Spaces - - /* not currently supported */ - -// 3.2 Alignment - - /* not currently supported */ - -// 3.3 Black Lines - - /* 783 - line does not end with a newline */ - +e783 - -append(783,[BARR-C:2018 Rule 3.3c]) - -// 3.4 Indentation - - /* 525 - unexpected negative indentation */ - +e525 - -append(525,[BARR-C:2018 Rule 3.4a]) - - /* 539 - unexpected positive indentation */ - +e539 - -append(539,[BARR-C:2018 Rule 3.4a]) - - /* 725 - unexpected lack of indentation */ - +e725 - -append(725,[BARR-C:2018 Rule 3.4a]) - -// 3.5 Tabs - - /* not currently supported */ - -// 3.6 Non-Printing Characters - - /* not currently supported */ - -//========== MODULE RULES ========== - -// 4.1 Naming Conventions - - /* 8516 - module name should contain only lowercase letters, numbers, and underscores */ - -hook(module_open, -cond(!('%[file_name]' ~ '^[[:lower:][:digit:]_./\\\\]+$'), - +message(8516, "module '%[file_name]' should contain only lowercase letters, numbers, and underscores"))) - +e8516 - -append(8516,[BARR-C:2018 Rule 4.1a]) - - /* 8517 - module does not end with '.c' */ - -hook(module_open, -cond(!('%[file_name]' ~ '[.]c$'), - +message(8517, "module '%[file_name]' should have '.c' extension"))) - +e8517 - -append(8517,[BARR-C:2018 Rule 4.1b]) - - /* 8518 - header does not end with '.h' */ - -hook(header_open, -cond(!('%[file_name]' ~ '[.]h$'), - +message(8517, "header '%[file_name]' should have '.h' extension"))) - +e8518 - -append(8518,[BARR-C:2018 Rule 4.1b]) - - /* 8519 - 'main' function defined in file that does not contain the word 'main' */ - -hook(func_decl, -cond('%[qual_name]' == 'main' && %[is_definition] && !('%[file]' ~ 'main'), - +message(8519, "main function defined in file '%[file]' which does not have the word 'main' in its name"))) - +e8519 - -append(8519,[BARR-C:2018 Rule 4.1d]) - -// 4.2 Header Files - - /* 451 - header file repeatedly included but has no header guard */ - +e451 - -append(451,[BARR-C:2018 Rule 4.2b]) - - /* 967 - header file does not have a standard include guard */ - +e967 - -append(967,[BARR-C:2018 Rule 4.2b]) - - /* 9107 - header cannot be included in more than one translation unit because of the definition of symbol */ - +e9107 - -append(9107,[BARR-C:2018 Rule 4.2c]) - - /* 755 - global macro not referenced */ - +e755 - -append(755,[BARR-C:2018 Rule 4.2c]) - - /* 756 - global typedef not referenced */ - +e756 - -append(756,[BARR-C:2018 Rule 4.2c]) - - /* 757 - global declarator not referenced */ - +e757 - -append(757,[BARR-C:2018 Rule 4.2c]) - - /* 758 - global tag not referenced */ - +e758 - -append(758,[BARR-C:2018 Rule 4.2c]) - - /* 759 - header declaration for symbol could be moved from header to module */ - +e759 - -append(759,[BARR-C:2018 Rule 4.2c]) - - /* 768 - global field not referenced */ - +e768 - -append(768,[BARR-C:2018 Rule 4.2c]) - - /* 769 - global enumeration constant not referenced */ - +e769 - -append(769,[BARR-C:2018 Rule 4.2c]) - -// 4.3 Source Files - - /* 9019 - declaration of symbol before #include */ - -append(9019,[BARR-C:2018 Rule 4.3b]) - - /* 8520 - #include used with absolute path */ - -hook(header_open, -cond('%[file_name]' ~ '^([[:alpha:]]:)?[/\\\\]', - +message(8520, "#include directive uses absolute path to include file '%[file_name]'"))) - +e8520 - -append(8520,[BARR-C:2018 Rule 4.3d]) - - /* 8521 - #include used to include module file */ - -hook(header_open, -cond('%[file_name]' ~ '[.]c$', - +message(8521, "#include directive used to include module file '%[file_name]'"))) - +e8521 - -append(8521,[BARR-C:2018 Rule 4.3f]) - -// 4.4 File Templates - - /* not statically checkable */ - -//========== DATA TYPE RULES ========== - -// 5.1 Naming Conventions - - /* 8526 - typedef name should consist of lowercase letters and underscores */ -//QL -hook(typename_decl, -cond(!('%[name]' ~ '^[[:lower:]_]*$'), -//QL +message(8526, "typedef name '%[name]' should consist of lowercase letters and underscores"))) -//QL +e8526 -//QL -append(8526,[BARR-C:2018 Rule 5.1a]) - - /* 8527 - typedef name should end with '_t' suffix */ -//QL -hook(typename_decl, -cond(!('%[name]' ~ '_t$'), -//QL +message(8527, "typedef name '%[name]' should end with '_t' suffix"))) -//QL +e8527 -//QL -append(8527,[BARR-C:2018 Rule 5.1a]) - - /* 8528 - non-anonymous struct/union/enum declared outside of typedef */ - -hook(record_decl, -cond(%[is_freestanding] && !%[is_anonymous], - +message(8528, "non-anonymous struct/union declared outside of a typedef"))) - -hook(enum_decl, -cond(%[is_freestanding] && '%[name]' != '', - +message(8528, "non-anonymous enum declared outside of a typedef"))) - +e8528 - -append(8528,[BARR-C:2018 Rule 5.1b]) - -// 5.2 Fixed-Width Integers - - /* 586 - keyword/type is deprecated */ - +e586 - - -deprecate(type,signed char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long long,[BARR-C:2018 Rule 5.2a]) - - -deprecate(keyword, short,[BARR-C:2018 Rule 5.2b]) - -deprecate(keyword, long,[BARR-C:2018 Rule 5.2b]) - - /* 9209 - plain character data used with prohibited operator */ -//QL +e9209 -//QL -append(9209,[BARR-C:2018 Rule 5.2c]) - -// 5.3 Signed and Unsigned Integers - - /* 9420 - bitfield does not have unsigned type */ - +e9420 - -append(9420,[BARR-C:2018 Rule 5.3a]) - - /* 9130 - bitwise operator applied to signed underlying type */ - +e9130 - -append(9130,[BARR-C:2018 Rule 5.3b]) - - /* 570 - negative value loses sign during implicit conversion */ - +e570 - -append(570,[BARR-C:2018 Rule 5.3c]) - - /* 713 - implicit conversion from unsigned to signed may lose precision */ - +e713 - -append(713,[BARR-C:2018 Rule 5.3c]) - - /* 8524 - combining signed and unsigned types with operator op1 */ - -hook(binary_expr, -cond(%[walk_lhs_expr{false}.walk_type.is_integer] && - %[walk_rhs_expr{false}.walk_type.is_integer] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - '%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]' != - '%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]', - +message(8524, "combining signed and unsigned types with operator '%[opcode]'"))) - +e8524 - -append(8524,[BARR-C:2018 Rule 5.3c]) - -// 5.4 Floating Point - - /* 586 - type is deprecated */ - -deprecate(type,float,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,double,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,long double,[BARR-C:2018 Rule 5.4b]) - - /* 777 - testing floating point values for equality */ - +e777 - -append(777,[BARR-C:2018 Rule 5.4b]) - - /* 9252 - testing floating point for equality using exact value */ - +e9252 - -append(9252,[BARR-C:2018 Rule 5.4b]) - -// 5.5 Structures and Unions - - /* not currently supported */ - -// 5.6 Booleans - - /* 8523 - cast to boolean */ - -hook(cast_expr, -cond(%[is_cstyle_cast] && %[walk_type.is_boolean], - +message(8523, "cast to boolean"))) - +e8523 - -append(8523,[BARR-C:2018 Rule 5.6b]) - -//========== PROCEDURE RULES ========== - -// 6.1 Naming Conventions - - /* 8501 - function has name that matches a keyword in C or C++ */ - -hook(func_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8501, "function '%[name]' matches the name of a C/C++ keyword"))) - +e8501 - -append(8501,[BARR-C:2018 Rule 6.1a]) - - /* 8502 - function has same name as standard library function */ - -hook(func_decl, -cond('%[name]' ~ '^(?:abort|abs|acos|acosf|acosh|acoshf|acoshl|acosl|asctime|asin|asinf|asinh|asinhf|asinhl|asinl|assert|atan|atan2|atan2f|atan2l|atanf|atanh|atanhf|atanhl|atanl|atexit|atof|atoi|atol|atoll|bsearch|btowc|cabs|cabsf|cabsl|cacos|cacosf|cacosh|cacoshf|cacoshl|cacosl|calloc|carg|cargf|cargl|casin|casinf|casinh|casinhf|casinhl|casinl|catan|catanf|catanh|catanhf|catanhl|catanl|cbrt|cbrtf|cbrtl|ccos|ccosf|ccosh|ccoshf|ccoshl|ccosl|ceil|ceilf|ceill|cexp|cexpf|cexpl|cimag|cimagf|cimagl|clearerr|clock|clog|clogf|clogl|conj|conjf|conjl|copysign|copysignf|copysignl|cos|cosf|cosh|coshf|coshl|cosl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|creal|crealf|creall|csin|csinf|csinh|csinhf|csinhl|csinl|csqrt|csqrtf|csqrtl|ctan|ctanf|ctanh|ctanhf|ctanhl|ctanl|ctime|difftime|div|erf|erfc|erfcf|erfcl|erff|erfl|exit|_Exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|fabs|fabsf|fabsl|fclose|fdim|fdimf|fdiml|feclearexcept|fegetenv|fegetexceptflag|fegetround|feholdexcept|feof|feraiseexcept|ferror|fesetenv|fesetexceptflag|fesetround|fetestexcept|feupdateenv|fflush|fgetc|fgetpos|fgets|fgetwc|fgetws|floor|floorf|floorl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|fmin|fminf|fminl|fmod|fmodf|fmodl|fopen|fpclassify|fprintf|fputc|fputs|fputwc|fputws|fread|free|freopen|frexp|frexpf|frexpl|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|getc|getchar|getenv|gets|getwc|getwchar|gmtime|hypot|hypotf|hypotl|ilogb|ilogbf|ilogbl|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless|islessequal|islessgreater|islower|isnan|isnormal|isprint|ispunct|isspace|isunordered|isupper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|iswlower|iswprint|iswpunct|iswspace|iswupper|iswxdigit|isxdigit|labs|ldexp|ldexpf|ldexpl|ldiv|lgamma|lgammaf|lgammal|llabs|lldiv|llrint|llrintf|llrintl|llround|llroundf|llroundl|localeconv|localtime|log|log10|log10f|log10l|log1p|log1pf|log1pl|log2|log2f|log2l|logb|logbf|logbl|logf|logl|longjmp|lrint|lrintf|lrintl|lround|lroundf|lroundl|malloc|mblen|mbrlen|mbrtowc|mbsinit|mbsrtowcs|mbstowcs|mbtowc|memchr|memcmp|memcpy|memmove|memset|mktime|modf|modff|modfl|nan|nanf|nanl|nearbyint|nearbyintf|nearbyintl|nextafter|nextafterf|nextafterl|nexttoward|nexttowardf|nexttowardl|perror|pow|powf|powl|printf|putc|putchar|puts|putwc|putwchar|qsort|raise|rand|realloc|remainder|remainderf|remainderl|remove|remquo|remquof|remquol|rename|rewind|rint|rintf|rintl|round|roundf|roundl|scalbln|scalblnf|scalblnl|scalbn|scalbnf|scalbnl|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sin|sinf|sinh|sinhf|sinhl|sinl|snprintf|sprintf|sqrt|sqrtf|sqrtl|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strtod|strtof|strtoimax|strtok|strtol|strtold|strtoll|strtoul|strtoull|strtoumax|strxfrm|swprintf|swscanf|system|tan|tanf|tanh|tanhf|tanhl|tanl|tgamma|tgammaf|tgammal|time|tmpfile|tmpnam|tolower|toupper|towctrans|towlower|towupper|trunc|truncf|truncl|ungetc|ungetwc|va_arg|va_copy|va_end|va_start|vfprintf|vfscanf|vfwprintf|vfwscanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcstod|wcstof|wcstoimax|wcstok|wcstol|wcstold|wcstoll|wcstombs|wcstoul|wcstoull|wcstoumax|wcsxfrm|wctob|wctomb|wctrans|wctype|wmemchr|wmemcmp|wmemcpy|wmemmove|wmemset|wprintf|wscanf)$', +message(8502, "function '%[name]' matches the name of a standard library function"))) - +e8502 - -append(8502,[BARR-C:2018 Rule 6.1b]) - - /* 8503 - function has name that begins with an underscore */ - -hook(func_decl, -cond('%[name]' ~ '^_', +message(8503, "function '%[name]' begins with an underscore"))) - +e8503 - -append(8503,[BARR-C:2018 Rule 6.1c]) - - /* 8504 - function name is longer than 31 characters */ - -hook(func_decl, -cond('%[name]' ~ '.{32,}', +message(8504, "function '%[name]' is longer than 31 characters"))) - +e8504 - -append(8504,[BARR-C:2018 Rule 6.1d]) - - /* 8505 - function name contains upper case letter(s) */ -//QL -hook(func_decl, -cond('%[name]' ~ '[[:upper:]]', +message(8505, "function '%[name]' contains uppercase letters"))) -//QL +e8505 -//QL -append(8505,[BARR-C:2018 Rule 6.1e]) - - /* 8506 - macro name contains lowercase letter(s) */ - -hook(macro_define, -cond(!%[is_builtin] && '%[name]' ~ '[[:lower:]]', +message(8506, "macro '%[name]' contains lowercase letters"))) - +e8506 - -append(8506,[BARR-C:2018 Rule 6.1f]) - -// 6.2 Functions - - /* 904 - return statement before end of function */ - +e904 - -append(904,[BARR-C:2018 Rule 6.2c]) - - /* 937 - old-style function declaration for function */ - +e937 - -append(937,[BARR-C:2018 Rule 6.2f]) - - /* 957 - function defined without a prototype in scope */ - +e957 - -append(957,[BARR-C:2018 Rule 6.2f]) - - /* 832 - parameter not explicitly declared, int assumed */ - +e832 - -append(832,[BARR-C:2018 Rule 6.2f]) - -// 6.3 Function-Like Macros - - /* 9026 - function-like macro defined */ - +e9026 - -append(9026,[BARR-C:2018 Rule 6.3a]) - - /* 665 - unparenthesized parameter in macro is passed an expression */ - +e665 - -append(665,[BARR-C:2018 Rule 6.3b]) - - /* 666 - expression with side effects passed to repeated parameter */ - +e666 - -append(666,[BARR-C:2018 Rule 6.3b]) - - /* 773 - expression-like macro not parenthesized */ - +e773 - -append(773,[BARR-C:2018 Rule 6.3b]) - - /* 9022 - unparenthesized macro parameter in definition of macro */ - +e9022 - -append(9022,[BARR-C:2018 Rule 6.3b]) - -// 6.4 Threads of Execution - - /* not currently supported */ - -// 6.5 Interrupt Service Routines - - /* not currently supported */ - -//========== VARIABLES ========== - -// 7.1 Naming Conventions - - /* 8507 - variable has name that matches a keyword in C or C++ */ - -hook(var_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|fortran|friend|goto|if|inline|int|interrupt|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8507, "variable '%[name]' matches the name of a C/C++ keyword"))) - +e8507 - -append(8507,[BARR-C:2018 Rule 7.1a]) - - /* 8525 - variable has same name as standard library variable */ - -hook(var_decl, -cond('%[name]' ~ '^(?:errno|stderr|stdin|stdout)$', - +message(8525, "variale '%[name]' matches the same name of a standard library variable"))) - +e8525 - -append(8525,[BARR-C:2018 Rule 7.1b]) - - /* 8508 - variable has name that begins with an underscore */ - -hook(var_decl, -cond('%[name]' ~ '^_', +message(8508, "variable '%[name]' begins with an underscore"))) - +e8508 - -append(8508,[BARR-C:2018 Rule 7.1c]) - - /* 8509 - variable name is longer than 31 characters */ - -hook(var_decl, -cond('%[name]' ~ '.{32,}', +message(8509, "variable '%[name]' is longer than 31 characters"))) - +e8509 - -append(8509,[BARR-C:2018 Rule 6.1d]) - - /* 8510 - variable name contains less than 3 characters */ -//QL -hook(var_decl, -cond('%[name]' ~ '^.{1,2}$', +message(8510, "variable '%[name]' contains less than 3 characters"))) -//QL +e8510 -//QL -append(8510,[BARR-C:2018 Rule 7.1e]) - - /* 8511 - variable name contains upper case letter(s) */ -//QL -hook(var_decl, -cond('%[name]' ~ '[[:upper:]]', +message(8511, "variable '%[name]' contains uppercase letters"))) -//QL +e8511 -//QL -append(8511,[BARR-C:2018 Rule 7.1f]) - - /* 8512 - global variable must start with 'g' */ -//QL -hook(var_decl, -cond('%[linkage]' == 'external' && !('%[name]' ~ '^g'), +message(8512, "global variable '%[name]' should have 'g' prefix"))) -//QL +e8512 -//QL -append(8512,[BARR-C:2018 Rule 7.1j]) - - /* 8513 - variable of pointer type should have 'p' prefix */ - /* 8514 - variable of pointer type should have 'pp' prefix */ -//QL -hook(var_decl, -cond('%[walk_type.is_pointer]' == 'true', -//QL -cond('%[walk_type.walk_pointee.is_pointer]' == 'true', -//QL -cond(!('%[name]' ~ '^g?pp'), +message(8513, "variable '%[name]' of type '%[walk_type.as_string]' should have 'pp' prefix")), -//QL -cond(!('%[name]' ~ '^g?p'), +message(8514, "variable '%[name]' of type '%[walk_type.as_string]' should have 'p' prefix")) -//QL ))) -//QL +e8513 -//QL +e8514 -//QL -append(8513,[BARR-C:2018 Rule 7.1k]) -//QL -append(8514,[BARR-C:2018 Rule 7.1l]) - - /* 8515 - boolean variable should have 'b' prefix */ -//QL -hook(var_decl, -cond('%[walk_type.is_boolean]' == 'true' && !('%[name]' ~ '^g?b'), +message(8515, "boolean variable '%[name]' should have 'b' prefix"))) -//QL +e8515 -//QL -append(8515,[BARR-C:2018 Rule 7.1m]) - -// 7.2 Initialization - - /* 530 - likely using an uninitialized value */ - +e530 - -append(530,[BARR-C:2018 Rule 7.2a]) - - /* 603 - argument to parameter of type pointer to const may be a pointer to uninitialized memory */ - +e603 - -append(603,[BARR-C:2018 Rule 7.2a]) - - /* 644 - potentially using an uninitialized value */ - +e644 - -append(644,[BARR-C:2018 Rule 7.2a]) - - /* 708 - union initialization */ - +e708 - -append(708,[BARR-C:2018 Rule 7.2a]) - - /* 727 - static local symbol not explicitly initialized */ - +e727 - -append(727,[BARR-C:2018 Rule 7.2a]) - - /* 728 - file scope static variable not explicitly initialized */ - +e728 - -append(728,[BARR-C:2018 Rule 7.2a]) - - /* 729 - external variable not explicitly initialized */ - +e729 - -append(729,[BARR-C:2018 Rule 7.2a]) - - /* 738 - address of static local symbol not explicitly initialized before passed to a function */ - +e738 - -append(738,[BARR-C:2018 Rule 7.2a]) - - /* 784 - nul character truncated from string */ - +e784 - -append(784,[BARR-C:2018 Rule 7.2a]) - - /* 785 - too few initializers for aggregate */ - +e785 - -append(785,[BARR-C:2018 Rule 7.2a]) - -//========== STATEMENT RULES ========== - -// 8.1 Variable Declarations - - /* 9146 - multiple declarators in a declaration */ - +e9146 - -append(9146,[BARR-C:2018 Rule 8.1a]) - -// 8.2 Conditional Statements - - /* 720 - boolean test of assignment */ - +e720 - -append(720,[BARR-C:2018 Rule 8.2c]) - - /* 820 - boolean test of parenthesized assignment */ - +e820 - -append(820,[BARR-C:2018 Rule 8.2c]) - - /* 9013 - no 'else' at end of 'if ... else if' chain */ - +e9013 - -append(9013,[BARR-C:2018 Rule 8.2d]) - -// 8.3 Switch Statements - - /* 9014 - switch without default */ - +e9014 - -append(9014,[BARR-C:2018 Rule 8.3b]) - - /* 616 - control flow falls through to next case without an intervening comment */ - +e616 - -append(616,[BARR-C:2018 Rule 8.3c]) - -// 8.4 Loops - - /* 850 - for statement index variable modified in body */ - +e850 - -append(850,[BARR-C:2018 Rule 8.4b]) - - /* 716 - infinite loop via while */ - +e716 - -append(716,[BARR-C:2018 Rule 8.4c]) - -// 8.5 Jumps - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 8.5a]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 8.5a]) - - /* 586 - function/macro is deprecated */ - -deprecate(function,abort,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,exit,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,longjmp,[BARR-C:2018 Rule 8.5b]) - -deprecate(macro,setjmp,[BARR-C:2018 Rule 8.5b]) - -// 8.6 Equivalence Test - - /* 8522 - variable should appear on RHS of '==' operator */ -//QL -hook(binary_expr, -cond('%[opcode]' == '==' && -//QL '%[walk_lhs_expr.walk_past_paren_cast.set_msg_loc.is_decl_ref_expr]' == 'true' && -//QL '%[walk_rhs_expr.is_constant_expr]' == 'true', -//QL +message(8522, "variable '%[walk_lhs_expr.walk_past_paren_cast.walk_decl.qual_name]' should appear on RHS of '==' operator"))) -//QL +e8522 -//QL -append(8522,[BARR-C:2018 Rule 8.6a]) diff --git a/ports/lint-plus/make.bat b/ports/lint-plus/make.bat deleted file mode 100644 index eff2d164..00000000 --- a/ports/lint-plus/make.bat +++ /dev/null @@ -1,69 +0,0 @@ -@echo off -:: =========================================================================== -:: Batch script for linting QP/C with PC-Lint-Plus2 -:: Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -:: -:: SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -:: -:: This software is dual-licensed under the terms of the open source GNU -:: General Public License version 3 (or any later version), or alternatively, -:: under the terms of one of the closed source Quantum Leaps commercial -:: licenses. -:: -:: The terms of the open source GNU General Public License version 3 -:: can be found at: -:: -:: The terms of the closed source Quantum Leaps commercial licenses -:: can be found at: -:: -:: Redistributions in source code must retain this top-level comment block. -:: Plagiarizing this software to sidestep the license obligations is illegal. -:: -:: Contact information: -:: -:: -:: =========================================================================== -@setlocal - -:: usage of make.bat -@echo Usage: make [16bit] [-u...] files -@echo examples: -@echo make -uQ_SPY -uQ_UTEST : use 32bit CPU (default) and undefine Q_SPY/Q_UTEST -@echo make 16bit -uQ_SPY : use 16bit CPU includes and undefine Q_SPY -@echo. - -:: NOTE: adjust to for your installation directory of PC-Lint-Plus -@set PCLP=C:\tools\lint-plus2\windows\pclp64.exe - -if NOT exist "%PCLP%" ( - @echo The PC-Lint-Plus toolset not found. Please adjust make.bat - @goto end -) - -:: set the QP/C directory -@set QPC=..\.. - -if "%1"=="16bit" ( - set LINTFLAGS=-i16bit options.lnt %2 %3 %4 - @echo 16bit CPU -) else ( - set LINTFLAGS=-i32bit options.lnt %1 %2 %3 %4 - @echo 32bit CPU default -) - -:: cleanup -@del *.log - -:: linting ------------------------------------------------------------------- -%PCLP% -os(lint_qf.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qf\*.c - -%PCLP% -os(lint_qv.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qv\*.c - -%PCLP% -os(lint_qk.log) std.lnt %LINTFLAGS% -iqk ..\..\src\qk\*.c - -%PCLP% -os(lint_qxk.log) std.lnt %LINTFLAGS% -iqxk ..\..\src\qxk\*.c - -%PCLP% -os(lint_qs.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qs\*.c - -:end -@endlocal diff --git a/ports/lint-plus/options.lnt b/ports/lint-plus/options.lnt deleted file mode 100644 index 977f0c9b..00000000 --- a/ports/lint-plus/options.lnt +++ /dev/null @@ -1,363 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-14 -//! @version Last updated for version: 7.3.4 -//! -//! @file -//! @brief PC-Lint-Plus option file for linting QP/C source code - -//============================================================================ -// general options --unit_check // perform only subset check (suppresses Global Wrapup) --max_threads=1 // suppress message "no '-max_threads=N' option" -++efreeze(686) // never suppress (see PC-Lint-Plus in Safety-Critical) -//-vf // print names of all source files (for debugging linting) - -// include directories --i. // QP/C port includes (see also qk/ and qv/) --i%QPC%/include // QP/C public includes - -// standards -// language standard... -au-misra4.lnt // MISRA-C:2023 (MC4) compliance - -// customized BARR-C:2018 style guidelines -au-barr.lnt // BARR-C:2018 style guidelines --e8505 // suppress [Rule 6.1e] function contains uppercase letters --e8511 // suppress [Rule 7.1f] variable contains uppercase letters --e8512 // suppress [Rule 7.1j] global variable should have 'g' prefix --e8510 // suppress [Rule 7.1e] variable contains less than 3 characters --e8513 // suppress [Rule 7.1k] variable should have 'pp' prefix --e8514 // suppress [Rule 7.1l] variable should have 'p' prefix --e8515 // suppress [Rule 7.1m] boolean variable should have 'b' prefix --e8526 // suppress [Rule 5.1a] typedef name should consist of lowercase letters --e8527 // suppress [Rule 5.1a] typedef name should end with '_t' suffix --e9209 // suppress [Rule 5.2c] plain char data used with prohibited operator & --e8522 // suppress [Rule 8.6a] variable should appear on RHS of '==' operator - -au-ds.lnt // Dan Saks recommendations -cpu.lnt // size/alignment options for the chosen CPU - -// defined macros (might be undefined on command-line with -u) --dQ_SPY --dQ_UTEST - -//============================================================================ -// QP/C options for QP/C Applications -qpc.lnt // QP/C options - -//============================================================================ -// additional suppression rules for building QP/C source code... - -// QEP ----------------------------------------------------------------------- - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QACTIVE_CAST_) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09B} --esym(9026, - QHSM_RESERVED_EVT_, - QS_STATE_ENTRY_, - QS_STATE_EXIT_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer -//! @tr{DVR-QP-MC4-R11_05} --emacro(9079, - Q_EVT_CAST) - -//! M4-R8.13(A) parameter of function could be pointer to const -//! @tr{DVR-QP-MC4-R08_13} --efunc(818, - QMsm_isIn_) - -// QF ------------------------------------------------------------------------ - -//! M4-D4.8(A) complete definition is unnecessary in this translation unit -//! @tr{DVP-QP-MC4-D04_08} --efile(9045, - -qp_pkg.h) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QF_CRIT_ENTRY, - QF_CRIT_EXIT, - Q_ASSERT_INCRIT, - Q_REQUIRE_INCRIT, - Q_ENSURE_INCRIT, - Q_INVARIANT_INCRIT, - Q_ERROR_INCRIT, - QF_SCHED_LOCK_, - QF_SCHED_UNLOCK_, - QF_ISR_CONTEXT_, - QF_MPOOL_EL, - Q_UINTPTR_CAST_) - -//! M4-R8.13(A) parameter of function could be pointer to const -//! @tr{DVR-QP-MC4-R08_13} --efunc(818, - QActive_start_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - QACTIVE_CAST_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVP-QP-MC4-R11_03B} --efunc(9087, - QActive_ctor, - QMActive_ctor) - -//! M4-R11.4(A) conversion between object pointer type and integer type -//! @tr{DVR-QP-MC4-R11_04} --emacro(9078, - Q_UINTPTR_CAST_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer type -//! @tr{DVR-QP-MC4-R11_05} --emacro(9079, - QACTIVE_CAST_, - QF_EPOOL_GET_) --efunc(9079, - QF_bzero_, - QF_deleteRef_, - QMPool_get, - QMPool_put, - QMPool_init, - QTimeEvt_tick_, - QTimeEvt_armX, - QTimeEvt_rearm) - -//! M4-R11.8(R) cast drops const qualifier -//! @tr{DVR-QP-MC4-R11_08} --emacro(9005, - QACTIVE_CAST_) --efunc(9005, - QEvt_refCtr_inc_, - QEvt_refCtr_dec_, - QF_gc) - -//! M4-R15.5(A) return statement before end of function -//! @tr{DVP-QS-MC4-R15_05} --efunc(904, - QActive_post_, - QActive_postLIFO_) - -//! M4-R18.3(R) relational operator <= applied to pointers -//! @tr{DVR-QP-MC4-R18_03} --efunc(946, - QMPool_get, - QMPool_put) - -//! definition of macro ends in semicolon -//! @tr{DVR-QP-PCLP-823} --esym(823, - QF_CRIT_STAT, - QF_SCHED_STAT_) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVP-QP-PCLP-826} --emacro(826, - QACTIVE_CAST_) - - -// QV ------------------------------------------------------------------------ - -// QK ------------------------------------------------------------------------ - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QK_ISR_CONTEXT_, - QK_ISR_ENTRY, - QK_ISR_EXIT) - -// QXK ----------------------------------------------------------------------- - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QXK_ISR_CONTEXT_, - QXK_CONTEXT_SWITCH_, - QXK_PTR_CAST_, - QXTHREAD_CAST_, - QXTHREAD_EQUEUE_SIGNAL_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - QXTHREAD_CAST_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVR-QP-MC4-R11_03C} --emacro(9087, - QXK_PTR_CAST_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer type -//! @tr{DVR-QP-MC4-R11_05} --emacro(9079, - QXK_PTR_CAST_) - -//! MC3-R8.13(A) could be pointer to const -//! @tr{DVR-QP-MC4-R08_13} --efunc(818, - QXThread_init_, - QXThread_dispatch_, - QXThread_postLIFO_) - -//! @tr{DVP-QP-PCLP-826} --emacro(826, - QXK_PTR_CAST_, - QXTHREAD_CAST_) - -//! cast increases required alignment from 2 to 4 -//! @tr{DVR-QP-PCLP-2445} --emacro(2445, - QXK_PTR_CAST_) - -// QS ------------------------------------------------------------------------ -// the following options are needed only when Q_SPY is defined... - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QS-MC4-D04_09A} --esym(9026, - QS_INSERT_BYTE_, - QS_INSERT_ESC_BYTE_, - QS_RX_TRAN_, - QS_CRIT_ENTRY, - QS_CRIT_EXIT) - -//! M4-R8.13(A) parameter ... of function could be pointer to const -//! @tr{DVR-QS-MC4-R08_13} --efunc(818, - QHsmDummy_init_, - QHsmDummy_dispatch_, - QActiveDummy_start_, - QActiveDummy_init_, - QActiveDummy_dispatch_) - -//! M4-R11.1(R) conversion between pointer to function and differing type -//! @tr{DVP-QS-MC4-R11_01} --emacro(9074, - QS_FUN_PRE_) --efunc(9074, - QS_getTestProbe_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVR-QS-MC4-R11_03C} --efile(9087, - -qs_rx.c, - -qutest.c) - -//! M4-R11.4(A) conversion between object pointer type and integer type -//! @tr{DVR-QS-MC4-R11_04} --emacro(9078, - QS_OBJ_PRE_, - QS_FUN_PRE_) --efunc(9078, - QS_rxHandleGoodFrame_, - QS_getTestProbe_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer type -//! @tr{DVR-QS-MC4-R11_05} --efile(9079, - -qs_rx.c, - -qutest.c) - -//! M4-R11.6(R) explicit cast from integer to 'void *' -//! @tr{DVR-QS-MC4-R11_06} --emacro(923, - QS_OBJ_PRE_, - QS_FUN_PRE_) --efunc(923, - QS_rxHandleGoodFrame_, - QS_getTestProbe_) - -//! M4-R14.3(R) boolean condition for 'if' always evaluates to 'false' -//! @tr{DVR-QS-MC4-R14_03} --emacro(774, - QS_BEGIN_PRE_) - -//! M4-R19.2(A) union declared -//! @tr{DVR-QS-MC4-R19_02} --efunc(9018, - QS_target_info_pre_, - QS_f32_fmt_, - QS_f64_fmt_) - -//! constant value used in Boolean context (left operand to || operator) -//! @tr{DVR-QS-PCLP-506} --emacro(506, - QS_BEGIN_PRE_) - -//! excessive shift value (precision 0 shifted right by ...) -//! @tr{DVR-QS-PCLP-572} --emacro(572, - QS_BEGIN_PRE_) - -//! union initialization -//! @tr{DVR-QS-PCLP-708} --efunc(708, - QS_f64_fmt_) - -//! union member not referenced -//! @tr{DVR-QS-PCLP-754} --esym(754, - Variant::aFlt, - AFltVar::prio, - *U32Rep::u32) - -//! Constant expression evaluates to 0 in 'binary' operation '>>' -//! @tr{DVR-QS-PCLP-778} --emacro(778, - QS_BEGIN_PRE_) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVR-QS-PCLP-818} --efile(826, - -qs_rx.c, - -qutest.c) - -//! definition of macro ends in semicolon -//! @tr{DVR-QS-PCLP-823} --esym(823, - QS_CRIT_STAT, - QS_BEGIN_PRE_) - -//! the right operand to << always evaluates to 0 -//! @tr{DVR-QS-PCLP-845} --emacro(845, - QS_BEGIN_PRE_) - -//! cast increases required alignment -//! @tr{DVP-QS-PCLP-2445} --efunc(2445, - QS_rxHandleGoodFrame_, - QS_rxPoke_) - diff --git a/ports/lint-plus/qk/qp_port.h b/ports/lint-plus/qk/qp_port.h deleted file mode 100644 index 1ec29dc2..00000000 --- a/ports/lint-plus/qk/qp_port.h +++ /dev/null @@ -1,94 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QP/C "port" to PC-Lint-Plus, QK kernel, generic C99 - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QF configuration for QK -- data members of the QActive class... - -// QK event-queue used for AOs -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QF "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// interrupt disabling mechanism -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -// QF critical section mechanism -#define QF_CRIT_STAT uint32_t crit_stat_; -#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) -#define QF_CRIT_EXIT() critExit(crit_stat_) - -// Check if the code executes in the ISR context -#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U) - -// Define the ISR entry sequence -#define QK_ISR_ENTRY() ((void)0) - -// Define the ISR exit sequence -#define QK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ -} while (false) - -void intDisable(void); -void intEnable(void); -uint32_t critEntry(void); -void critExit(uint32_t stat); -uint32_t QK_get_IPSR(void); - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QK kernel uses the native QP event queue -#include "qmpool.h" // QK kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qk.h" // QK kernel - -#endif // QP_PORT_H_ - diff --git a/ports/lint-plus/ql-style.lnt b/ports/lint-plus/ql-style.lnt deleted file mode 100644 index c4e6efaa..00000000 --- a/ports/lint-plus/ql-style.lnt +++ /dev/null @@ -1,562 +0,0 @@ -// --------------------------------------------------------------------------- -// Copyright Gimpel Software LLC 2019. All rights reserved. -// -// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for -// use with PC-lint Plus. Redistribution is permitted but any redistribution -// must preserve this notice and, if the redistributed file has been modified, -// provide notice that the file has been modified from the original. -// --------------------------------------------------------------------------- - -// Adapted by Quantum Leaps from au-barr.lnt -// -// ql-style.lnt.lnt -- Author options - Quantum-Leaps:2018 -// -// This options file contains options to help enforce the -// checks advocated by the Quantum Leaps Coding Standard -// https://barrgroup.com/Embedded-Systems/Books/Embedded-C-Coding-Standard - -//========== GENERAL RULES ========== - -// 1.2 Line Widths - - /* not currently supported */ - -// 1.3 Braces - - /* 9012 - body should be a compound statement */ - +e9012 - -append(9012,[BARR-C:2018 Rule 1.3a]) - -// 1.4 Parentheses - - /* 9050 - dependence placed on precedence */ - +e9050 - -append(9050,[BARR-C:2018 Rule 1.4a]) - - /* 9097 - unparenthesized argument to sizeof */ - +e9097 - -append(9097,[BARR-C:2018 Rule 1.4a]) - - /* 821 - right hand side of assignment not parenthesized */ - +e821 - -append(821,[BARR-C:2018 Rule 1.4a]) - - /* 834 - operator op1 followed by operator op2 could be confusing */ - +e834 - -append(834,[BARR-C:2018 Rule 1.4a]) - - /* 9240 - left/right side of logical operator is not a primary expression */ - +e9240 - -append(9240,[BARR-C:2018 Rule 1.4b]) - -// 1.5 Common Abbreviations - - /* not currently supported */ - -// 1.6 Casts - - /* not currently supported */ - -// 1.7 Keywords to Avoid - - /* 586 - keyword is deprecated */ - -deprecate(keyword, auto,[BARR-C:2018 Rule 1.7a]) - -deprecate(keyword, register,[BARR-C:2018 Rule 1.7b]) - -deprecate(keyword, continue,[BARR-C:2018 Rule 1.7d]) - - /* 801 - goto statement used */ - +e801 - -append(801,[BARR-C:2018 Rule 1.7c]) - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 1.7c]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 1.7c]) - -// 1.8 Keywords to Frequent - - /* 765 - external symbol could be made static */ - +e765 - -append(765,[BARR-C:2018 Rule 1.8a]) - - /* 818 - parameter of function could be pointer to const */ - +e818 - -append(818,[BARR-C:2018 Rule 1.8b]) - - /* 843 - static storage duration variable could be made const */ - +e843 - -append(843,[BARR-C:2018 Rule 1.8b]) - - /* 844 - static storage duration variable could be made pointer to const */ - +e844 - -append(844,[BARR-C:2018 Rule 1.8b]) - - /* 952 - parameter of function could be const */ - +e952 - -append(952,[BARR-C:2018 Rule 1.8b]) - - /* 953 - local variable could be const */ - +e953 - -append(953,[BARR-C:2018 Rule 1.8b]) - - /* 954 - local variable could be pointer to const */ - +e954 - -append(954,[BARR-C:2018 Rule 1.8b]) - - /* 2765 - reference to variable which is neither atomic nor volatile sig_atomic_t within signal handler */ - +e2765 - -append(2765,[BARR-C:2018 Rule 1.8c]) - -//========== COMMENTS ========== - -// 2.1 Acceptable Formats - - /* 427 - C++ comment continued via back-slash */ - +e427 - -append(427,[BARR-C:2018 Rule 2.1b]) - - /* 602 - nested block comment */ - +e602 - -append(602,[BARR-C:2018 Rule 2.1b]) - - /* 9059 - C comment contains C++ comment */ - +e9059 - -append(9059,[BARR-C:2018 Rule 2.1b]) - - // 9259 - C comment contains '://' sequence - +e9259 - -append(9259,[BARR-C:2018 Rule 2.1b]) - - /* 9066 - C++ comment contains C comment */ - +e9066 - -append(9066,[BARR-C:2018 Rule 2.1b]) - -// 2.2 Locations and Comments - - /* not statically checkable */ - -//========== WHITE SPACE RULES ========== - -// 3.1 Spaces - - /* not currently supported */ - -// 3.2 Alignment - - /* not currently supported */ - -// 3.3 Black Lines - - /* 783 - line does not end with a newline */ - +e783 - -append(783,[BARR-C:2018 Rule 3.3c]) - -// 3.4 Indentation - - /* 525 - unexpected negative indentation */ - +e525 - -append(525,[BARR-C:2018 Rule 3.4a]) - - /* 539 - unexpected positive indentation */ - +e539 - -append(539,[BARR-C:2018 Rule 3.4a]) - - /* 725 - unexpected lack of indentation */ - +e725 - -append(725,[BARR-C:2018 Rule 3.4a]) - -// 3.5 Tabs - - /* not currently supported */ - -// 3.6 Non-Printing Characters - - /* not currently supported */ - -//========== MODULE RULES ========== - -// 4.1 Naming Conventions - - /* 8517 - module does not end with '.c' */ - -hook(module_open, -cond(!('%[file_name]' ~ '[.]c$'), - +message(8517, "module '%[file_name]' should have '.c' extension"))) - +e8517 - -append(8517,[BARR-C:2018 Rule 4.1b]) - - /* 8518 - header does not end with '.h' */ - -hook(header_open, -cond(!('%[file_name]' ~ '[.]h$'), - +message(8517, "header '%[file_name]' should have '.h' extension"))) - +e8518 - -append(8518,[BARR-C:2018 Rule 4.1b]) - - /* 8519 - 'main' function defined in file that does not contain the word 'main' */ - -hook(func_decl, -cond('%[qual_name]' == 'main' && %[is_definition] && !('%[file]' ~ 'main'), - +message(8519, "main function defined in file '%[file]' which does not have the word 'main' in its name"))) - +e8519 - -append(8519,[BARR-C:2018 Rule 4.1d]) - -// 4.2 Header Files - - /* 451 - header file repeatedly included but has no header guard */ - +e451 - -append(451,[BARR-C:2018 Rule 4.2b]) - - /* 967 - header file does not have a standard include guard */ - +e967 - -append(967,[BARR-C:2018 Rule 4.2b]) - - /* 9107 - header cannot be included in more than one translation unit because of the definition of symbol */ - +e9107 - -append(9107,[BARR-C:2018 Rule 4.2c]) - - /* 755 - global macro not referenced */ - +e755 - -append(755,[BARR-C:2018 Rule 4.2c]) - - /* 756 - global typedef not referenced */ - +e756 - -append(756,[BARR-C:2018 Rule 4.2c]) - - /* 757 - global declarator not referenced */ - +e757 - -append(757,[BARR-C:2018 Rule 4.2c]) - - /* 758 - global tag not referenced */ - +e758 - -append(758,[BARR-C:2018 Rule 4.2c]) - - /* 759 - header declaration for symbol could be moved from header to module */ - +e759 - -append(759,[BARR-C:2018 Rule 4.2c]) - - /* 768 - global field not referenced */ - +e768 - -append(768,[BARR-C:2018 Rule 4.2c]) - - /* 769 - global enumeration constant not referenced */ - +e769 - -append(769,[BARR-C:2018 Rule 4.2c]) - -// 4.3 Source Files - - /* 9019 - declaration of symbol before #include */ - -append(9019,[BARR-C:2018 Rule 4.3b]) - - /* 8520 - #include used with absolute path */ - -hook(header_open, -cond('%[file_name]' ~ '^([[:alpha:]]:)?[/\\\\]', - +message(8520, "#include directive uses absolute path to include file '%[file_name]'"))) - +e8520 - -append(8520,[BARR-C:2018 Rule 4.3d]) - - /* 8521 - #include used to include module file */ - -hook(header_open, -cond('%[file_name]' ~ '[.]c$', - +message(8521, "#include directive used to include module file '%[file_name]'"))) - +e8521 - -append(8521,[BARR-C:2018 Rule 4.3f]) - -// 4.4 File Templates - - /* not statically checkable */ - -//========== DATA TYPE RULES ========== - - /* 8528 - non-anonymous struct/union/enum declared outside of typedef */ - -hook(record_decl, -cond(%[is_freestanding] && !%[is_anonymous], - +message(8528, "non-anonymous struct/union declared outside of a typedef"))) - -hook(enum_decl, -cond(%[is_freestanding] && '%[name]' != '', - +message(8528, "non-anonymous enum declared outside of a typedef"))) - +e8528 - -append(8528,[BARR-C:2018 Rule 5.1b]) - -// 5.2 Fixed-Width Integers - - /* 586 - keyword/type is deprecated */ - +e586 - - -deprecate(type,signed char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long long,[BARR-C:2018 Rule 5.2a]) - - -deprecate(keyword, short,[BARR-C:2018 Rule 5.2b]) - -deprecate(keyword, long,[BARR-C:2018 Rule 5.2b]) - -// 5.3 Signed and Unsigned Integers - - /* 9420 - bitfield does not have unsigned type */ - +e9420 - -append(9420,[BARR-C:2018 Rule 5.3a]) - - /* 9130 - bitwise operator applied to signed underlying type */ - +e9130 - -append(9130,[BARR-C:2018 Rule 5.3b]) - - /* 570 - negative value loses sign during implicit conversion */ - +e570 - -append(570,[BARR-C:2018 Rule 5.3c]) - - /* 713 - implicit conversion from unsigned to signed may lose precision */ - +e713 - -append(713,[BARR-C:2018 Rule 5.3c]) - - /* 8524 - combining signed and unsigned types with operator op1 */ - -hook(binary_expr, -cond(%[walk_lhs_expr{false}.walk_type.is_integer] && - %[walk_rhs_expr{false}.walk_type.is_integer] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - '%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]' != - '%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]', - +message(8524, "combining signed and unsigned types with operator '%[opcode]'"))) - +e8524 - -append(8524,[BARR-C:2018 Rule 5.3c]) - -// 5.4 Floating Point - - /* 586 - type is deprecated */ - -deprecate(type,float,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,double,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,long double,[BARR-C:2018 Rule 5.4b]) - - /* 777 - testing floating point values for equality */ - +e777 - -append(777,[BARR-C:2018 Rule 5.4b]) - - /* 9252 - testing floating point for equality using exact value */ - +e9252 - -append(9252,[BARR-C:2018 Rule 5.4b]) - -// 5.5 Structures and Unions - - /* not currently supported */ - -// 5.6 Booleans - - /* 8523 - cast to boolean */ - -hook(cast_expr, -cond(%[is_cstyle_cast] && %[walk_type.is_boolean], - +message(8523, "cast to boolean"))) - +e8523 - -append(8523,[BARR-C:2018 Rule 5.6b]) - -//========== PROCEDURE RULES ========== - -// 6.1 Naming Conventions - - /* 8501 - function has name that matches a keyword in C or C++ */ - -hook(func_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8501, "function '%[name]' matches the name of a C/C++ keyword"))) - +e8501 - -append(8501,[BARR-C:2018 Rule 6.1a]) - - /* 8502 - function has same name as standard library function */ - -hook(func_decl, -cond('%[name]' ~ '^(?:abort|abs|acos|acosf|acosh|acoshf|acoshl|acosl|asctime|asin|asinf|asinh|asinhf|asinhl|asinl|assert|atan|atan2|atan2f|atan2l|atanf|atanh|atanhf|atanhl|atanl|atexit|atof|atoi|atol|atoll|bsearch|btowc|cabs|cabsf|cabsl|cacos|cacosf|cacosh|cacoshf|cacoshl|cacosl|calloc|carg|cargf|cargl|casin|casinf|casinh|casinhf|casinhl|casinl|catan|catanf|catanh|catanhf|catanhl|catanl|cbrt|cbrtf|cbrtl|ccos|ccosf|ccosh|ccoshf|ccoshl|ccosl|ceil|ceilf|ceill|cexp|cexpf|cexpl|cimag|cimagf|cimagl|clearerr|clock|clog|clogf|clogl|conj|conjf|conjl|copysign|copysignf|copysignl|cos|cosf|cosh|coshf|coshl|cosl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|creal|crealf|creall|csin|csinf|csinh|csinhf|csinhl|csinl|csqrt|csqrtf|csqrtl|ctan|ctanf|ctanh|ctanhf|ctanhl|ctanl|ctime|difftime|div|erf|erfc|erfcf|erfcl|erff|erfl|exit|_Exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|fabs|fabsf|fabsl|fclose|fdim|fdimf|fdiml|feclearexcept|fegetenv|fegetexceptflag|fegetround|feholdexcept|feof|feraiseexcept|ferror|fesetenv|fesetexceptflag|fesetround|fetestexcept|feupdateenv|fflush|fgetc|fgetpos|fgets|fgetwc|fgetws|floor|floorf|floorl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|fmin|fminf|fminl|fmod|fmodf|fmodl|fopen|fpclassify|fprintf|fputc|fputs|fputwc|fputws|fread|free|freopen|frexp|frexpf|frexpl|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|getc|getchar|getenv|gets|getwc|getwchar|gmtime|hypot|hypotf|hypotl|ilogb|ilogbf|ilogbl|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless|islessequal|islessgreater|islower|isnan|isnormal|isprint|ispunct|isspace|isunordered|isupper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|iswlower|iswprint|iswpunct|iswspace|iswupper|iswxdigit|isxdigit|labs|ldexp|ldexpf|ldexpl|ldiv|lgamma|lgammaf|lgammal|llabs|lldiv|llrint|llrintf|llrintl|llround|llroundf|llroundl|localeconv|localtime|log|log10|log10f|log10l|log1p|log1pf|log1pl|log2|log2f|log2l|logb|logbf|logbl|logf|logl|longjmp|lrint|lrintf|lrintl|lround|lroundf|lroundl|malloc|mblen|mbrlen|mbrtowc|mbsinit|mbsrtowcs|mbstowcs|mbtowc|memchr|memcmp|memcpy|memmove|memset|mktime|modf|modff|modfl|nan|nanf|nanl|nearbyint|nearbyintf|nearbyintl|nextafter|nextafterf|nextafterl|nexttoward|nexttowardf|nexttowardl|perror|pow|powf|powl|printf|putc|putchar|puts|putwc|putwchar|qsort|raise|rand|realloc|remainder|remainderf|remainderl|remove|remquo|remquof|remquol|rename|rewind|rint|rintf|rintl|round|roundf|roundl|scalbln|scalblnf|scalblnl|scalbn|scalbnf|scalbnl|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sin|sinf|sinh|sinhf|sinhl|sinl|snprintf|sprintf|sqrt|sqrtf|sqrtl|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strtod|strtof|strtoimax|strtok|strtol|strtold|strtoll|strtoul|strtoull|strtoumax|strxfrm|swprintf|swscanf|system|tan|tanf|tanh|tanhf|tanhl|tanl|tgamma|tgammaf|tgammal|time|tmpfile|tmpnam|tolower|toupper|towctrans|towlower|towupper|trunc|truncf|truncl|ungetc|ungetwc|va_arg|va_copy|va_end|va_start|vfprintf|vfscanf|vfwprintf|vfwscanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcstod|wcstof|wcstoimax|wcstok|wcstol|wcstold|wcstoll|wcstombs|wcstoul|wcstoull|wcstoumax|wcsxfrm|wctob|wctomb|wctrans|wctype|wmemchr|wmemcmp|wmemcpy|wmemmove|wmemset|wprintf|wscanf)$', +message(8502, "function '%[name]' matches the name of a standard library function"))) - +e8502 - -append(8502,[BARR-C:2018 Rule 6.1b]) - - /* 8503 - function has name that begins with an underscore */ - -hook(func_decl, -cond('%[name]' ~ '^_', +message(8503, "function '%[name]' begins with an underscore"))) - +e8503 - -append(8503,[BARR-C:2018 Rule 6.1c]) - - /* 8504 - function name is longer than 31 characters */ - -hook(func_decl, -cond('%[name]' ~ '.{32,}', +message(8504, "function '%[name]' is longer than 31 characters"))) - +e8504 - -append(8504,[BARR-C:2018 Rule 6.1d]) - - /* 8506 - macro name contains lowercase letter(s) */ - -hook(macro_define, -cond(!%[is_builtin] && '%[name]' ~ '[[:lower:]]', +message(8506, "macro '%[name]' contains lowercase letters"))) - +e8506 - -append(8506,[BARR-C:2018 Rule 6.1f]) - -// 6.2 Functions - - /* 904 - return statement before end of function */ - +e904 - -append(904,[BARR-C:2018 Rule 6.2c]) - - /* 937 - old-style function declaration for function */ - +e937 - -append(937,[BARR-C:2018 Rule 6.2f]) - - /* 957 - function defined without a prototype in scope */ - +e957 - -append(957,[BARR-C:2018 Rule 6.2f]) - - /* 832 - parameter not explicitly declared, int assumed */ - +e832 - -append(832,[BARR-C:2018 Rule 6.2f]) - -// 6.3 Function-Like Macros - - /* 9026 - function-like macro defined */ - +e9026 - -append(9026,[BARR-C:2018 Rule 6.3a]) - - /* 665 - unparenthesized parameter in macro is passed an expression */ - +e665 - -append(665,[BARR-C:2018 Rule 6.3b]) - - /* 666 - expression with side effects passed to repeated parameter */ - +e666 - -append(666,[BARR-C:2018 Rule 6.3b]) - - /* 773 - expression-like macro not parenthesized */ - +e773 - -append(773,[BARR-C:2018 Rule 6.3b]) - - /* 9022 - unparenthesized macro parameter in definition of macro */ - +e9022 - -append(9022,[BARR-C:2018 Rule 6.3b]) - -// 6.4 Threads of Execution - - /* not currently supported */ - -// 6.5 Interrupt Service Routines - - /* not currently supported */ - -//========== VARIABLES ========== - -// 7.1 Naming Conventions - - /* 8507 - variable has name that matches a keyword in C or C++ */ - -hook(var_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|fortran|friend|goto|if|inline|int|interrupt|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8507, "variable '%[name]' matches the name of a C/C++ keyword"))) - +e8507 - -append(8507,[BARR-C:2018 Rule 7.1a]) - - /* 8525 - variable has same name as standard library variable */ - -hook(var_decl, -cond('%[name]' ~ '^(?:errno|stderr|stdin|stdout)$', - +message(8525, "variale '%[name]' matches the same name of a standard library variable"))) - +e8525 - -append(8525,[BARR-C:2018 Rule 7.1b]) - - /* 8508 - variable has name that begins with an underscore */ - -hook(var_decl, -cond('%[name]' ~ '^_', +message(8508, "variable '%[name]' begins with an underscore"))) - +e8508 - -append(8508,[BARR-C:2018 Rule 7.1c]) - - /* 8509 - variable name is longer than 31 characters */ - -hook(var_decl, -cond('%[name]' ~ '.{32,}', +message(8509, "variable '%[name]' is longer than 31 characters"))) - +e8509 - -append(8509,[BARR-C:2018 Rule 6.1d]) - - -// 7.2 Initialization - - /* 530 - likely using an uninitialized value */ - +e530 - -append(530,[BARR-C:2018 Rule 7.2a]) - - /* 603 - argument to parameter of type pointer to const may be a pointer to uninitialized memory */ - +e603 - -append(603,[BARR-C:2018 Rule 7.2a]) - - /* 644 - potentially using an uninitialized value */ - +e644 - -append(644,[BARR-C:2018 Rule 7.2a]) - - /* 708 - union initialization */ - +e708 - -append(708,[BARR-C:2018 Rule 7.2a]) - - /* 727 - static local symbol not explicitly initialized */ - +e727 - -append(727,[BARR-C:2018 Rule 7.2a]) - - /* 728 - file scope static variable not explicitly initialized */ - +e728 - -append(728,[BARR-C:2018 Rule 7.2a]) - - /* 729 - external variable not explicitly initialized */ - +e729 - -append(729,[BARR-C:2018 Rule 7.2a]) - - /* 738 - address of static local symbol not explicitly initialized before passed to a function */ - +e738 - -append(738,[BARR-C:2018 Rule 7.2a]) - - /* 784 - nul character truncated from string */ - +e784 - -append(784,[BARR-C:2018 Rule 7.2a]) - - /* 785 - too few initializers for aggregate */ - +e785 - -append(785,[BARR-C:2018 Rule 7.2a]) - -//========== STATEMENT RULES ========== - -// 8.1 Variable Declarations - - /* 9146 - multiple declarators in a declaration */ - +e9146 - -append(9146,[BARR-C:2018 Rule 8.1a]) - -// 8.2 Conditional Statements - - /* 720 - boolean test of assignment */ - +e720 - -append(720,[BARR-C:2018 Rule 8.2c]) - - /* 820 - boolean test of parenthesized assignment */ - +e820 - -append(820,[BARR-C:2018 Rule 8.2c]) - - /* 9013 - no 'else' at end of 'if ... else if' chain */ - +e9013 - -append(9013,[BARR-C:2018 Rule 8.2d]) - -// 8.3 Switch Statements - - /* 9014 - switch without default */ - +e9014 - -append(9014,[BARR-C:2018 Rule 8.3b]) - - /* 616 - control flow falls through to next case without an intervening comment */ - +e616 - -append(616,[BARR-C:2018 Rule 8.3c]) - -// 8.4 Loops - - /* 850 - for statement index variable modified in body */ - +e850 - -append(850,[BARR-C:2018 Rule 8.4b]) - - /* 716 - infinite loop via while */ - +e716 - -append(716,[BARR-C:2018 Rule 8.4c]) - -// 8.5 Jumps - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 8.5a]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 8.5a]) - - /* 586 - function/macro is deprecated */ - -deprecate(function,abort,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,exit,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,longjmp,[BARR-C:2018 Rule 8.5b]) - -deprecate(macro,setjmp,[BARR-C:2018 Rule 8.5b]) - -// 8.6 Equivalence Test - - /* 8522 - variable should appear on RHS of '==' operator */ - -hook(binary_expr, -cond('%[opcode]' == '==' && - '%[walk_lhs_expr.walk_past_paren_cast.set_msg_loc.is_decl_ref_expr]' == 'true' && - '%[walk_rhs_expr.is_constant_expr]' == 'true', - +message(8522, "variable '%[walk_lhs_expr.walk_past_paren_cast.walk_decl.qual_name]' should appear on RHS of '==' operator"))) - +e8522 - -append(8522,[BARR-C:2018 Rule 8.6a]) diff --git a/ports/lint-plus/qpc.lnt b/ports/lint-plus/qpc.lnt deleted file mode 100644 index 930cb664..00000000 --- a/ports/lint-plus/qpc.lnt +++ /dev/null @@ -1,426 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for version: 7.4.0 -//! -//! @file -//! @brief PC-Lint-Plus option file for analysing both **QP/C** -//! and **QP/C Applications** - -// C Language Standard --std=c99 // apply the C99 Language Standard - -//! M4-D4.8(A) complete definition is unnecessary in this translation unit -//! @tr{DVP-QP-MC4-D04_08} --efile(9045, - -qp.h, - -qequeue.h, - -qmpool.h, - -qv.h, - -qk.h, - -qxk.h, - -qs.h) - -// Functional Safety (FuSa) System -------------------------------------------- - -// "no return" semantics for error/failure callbacks --sem(Q_onError, r_no) --sem(assert_failed, r_no) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} (false-positive) --esym(9026, - Q_DEFINE_THIS_MODULE, - Q_ASSERT_STATIC, - Q_ASSERT, - Q_ASSERT_ID, - Q_ERROR, - Q_ERROR_ID, - Q_REQUIRE, - Q_REQUIRE_ID, - Q_ENSURE, - Q_ENSURE_ID, - Q_INVARIANT, - Q_INVARIANT_ID, - Q_DIM) - -//! PCLP definition of macro ends in semicolon -//! @tr{DVP-QP-PCLP-823} --esym(823, - Q_DEFINE_THIS_MODULE) - -//! BARR-C(R1.8b) parameter of function could be const --efunc(952, - Q_onError -) - -// QEP ----------------------------------------------------------------------- -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} (false-positive) --esym(9026, - Q_UNUSED_PAR, - Q_TRAN, - Q_TRAN_HIST, - Q_SUPER, - Q_HANDLED, - Q_UNHANDLED, - Q_IGNORED, - Q_ASM_UPCAST, - Q_HSM_UPCAST, - Q_MSM_UPCAST, - Q_EVT_CAST, - QEVT_INITIALIZER, - Q_UINT2PTR_CAST, - Q_STATE_CAST, - Q_ACTION_CAST, - QASM_INIT, - QASM_DISPATCH, - QASM_IS_IN) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09B} (correct identification) --esym(9026, - QM_ENTRY, - QM_EXIT, - QM_SM_EXIT, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_HIST, - QM_TRAN_EP, - QM_TRAN_XP, - QM_SUPER, - QM_SUPER_SUB, - QM_HANDLED, - QM_UNHANDLED, - QMSM_INIT, - QMSM_DISPATCH) - -//! M4-R11.1(R) conversion between pointer to function type -//! @tr{DVP-QP-MC4-R11_01} --emacro(9074, - Q_STATE_CAST, - Q_ACTION_CAST, - Q_TRAN, - Q_TRAN_HIST, - Q_SUPER, - QM_ENTRY, - QM_EXIT, - QM_SM_EXIT, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_HIST, - QM_TRAN_EP, - QM_TRAN_XP) - -//! M4-R11.3(R) cast from pointer to pointer (upcast) -//! @tr{DVP-QP-MC4-R11_03A} --emacro(9087, - Q_ASM_UPCAST, - Q_HSM_UPCAST, - Q_MSM_UPCAST, - QM_TRAN, - QM_TRAN_EP, - QM_TRAN_INIT) - -//! M4-R11.3(R) cast from pointer to pointer (downcast) -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - Q_EVT_CAST) - -//! M4-R12.3(A) comma operator used -//! @tr{DVP-QP-MC4-R12_03} --emacro(9008, - Q_SUPER, - Q_TRAN, - Q_TRAN_HIST, - QM_ENTRY, - QM_EXIT, - QM_SUPER_SUB, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_EP, - QM_TRAN_XP, - QM_SM_EXIT, - QM_SUPER_SUB) - -//! M4-R13.4(A) result of assignment used in left operand to ',' operator -//! @tr{DVP-QP-MC4-R13_04} --emacro(9084, - Q_SUPER, - Q_TRAN, - QM_ENTRY, - QM_EXIT, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_HIST, - QM_TRAN_EP, - QM_TRAN_XP, - QM_SM_EXIT, - QM_SUPER_SUB) - -//! M4-R19.2(A) union declared -//! @tr{DVP-QP-MC4-R19_02} --esym(9018, - QAsmAttr) - -//! '' not referenced in QM-style state machines -//! @tr{DVP-QP-PCLP-754} --esym(754, - *(anonymous struct)::act, - *(anonymous struct)::target) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVP-QP-PCLP-826} --emacro(826, - Q_EVT_CAST) - -// deprecated QEP facilities... --deprecate( type, QFsm, QP/C API pre 5.4.x) --deprecate( function, QFsm_ctor, QP/C API pre 5.4.x) --deprecate( function, QF_onIdle, QP/C API pre 5.4.x) --deprecate( macro, Q_IGNORED, QP/C API pre 5.4.x) --deprecate( macro, QMSM_INIT, QP/C API pre 5.8.x) --deprecate( macro, QMSM_DISPATCH, QP/C API pre 5.8.x) - -// QF ------------------------------------------------------------------------ - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09B} --esym(9026, - QF_INT_DISABLE, - QF_INT_ENABLE, - Q_PRIO, - QF_LOG2, - Q_NEW, - Q_NEW_X, - Q_NEW_REF, - Q_DELETE_REF, - QF_PUBLISH, - QF_CRIT_ENTRY, - QF_CRIT_EXIT, - QF_CRIT_EXIT_NOP, - QF_MEM_SYS, - QF_MEM_APP, - QF_MPOOL_EL, - QF_LOG2, - QF_EPOOL_INIT_, - QF_EPOOL_EVENT_SIZE_, - QF_EPOOL_GET_, - QF_EPOOL_PUT_, - QF_PTR_INC_, - QACTIVE_START, - QACTIVE_POST, - QACTIVE_POST_X, - QACTIVE_POST_LIFO, - QACTIVE_PUBLISH, - QACTIVE_EQUEUE_WAIT_, - QACTIVE_EQUEUE_SIGNAL_, - QACTIVE_EQUEUE_ONEMPTY_, - QTIMEEVT_TICK, - QTIMEEVT_TICK_X, - QTICKER_TRIG, - QF_TICK, - QF_TICK_X) - -//! M4-R11.3(R) cast to pointer to different object type (upcast) -//! @tr{DVP-QP-MC4-R11_03A} --emacro(9087, - QACTIVE_POST, - QACTIVE_POST_LIFO) - -//! M4-R11.3(R) cast to pointer to different object type (downcast) -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - Q_NEW, - Q_NEW_X) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVP-QP-PCLP-826} --emacro(826, - QACTIVE_POST, - QACTIVE_POST_X, - QACTIVE_POST_LIFO, - Q_NEW, - Q_NEW_X) - -// deprecated QF facilities... --deprecate( macro,QTimeEvt_ctor, QP/C API pre 5.8.x) --deprecate( macro,QTimeEvt_postIn, QP/C API pre 5.8.x) --deprecate( macro,QTimeEvt_postEvery, QP/C API pre 5.8.x) - -// QV ------------------------------------------------------------------------ -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QV_CPU_SLEEP) - -// QK ------------------------------------------------------------------------ -// M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QK_ISR_ENTRY, - QK_ISR_EXIT, - QK_ISR_CONTEXT_) - -// QXK ----------------------------------------------------------------------- -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QXK_ISR_ENTRY, - QXK_ISR_EXIT, - QXK_TLS, - QXTHREAD_START, - QXTHREAD_POST_X) - -// deprecated QXK facilities... --deprecate( macro, Q_XTHREAD_CAST, QP/C API pre 6.7.x) - -// QS ------------------------------------------------------------------------ - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QS-MC4-D04_09A} --esym(9026, - QS_INIT, - QS_EXIT, - QS_DUMP, - QS_RESET, - QS_GLB_FILTER, - QS_LOC_FILTER, - QS_FILTER_ON, - QS_FILTER_OFF, - QS_FILTER_SM_OBJ, - QS_FILTER_AO_OBJ, - QS_FILTER_MP_OBJ, - QS_FILTER_EQ_OBJ, - QS_FILTER_TE_OBJ, - QS_FILTER_AP_OBJ, - QS_GET_BYTE, - QS_GET_BLOCK, - QS_BEGIN, - QS_BEGIN_ID, - QS_END, - QS_BEGIN_INCRIT, - QS_END_INCRIT, - QS_TR_CRIT_ENTRY, - QS_TR_CRIT_EXIT, - QS_TR_ISR_ENTRY, - QS_TR_ISR_EXIT, - QS_ONLY, - QS_REC_DONE, - QS_I8, - QS_U8, - QS_I16, - QS_U16, - QS_I32, - QS_I64, - QS_U32, - QS_F32, - QS_F64, - QS_U64, - QS_U32_HEX, - QS_STR, - QS_OBJ, - QS_FUN, - QS_SIG_DICTIONARY, - QS_OBJ_DICTIONARY, - QS_OBJ_ARR_DICTIONARY, - QS_FUN_DICTIONARY, - QS_USR_DICTIONARY, - QS_ENUM_DICTIONARY, - QS_ASSERTION, - QS_FLUSH, - QS_MEM, - QS_SIG, - QS_ENUM, - QS_PTR_AT_, - QS_RX_PUT, - QS_OUTPUT, - QS_RX_INPUT, - QS_TEST_PAUSE, - QS_TEST_PROBE_DEF, - QS_TEST_PROBE, - QS_TEST_PROBE_ID) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QS-MC4-D04_09A} --esym(9026, - QS_CRIT_ENTRY, - QS_CRIT_EXIT, - QS_MEM_SYS, - QS_MEM_APP, - QS_GLB_CHECK_, - QS_LOC_CHECK_, - QS_BEGIN_PRE_, - QS_END_PRE_, - QS_U8_PRE_, - QS_2U8_PRE_, - QS_U16_PRE_, - QS_U32_PRE_, - QS_STR_PRE_, - QS_TIME_PRE_, - QS_SIG_PRE_, - QS_EVS_PRE_, - QS_OBJ_PRE_, - QS_FUN_PRE_, - QS_EQC_PRE_, - QS_MPC_PRE_, - QS_MPS_PRE_, - QS_TEC_PRE_) - -//! M4-R11.1(R) conversion between pointer to function type -//! @tr{DVP-QS-MC4-R11_01} --emacro(9074, - QS_FUN_DICTIONARY, - QS_TEST_PROBE_DEF) - -// M4-R15.5(A) return statement before end of function -//! @tr{DVP-QS-MC4-R15_05} --emacro(904, - QS_TEST_PROBE) - -//! M4-R19.2(A) union declared -//! @tr{DVR-QS-MC4-R19_02} --esym(9018, - Variant) - -//! M4-R20.10(A) stringize operator -//! @tr{DVP-QS-MC4-R20_10} --esym(9024, - QS_OBJ_DICTIONARY, - QS_OBJ_ARR_DICTIONARY, - QS_FUN_DICTIONARY, - QS_SIG_DICTIONARY, - QS_USR_DICTIONARY, - QS_ENUM_DICTIONARY) - -//! implicit conversion of enum to integral type 'int' -//! @tr{DVP-QS-PCLP-641} --emacro(641, - QS_SIG_DICTIONARY) - -//! definition of macro ends in semicolon -//! @tr{DVP-QS-PCLP-823} --esym(823, - QS_TEST_PROBE_DEF) diff --git a/ports/lint-plus/qv/qp_port.h b/ports/lint-plus/qv/qp_port.h deleted file mode 100644 index 625fa957..00000000 --- a/ports/lint-plus/qv/qp_port.h +++ /dev/null @@ -1,86 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QP/C "port" to PC-Lint-Plus, QV kernel, generic C99 - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QF configuration for QV -- data members of the QActive class... - -// QV event-queue used for AOs -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QF "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// interrupt disabling mechanism -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -// QF critical section mechanism -#define QF_CRIT_STAT uint32_t crit_stat_; -#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) -#define QF_CRIT_EXIT() critExit(crit_stat_) - -#define QV_CPU_SLEEP() \ -do { \ - __disable_interrupt(); \ - QF_INT_ENABLE(); \ - __WFI(); \ - __enable_interrupt(); \ -} while (false) - -void intDisable(void); -void intEnable(void); -uint32_t critEntry(void); -void critExit(uint32_t stat); - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QV kernel uses the native QP event queue -#include "qmpool.h" // QV kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qv.h" // QV kernel - -#endif // QP_PORT_H_ - diff --git a/ports/lint-plus/qxk/qp_port.h b/ports/lint-plus/qxk/qp_port.h deleted file mode 100644 index 84a2f19c..00000000 --- a/ports/lint-plus/qxk/qp_port.h +++ /dev/null @@ -1,101 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QP/C "port" to PC-Lint-Plus, QXK kernel, generic C99 - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QF configuration for QXK -- data members of the QActive class... - -// QXK event-queue type used for AOs and eXtended threads. -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QXK OS-Object type used for the private stack pointer for eXtended threads. -// (The private stack pointer is NULL for basic-threads). -#define QACTIVE_OS_OBJ_TYPE void* - -// QF "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// interrupt disabling mechanism -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -// QF critical section mechanism -#define QF_CRIT_STAT uint32_t crit_stat_; -#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) -#define QF_CRIT_EXIT() critExit(crit_stat_) - -// Check if the code executes in the ISR context -#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) - -// Define the ISR entry sequence -#define QXK_ISR_ENTRY() ((void)0) - -// Define the ISR exit sequence -#define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ -} while (false) - -#define QXK_CONTEXT_SWITCH_() (QXK_trigPendSV()) - -void intDisable(void); -void intEnable(void); -uint32_t critEntry(void); -void critExit(uint32_t stat); -uint32_t QXK_get_IPSR(void); -void QXK_trigPendSV(void); - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QXK kernel uses the native QP event queue -#include "qmpool.h" // QXK kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qxk.h" // QXK kernel - -#endif // QP_PORT_H_ - diff --git a/ports/lint-plus/std.lnt b/ports/lint-plus/std.lnt deleted file mode 100644 index 722f7106..00000000 --- a/ports/lint-plus/std.lnt +++ /dev/null @@ -1,44 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-06-06 -//! @version Last updated for version: 7.3.0 -//! -//! @file -//! @brief PC-Lint-Plus standard option file - -// message formatting options... --hF1 // output: a single line -+ffn // use full path names --width(120,4) // break lines after 99 characters with 4 characters indent -+flm // make sure no foreign includes change the format - --zero(99) // don't stop because of warnings --passes(2) // make two passes (for better error messages) --restore_at_end // don't let -e options bleed to other files --summary() // output a summary of all produced messages - -// globally suppress the following warnings: --e546 // explicitly taking address of function --e717 // monocarpic do-while used to group statements diff --git a/ports/lint-plus/stdbool.h b/ports/lint-plus/stdbool.h deleted file mode 100644 index acefc5f2..00000000 --- a/ports/lint-plus/stdbool.h +++ /dev/null @@ -1,30 +0,0 @@ -//! @file -//! @brief Boolean type and constansts. WG14/N843 C99 Standard, Section 7.16 -//! -//! @description -//! This header is part of the ANSI C99 standard library to define the -//! standard Boolean type as well as the 'true' and 'false' constansts. -#ifndef STDBOOL_H_ -#define STDBOOL_H_ - -//lint -save -//lint -e9071 M3-R21.1(r), defined macro is reserved to the compiler -//lint -e9093 the name is reserved to the compiler -//lint -emacro(8523, false, true) cast to boolean - -#ifndef __cplusplus - -typedef _Bool bool; //!< standard Boolean data type - -//! standard 'false' constant -#define false ((bool)0) - -//! standard 'true' constant -#define true ((bool)1) - -#endif // !__cplusplus - -//lint -restore - -#endif // STDBOOL_H_ - diff --git a/ports/lint-plus2/16bit/cpu.lnt b/ports/lint-plus2/16bit/cpu.lnt deleted file mode 100644 index d5cc76b1..00000000 --- a/ports/lint-plus2/16bit/cpu.lnt +++ /dev/null @@ -1,6 +0,0 @@ -// Size Options for 16bit CPU (e.g., MSP430) --si2 -sl4 -sll8 -ss2 -sw2 -sp2 -sf4 -sd8 -sld8 - -// Alignment options for 16bit CPU --ai2 -al2 -all2 -as2 -af4 -ad8 -ald8 - diff --git a/ports/lint-plus2/16bit/qs_port.h b/ports/lint-plus2/16bit/qs_port.h deleted file mode 100644 index 65f5a327..00000000 --- a/ports/lint-plus2/16bit/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 2U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 2U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/lint-plus2/16bit/stdint.h b/ports/lint-plus2/16bit/stdint.h deleted file mode 100644 index c1b99efc..00000000 --- a/ports/lint-plus2/16bit/stdint.h +++ /dev/null @@ -1,47 +0,0 @@ -//! @file -//! @brief Selected exact-width and fast minimum-width integer types -//! for 16-bit CPU architecture (e.g., MSP430). -//! -//! @description -//! This header is part of the ANSI C99 standard library to define the -//! standard exact-width integer types (see C99 Section 7.18.1.1). -//! If the compiler does not provide the stdint.h header file, you can -//! either create one in the QP port directory, or you can typedef the -//! 8 exact-width integer types directly in the qep_port.h header file. -//! -//! @note The version included in the QP documentation contains only the 8 -//! exact-width types and 6 fast minimum-width types actually used in QP. -//! The actual definition of the integer types is platform dependent. -#ifndef STDINT_H_ -#define STDINT_H_ - -//lint -save -//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler -//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated - -// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 -typedef signed char int8_t; //!< exact-width 8-bit signed int -typedef signed int int16_t; //!< exact-width 16-bit signed int -typedef signed long int int32_t; //!< exact-width 32-bit signed int -typedef signed long long int64_t; //!< exact-width 64-bit signed int - -typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int -typedef unsigned int uint16_t; //!< exact-width 16-bit unsigned int -typedef unsigned long int uint32_t; //!< exact-width 32-bit unsigned int -typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int - -// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 -typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int -typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int -typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int -typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int -typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int -typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int - -// unsigned integer type capable of holding a pointer to void. -typedef unsigned uintptr_t; //!< unsigned int capable of holding void* - -//lint -restore - -#endif // STDINT_H_ - diff --git a/ports/lint-plus2/32bit/cpu.lnt b/ports/lint-plus2/32bit/cpu.lnt deleted file mode 100644 index 9281e892..00000000 --- a/ports/lint-plus2/32bit/cpu.lnt +++ /dev/null @@ -1,3 +0,0 @@ -// Size Options for 32bit CPU (e.g., ARM Cortex-M) --si4 -sl4 -sll8 -ss2 -sw4 -sp4 -sf4 -sd8 -sld8 - diff --git a/ports/lint-plus2/32bit/qs_port.h b/ports/lint-plus2/32bit/qs_port.h deleted file mode 100644 index 7895e109..00000000 --- a/ports/lint-plus2/32bit/qs_port.h +++ /dev/null @@ -1,57 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -// object pointer size in bytes -#define QS_OBJ_PTR_SIZE 4U - -// function pointer size in bytes -#define QS_FUN_PTR_SIZE 4U - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/lint-plus2/32bit/stdint.h b/ports/lint-plus2/32bit/stdint.h deleted file mode 100644 index 96e3af0c..00000000 --- a/ports/lint-plus2/32bit/stdint.h +++ /dev/null @@ -1,47 +0,0 @@ -//! @file -//! @brief Selected exact-width and fast minimum-width integer types -//! for 32-bit CPU architecture (e.g., ARM Cortex-M). -//! -//! @description -//! This header is part of the ANSI C99 standard library to define the -//! standard exact-width integer types (see C99 Section 7.18.1.1). -//! If the compiler does not provide the stdint.h header file, you can -//! either create one in the QP port directory, or you can typedef the -//! 8 exact-width integer types directly in the qep_port.h header file. -//! -//! @note The version included in the QP documentation contains only the 8 -//! exact-width types and 6 fast minimum-width types actually used in QP. -//! The actual definition of the integer types is platform dependent. -#ifndef STDINT_H_ -#define STDINT_H_ - -//lint -save -//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler -//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated - -// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 -typedef signed char int8_t; //!< exact-width 8-bit signed int -typedef signed short int16_t; //!< exact-width 16-bit signed int -typedef signed int int32_t; //!< exact-width 32-bit signed int -typedef signed long long int64_t; //!< exact-width 64-bit signed int - -typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int -typedef unsigned short uint16_t; //!< exact-width 16-bit unsigned int -typedef unsigned int uint32_t; //!< exact-width 32-bit unsigned int -typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int - -// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 -typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int -typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int -typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int -typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int -typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int -typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int - -// unsigned integer type capable of holding a pointer to void. -typedef unsigned uintptr_t; //!< unsigned int capable of holding void* - -//lint -restore - -#endif // STDINT_H_ - diff --git a/ports/lint-plus2/au-ds.lnt b/ports/lint-plus2/au-ds.lnt deleted file mode 100644 index 38fcd673..00000000 --- a/ports/lint-plus2/au-ds.lnt +++ /dev/null @@ -1,21 +0,0 @@ -// au-ds.lnt -- Author options - Dan Saks - -/* - This options file can be used to explicitly activate those - checks advocated by Dan Saks in his series of presentations on - "C++ Gotchas". - - You can use this file directly when linting your programs as in: - - lin au-ds files - - */ - -+fsc // consider string constants as const char * -+e1933 // turn on "virtual call from member detection" - -// The rationale for the following two options are fully described -// in Dan Saks' article "const T vs. T const". Visit his web site -// at www.dansaks.com and click "Published Articles". -// --fqb +e963 // require T const rather than const T diff --git a/ports/lint-plus2/make.bat b/ports/lint-plus2/make.bat deleted file mode 100644 index 32a1c8f5..00000000 --- a/ports/lint-plus2/make.bat +++ /dev/null @@ -1,70 +0,0 @@ -@echo off -:: =========================================================================== -:: Batch script for linting QP/C with PC-Lint-Plus2 -:: Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -:: -:: SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -:: -:: This software is dual-licensed under the terms of the open source GNU -:: General Public License version 3 (or any later version), or alternatively, -:: under the terms of one of the closed source Quantum Leaps commercial -:: licenses. -:: -:: The terms of the open source GNU General Public License version 3 -:: can be found at: -:: -:: The terms of the closed source Quantum Leaps commercial licenses -:: can be found at: -:: -:: Redistributions in source code must retain this top-level comment block. -:: Plagiarizing this software to sidestep the license obligations is illegal. -:: -:: Contact information: -:: -:: -:: =========================================================================== -@setlocal - -:: usage of make.bat -@echo Usage: make [16bit] [-u...] files -@echo examples: -@echo make -uQ_SPY -uQ_UTEST : use 32bit CPU (default) and undefine Q_SPY/Q_UTEST -@echo make 16bit -uQ_SPY : use 16bit CPU includes and undefine Q_SPY -@echo. - -:: NOTE: adjust to for your installation directory of PC-Lint-Plus -@set PCLP=C:\tools\lint-plus2.2-beta\windows -@set PCLP_EXE=%PCLP%\pclp64.exe - -if NOT exist "%PCLP%" ( - @echo The PC-Lint-Plus toolset not found. Please adjust make.bat - @goto end -) - -:: set the QP/C directory -@set QPC=..\.. - -if "%1"=="16bit" ( - set LINTFLAGS=-i16bit options.lnt %1 %2 %3 %4 - @echo 16bit CPU -) else ( - set LINTFLAGS=-i32bit options.lnt %1 %2 %3 %4 - @echo 32bit CPU default -) - -:: cleanup -@del *.log - -:: linting ------------------------------------------------------------------- -%PCLP_EXE% -os(lint_qf.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qf\*.c - -%PCLP_EXE% -os(lint_qv.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qv\*.c - -%PCLP_EXE% -os(lint_qk.log) std.lnt %LINTFLAGS% -iqk ..\..\src\qk\*.c - -%PCLP_EXE% -os(lint_qxk.log) std.lnt %LINTFLAGS% -iqxk ..\..\src\qxk\*.c - -%PCLP_EXE% -os(lint_qs.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qs\*.c - -:end -@endlocal diff --git a/ports/lint-plus2/options.lnt b/ports/lint-plus2/options.lnt deleted file mode 100644 index ab0473dd..00000000 --- a/ports/lint-plus2/options.lnt +++ /dev/null @@ -1,368 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-14 -//! @version Last updated for version: 7.3.4 -//! -//! @file -//! @brief PC-Lint-Plus option file for linting QP/C source code - -//============================================================================ -// general options --unit_check // perform only subset check (suppresses Global Wrapup) --max_threads=1 // suppress message "no '-max_threads=N' option" -++efreeze(686) // never suppress (see PC-Lint-Plus in Safety-Critical) -//-vf // print names of all source files (for debugging linting) - -// include directories --i%PCLP%/lnt // PC-Lint-Plus standard .lnt files --i. // QP/C port includes (see also qk/ and qv/) --i%QPC%/include // QP/C public includes - -// standards -// language standard... -au-misra3.lnt // MISRA-C:2023 (MC4) compliance -au-misra3-amd1.lnt // MISRA-C:2023 (MC4) compliance -au-misra3-amd2.lnt // MISRA-C:2023 (MC4) compliance -au-misra3-amd3.lnt // MISRA-C:2023 (MC4) compliance -au-misra3-amd4.lnt // MISRA-C:2023 (MC4) compliance - -// customized BARR-C:2018 style guidelines -au-barr.lnt // BARR-C:2018 style guidelines --e8505 // suppress [Rule 6.1e] function contains uppercase letters --e8511 // suppress [Rule 7.1f] variable contains uppercase letters --e8512 // suppress [Rule 7.1j] global variable should have 'g' prefix --e8510 // suppress [Rule 7.1e] variable contains less than 3 characters --e8513 // suppress [Rule 7.1k] variable should have 'pp' prefix --e8514 // suppress [Rule 7.1l] variable should have 'p' prefix --e8515 // suppress [Rule 7.1m] boolean variable should have 'b' prefix --e8526 // suppress [Rule 5.1a] typedef name should consist of lowercase letters --e8527 // suppress [Rule 5.1a] typedef name should end with '_t' suffix --e9209 // suppress [Rule 5.2c] plain char data used with prohibited operator & --e8522 // suppress [Rule 8.6a] variable should appear on RHS of '==' operator - -au-ds.lnt // Dan Saks recommendations -cpu.lnt // size/alignment options for the chosen CPU - -// defined macros (might be undefined on command-line with -u) --dQ_SPY --dQ_UTEST - -//============================================================================ -// QP/C options for QP/C Applications -qpc.lnt // QP/C options - -//============================================================================ -// additional suppression rules for building QP/C source code... - -// QEP ----------------------------------------------------------------------- - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QACTIVE_CAST_) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09B} --esym(9026, - QHSM_RESERVED_EVT_, - QS_STATE_ENTRY_, - QS_STATE_EXIT_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer -//! @tr{DVR-QP-MC4-R11_05} --emacro(9079, - Q_EVT_CAST) - -//! M4-R8.13(A) parameter of function could be pointer to const -//! @tr{DVR-QP-MC4-R08_13} --efunc(818, - QMsm_isIn_) - -// QF ------------------------------------------------------------------------ - -//! M4-D4.8(A) complete definition is unnecessary in this translation unit -//! @tr{DVP-QP-MC4-D04_08} --efile(9045, - -qp_pkg.h) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QF_CRIT_ENTRY, - QF_CRIT_EXIT, - Q_ASSERT_INCRIT, - Q_REQUIRE_INCRIT, - Q_ENSURE_INCRIT, - Q_INVARIANT_INCRIT, - Q_ERROR_INCRIT, - QF_SCHED_LOCK_, - QF_SCHED_UNLOCK_, - QF_ISR_CONTEXT_, - QF_MPOOL_EL, - Q_UINTPTR_CAST_) - -//! M4-R8.13(A) parameter of function could be pointer to const -//! @tr{DVR-QP-MC4-R08_13} --efunc(818, - QActive_start_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - QACTIVE_CAST_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVP-QP-MC4-R11_03B} --efunc(9087, - QActive_ctor, - QMActive_ctor) - -//! M4-R11.4(A) conversion between object pointer type and integer type -//! @tr{DVR-QP-MC4-R11_04} --emacro(9078, - Q_UINTPTR_CAST_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer type -//! @tr{DVR-QP-MC4-R11_05} --emacro(9079, - QACTIVE_CAST_, - QF_EPOOL_GET_) --efunc(9079, - QF_bzero_, - QF_deleteRef_, - QMPool_get, - QMPool_put, - QMPool_init, - QTimeEvt_tick_, - QTimeEvt_armX, - QTimeEvt_rearm) - -//! M4-R11.8(R) cast drops const qualifier -//! @tr{DVR-QP-MC4-R11_08} --emacro(9005, - QACTIVE_CAST_) --efunc(9005, - QEvt_refCtr_inc_, - QEvt_refCtr_dec_, - QF_gc) - -//! M4-R15.5(A) return statement before end of function -//! @tr{DVP-QS-MC4-R15_05} --efunc(904, - QActive_post_, - QActive_postLIFO_) - -//! M4-R18.3(R) relational operator <= applied to pointers -//! @tr{DVR-QP-MC4-R18_03} --efunc(946, - QMPool_get, - QMPool_put) - -//! definition of macro ends in semicolon -//! @tr{DVR-QP-PCLP-823} --esym(823, - QF_CRIT_STAT, - QF_SCHED_STAT_) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVP-QP-PCLP-826} --emacro(826, - QACTIVE_CAST_) - - -// QV ------------------------------------------------------------------------ - -// QK ------------------------------------------------------------------------ - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QK_ISR_CONTEXT_, - QK_ISR_ENTRY, - QK_ISR_EXIT) - -// QXK ----------------------------------------------------------------------- - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QXK_ISR_CONTEXT_, - QXK_CONTEXT_SWITCH_, - QXK_PTR_CAST_, - QXTHREAD_CAST_, - QXTHREAD_EQUEUE_SIGNAL_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - QXTHREAD_CAST_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVR-QP-MC4-R11_03C} --emacro(9087, - QXK_PTR_CAST_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer type -//! @tr{DVR-QP-MC4-R11_05} --emacro(9079, - QXK_PTR_CAST_) - -//! MC3-R8.13(A) could be pointer to const -//! @tr{DVR-QP-MC4-R08_13} --efunc(818, - QXThread_init_, - QXThread_dispatch_, - QXThread_postLIFO_) - -//! @tr{DVP-QP-PCLP-826} --emacro(826, - QXK_PTR_CAST_, - QXTHREAD_CAST_) - -//! cast increases required alignment from 2 to 4 -//! @tr{DVR-QP-PCLP-2445} --emacro(2445, - QXK_PTR_CAST_) - -// QS ------------------------------------------------------------------------ -// the following options are needed only when Q_SPY is defined... - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QS-MC4-D04_09A} --esym(9026, - QS_INSERT_BYTE_, - QS_INSERT_ESC_BYTE_, - QS_RX_TRAN_, - QS_CRIT_ENTRY, - QS_CRIT_EXIT) - -//! M4-R8.13(A) parameter ... of function could be pointer to const -//! @tr{DVR-QS-MC4-R08_13} --efunc(818, - QHsmDummy_init_, - QHsmDummy_dispatch_, - QActiveDummy_start_, - QActiveDummy_init_, - QActiveDummy_dispatch_) - -//! M4-R11.1(R) conversion between pointer to function and differing type -//! @tr{DVP-QS-MC4-R11_01} --emacro(9074, - QS_FUN_PRE_) --efunc(9074, - QS_getTestProbe_) - -//! M4-R11.3(R) cast from pointer to object type -//! @tr{DVR-QS-MC4-R11_03C} --efile(9087, - -qs_rx.c, - -qutest.c) - -//! M4-R11.4(A) conversion between object pointer type and integer type -//! @tr{DVR-QS-MC4-R11_04} --emacro(9078, - QS_OBJ_PRE_, - QS_FUN_PRE_) --efunc(9078, - QS_rxHandleGoodFrame_, - QS_getTestProbe_) - -//! M4-R11.5(A) conversion from pointer to void to other pointer type -//! @tr{DVR-QS-MC4-R11_05} --efile(9079, - -qs_rx.c, - -qutest.c) - -//! M4-R11.6(R) explicit cast from integer to 'void *' -//! @tr{DVR-QS-MC4-R11_06} --emacro(923, - QS_OBJ_PRE_, - QS_FUN_PRE_) --efunc(923, - QS_rxHandleGoodFrame_, - QS_getTestProbe_) - -//! M4-R14.3(R) boolean condition for 'if' always evaluates to 'false' -//! @tr{DVR-QS-MC4-R14_03} --emacro(774, - QS_BEGIN_PRE_) - -//! M4-R19.2(A) union declared -//! @tr{DVR-QS-MC4-R19_02} --efunc(9018, - QS_target_info_pre_, - QS_f32_fmt_, - QS_f64_fmt_) - -//! constant value used in Boolean context (left operand to || operator) -//! @tr{DVR-QS-PCLP-506} --emacro(506, - QS_BEGIN_PRE_) - -//! excessive shift value (precision 0 shifted right by ...) -//! @tr{DVR-QS-PCLP-572} --emacro(572, - QS_BEGIN_PRE_) - -//! union initialization -//! @tr{DVR-QS-PCLP-708} --efunc(708, - QS_f64_fmt_) - -//! union member not referenced -//! @tr{DVR-QS-PCLP-754} --esym(754, - Variant::aFlt, - AFltVar::prio, - *U32Rep::u32) - -//! Constant expression evaluates to 0 in 'binary' operation '>>' -//! @tr{DVR-QS-PCLP-778} --emacro(778, - QS_BEGIN_PRE_) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVR-QS-PCLP-818} --efile(826, - -qs_rx.c, - -qutest.c) - -//! definition of macro ends in semicolon -//! @tr{DVR-QS-PCLP-823} --esym(823, - QS_CRIT_STAT, - QS_BEGIN_PRE_) - -//! the right operand to << always evaluates to 0 -//! @tr{DVR-QS-PCLP-845} --emacro(845, - QS_BEGIN_PRE_) - -//! cast increases required alignment -//! @tr{DVP-QS-PCLP-2445} --efunc(2445, - QS_rxHandleGoodFrame_, - QS_rxPoke_) - diff --git a/ports/lint-plus2/qk/qp_port.h b/ports/lint-plus2/qk/qp_port.h deleted file mode 100644 index ce5a3878..00000000 --- a/ports/lint-plus2/qk/qp_port.h +++ /dev/null @@ -1,94 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-01 -//! @version Last updated for: @ref qpc_7_3_4 -//! -//! @file -//! @brief QP/C "port" to PC-Lint-Plus, QK kernel, generic C99 - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN [[noreturn]] void - -// QF configuration for QK -- data members of the QActive class... - -// QK event-queue used for AOs -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QF "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// interrupt disabling mechanism -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -// QF critical section mechanism -#define QF_CRIT_STAT uint32_t crit_stat_; -#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) -#define QF_CRIT_EXIT() critExit(crit_stat_) - -// Check if the code executes in the ISR context -#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U) - -// Define the ISR entry sequence -#define QK_ISR_ENTRY() ((void)0) - -// Define the ISR exit sequence -#define QK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ -} while (false) - -void intDisable(void); -void intEnable(void); -uint32_t critEntry(void); -void critExit(uint32_t stat); -uint32_t QK_get_IPSR(void); - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QK kernel uses the native QP event queue -#include "qmpool.h" // QK kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qk.h" // QK kernel - -#endif // QP_PORT_H_ - diff --git a/ports/lint-plus2/ql-style.lnt b/ports/lint-plus2/ql-style.lnt deleted file mode 100644 index c4e6efaa..00000000 --- a/ports/lint-plus2/ql-style.lnt +++ /dev/null @@ -1,562 +0,0 @@ -// --------------------------------------------------------------------------- -// Copyright Gimpel Software LLC 2019. All rights reserved. -// -// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for -// use with PC-lint Plus. Redistribution is permitted but any redistribution -// must preserve this notice and, if the redistributed file has been modified, -// provide notice that the file has been modified from the original. -// --------------------------------------------------------------------------- - -// Adapted by Quantum Leaps from au-barr.lnt -// -// ql-style.lnt.lnt -- Author options - Quantum-Leaps:2018 -// -// This options file contains options to help enforce the -// checks advocated by the Quantum Leaps Coding Standard -// https://barrgroup.com/Embedded-Systems/Books/Embedded-C-Coding-Standard - -//========== GENERAL RULES ========== - -// 1.2 Line Widths - - /* not currently supported */ - -// 1.3 Braces - - /* 9012 - body should be a compound statement */ - +e9012 - -append(9012,[BARR-C:2018 Rule 1.3a]) - -// 1.4 Parentheses - - /* 9050 - dependence placed on precedence */ - +e9050 - -append(9050,[BARR-C:2018 Rule 1.4a]) - - /* 9097 - unparenthesized argument to sizeof */ - +e9097 - -append(9097,[BARR-C:2018 Rule 1.4a]) - - /* 821 - right hand side of assignment not parenthesized */ - +e821 - -append(821,[BARR-C:2018 Rule 1.4a]) - - /* 834 - operator op1 followed by operator op2 could be confusing */ - +e834 - -append(834,[BARR-C:2018 Rule 1.4a]) - - /* 9240 - left/right side of logical operator is not a primary expression */ - +e9240 - -append(9240,[BARR-C:2018 Rule 1.4b]) - -// 1.5 Common Abbreviations - - /* not currently supported */ - -// 1.6 Casts - - /* not currently supported */ - -// 1.7 Keywords to Avoid - - /* 586 - keyword is deprecated */ - -deprecate(keyword, auto,[BARR-C:2018 Rule 1.7a]) - -deprecate(keyword, register,[BARR-C:2018 Rule 1.7b]) - -deprecate(keyword, continue,[BARR-C:2018 Rule 1.7d]) - - /* 801 - goto statement used */ - +e801 - -append(801,[BARR-C:2018 Rule 1.7c]) - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 1.7c]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 1.7c]) - -// 1.8 Keywords to Frequent - - /* 765 - external symbol could be made static */ - +e765 - -append(765,[BARR-C:2018 Rule 1.8a]) - - /* 818 - parameter of function could be pointer to const */ - +e818 - -append(818,[BARR-C:2018 Rule 1.8b]) - - /* 843 - static storage duration variable could be made const */ - +e843 - -append(843,[BARR-C:2018 Rule 1.8b]) - - /* 844 - static storage duration variable could be made pointer to const */ - +e844 - -append(844,[BARR-C:2018 Rule 1.8b]) - - /* 952 - parameter of function could be const */ - +e952 - -append(952,[BARR-C:2018 Rule 1.8b]) - - /* 953 - local variable could be const */ - +e953 - -append(953,[BARR-C:2018 Rule 1.8b]) - - /* 954 - local variable could be pointer to const */ - +e954 - -append(954,[BARR-C:2018 Rule 1.8b]) - - /* 2765 - reference to variable which is neither atomic nor volatile sig_atomic_t within signal handler */ - +e2765 - -append(2765,[BARR-C:2018 Rule 1.8c]) - -//========== COMMENTS ========== - -// 2.1 Acceptable Formats - - /* 427 - C++ comment continued via back-slash */ - +e427 - -append(427,[BARR-C:2018 Rule 2.1b]) - - /* 602 - nested block comment */ - +e602 - -append(602,[BARR-C:2018 Rule 2.1b]) - - /* 9059 - C comment contains C++ comment */ - +e9059 - -append(9059,[BARR-C:2018 Rule 2.1b]) - - // 9259 - C comment contains '://' sequence - +e9259 - -append(9259,[BARR-C:2018 Rule 2.1b]) - - /* 9066 - C++ comment contains C comment */ - +e9066 - -append(9066,[BARR-C:2018 Rule 2.1b]) - -// 2.2 Locations and Comments - - /* not statically checkable */ - -//========== WHITE SPACE RULES ========== - -// 3.1 Spaces - - /* not currently supported */ - -// 3.2 Alignment - - /* not currently supported */ - -// 3.3 Black Lines - - /* 783 - line does not end with a newline */ - +e783 - -append(783,[BARR-C:2018 Rule 3.3c]) - -// 3.4 Indentation - - /* 525 - unexpected negative indentation */ - +e525 - -append(525,[BARR-C:2018 Rule 3.4a]) - - /* 539 - unexpected positive indentation */ - +e539 - -append(539,[BARR-C:2018 Rule 3.4a]) - - /* 725 - unexpected lack of indentation */ - +e725 - -append(725,[BARR-C:2018 Rule 3.4a]) - -// 3.5 Tabs - - /* not currently supported */ - -// 3.6 Non-Printing Characters - - /* not currently supported */ - -//========== MODULE RULES ========== - -// 4.1 Naming Conventions - - /* 8517 - module does not end with '.c' */ - -hook(module_open, -cond(!('%[file_name]' ~ '[.]c$'), - +message(8517, "module '%[file_name]' should have '.c' extension"))) - +e8517 - -append(8517,[BARR-C:2018 Rule 4.1b]) - - /* 8518 - header does not end with '.h' */ - -hook(header_open, -cond(!('%[file_name]' ~ '[.]h$'), - +message(8517, "header '%[file_name]' should have '.h' extension"))) - +e8518 - -append(8518,[BARR-C:2018 Rule 4.1b]) - - /* 8519 - 'main' function defined in file that does not contain the word 'main' */ - -hook(func_decl, -cond('%[qual_name]' == 'main' && %[is_definition] && !('%[file]' ~ 'main'), - +message(8519, "main function defined in file '%[file]' which does not have the word 'main' in its name"))) - +e8519 - -append(8519,[BARR-C:2018 Rule 4.1d]) - -// 4.2 Header Files - - /* 451 - header file repeatedly included but has no header guard */ - +e451 - -append(451,[BARR-C:2018 Rule 4.2b]) - - /* 967 - header file does not have a standard include guard */ - +e967 - -append(967,[BARR-C:2018 Rule 4.2b]) - - /* 9107 - header cannot be included in more than one translation unit because of the definition of symbol */ - +e9107 - -append(9107,[BARR-C:2018 Rule 4.2c]) - - /* 755 - global macro not referenced */ - +e755 - -append(755,[BARR-C:2018 Rule 4.2c]) - - /* 756 - global typedef not referenced */ - +e756 - -append(756,[BARR-C:2018 Rule 4.2c]) - - /* 757 - global declarator not referenced */ - +e757 - -append(757,[BARR-C:2018 Rule 4.2c]) - - /* 758 - global tag not referenced */ - +e758 - -append(758,[BARR-C:2018 Rule 4.2c]) - - /* 759 - header declaration for symbol could be moved from header to module */ - +e759 - -append(759,[BARR-C:2018 Rule 4.2c]) - - /* 768 - global field not referenced */ - +e768 - -append(768,[BARR-C:2018 Rule 4.2c]) - - /* 769 - global enumeration constant not referenced */ - +e769 - -append(769,[BARR-C:2018 Rule 4.2c]) - -// 4.3 Source Files - - /* 9019 - declaration of symbol before #include */ - -append(9019,[BARR-C:2018 Rule 4.3b]) - - /* 8520 - #include used with absolute path */ - -hook(header_open, -cond('%[file_name]' ~ '^([[:alpha:]]:)?[/\\\\]', - +message(8520, "#include directive uses absolute path to include file '%[file_name]'"))) - +e8520 - -append(8520,[BARR-C:2018 Rule 4.3d]) - - /* 8521 - #include used to include module file */ - -hook(header_open, -cond('%[file_name]' ~ '[.]c$', - +message(8521, "#include directive used to include module file '%[file_name]'"))) - +e8521 - -append(8521,[BARR-C:2018 Rule 4.3f]) - -// 4.4 File Templates - - /* not statically checkable */ - -//========== DATA TYPE RULES ========== - - /* 8528 - non-anonymous struct/union/enum declared outside of typedef */ - -hook(record_decl, -cond(%[is_freestanding] && !%[is_anonymous], - +message(8528, "non-anonymous struct/union declared outside of a typedef"))) - -hook(enum_decl, -cond(%[is_freestanding] && '%[name]' != '', - +message(8528, "non-anonymous enum declared outside of a typedef"))) - +e8528 - -append(8528,[BARR-C:2018 Rule 5.1b]) - -// 5.2 Fixed-Width Integers - - /* 586 - keyword/type is deprecated */ - +e586 - - -deprecate(type,signed char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned char,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned short,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned int,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,signed long long,[BARR-C:2018 Rule 5.2a]) - -deprecate(type,unsigned long long,[BARR-C:2018 Rule 5.2a]) - - -deprecate(keyword, short,[BARR-C:2018 Rule 5.2b]) - -deprecate(keyword, long,[BARR-C:2018 Rule 5.2b]) - -// 5.3 Signed and Unsigned Integers - - /* 9420 - bitfield does not have unsigned type */ - +e9420 - -append(9420,[BARR-C:2018 Rule 5.3a]) - - /* 9130 - bitwise operator applied to signed underlying type */ - +e9130 - -append(9130,[BARR-C:2018 Rule 5.3b]) - - /* 570 - negative value loses sign during implicit conversion */ - +e570 - -append(570,[BARR-C:2018 Rule 5.3c]) - - /* 713 - implicit conversion from unsigned to signed may lose precision */ - +e713 - -append(713,[BARR-C:2018 Rule 5.3c]) - - /* 8524 - combining signed and unsigned types with operator op1 */ - -hook(binary_expr, -cond(%[walk_lhs_expr{false}.walk_type.is_integer] && - %[walk_rhs_expr{false}.walk_type.is_integer] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - '%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]' != - '%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]', - +message(8524, "combining signed and unsigned types with operator '%[opcode]'"))) - +e8524 - -append(8524,[BARR-C:2018 Rule 5.3c]) - -// 5.4 Floating Point - - /* 586 - type is deprecated */ - -deprecate(type,float,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,double,[BARR-C:2018 Rule 5.4b]) - -deprecate(type,long double,[BARR-C:2018 Rule 5.4b]) - - /* 777 - testing floating point values for equality */ - +e777 - -append(777,[BARR-C:2018 Rule 5.4b]) - - /* 9252 - testing floating point for equality using exact value */ - +e9252 - -append(9252,[BARR-C:2018 Rule 5.4b]) - -// 5.5 Structures and Unions - - /* not currently supported */ - -// 5.6 Booleans - - /* 8523 - cast to boolean */ - -hook(cast_expr, -cond(%[is_cstyle_cast] && %[walk_type.is_boolean], - +message(8523, "cast to boolean"))) - +e8523 - -append(8523,[BARR-C:2018 Rule 5.6b]) - -//========== PROCEDURE RULES ========== - -// 6.1 Naming Conventions - - /* 8501 - function has name that matches a keyword in C or C++ */ - -hook(func_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8501, "function '%[name]' matches the name of a C/C++ keyword"))) - +e8501 - -append(8501,[BARR-C:2018 Rule 6.1a]) - - /* 8502 - function has same name as standard library function */ - -hook(func_decl, -cond('%[name]' ~ '^(?:abort|abs|acos|acosf|acosh|acoshf|acoshl|acosl|asctime|asin|asinf|asinh|asinhf|asinhl|asinl|assert|atan|atan2|atan2f|atan2l|atanf|atanh|atanhf|atanhl|atanl|atexit|atof|atoi|atol|atoll|bsearch|btowc|cabs|cabsf|cabsl|cacos|cacosf|cacosh|cacoshf|cacoshl|cacosl|calloc|carg|cargf|cargl|casin|casinf|casinh|casinhf|casinhl|casinl|catan|catanf|catanh|catanhf|catanhl|catanl|cbrt|cbrtf|cbrtl|ccos|ccosf|ccosh|ccoshf|ccoshl|ccosl|ceil|ceilf|ceill|cexp|cexpf|cexpl|cimag|cimagf|cimagl|clearerr|clock|clog|clogf|clogl|conj|conjf|conjl|copysign|copysignf|copysignl|cos|cosf|cosh|coshf|coshl|cosl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|creal|crealf|creall|csin|csinf|csinh|csinhf|csinhl|csinl|csqrt|csqrtf|csqrtl|ctan|ctanf|ctanh|ctanhf|ctanhl|ctanl|ctime|difftime|div|erf|erfc|erfcf|erfcl|erff|erfl|exit|_Exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|fabs|fabsf|fabsl|fclose|fdim|fdimf|fdiml|feclearexcept|fegetenv|fegetexceptflag|fegetround|feholdexcept|feof|feraiseexcept|ferror|fesetenv|fesetexceptflag|fesetround|fetestexcept|feupdateenv|fflush|fgetc|fgetpos|fgets|fgetwc|fgetws|floor|floorf|floorl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|fmin|fminf|fminl|fmod|fmodf|fmodl|fopen|fpclassify|fprintf|fputc|fputs|fputwc|fputws|fread|free|freopen|frexp|frexpf|frexpl|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|getc|getchar|getenv|gets|getwc|getwchar|gmtime|hypot|hypotf|hypotl|ilogb|ilogbf|ilogbl|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless|islessequal|islessgreater|islower|isnan|isnormal|isprint|ispunct|isspace|isunordered|isupper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|iswlower|iswprint|iswpunct|iswspace|iswupper|iswxdigit|isxdigit|labs|ldexp|ldexpf|ldexpl|ldiv|lgamma|lgammaf|lgammal|llabs|lldiv|llrint|llrintf|llrintl|llround|llroundf|llroundl|localeconv|localtime|log|log10|log10f|log10l|log1p|log1pf|log1pl|log2|log2f|log2l|logb|logbf|logbl|logf|logl|longjmp|lrint|lrintf|lrintl|lround|lroundf|lroundl|malloc|mblen|mbrlen|mbrtowc|mbsinit|mbsrtowcs|mbstowcs|mbtowc|memchr|memcmp|memcpy|memmove|memset|mktime|modf|modff|modfl|nan|nanf|nanl|nearbyint|nearbyintf|nearbyintl|nextafter|nextafterf|nextafterl|nexttoward|nexttowardf|nexttowardl|perror|pow|powf|powl|printf|putc|putchar|puts|putwc|putwchar|qsort|raise|rand|realloc|remainder|remainderf|remainderl|remove|remquo|remquof|remquol|rename|rewind|rint|rintf|rintl|round|roundf|roundl|scalbln|scalblnf|scalblnl|scalbn|scalbnf|scalbnl|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sin|sinf|sinh|sinhf|sinhl|sinl|snprintf|sprintf|sqrt|sqrtf|sqrtl|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strtod|strtof|strtoimax|strtok|strtol|strtold|strtoll|strtoul|strtoull|strtoumax|strxfrm|swprintf|swscanf|system|tan|tanf|tanh|tanhf|tanhl|tanl|tgamma|tgammaf|tgammal|time|tmpfile|tmpnam|tolower|toupper|towctrans|towlower|towupper|trunc|truncf|truncl|ungetc|ungetwc|va_arg|va_copy|va_end|va_start|vfprintf|vfscanf|vfwprintf|vfwscanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcstod|wcstof|wcstoimax|wcstok|wcstol|wcstold|wcstoll|wcstombs|wcstoul|wcstoull|wcstoumax|wcsxfrm|wctob|wctomb|wctrans|wctype|wmemchr|wmemcmp|wmemcpy|wmemmove|wmemset|wprintf|wscanf)$', +message(8502, "function '%[name]' matches the name of a standard library function"))) - +e8502 - -append(8502,[BARR-C:2018 Rule 6.1b]) - - /* 8503 - function has name that begins with an underscore */ - -hook(func_decl, -cond('%[name]' ~ '^_', +message(8503, "function '%[name]' begins with an underscore"))) - +e8503 - -append(8503,[BARR-C:2018 Rule 6.1c]) - - /* 8504 - function name is longer than 31 characters */ - -hook(func_decl, -cond('%[name]' ~ '.{32,}', +message(8504, "function '%[name]' is longer than 31 characters"))) - +e8504 - -append(8504,[BARR-C:2018 Rule 6.1d]) - - /* 8506 - macro name contains lowercase letter(s) */ - -hook(macro_define, -cond(!%[is_builtin] && '%[name]' ~ '[[:lower:]]', +message(8506, "macro '%[name]' contains lowercase letters"))) - +e8506 - -append(8506,[BARR-C:2018 Rule 6.1f]) - -// 6.2 Functions - - /* 904 - return statement before end of function */ - +e904 - -append(904,[BARR-C:2018 Rule 6.2c]) - - /* 937 - old-style function declaration for function */ - +e937 - -append(937,[BARR-C:2018 Rule 6.2f]) - - /* 957 - function defined without a prototype in scope */ - +e957 - -append(957,[BARR-C:2018 Rule 6.2f]) - - /* 832 - parameter not explicitly declared, int assumed */ - +e832 - -append(832,[BARR-C:2018 Rule 6.2f]) - -// 6.3 Function-Like Macros - - /* 9026 - function-like macro defined */ - +e9026 - -append(9026,[BARR-C:2018 Rule 6.3a]) - - /* 665 - unparenthesized parameter in macro is passed an expression */ - +e665 - -append(665,[BARR-C:2018 Rule 6.3b]) - - /* 666 - expression with side effects passed to repeated parameter */ - +e666 - -append(666,[BARR-C:2018 Rule 6.3b]) - - /* 773 - expression-like macro not parenthesized */ - +e773 - -append(773,[BARR-C:2018 Rule 6.3b]) - - /* 9022 - unparenthesized macro parameter in definition of macro */ - +e9022 - -append(9022,[BARR-C:2018 Rule 6.3b]) - -// 6.4 Threads of Execution - - /* not currently supported */ - -// 6.5 Interrupt Service Routines - - /* not currently supported */ - -//========== VARIABLES ========== - -// 7.1 Naming Conventions - - /* 8507 - variable has name that matches a keyword in C or C++ */ - -hook(var_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|fortran|friend|goto|if|inline|int|interrupt|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8507, "variable '%[name]' matches the name of a C/C++ keyword"))) - +e8507 - -append(8507,[BARR-C:2018 Rule 7.1a]) - - /* 8525 - variable has same name as standard library variable */ - -hook(var_decl, -cond('%[name]' ~ '^(?:errno|stderr|stdin|stdout)$', - +message(8525, "variale '%[name]' matches the same name of a standard library variable"))) - +e8525 - -append(8525,[BARR-C:2018 Rule 7.1b]) - - /* 8508 - variable has name that begins with an underscore */ - -hook(var_decl, -cond('%[name]' ~ '^_', +message(8508, "variable '%[name]' begins with an underscore"))) - +e8508 - -append(8508,[BARR-C:2018 Rule 7.1c]) - - /* 8509 - variable name is longer than 31 characters */ - -hook(var_decl, -cond('%[name]' ~ '.{32,}', +message(8509, "variable '%[name]' is longer than 31 characters"))) - +e8509 - -append(8509,[BARR-C:2018 Rule 6.1d]) - - -// 7.2 Initialization - - /* 530 - likely using an uninitialized value */ - +e530 - -append(530,[BARR-C:2018 Rule 7.2a]) - - /* 603 - argument to parameter of type pointer to const may be a pointer to uninitialized memory */ - +e603 - -append(603,[BARR-C:2018 Rule 7.2a]) - - /* 644 - potentially using an uninitialized value */ - +e644 - -append(644,[BARR-C:2018 Rule 7.2a]) - - /* 708 - union initialization */ - +e708 - -append(708,[BARR-C:2018 Rule 7.2a]) - - /* 727 - static local symbol not explicitly initialized */ - +e727 - -append(727,[BARR-C:2018 Rule 7.2a]) - - /* 728 - file scope static variable not explicitly initialized */ - +e728 - -append(728,[BARR-C:2018 Rule 7.2a]) - - /* 729 - external variable not explicitly initialized */ - +e729 - -append(729,[BARR-C:2018 Rule 7.2a]) - - /* 738 - address of static local symbol not explicitly initialized before passed to a function */ - +e738 - -append(738,[BARR-C:2018 Rule 7.2a]) - - /* 784 - nul character truncated from string */ - +e784 - -append(784,[BARR-C:2018 Rule 7.2a]) - - /* 785 - too few initializers for aggregate */ - +e785 - -append(785,[BARR-C:2018 Rule 7.2a]) - -//========== STATEMENT RULES ========== - -// 8.1 Variable Declarations - - /* 9146 - multiple declarators in a declaration */ - +e9146 - -append(9146,[BARR-C:2018 Rule 8.1a]) - -// 8.2 Conditional Statements - - /* 720 - boolean test of assignment */ - +e720 - -append(720,[BARR-C:2018 Rule 8.2c]) - - /* 820 - boolean test of parenthesized assignment */ - +e820 - -append(820,[BARR-C:2018 Rule 8.2c]) - - /* 9013 - no 'else' at end of 'if ... else if' chain */ - +e9013 - -append(9013,[BARR-C:2018 Rule 8.2d]) - -// 8.3 Switch Statements - - /* 9014 - switch without default */ - +e9014 - -append(9014,[BARR-C:2018 Rule 8.3b]) - - /* 616 - control flow falls through to next case without an intervening comment */ - +e616 - -append(616,[BARR-C:2018 Rule 8.3c]) - -// 8.4 Loops - - /* 850 - for statement index variable modified in body */ - +e850 - -append(850,[BARR-C:2018 Rule 8.4b]) - - /* 716 - infinite loop via while */ - +e716 - -append(716,[BARR-C:2018 Rule 8.4c]) - -// 8.5 Jumps - - /* 9041 - goto appears in block which is not nested in block containing label */ - +e9041 - -append(9041,[BARR-C:2018 Rule 8.5a]) - - /* 9064 - goto references earlier label */ - +e9064 - -append(9064,[BARR-C:2018 Rule 8.5a]) - - /* 586 - function/macro is deprecated */ - -deprecate(function,abort,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,exit,[BARR-C:2018 Rule 8.5b]) - -deprecate(function,longjmp,[BARR-C:2018 Rule 8.5b]) - -deprecate(macro,setjmp,[BARR-C:2018 Rule 8.5b]) - -// 8.6 Equivalence Test - - /* 8522 - variable should appear on RHS of '==' operator */ - -hook(binary_expr, -cond('%[opcode]' == '==' && - '%[walk_lhs_expr.walk_past_paren_cast.set_msg_loc.is_decl_ref_expr]' == 'true' && - '%[walk_rhs_expr.is_constant_expr]' == 'true', - +message(8522, "variable '%[walk_lhs_expr.walk_past_paren_cast.walk_decl.qual_name]' should appear on RHS of '==' operator"))) - +e8522 - -append(8522,[BARR-C:2018 Rule 8.6a]) diff --git a/ports/lint-plus2/qpc.lnt b/ports/lint-plus2/qpc.lnt deleted file mode 100644 index cb9681b8..00000000 --- a/ports/lint-plus2/qpc.lnt +++ /dev/null @@ -1,427 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-12-12 -//! @version Last updated for version: 7.3.1 -//! -//! @file -//! @brief PC-Lint-Plus option file for analysing both **QP/C** -//! and **QP/C Applications** - -// C Language Standard --std=c99 // apply the C99 Language Standard - -//! M4-D4.8(A) complete definition is unnecessary in this translation unit -//! @tr{DVP-QP-MC4-D04_08} --efile(9045, - -qp.h, - -qequeue.h, - -qmpool.h, - -qv.h, - -qk.h, - -qxk.h, - -qs.h) - -// Functional Safety (FuSa) System -------------------------------------------- - -// "no return" semantics for error/failure callbacks --sem(Q_onError, r_no) --sem(assert_failed, r_no) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} (false-positive) --esym(9026, - Q_DEFINE_THIS_MODULE, - Q_ASSERT_STATIC, - Q_ASSERT, - Q_ASSERT_ID, - Q_ERROR, - Q_ERROR_ID, - Q_REQUIRE, - Q_REQUIRE_ID, - Q_ENSURE, - Q_ENSURE_ID, - Q_INVARIANT, - Q_INVARIANT_ID, - Q_DIM) - -//! PCLP definition of macro ends in semicolon -//! @tr{DVP-QP-PCLP-823} --esym(823, - Q_DEFINE_THIS_MODULE, - Q_DEFINE_THIS_FILE) - -//! BARR-C(R1.8b) parameter of function could be const --efunc(952, - Q_onError -) - -// QEP ----------------------------------------------------------------------- -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} (false-positive) --esym(9026, - Q_UNUSED_PAR, - Q_TRAN, - Q_TRAN_HIST, - Q_SUPER, - Q_HANDLED, - Q_UNHANDLED, - Q_IGNORED, - Q_ASM_UPCAST, - Q_HSM_UPCAST, - Q_MSM_UPCAST, - Q_EVT_CAST, - QEVT_INITIALIZER, - Q_UINT2PTR_CAST, - Q_STATE_CAST, - Q_ACTION_CAST, - QASM_INIT, - QASM_DISPATCH, - QASM_IS_IN) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09B} (correct identification) --esym(9026, - QM_ENTRY, - QM_EXIT, - QM_SM_EXIT, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_HIST, - QM_TRAN_EP, - QM_TRAN_XP, - QM_SUPER, - QM_SUPER_SUB, - QM_HANDLED, - QM_UNHANDLED, - QMSM_INIT, - QMSM_DISPATCH) - -//! M4-R11.1(R) conversion between pointer to function type -//! @tr{DVP-QP-MC4-R11_01} --emacro(9074, - Q_STATE_CAST, - Q_ACTION_CAST, - Q_TRAN, - Q_TRAN_HIST, - Q_SUPER, - QM_ENTRY, - QM_EXIT, - QM_SM_EXIT, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_HIST, - QM_TRAN_EP, - QM_TRAN_XP) - -//! M4-R11.3(R) cast from pointer to pointer (upcast) -//! @tr{DVP-QP-MC4-R11_03A} --emacro(9087, - Q_ASM_UPCAST, - Q_HSM_UPCAST, - Q_MSM_UPCAST, - QM_TRAN, - QM_TRAN_EP, - QM_TRAN_INIT) - -//! M4-R11.3(R) cast from pointer to pointer (downcast) -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - Q_EVT_CAST) - -//! M4-R12.3(A) comma operator used -//! @tr{DVP-QP-MC4-R12_03} --emacro(9008, - Q_SUPER, - Q_TRAN, - Q_TRAN_HIST, - QM_ENTRY, - QM_EXIT, - QM_SUPER_SUB, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_EP, - QM_TRAN_XP, - QM_SM_EXIT, - QM_SUPER_SUB) - -//! M4-R13.4(A) result of assignment used in left operand to ',' operator -//! @tr{DVP-QP-MC4-R13_04} --emacro(9084, - Q_SUPER, - Q_TRAN, - QM_ENTRY, - QM_EXIT, - QM_TRAN, - QM_TRAN_INIT, - QM_TRAN_HIST, - QM_TRAN_EP, - QM_TRAN_XP, - QM_SM_EXIT, - QM_SUPER_SUB) - -//! M4-R19.2(A) union declared -//! @tr{DVP-QP-MC4-R19_02} --esym(9018, - QAsmAttr) - -//! '' not referenced in QM-style state machines -//! @tr{DVP-QP-PCLP-754} --esym(754, - *(anonymous struct)::act, - *(anonymous struct)::target) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVP-QP-PCLP-826} --emacro(826, - Q_EVT_CAST) - -// deprecated QEP facilities... --deprecate( type, QFsm, QP/C API pre 5.4.x) --deprecate( function, QFsm_ctor, QP/C API pre 5.4.x) --deprecate( function, QF_onIdle, QP/C API pre 5.4.x) --deprecate( macro, Q_IGNORED, QP/C API pre 5.4.x) --deprecate( macro, QMSM_INIT, QP/C API pre 5.8.x) --deprecate( macro, QMSM_DISPATCH, QP/C API pre 5.8.x) - -// QF ------------------------------------------------------------------------ - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09B} --esym(9026, - QF_INT_DISABLE, - QF_INT_ENABLE, - Q_PRIO, - QF_LOG2, - Q_NEW, - Q_NEW_X, - Q_NEW_REF, - Q_DELETE_REF, - QF_PUBLISH, - QF_CRIT_ENTRY, - QF_CRIT_EXIT, - QF_CRIT_EXIT_NOP, - QF_MEM_SYS, - QF_MEM_APP, - QF_MPOOL_EL, - QF_LOG2, - QF_EPOOL_INIT_, - QF_EPOOL_EVENT_SIZE_, - QF_EPOOL_GET_, - QF_EPOOL_PUT_, - QF_PTR_INC_, - QACTIVE_START, - QACTIVE_POST, - QACTIVE_POST_X, - QACTIVE_POST_LIFO, - QACTIVE_PUBLISH, - QACTIVE_EQUEUE_WAIT_, - QACTIVE_EQUEUE_SIGNAL_, - QACTIVE_EQUEUE_ONEMPTY_, - QTIMEEVT_TICK, - QTIMEEVT_TICK_X, - QTICKER_TRIG, - QF_TICK, - QF_TICK_X) - -//! M4-R11.3(R) cast to pointer to different object type (upcast) -//! @tr{DVP-QP-MC4-R11_03A} --emacro(9087, - QACTIVE_POST, - QACTIVE_POST_LIFO) - -//! M4-R11.3(R) cast to pointer to different object type (downcast) -//! @tr{DVP-QP-MC4-R11_03B} --emacro(9087, - Q_NEW, - Q_NEW_X) - -//! suspicious pointer-to-pointer conversion (area too small) -//! @tr{DVP-QP-PCLP-826} --emacro(826, - QACTIVE_POST, - QACTIVE_POST_X, - QACTIVE_POST_LIFO, - Q_NEW, - Q_NEW_X) - -// deprecated QF facilities... --deprecate( macro,QTimeEvt_ctor, QP/C API pre 5.8.x) --deprecate( macro,QTimeEvt_postIn, QP/C API pre 5.8.x) --deprecate( macro,QTimeEvt_postEvery, QP/C API pre 5.8.x) - -// QV ------------------------------------------------------------------------ -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QV_CPU_SLEEP) - -// QK ------------------------------------------------------------------------ -// M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QK_ISR_ENTRY, - QK_ISR_EXIT, - QK_ISR_CONTEXT_) - -// QXK ----------------------------------------------------------------------- -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QP-MC4-D04_09A} --esym(9026, - QXK_ISR_ENTRY, - QXK_ISR_EXIT, - QXK_TLS, - QXTHREAD_START, - QXTHREAD_POST_X) - -// deprecated QXK facilities... --deprecate( macro, Q_XTHREAD_CAST, QP/C API pre 6.7.x) - -// QS ------------------------------------------------------------------------ - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QS-MC4-D04_09A} --esym(9026, - QS_INIT, - QS_EXIT, - QS_DUMP, - QS_RESET, - QS_GLB_FILTER, - QS_LOC_FILTER, - QS_FILTER_ON, - QS_FILTER_OFF, - QS_FILTER_SM_OBJ, - QS_FILTER_AO_OBJ, - QS_FILTER_MP_OBJ, - QS_FILTER_EQ_OBJ, - QS_FILTER_TE_OBJ, - QS_FILTER_AP_OBJ, - QS_GET_BYTE, - QS_GET_BLOCK, - QS_BEGIN, - QS_BEGIN_ID, - QS_END, - QS_BEGIN_INCRIT, - QS_END_INCRIT, - QS_TR_CRIT_ENTRY, - QS_TR_CRIT_EXIT, - QS_TR_ISR_ENTRY, - QS_TR_ISR_EXIT, - QS_ONLY, - QS_REC_DONE, - QS_I8, - QS_U8, - QS_I16, - QS_U16, - QS_I32, - QS_I64, - QS_U32, - QS_F32, - QS_F64, - QS_U64, - QS_U32_HEX, - QS_STR, - QS_OBJ, - QS_FUN, - QS_SIG_DICTIONARY, - QS_OBJ_DICTIONARY, - QS_OBJ_ARR_DICTIONARY, - QS_FUN_DICTIONARY, - QS_USR_DICTIONARY, - QS_ENUM_DICTIONARY, - QS_ASSERTION, - QS_FLUSH, - QS_MEM, - QS_SIG, - QS_ENUM, - QS_PTR_AT_, - QS_RX_PUT, - QS_OUTPUT, - QS_RX_INPUT, - QS_TEST_PAUSE, - QS_TEST_PROBE_DEF, - QS_TEST_PROBE, - QS_TEST_PROBE_ID) - -//! M4-D4.9(A) function-like macro -//! @tr{DVP-QS-MC4-D04_09A} --esym(9026, - QS_CRIT_ENTRY, - QS_CRIT_EXIT, - QS_MEM_SYS, - QS_MEM_APP, - QS_GLB_CHECK_, - QS_LOC_CHECK_, - QS_BEGIN_PRE_, - QS_END_PRE_, - QS_U8_PRE_, - QS_2U8_PRE_, - QS_U16_PRE_, - QS_U32_PRE_, - QS_STR_PRE_, - QS_TIME_PRE_, - QS_SIG_PRE_, - QS_EVS_PRE_, - QS_OBJ_PRE_, - QS_FUN_PRE_, - QS_EQC_PRE_, - QS_MPC_PRE_, - QS_MPS_PRE_, - QS_TEC_PRE_) - -//! M4-R11.1(R) conversion between pointer to function type -//! @tr{DVP-QS-MC4-R11_01} --emacro(9074, - QS_FUN_DICTIONARY, - QS_TEST_PROBE_DEF) - -// M4-R15.5(A) return statement before end of function -//! @tr{DVP-QS-MC4-R15_05} --emacro(904, - QS_TEST_PROBE) - -//! M4-R19.2(A) union declared -//! @tr{DVR-QS-MC4-R19_02} --esym(9018, - Variant) - -//! M4-R20.10(A) stringize operator -//! @tr{DVP-QS-MC4-R20_10} --esym(9024, - QS_OBJ_DICTIONARY, - QS_OBJ_ARR_DICTIONARY, - QS_FUN_DICTIONARY, - QS_SIG_DICTIONARY, - QS_USR_DICTIONARY, - QS_ENUM_DICTIONARY) - -//! implicit conversion of enum to integral type 'int' -//! @tr{DVP-QS-PCLP-641} --emacro(641, - QS_SIG_DICTIONARY) - -//! definition of macro ends in semicolon -//! @tr{DVP-QS-PCLP-823} --esym(823, - QS_TEST_PROBE_DEF) diff --git a/ports/lint-plus2/qv/qp_port.h b/ports/lint-plus2/qv/qp_port.h deleted file mode 100644 index 536fe652..00000000 --- a/ports/lint-plus2/qv/qp_port.h +++ /dev/null @@ -1,86 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-01 -//! @version Last updated for: @ref qpc_7_3_4 -//! -//! @file -//! @brief QP/C "port" to PC-Lint-Plus, QV kernel, generic C99 - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN [[noreturn]] void - -// QF configuration for QV -- data members of the QActive class... - -// QV event-queue used for AOs -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QF "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// interrupt disabling mechanism -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -// QF critical section mechanism -#define QF_CRIT_STAT uint32_t crit_stat_; -#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) -#define QF_CRIT_EXIT() critExit(crit_stat_) - -#define QV_CPU_SLEEP() \ -do { \ - __disable_interrupt(); \ - QF_INT_ENABLE(); \ - __WFI(); \ - __enable_interrupt(); \ -} while (false) - -void intDisable(void); -void intEnable(void); -uint32_t critEntry(void); -void critExit(uint32_t stat); - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QV kernel uses the native QP event queue -#include "qmpool.h" // QV kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qv.h" // QV kernel - -#endif // QP_PORT_H_ - diff --git a/ports/lint-plus2/qxk/qp_port.h b/ports/lint-plus2/qxk/qp_port.h deleted file mode 100644 index 375d137c..00000000 --- a/ports/lint-plus2/qxk/qp_port.h +++ /dev/null @@ -1,101 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-05-01 -//! @version Last updated for: @ref qpc_7_3_4 -//! -//! @file -//! @brief QP/C "port" to PC-Lint-Plus, QXK kernel, generic C99 - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN [[noreturn]] void - -// QF configuration for QXK -- data members of the QActive class... - -// QXK event-queue type used for AOs and eXtended threads. -#define QACTIVE_EQUEUE_TYPE QEQueue - -// QXK OS-Object type used for the private stack pointer for eXtended threads. -// (The private stack pointer is NULL for basic-threads). -#define QACTIVE_OS_OBJ_TYPE void* - -// QF "thread" type used to store the MPU settings in the AO -#define QACTIVE_THREAD_TYPE void const * - -// interrupt disabling mechanism -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -// QF critical section mechanism -#define QF_CRIT_STAT uint32_t crit_stat_; -#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) -#define QF_CRIT_EXIT() critExit(crit_stat_) - -// Check if the code executes in the ISR context -#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) - -// Define the ISR entry sequence -#define QXK_ISR_ENTRY() ((void)0) - -// Define the ISR exit sequence -#define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ -} while (false) - -#define QXK_CONTEXT_SWITCH_() (QXK_trigPendSV()) - -void intDisable(void); -void intEnable(void); -uint32_t critEntry(void); -void critExit(uint32_t stat); -uint32_t QXK_get_IPSR(void); -void QXK_trigPendSV(void); - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QXK kernel uses the native QP event queue -#include "qmpool.h" // QXK kernel uses the native QP memory pool -#include "qp.h" // QP framework -#include "qxk.h" // QXK kernel - -#endif // QP_PORT_H_ - diff --git a/ports/lint-plus2/std.lnt b/ports/lint-plus2/std.lnt deleted file mode 100644 index 722f7106..00000000 --- a/ports/lint-plus2/std.lnt +++ /dev/null @@ -1,44 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-06-06 -//! @version Last updated for version: 7.3.0 -//! -//! @file -//! @brief PC-Lint-Plus standard option file - -// message formatting options... --hF1 // output: a single line -+ffn // use full path names --width(120,4) // break lines after 99 characters with 4 characters indent -+flm // make sure no foreign includes change the format - --zero(99) // don't stop because of warnings --passes(2) // make two passes (for better error messages) --restore_at_end // don't let -e options bleed to other files --summary() // output a summary of all produced messages - -// globally suppress the following warnings: --e546 // explicitly taking address of function --e717 // monocarpic do-while used to group statements diff --git a/ports/lint-plus2/stdbool.h b/ports/lint-plus2/stdbool.h deleted file mode 100644 index acefc5f2..00000000 --- a/ports/lint-plus2/stdbool.h +++ /dev/null @@ -1,30 +0,0 @@ -//! @file -//! @brief Boolean type and constansts. WG14/N843 C99 Standard, Section 7.16 -//! -//! @description -//! This header is part of the ANSI C99 standard library to define the -//! standard Boolean type as well as the 'true' and 'false' constansts. -#ifndef STDBOOL_H_ -#define STDBOOL_H_ - -//lint -save -//lint -e9071 M3-R21.1(r), defined macro is reserved to the compiler -//lint -e9093 the name is reserved to the compiler -//lint -emacro(8523, false, true) cast to boolean - -#ifndef __cplusplus - -typedef _Bool bool; //!< standard Boolean data type - -//! standard 'false' constant -#define false ((bool)0) - -//! standard 'true' constant -#define true ((bool)1) - -#endif // !__cplusplus - -//lint -restore - -#endif // STDBOOL_H_ - diff --git a/ports/msp430/qk/qp_port.h b/ports/msp430/qk/qp_port.h index be004a4b..aac07481 100644 --- a/ports/msp430/qk/qp_port.h +++ b/ports/msp430/qk/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to MSP430, QK kernel, TI, GNU, IAR compilers @@ -36,10 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#include "qp_config.h" // external QP configuration required in this port +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application #if defined(__TI_COMPILER_VERSION__) || defined(__GNUC__) // no-return function specifier (C11 Standard) diff --git a/ports/msp430/qk/qs_port.h b/ports/msp430/qk/qs_port.h index 65f5a327..e8d3f8f5 100644 --- a/ports/msp430/qk/qs_port.h +++ b/ports/msp430/qk/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. diff --git a/ports/msp430/qutest/qp_port.h b/ports/msp430/qutest/qp_port.h index c6f3b044..1238ed36 100644 --- a/ports/msp430/qutest/qp_port.h +++ b/ports/msp430/qutest/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C "port" for QUTEST on MSP430, generic C11 compiler @@ -36,10 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#include "qp_config.h" // external QP configuration required in this port +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application #if defined(__TI_COMPILER_VERSION__) || defined(__GNUC__) // no-return function specifier (C11 Standard) @@ -88,8 +87,7 @@ #define QF_SCHED_UNLOCK_() ((void)0) // native event queue operations - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(110, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) #ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ diff --git a/ports/msp430/qutest/qs_port.h b/ports/msp430/qutest/qs_port.h index 65f5a327..e8d3f8f5 100644 --- a/ports/msp430/qutest/qs_port.h +++ b/ports/msp430/qutest/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. diff --git a/ports/msp430/qv/qp_port.h b/ports/msp430/qv/qp_port.h index 101b994c..533c0e18 100644 --- a/ports/msp430/qv/qp_port.h +++ b/ports/msp430/qv/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to MSP430, QV kernel, TI, GNU, IAR compilers @@ -36,10 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#include "qp_config.h" // external QP configuration required in this port +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application #if defined(__TI_COMPILER_VERSION__) || defined(__GNUC__) // no-return function specifier (C11 Standard) diff --git a/ports/msp430/qv/qs_port.h b/ports/msp430/qv/qs_port.h index 65f5a327..e8d3f8f5 100644 --- a/ports/msp430/qv/qs_port.h +++ b/ports/msp430/qv/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. diff --git a/ports/posix-qutest/CMakeLists.txt b/ports/posix-qutest/CMakeLists.txt deleted file mode 100644 index 79dad1d5..00000000 --- a/ports/posix-qutest/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# ports/posix-qutest -target_include_directories(qpc PUBLIC .) -target_sources(qpc PRIVATE - qutest_port.c -) \ No newline at end of file diff --git a/ports/posix-qutest/qp_port.h b/ports/posix-qutest/qp_port.h deleted file mode 100644 index 7f0198ee..00000000 --- a/ports/posix-qutest/qp_port.h +++ /dev/null @@ -1,108 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-10 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QP/C "port" for QUTEST unit test harness, generic C11 compiler - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -// no-return function specifier (C11 Standard) -#define Q_NORETURN _Noreturn void - -// QUTest event queue and thread types -#define QACTIVE_EQUEUE_TYPE QEQueue -// QACTIVE_OS_OBJ_TYPE not used in this port -// QACTIVE_THREAD_TYPE not used in this port - -// QF interrupt disable/enable -#define QF_INT_DISABLE() (QS_onIntDisable()) -#define QF_INT_ENABLE() (QS_onIntEnable()) - -// QF critical section -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() QF_INT_DISABLE() -#define QF_CRIT_EXIT() QF_INT_ENABLE() - -// QF_LOG2 not defined -- use the internal LOG2() implementation - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QUTest port uses QEQueue event-queue -#include "qmpool.h" // QUTest port uses QMPool memory-pool -#include "qp.h" // QP platform-independent public interface - -void QS_onIntDisable(void); -void QS_onIntEnable(void); - -//============================================================================ -// interface used only inside QF implementation, but not in applications - -#ifdef QP_IMPL - - // QUTest scheduler locking (not used) - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - // native event queue operations - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(305, (me_)->eQueue.frontEvt != (QEvt *)0) -#ifndef Q_UNSAFE - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) -#else - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) -#endif - - // native QF event pool operations - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - #define QF_EPOOL_PUT_(p_, e_, qsId_) \ - (QMPool_put(&(p_), (e_), (qsId_))) - -#endif // QP_IMPL - -#endif // QP_PORT_H_ - diff --git a/ports/posix-qutest/qs_port.h b/ports/posix-qutest/qs_port.h deleted file mode 100644 index 4cc04e7d..00000000 --- a/ports/posix-qutest/qs_port.h +++ /dev/null @@ -1,62 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to POSIX with GNU - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -#if defined(__LP64__) || defined(_LP64) // 64-bit architecture? - #define QS_OBJ_PTR_SIZE 8U - #define QS_FUN_PTR_SIZE 8U -#else // 32-bit architecture - #define QS_OBJ_PTR_SIZE 4U - #define QS_FUN_PTR_SIZE 4U -#endif - -void QS_output(void); // handle the QS output -void QS_rx_input(void); // handle the QS-RX input - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/posix-qutest/qutest_port.c b/ports/posix-qutest/qutest_port.c deleted file mode 100644 index e8b79c7f..00000000 --- a/ports/posix-qutest/qutest_port.c +++ /dev/null @@ -1,301 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C "port" to QUTest with POSIX - -// expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) -#define _POSIX_C_SOURCE 200809L - -#ifndef Q_SPY - #error "Q_SPY must be defined for QUTest application" -#endif // Q_SPY - -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#include "qs_port.h" // QS port - -#include "safe_std.h" // portable "safe" / facilities -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define QS_TX_SIZE (8*1024) -#define QS_RX_SIZE (2*1024) -#define QS_TX_CHUNK QS_TX_SIZE -#define QS_TIMEOUT_MS 10L - -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 - -Q_DEFINE_THIS_MODULE("qutest_port") - -// local variables ........................................................... -static int l_sock = INVALID_SOCKET; -static struct timespec const c_timeout = { 0, QS_TIMEOUT_MS*1000000L }; - -static void sigIntHandler(int dummy); // prototype -static void sigIntHandler(int dummy) { - (void)dummy; // unused parameter - QS_onCleanup(); - //PRINTF_S("\n%s\n"," disconnecting from QSPY"); - exit(-1); -} - -//............................................................................ -uint8_t QS_onStartup(void const *arg) { - // initialize the QS transmit and receive buffers - static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel - QS_initBuf(qsBuf, sizeof(qsBuf)); - - static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - char hostName[128]; - char const *serviceName = "6601"; // default QSPY server port - char const *src; - char *dst; - int status; - - struct addrinfo *result = NULL; - struct addrinfo *rp = NULL; - struct addrinfo hints; - int sockopt_bool; - - // extract hostName from 'arg' (hostName:port_remote)... - src = (arg != (void *)0) - ? (char const *)arg - : "localhost"; // default QSPY host - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName) - 1])) - { - *dst++ = *src++; - } - *dst = '\0'; // zero-terminate hostName - - // extract serviceName from 'arg' (hostName:serviceName)... - if (*src == ':') { - serviceName = src + 1; - } - //printf(" Connecting to QSPY on Host=%s:%s...\n", - // hostName, serviceName); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - status = getaddrinfo(hostName, serviceName, &hints, &result); - if (status != 0) { - FPRINTF_S(stderr, - " ERROR cannot resolve host Name=%s:%s,Err=%d\n", - hostName, serviceName, status); - goto error; - } - - for (rp = result; rp != NULL; rp = rp->ai_next) { - l_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (l_sock != INVALID_SOCKET) { - if (connect(l_sock, rp->ai_addr, rp->ai_addrlen) - == SOCKET_ERROR) - { - close(l_sock); - l_sock = INVALID_SOCKET; - } - break; - } - } - - freeaddrinfo(result); - - // socket could not be opened & connected? - if (l_sock == INVALID_SOCKET) { - FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " - "host=%s:%s\n", - hostName, serviceName); - goto error; - } - - // set the socket to non-blocking mode - status = fcntl(l_sock, F_GETFL, 0); - if (status == -1) { - FPRINTF_S(stderr, - " ERROR Socket configuration failed errno=%d\n", - errno); - QS_EXIT(); - goto error; - } - if (fcntl(l_sock, F_SETFL, status | O_NONBLOCK) != 0) { - FPRINTF_S(stderr, " ERROR Failed to set non-blocking socket " - "errno=%d\n", errno); - QF_stop(); // <== stop and exit the application - goto error; - } - - // configure the socket to reuse the address and not to linger - sockopt_bool = 1; - setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, - &sockopt_bool, sizeof(sockopt_bool)); - sockopt_bool = 0; // negative option - setsockopt(l_sock, SOL_SOCKET, SO_LINGER, - &sockopt_bool, sizeof(sockopt_bool)); - QS_onFlush(); - - // install the SIGINT (Ctrl-C) signal handler - struct sigaction sig_act; - memset(&sig_act, 0, sizeof(sig_act)); - sig_act.sa_handler = &sigIntHandler; - sigaction(SIGINT, &sig_act, NULL); - - return 1U; // success - -error: - return 0U; // failure -} -//............................................................................ -void QS_onCleanup(void) { - nanosleep(&c_timeout, NULL); // allow the last QS output to come out - if (l_sock != INVALID_SOCKET) { - close(l_sock); - l_sock = INVALID_SOCKET; - } - //PRINTF_S("%s\n", " Disconnected from QSPY"); -} -//............................................................................ -void QS_onReset(void) { - QS_onCleanup(); - //PRINTF_S("\n%s\n", "QS_onReset"); - exit(0); -} -//............................................................................ -void QS_onFlush(void) { - // NOTE: - // No critical section in QS_onFlush() to avoid nesting of critical sections - // in case QS_onFlush() is called from Q_onError(). - if (l_sock == INVALID_SOCKET) { // socket NOT initialized? - FPRINTF_S(stderr, " ERROR %s\n", - "invalid TCP socket"); - QF_stop(); // <== stop and exit the application - return; - } - - uint16_t nBytes = QS_TX_CHUNK; - uint8_t const *data; - while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - for (;;) { // for-ever until break or return - int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { // sending failed? - if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) { - // sleep for the timeout and then loop back - // to send() the SAME data again - nanosleep(&c_timeout, NULL); - } - else { // some other socket error... - FPRINTF_S(stderr, " ERROR sending data over TCP," - "errno=%d\n", errno); - QF_stop(); // <== stop and exit the application - return; - } - } - else if (nSent < (int)nBytes) { // sent fewer than requested? - nanosleep(&c_timeout, NULL); // sleep for the timeout - // adjust the data and loop back to send() the rest - data += nSent; - nBytes -= (uint16_t)nSent; - } - else { - break; // break out of the for-ever loop - } - } - // set nBytes for the next call to QS_getBlock() - nBytes = QS_TX_CHUNK; - } -} - -//............................................................................ -void QS_onTestLoop() { - fd_set readSet; - FD_ZERO(&readSet); - - QS_rxPriv_.inTestLoop = true; - while (QS_rxPriv_.inTestLoop) { - FD_SET(l_sock, &readSet); - - struct timeval timeout = { - (long)0, (long)(QS_TIMEOUT_MS * 1000) - }; - - // selective, timed blocking on the TCP/IP socket... - timeout.tv_usec = (long)(QS_TIMEOUT_MS * 1000); - int status = select(l_sock + 1, &readSet, - (fd_set *)0, (fd_set *)0, &timeout); - if (status < 0) { - FPRINTF_S(stderr, " ERROR socket select,errno=%d\n", - errno); - QF_stop(); // <== stop and exit the application - } - else if ((status > 0) && FD_ISSET(l_sock, &readSet)) { // socket ready - status = recv(l_sock, - (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { // any data received? - QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = (QSCtr)status; // # bytes received - QS_rxParse(); // parse all received bytes - } - } - - QS_onFlush(); - } - // set inTestLoop to true in case calls to QS_onTestLoop() nest, - // which can happen through the calls to QS_TEST_PAUSE(). - QS_rxPriv_.inTestLoop = true; -} - -//............................................................................ -void QS_onIntDisable(void) { - if (QS_tstPriv_.intLock != 0U) { - Q_onError(&Q_this_module_[0], 998); - } - ++QS_tstPriv_.intLock; -} -//............................................................................ -void QS_onIntEnable(void) { - --QS_tstPriv_.intLock; - if (QS_tstPriv_.intLock != 0U) { - Q_onError(&Q_this_module_[0], 999); - } -} diff --git a/ports/posix-qutest/safe_std.h b/ports/posix-qutest/safe_std.h deleted file mode 100644 index c752662c..00000000 --- a/ports/posix-qutest/safe_std.h +++ /dev/null @@ -1,106 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities -#ifndef SAFE_STD_H -#define SAFE_STD_H - -#include -#include - -// portable "safe" facilities from and ................ -#ifdef _WIN32 // Windows OS? - -#define MEMMOVE_S(dest_, num_, src_, count_) \ - memmove_s(dest_, num_, src_, count_) - -#define STRNCPY_S(dest_, destsiz_, src_) \ - strncpy_s(dest_, destsiz_, src_, _TRUNCATE) - -#define STRCAT_S(dest_, destsiz_, src_) \ - strcat_s(dest_, destsiz_, src_) - -#define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, __VA_ARGS__) - -#define PRINTF_S(format_, ...) \ - printf_s(format_, __VA_ARGS__) - -#define FPRINTF_S(fp_, format_, ...) \ - fprintf_s(fp_, format_, __VA_ARGS__) - -#ifdef _MSC_VER -#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ - fread_s(buf_, bufsiz_, elsiz_, count_, fp_) -#else -#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ - fread(buf_, elsiz_, count_, fp_) -#endif // _MSC_VER - -#define FOPEN_S(fp_, fName_, mode_) \ -if (fopen_s(&fp_, fName_, mode_) != 0) { \ - fp_ = (FILE *)0; \ -} else (void)0 - -#define LOCALTIME_S(tm_, time_) \ - localtime_s(tm_, time_) - -#else // other OS (Linux, MacOS, etc.) ..................................... - -#define MEMMOVE_S(dest_, num_, src_, count_) \ - memmove(dest_, src_, count_) - -#define STRNCPY_S(dest_, destsiz_, src_) do { \ - strncpy(dest_, src_, destsiz_); \ - dest_[(destsiz_) - 1] = '\0'; \ -} while (false) - -#define STRCAT_S(dest_, destsiz_, src_) \ - strcat(dest_, src_) - -#define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - snprintf(buf_, bufsiz_, format_, __VA_ARGS__) - -#define PRINTF_S(format_, ...) \ - printf(format_, __VA_ARGS__) - -#define FPRINTF_S(fp_, format_, ...) \ - fprintf(fp_, format_, __VA_ARGS__) - -#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ - fread(buf_, elsiz_, count_, fp_) - -#define FOPEN_S(fp_, fName_, mode_) \ - (fp_ = fopen(fName_, mode_)) - -#define LOCALTIME_S(tm_, time_) \ - memcpy(tm_, localtime(time_), sizeof(struct tm)) - -#endif // _WIN32 - -#endif // SAFE_STD_H diff --git a/ports/posix-qv/qf_port.c b/ports/posix-qv/qf_port.c index 26e731e2..2c0796bc 100644 --- a/ports/posix-qv/qf_port.c +++ b/ports/posix-qv/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-07-19 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-18 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C port to POSIX-QV (single-threaded) @@ -184,13 +184,7 @@ void QF_init(void) { // lock memory so we're never swapped out to disk //mlockall(MCL_CURRENT | MCL_FUTURE); // un-comment when supported - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) - { - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, Q_USER_SIG, tickRate); - } + QTimeEvt_init(); // initialize QTimeEvts l_tick.tv_sec = 0; l_tick.tv_nsec = NSEC_PER_SEC / DEFAULT_TICKS_PER_SEC; // default rate @@ -255,8 +249,8 @@ int QF_run(void) { QF_CRIT_ENTRY(); // produce the QS_QF_RUN trace record - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() while (l_isRunning) { Q_ASSERT_INCRIT(300, QPSet_verify_(&QF_readySet_, &QF_readySet_dis_)); @@ -369,7 +363,7 @@ int QF_consoleWaitForKey(void) { // QActive functions ========================================================= void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { diff --git a/ports/posix-qv/qp_port.h b/ports/posix-qv/qp_port.h index e2fabefc..25b41f5e 100644 --- a/ports/posix-qv/qp_port.h +++ b/ports/posix-qv/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-02-16 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to POSIX-QV (single-threaded) with GNU compiler @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -78,9 +75,9 @@ void QF_onClockTick(void); #endif // include files ------------------------------------------------------------- -#include "qequeue.h" // POSIX-QV needs the native event-queue -#include "qmpool.h" // POSIX-QV needs the native memory-pool -#include "qp.h" // QP platform-independent public interface +#include "qequeue.h" // POSIX-QV needs the native event-queue +#include "qmpool.h" // POSIX-QV needs the native memory-pool +#include "qp.h" // QP platform-independent public interface //============================================================================ // interface used only inside QF implementation, but not in applications @@ -93,8 +90,7 @@ void QF_onClockTick(void); #define QF_SCHED_UNLOCK_() ((void)0) // QF event queue customization for POSIX-QV... - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) #ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QF_readySet_, (me_)->prio); \ diff --git a/ports/posix-qv/qs_port.c b/ports/posix-qv/qs_port.c index e0ef1766..b36c4a6b 100644 --- a/ports/posix-qv/qs_port.c +++ b/ports/posix-qv/qs_port.c @@ -23,7 +23,7 @@ // //============================================================================ //! @date Last updated on: 2024-07-18 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to POSIX @@ -285,10 +285,10 @@ void QS_output(void) { //............................................................................ void QS_rx_input(void) { int status = recv(l_sock, - (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); + (char *)QS_rxPriv_->buf, (int)QS_rxPriv_->end, 0); if (status > 0) { // any data received? - QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; // # bytes received + QS_rxPriv_->tail = 0U; + QS_rxPriv_->head = status; // # bytes received QS_rxParse(); // parse all received bytes } } diff --git a/ports/posix-qv/qs_port.h b/ports/posix-qv/qs_port.h index 4cc04e7d..7f0a9ccb 100644 --- a/ports/posix-qv/qs_port.h +++ b/ports/posix-qv/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to POSIX with GNU diff --git a/ports/posix/qf_port.c b/ports/posix/qf_port.c index a771a4ca..0b5d94f9 100644 --- a/ports/posix/qf_port.c +++ b/ports/posix/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-07-18 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-18 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C port to POSIX (multithreaded with P-threads) @@ -142,13 +142,7 @@ void QF_init(void) { // calling QF_run() pthread_mutex_lock(&l_startupMutex); - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) - { - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, Q_USER_SIG, tickRate); - } + QTimeEvt_init(); // initialize QTimeEvts l_tick.tv_sec = 0; l_tick.tv_nsec = NSEC_PER_SEC / DEFAULT_TICKS_PER_SEC; // default rate @@ -167,8 +161,8 @@ int QF_run(void) { QF_onStartup(); // application-specific startup callback // produce the QS_QF_RUN trace record - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() // try to set the priority of the ticker thread, see NOTE01 struct sched_param sparam; @@ -313,7 +307,7 @@ static void *thread_routine(void *arg) { // the expected POSIX signature // QActive functions ======================================================= void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { diff --git a/ports/posix/qp_port.h b/ports/posix/qp_port.h index 38381d05..8b11cb47 100644 --- a/ports/posix/qp_port.h +++ b/ports/posix/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-02-16 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to to POSIX (multithreaded with P-threads) @@ -36,13 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard -#include // POSIX-thread API - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -95,10 +91,10 @@ void QF_onClockTick(void); // QF event queue customization for POSIX... #define QACTIVE_EQUEUE_WAIT_(me_) do { \ while ((me_)->eQueue.frontEvt == (QEvt *)0) { \ - Q_ASSERT_INCRIT(301, QF_critSectNest_ == 1); \ + Q_ASSERT_INCRIT(400, QF_critSectNest_ == 1); \ --QF_critSectNest_; \ pthread_cond_wait(&(me_)->osObject, &QF_critSectMutex_); \ - Q_ASSERT_INCRIT(302, QF_critSectNest_ == 0); \ + Q_ASSERT_INCRIT(401, QF_critSectNest_ == 0); \ ++QF_critSectNest_; \ } \ } while (false) diff --git a/ports/posix/qs_port.c b/ports/posix/qs_port.c index e0ef1766..b36c4a6b 100644 --- a/ports/posix/qs_port.c +++ b/ports/posix/qs_port.c @@ -23,7 +23,7 @@ // //============================================================================ //! @date Last updated on: 2024-07-18 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to POSIX @@ -285,10 +285,10 @@ void QS_output(void) { //............................................................................ void QS_rx_input(void) { int status = recv(l_sock, - (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); + (char *)QS_rxPriv_->buf, (int)QS_rxPriv_->end, 0); if (status > 0) { // any data received? - QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; // # bytes received + QS_rxPriv_->tail = 0U; + QS_rxPriv_->head = status; // # bytes received QS_rxParse(); // parse all received bytes } } diff --git a/ports/posix/qs_port.h b/ports/posix/qs_port.h index 4cc04e7d..7f0a9ccb 100644 --- a/ports/posix/qs_port.h +++ b/ports/posix/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to POSIX with GNU diff --git a/ports/qep-only/qp_port.h b/ports/qep-only/qp_port.h index 450e5aa0..b8ea5c65 100644 --- a/ports/qep-only/qp_port.h +++ b/ports/qep-only/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C dummy port @@ -36,27 +36,13 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void -#define QF_MAX_EPOOL 0U - -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() ((void)0) -#define QF_CRIT_EXIT() ((void)0) - -#define QF_MEM_SYS() ((void)0) -#define QF_MEM_APP() ((void)0) - // include files ------------------------------------------------------------- -#include "qp.h" // QP platform-independent public interface +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application +#include "qp.h" // QP platform-independent public interface #endif // QP_PORT_H_ - diff --git a/ports/qube/qp_port.h b/ports/qube/qp_port.h index 316c5c77..be36cfa0 100644 --- a/ports/qube/qp_port.h +++ b/ports/qube/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port for the "Qube" execution harness (Windows, Linux, macOS) @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -84,8 +81,7 @@ extern uint_fast8_t QF_intLock_; #define QF_SCHED_UNLOCK_() ((void)0) // native event queue operations - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) #ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \ diff --git a/ports/qube/qs_port.h b/ports/qube/qs_port.h index 6339a5a2..19d2b713 100644 --- a/ports/qube/qs_port.h +++ b/ports/qube/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port for the "Qube" execution harness (Windows, Linux, macOS) diff --git a/ports/qube/qube.c b/ports/qube/qube.c index c40c4426..582bf30f 100644 --- a/ports/qube/qube.c +++ b/ports/qube/qube.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-18 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief Qube command-line QP execution environment @@ -304,8 +304,8 @@ int_t QF_run(void) { QS_OBJ_DICTIONARY(&Qube); // produce the QS_QF_RUN trace record - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -359,7 +359,7 @@ int_t QF_run(void) { //-------------------------------------------------------------------------- void QActive_start(QActive* const me, QPrioSpec const prioSpec, - QEvt const** const qSto, + QEvtPtr * const qSto, uint_fast16_t const qLen, void* const stkSto, uint_fast16_t const stkSize, diff --git a/ports/risc-v/qv/gnu/qp_port.h b/ports/risc-v/qv/gnu/qp_port.h index 124f5c41..1da79c98 100644 --- a/ports/risc-v/qv/gnu/qp_port.h +++ b/ports/risc-v/qv/gnu/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to RISC-V, QV kernel, GNU-RISCV compiler @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -66,10 +63,10 @@ #define QF_CRIT_EXIT_NOP() __asm__ volatile ("nop") // include files ------------------------------------------------------------- -#include "qequeue.h" // QK kernel uses the native QP event queue -#include "qmpool.h" // QK kernel uses the native QP memory pool -#include "qp.h" // QP platform-independent public interface -#include "qv.h" // QV kernel integrates directly with QP +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel //============================================================================ // NOTE2: diff --git a/ports/risc-v/qv/gnu/qs_port.h b/ports/risc-v/qv/gnu/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/risc-v/qv/gnu/qs_port.h +++ b/ports/risc-v/qv/gnu/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/threadx/qf_port.c b/ports/threadx/qf_port.c index 85568022..b34574e7 100644 --- a/ports/threadx/qf_port.c +++ b/ports/threadx/qf_port.c @@ -1,29 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-26 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C, port to ThreadX @@ -43,6 +46,9 @@ Q_DEFINE_THIS_MODULE("qf_port") //............................................................................ void QF_init(void) { + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + QTimeEvt_init(); // initialize QTimeEvts } //............................................................................ int_t QF_run(void) { @@ -51,8 +57,8 @@ int_t QF_run(void) { // produce the QS_QF_RUN trace record QS_CRIT_STAT QS_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() QS_CRIT_EXIT(); return 0; // return success @@ -75,30 +81,32 @@ static void thread_function(ULONG thread_input) { // ThreadX signature //............................................................................ void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority me->pthre = (uint8_t)(prioSpec >> 8U); // QF preemption-threshold - QActive_register_(me); // register this AO + QActive_register_(me); // make QF aware of this AO + // create the ThreadX message queue for the AO UINT tx_err = tx_queue_create(&me->eQueue, me->thread.tx_thread_name, TX_1_ULONG, (VOID *)qSto, - (ULONG)(qLen * sizeof(ULONG))); + (ULONG)(qLen * sizeof(QEvtPtr))); QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(210, tx_err == TX_SUCCESS); + Q_ASSERT_INCRIT(110, tx_err == TX_SUCCESS); QF_CRIT_EXIT(); - QASM_INIT(&me->super, par, me->prio); // initial tran. (virtual) + // top-most initial tran. (virtual call) + QASM_INIT(&me->super, par, me->prio); QS_FLUSH(); // flush the trace buffer to the host - UINT tx_prio = QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - me->prio; - UINT tx_pt = QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - me->pthre; + UINT tx_prio = QF_TO_TX_PRIO_MAP(me->prio); + UINT tx_pt = QF_TO_TX_PRIO_MAP(me->pthre); tx_err = tx_thread_create( &me->thread, // ThreadX thread control block me->thread.tx_thread_name, // unique thread name @@ -112,17 +120,16 @@ void QActive_start(QActive * const me, TX_AUTO_START); QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(220, tx_err == TX_SUCCESS); + Q_ASSERT_INCRIT(120, tx_err == TX_SUCCESS); QF_CRIT_EXIT(); } //............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { // this function must be called before QActive_start(), // which implies that me->thread.tx_thread_name must not be used yet; - // QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(300, me->thread.tx_thread_name == (char *)0); + Q_REQUIRE_INCRIT(150, me->thread.tx_thread_name == (char *)0); switch (attr1) { case THREAD_NAME_ATTR: @@ -130,6 +137,8 @@ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { me->thread.tx_thread_name = (char *)attr2; break; // ... + default: + break; } QF_CRIT_EXIT(); } @@ -137,9 +146,18 @@ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { +#ifndef Q_SPY + Q_UNUSED_PAR(sender); +#endif + QF_CRIT_STAT QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + uint_fast16_t nFree = (uint_fast16_t)me->eQueue.tx_queue_available_storage; bool status; @@ -149,7 +167,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e, } else { status = false; // cannot post - Q_ERROR_INCRIT(510); // must be able to post the event + Q_ERROR_INCRIT(210); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { @@ -161,15 +179,15 @@ bool QActive_post_(QActive * const me, QEvt const * const e, if (status) { // can post the event? - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(nFree); // # free entries available - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(nFree); // # free entries available + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter @@ -178,22 +196,22 @@ bool QActive_post_(QActive * const me, QEvt const * const e, UINT tx_err = tx_queue_send(&me->eQueue, (VOID *)&e, TX_NO_WAIT); - // posting to the ThreadX message queue must succeed, see NOTE3 QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(520, tx_err == TX_SUCCESS); + // posting to the ThreadX message queue must succeed, see NOTE3 + Q_ASSERT_INCRIT(220, tx_err == TX_SUCCESS); QF_CRIT_EXIT(); } else { - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(nFree); // # free entries available - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(nFree); // # free entries available + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() QF_CRIT_EXIT(); } @@ -205,14 +223,19 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(me->eQueue.tx_queue_available_storage); // # free - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + Q_REQUIRE_INCRIT(300, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(me->eQueue.tx_queue_available_storage); // # free + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter @@ -221,27 +244,27 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { UINT tx_err = tx_queue_front_send(&me->eQueue, (VOID *)&e, TX_NO_WAIT); - // LIFO posting must succeed, see NOTE3 QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(610, tx_err == TX_SUCCESS); + // LIFO posting must succeed, see NOTE3 + Q_ASSERT_INCRIT(310, tx_err == TX_SUCCESS); QF_CRIT_EXIT(); } //............................................................................ QEvt const *QActive_get_(QActive * const me) { - QEvt const *e; + QEvtPtr e; UINT tx_err = tx_queue_receive(&me->eQueue, (VOID *)&e, TX_WAIT_FOREVER); QF_CRIT_STAT QF_CRIT_ENTRY(); Q_ASSERT_INCRIT(710, tx_err == TX_SUCCESS); - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count - QS_EQC_PRE_(me->eQueue.tx_queue_available_storage);// # free - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(me->eQueue.tx_queue_available_storage);// # free + QS_END_PRE() QF_CRIT_EXIT(); return e; @@ -260,19 +283,18 @@ void QFSchedLock_(QFSchedLock * const lockStat, uint_fast8_t prio) { // change the preemption threshold of the current thread UINT tx_err = tx_thread_preemption_change(lockStat->lockHolder, - (QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - prio), + QF_TO_TX_PRIO_MAP(prio), &lockStat->prevThre); if (tx_err == TX_SUCCESS) { lockStat->lockPrio = prio; QF_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_((QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - - lockStat->prevThre), + QS_BEGIN_PRE(QS_SCHED_LOCK, 0U) + QS_TIME_PRE(); // timestamp + QS_2U8_PRE(TX_TO_QF_PRIO_MAP(lockStat->prevThre), prio); // new lock prio - QS_END_PRE_() + QS_END_PRE() QF_CRIT_EXIT(); } else if (tx_err == TX_THRESH_ERROR) { @@ -294,14 +316,13 @@ void QFSchedUnlock_(QFSchedLock const * const lockStat) { QF_CRIT_ENTRY(); // the lock holder must be valid and the scheduler must be locked Q_REQUIRE_INCRIT(900, (lockStat->lockHolder != (TX_THREAD *)0) - && (lockStat->lockPrio != 0U)); + && (lockStat->lockPrio != 0U)); - QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_(lockStat->lockPrio, // prev lock prio - (QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - - lockStat->prevThre)); // new lock prio - QS_END_PRE_() + QS_BEGIN_PRE(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE(); // timestamp + QS_2U8_PRE(lockStat->lockPrio, // prev lock prio + TX_TO_QF_PRIO_MAP(lockStat->prevThre)); // new lock prio + QS_END_PRE() QF_CRIT_EXIT(); // restore the preemption threshold of the lock holder diff --git a/ports/threadx/qp_port.h b/ports/threadx/qp_port.h index 69c30128..9a5e2ca6 100644 --- a/ports/threadx/qp_port.h +++ b/ports/threadx/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C, port to ThreadX, generic C11 compiler @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -51,36 +48,43 @@ #define QACTIVE_THREAD_TYPE TX_THREAD #define QACTIVE_OS_OBJ_TYPE uint8_t -// QF priority offset within ThreadX priority numbering scheme, see NOTE1 -#define QF_TX_PRIO_OFFSET 8U +// QF priority offset within ThreadX priority numbering scheme +#define QF_TX_PRIO_OFFSET 2U + +#ifndef QF_MAX_ACTIVE +#define QF_MAX_ACTIVE (TX_MAX_PRIORITIES - QF_TX_PRIO_OFFSET) +#else +#error "QF_MAX_ACTIVE shouild not be externally defined in QP-ThreadX port" +#endif + +// mapping between QF-priority and TX-priority, see NOTE1 +#define QF_TO_TX_PRIO_MAP(qp_prio_) \ + (TX_MAX_PRIORITIES - QF_TX_PRIO_OFFSET - (qp_prio_)) + +// mapping between TX-priority and QF-priority, see NOTE1 +#define TX_TO_QF_PRIO_MAP(tx_prio_) \ + (TX_MAX_PRIORITIES - QF_TX_PRIO_OFFSET - (tx_prio_)) // QF critical section for ThreadX, see NOTE3 #define QF_CRIT_STAT UINT int_ctrl_; #define QF_CRIT_ENTRY() (int_ctrl_ = tx_interrupt_control(TX_INT_DISABLE)) #define QF_CRIT_EXIT() ((void)tx_interrupt_control(int_ctrl_)) +// include files ------------------------------------------------------------- +#include "tx_api.h" // ThreadX API + +#include "qequeue.h" // QP event queue (for deferring events) +#include "qmpool.h" // QP memory pool (for event pools) +#include "qp.h" // QP platform-independent public interface + enum ThreadX_ThreadAttrs { THREAD_NAME_ATTR }; -// include files ------------------------------------------------------------- -#include "tx_api.h" // ThreadX API - -#include "qequeue.h" // QP native QF event queue for deferring events -#include "qmpool.h" // QP native QF event pool -#include "qp.h" // QP platform-independent public interface - //============================================================================ // interface used only inside QF implementation, but not in applications #ifdef QP_IMPL - //! ThreadX-specific scheduler locking (implemented in qf_port.c) - typedef struct { - uint_fast8_t lockPrio; //!< lock prio [QF numbering scheme] - UINT prevThre; //!< previoius preemption threshold - TX_THREAD *lockHolder; //!< the thread holding the lock - } QFSchedLock; - // ThreadX-specific scheduler locking (implemented in qf_port.cpp) #define QF_SCHED_STAT_ QFSchedLock lockStat_; #define QF_SCHED_LOCK_(prio_) do { \ @@ -97,6 +101,12 @@ enum ThreadX_ThreadAttrs { } \ } while (false) + typedef struct { + uint_fast8_t lockPrio; // lock prio [QF numbering scheme] + UINT prevThre; // previoius preemption threshold + TX_THREAD *lockHolder; // the thread holding the lock + } QFSchedLock; + // internal implementation of scheduler locking/unlocking void QFSchedLock_(QFSchedLock * const lockStat, uint_fast8_t prio); void QFSchedUnlock_(QFSchedLock const * const lockStat); @@ -113,19 +123,17 @@ enum ThreadX_ThreadAttrs { #define QF_EPOOL_PUT_(p_, e_, qsId_) \ (QMPool_put(&(p_), (e_), (qsId_))) -#endif // QP_IMPL +#endif // ifdef QP_IMPL //============================================================================ // NOTE1: -// QF_TX_PRIO_OFFSET specifies the number of highest-urgency ThreadX -// priorities not available to QP active objects. These highest-urgency -// priorities might be used by ThreadX threads that run "above" QP active -// objects. -// // Because the ThreadX priority numbering is "upside down" compared // to the QP priority numbering, the ThreadX priority for an active object -// thread is calculated as follows: -// tx_prio = QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - qp_prio +// thread is calculated as specified in the macro QF_TO_TX_PRIO_MAP(prio_). +// This mapping leaves the QF_TX_PRIO_OFFSET number of lowest-priority +// ThreadX threads NOT available as threads for QP Active Objects. The use +// of such lowest-priority ThredX threads is, for example, to emulate idle +// thread, etc. // // NOTE3: // The ThreadX critical section must be able to nest, which is the case with diff --git a/ports/threadx/qs_port.h b/ports/threadx/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/threadx/qs_port.h +++ b/ports/threadx/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/uc-os2/qf_port.c b/ports/uc-os2/qf_port.c index 5d2422e1..216c4d83 100644 --- a/ports/uc-os2/qf_port.c +++ b/ports/uc-os2/qf_port.c @@ -1,29 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-26 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to uC-OS2, generic C11 compiler @@ -46,7 +49,10 @@ static void task_function(void *pdata); // uC-OS2 task signature //............................................................................ void QF_init(void) { - OSInit(); // initialize uC-OS2 + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + QTimeEvt_init(); // initialize QTimeEvts + OSInit(); // initialize uC-OS2 } //............................................................................ int_t QF_run(void) { @@ -55,8 +61,8 @@ int_t QF_run(void) { // produce the QS_QF_RUN trace record QS_CRIT_STAT QS_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() QS_CRIT_EXIT(); OSStart(); // start uC-OS2 multitasking, should never return @@ -65,7 +71,7 @@ int_t QF_run(void) { } //............................................................................ void QF_stop(void) { - QF_onCleanup(); // cleanup callback + QF_onCleanup(); // cleanup callback } //............................................................................ @@ -85,20 +91,20 @@ static void task_function(void *pdata) { // uC-OS2 task signature //............................................................................ void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { // task name to be passed to OSTaskCreateExt() void * const task_name = (void *)me->eQueue; - // create uC-OS2 queue and make sure it was created correctly + // create uC-OS2 queue me->eQueue = OSQCreate((void **)qSto, qLen); // create uC-OS2 queue QF_CRIT_STAT QF_CRIT_ENTRY(); // the uC-OS2 queue must be created correctly - Q_ASSERT_INCRIT(210, me->eQueue != (OS_EVENT *)0); + Q_ASSERT_INCRIT(110, me->eQueue != (OS_EVENT *)0); QF_CRIT_EXIT(); me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO @@ -161,17 +167,22 @@ void QActive_start(QActive * const me, // uC-OS2 task must be created correctly Q_ASSERT_INCRIT(220, err == OS_ERR_NONE); QF_CRIT_EXIT(); + +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif } //............................................................................ -// NOTE: This function must be called BEFORE starting an active object void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { + // NOTE: this function must be called *before* QActive_start(), + // which implies that me->thread.tx_thread_name must not be used yet; QF_CRIT_STAT QF_CRIT_ENTRY(); switch (attr1) { case TASK_NAME_ATTR: // this function must be called before QActive_start(), // which implies that me->eQueue must not be used yet; - Q_ASSERT_INCRIT(300, me->eQueue == (OS_EVENT *)0); + Q_ASSERT_INCRIT(150, me->eQueue == (OS_EVENT *)0); // temporarily store the name, cast 'const' away me->eQueue = (OS_EVENT *)attr2; break; @@ -189,21 +200,27 @@ bool QActive_post_(QActive * const me, QEvt const * const e, { QF_CRIT_STAT QF_CRIT_ENTRY(); + + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); +#endif + uint_fast16_t const nFree = (uint_fast16_t)(((OS_Q_DATA *)me->eQueue)->OSQSize - ((OS_Q_DATA *)me->eQueue)->OSNMsgs); bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; // can post + status = true; // can post } else { status = false; // cannot post - Q_ERROR_INCRIT(710); // must be able to post the event + Q_ERROR_INCRIT(210); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { - status = true; // can post + status = true; // can post } else { status = false; // cannot post @@ -211,40 +228,43 @@ bool QActive_post_(QActive * const me, QEvt const * const e, if (status) { // can post the event? - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(nFree); // # free entries + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter } - QF_CRIT_EXIT(); INT8U err = OSQPost(me->eQueue, (void *)e); QF_CRIT_ENTRY(); // posting to uC-OS2 message queue must succeed, see NOTE3 - Q_ASSERT_INCRIT(720, err == OS_ERR_NONE); + Q_ASSERT_INCRIT(220, err == OS_ERR_NONE); QF_CRIT_EXIT(); + +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif } else { - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count - QS_EQC_PRE_(nFree); // # free entries available - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(nFree); // # free entries available + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() QF_CRIT_EXIT(); } @@ -256,17 +276,22 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id & ref-Count - QS_EQC_PRE_(((OS_Q *)me->eQueue)->OSQSize - - ((OS_Q *)me->eQueue)->OSQEntries); // # free entries - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + Q_REQUIRE_INCRIT(300, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +#endif - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(((OS_Q *)me->eQueue)->OSQSize + - ((OS_Q *)me->eQueue)->OSQEntries); // # free entries + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() + + if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter } QF_CRIT_EXIT(); @@ -275,8 +300,12 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_ENTRY(); // posting to uC-OS2 message queue must succeed, see NOTE3 - Q_ASSERT_INCRIT(810, err == OS_ERR_NONE); + Q_ASSERT_INCRIT(310, err == OS_ERR_NONE); QF_CRIT_EXIT(); + +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif } //............................................................................ QEvt const *QActive_get_(QActive * const me) { @@ -285,18 +314,21 @@ QEvt const *QActive_get_(QActive * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(910, err == OS_ERR_NONE); + Q_ASSERT_INCRIT(410, err == OS_ERR_NONE); - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id & ref-Count - QS_EQC_PRE_(((OS_Q *)me->eQueue)->OSQSize + QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(((OS_Q *)me->eQueue)->OSQSize - ((OS_Q *)me->eQueue)->OSQEntries); // # free entries - QS_END_PRE_() + QS_END_PRE() QF_CRIT_EXIT(); +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif return e; } diff --git a/ports/uc-os2/qp_port.h b/ports/uc-os2/qp_port.h index 56e75d00..26895144 100644 --- a/ports/uc-os2/qp_port.h +++ b/ports/uc-os2/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to uC-OS2, generic C11 compiler @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void diff --git a/ports/uc-os2/qs_port.h b/ports/uc-os2/qs_port.h index 7895e109..cdb29f7d 100644 --- a/ports/uc-os2/qs_port.h +++ b/ports/uc-os2/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. diff --git a/ports/win32-qutest/CMakeLists.txt b/ports/win32-qutest/CMakeLists.txt deleted file mode 100644 index 7f537635..00000000 --- a/ports/win32-qutest/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# ports/win32-qutest -target_include_directories(qpc PUBLIC .) -target_sources(qpc PRIVATE - qutest_port.c -) \ No newline at end of file diff --git a/ports/win32-qutest/README.md b/ports/win32-qutest/README.md deleted file mode 100644 index d715877c..00000000 --- a/ports/win32-qutest/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Win32-API (Windows port for QUTest Unit Testing Harness) - -Documentation for this port is available in the QP/C Manual at: - -- https://www.state-machine.com/qpc/win32-qutest.html diff --git a/ports/win32-qutest/qp_port.h b/ports/win32-qutest/qp_port.h deleted file mode 100644 index e433c40b..00000000 --- a/ports/win32-qutest/qp_port.h +++ /dev/null @@ -1,140 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-10 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QP/C port to Win32-QUTest with GNU or Visual Studio C/C++ - -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif - -#ifdef __GNUC__ - - // no-return function specifier (GCC-ARM compiler) - #define Q_NORETURN __attribute__ ((noreturn)) void - -#elif (defined _MSC_VER) - #ifdef __cplusplus - // no-return function specifier (Microsoft Visual Studio C++ compiler) - #define Q_NORETURN [[ noreturn ]] void - #else - // no-return function specifier C11 - #define Q_NORETURN _Noreturn void - #endif - - // This is the case where QP/C is compiled by the Microsoft Visual C++ - // compiler in the C++ mode, which can happen when qep_port.h is included - // in a C++ module, or the compilation is forced to C++ by the option /TP. - // - // The following pragma suppresses the level-4 C++ warnings C4510, C4512, - // and C4610, which warn that default constructors and assignment operators - // could not be generated for structures QMState and QMTranActTable. - // - // The QP/C source code cannot be changed to avoid these C++ warnings - // because the structures QMState and QMTranActTable must remain PODs - // (Plain Old Datatypes) to be initializable statically with constant - // initializers. - // - #pragma warning (disable: 4510 4512 4610) - -#endif - -// QUTest event queue and thread types -#define QACTIVE_EQUEUE_TYPE QEQueue -// QACTIVE_OS_OBJ_TYPE not used in this port -// QACTIVE_THREAD_TYPE not used in this port - -// QF interrupt disable/enable -#define QF_INT_DISABLE() (QS_onIntDisable()) -#define QF_INT_ENABLE() (QS_onIntEnable()) - -// QF critical section -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() QF_INT_DISABLE() -#define QF_CRIT_EXIT() QF_INT_ENABLE() - -// QF_LOG2 not defined -- use the internal LOG2() implementation - -// include files ------------------------------------------------------------- -#include "qequeue.h" // QUTest port uses QEQueue event-queue -#include "qmpool.h" // QUTest port uses QMPool memory-pool -#include "qp.h" // QP platform-independent public interface - -void QS_onIntDisable(void); -void QS_onIntEnable(void); - -#ifdef _MSC_VER - #pragma warning (default: 4510 4512 4610) -#endif - -//============================================================================ -// interface used only inside QF implementation, but not in applications - -#ifdef QP_IMPL - - // QUTest scheduler locking (not used) - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - // native event queue operations - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(305, (me_)->eQueue.frontEvt != (QEvt *)0) -#ifndef Q_UNSAFE - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) -#else - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) -#endif - - // native QF event pool operations - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - #define QF_EPOOL_PUT_(p_, e_, qsId_) \ - (QMPool_put(&(p_), (e_), (qsId_))) - -#endif // QP_IMPL - -#endif // QP_PORT_H_ - diff --git a/ports/win32-qutest/qs_port.h b/ports/win32-qutest/qs_port.h deleted file mode 100644 index abe0298b..00000000 --- a/ports/win32-qutest/qs_port.h +++ /dev/null @@ -1,62 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C port to Win32 with GNU or Visual C++ compilers - -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -#ifdef _WIN64 // 64-bit architecture? - #define QS_OBJ_PTR_SIZE 8U - #define QS_FUN_PTR_SIZE 8U -#else // 32-bit architecture - #define QS_OBJ_PTR_SIZE 4U - #define QS_FUN_PTR_SIZE 4U -#endif - -void QS_output(void); // handle the QS output -void QS_rx_input(void); // handle the QS-RX input - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -// *before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QP -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ diff --git a/ports/win32-qutest/qutest_port.c b/ports/win32-qutest/qutest_port.c deleted file mode 100644 index 29645287..00000000 --- a/ports/win32-qutest/qutest_port.c +++ /dev/null @@ -1,289 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 -//! -//! @file -//! @brief QS/C QUTest port for Win32 - -#ifndef Q_SPY - #error "Q_SPY must be defined for QUTest application" -#endif // Q_SPY - -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qsafe.h" // QP Functional Safety (FuSa) System -#include "qs_port.h" // QS port - -#include "safe_std.h" // portable "safe" / facilities -#include -#include - -// Minimum required Windows version is Windows-XP or newer (0x0501) -#ifdef WINVER -#undef WINVER -#endif -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif - -#define WINVER _WIN32_WINNT_WINXP -#define _WIN32_WINNT _WIN32_WINNT_WINXP - -#include - -#define QS_TX_SIZE (8*1024) -#define QS_RX_SIZE (2*1024) -#define QS_TX_CHUNK QS_TX_SIZE -#define QS_TIMEOUT_MS 10U - -Q_DEFINE_THIS_MODULE("qutest_port") - -// local variables ......................................................... -static SOCKET l_sock = INVALID_SOCKET; - -//............................................................................ -uint8_t QS_onStartup(void const *arg) { - // initialize the QS transmit and receive buffers - static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel - QS_initBuf(qsBuf, sizeof(qsBuf)); - - static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - char hostName[128]; - char const *serviceName = "6601"; // default QSPY server port - char const *src; - char *dst; - int status; - - struct addrinfo *result = NULL; - struct addrinfo *rp = NULL; - struct addrinfo hints; - BOOL sockopt_bool; - ULONG ioctl_opt; - WSADATA wsaData; - - // initialize Windows sockets version 2.2 - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { - FPRINTF_S(stderr, " ERROR %s\n", - "Windows Sockets cannot be initialized"); - goto error; - } - - // extract hostName from 'arg' (hostName:port_remote)... - src = (arg != (void *)0) - ? (char const *)arg - : "localhost"; // default QSPY host - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName) - 1])) - { - *dst++ = *src++; - } - *dst = '\0'; // zero-terminate hostName - - // extract serviceName from 'arg' (hostName:serviceName)... - if (*src == ':') { - serviceName = src + 1; - } - //printf(" Connecting to QSPY on Host=%s:%s...\n", - // hostName, serviceName); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - status = getaddrinfo(hostName, serviceName, &hints, &result); - if (status != 0) { - FPRINTF_S(stderr, - " ERROR cannot resolve host Name=%s:%s,Err=%d\n", - hostName, serviceName, status); - goto error; - } - - for (rp = result; rp != NULL; rp = rp->ai_next) { - l_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (l_sock != INVALID_SOCKET) { - if (connect(l_sock, rp->ai_addr, (int)rp->ai_addrlen) - == SOCKET_ERROR) - { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - break; - } - } - - freeaddrinfo(result); - - // socket could not be opened & connected? - if (l_sock == INVALID_SOCKET) { - FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " - "host=%s:%s\n", - hostName, serviceName); - goto error; - } - - // set the socket to non-blocking mode - ioctl_opt = 1; - if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) != NO_ERROR) { - FPRINTF_S(stderr, " ERROR %s WASErr=%d\n,", - "Failed to set non-blocking socket", WSAGetLastError()); - QF_stop(); // <== stop and exit the application - goto error; - } - - // configure the socket to reuse the address and not to linger - sockopt_bool = TRUE; - setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, - (const char *)&sockopt_bool, sizeof(sockopt_bool)); - sockopt_bool = TRUE; - setsockopt(l_sock, SOL_SOCKET, SO_DONTLINGER, - (const char *)&sockopt_bool, sizeof(sockopt_bool)); - //PRINTF_S(" Connected to QSPY at Host=%s:%d\n", - // hostName, port_remote); - QS_onFlush(); - - return 1U; // success - -error: - return 0U; // failure -} -//............................................................................ -void QS_onCleanup(void) { - Sleep(QS_TIMEOUT_MS * 10U); // allow the last QS output to come out - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - WSACleanup(); - //PRINTF_S("%s\n", " Disconnected from QSPY"); -} -//............................................................................ -void QS_onReset(void) { - QS_onCleanup(); - //PRINTF_S("\n%s\n", "QS_onReset"); - exit(0); -} -//............................................................................ -void QS_onFlush(void) { - // NOTE: - // No critical section in QS_onFlush() to avoid nesting of critical sections - // in case QS_onFlush() is called from Q_onError(). - if (l_sock == INVALID_SOCKET) { // socket NOT initialized? - FPRINTF_S(stderr, " ERROR %s\n", - "invalid TCP socket"); - QF_stop(); // <== stop and exit the application - return; - } - - uint16_t nBytes = QS_TX_CHUNK; - uint8_t const *data; - while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - for (;;) { // for-ever until break or return - int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { // sending failed? - int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - // sleep for the timeout and then loop back - // to send() the SAME data again - Sleep(QS_TIMEOUT_MS); - } - else { // some other socket error... - FPRINTF_S(stderr, " ERROR %s WASErr=%d\n", - "sending data over TCP", err); - QF_stop(); // <== stop and exit the application - return; - } - } - else if (nSent < (int)nBytes) { // sent fewer than requested? - Sleep(QS_TIMEOUT_MS); // sleep for the timeout - // adjust the data and loop back to send() the rest - data += nSent; - nBytes -= (uint16_t)nSent; - } - else { - break; // break out of the for-ever loop - } - } - // set nBytes for the next call to QS_getBlock() - nBytes = QS_TX_CHUNK; - } -} - -//............................................................................ -void QS_onTestLoop() { - fd_set readSet; - FD_ZERO(&readSet); - - QS_rxPriv_.inTestLoop = true; - while (QS_rxPriv_.inTestLoop) { - FD_SET(l_sock, &readSet); - - struct timeval timeout = { - (long)0, (long)(QS_TIMEOUT_MS * 1000) - }; - - // selective, timed blocking on the TCP/IP socket... - int status = select(0, &readSet, (fd_set *)0, (fd_set *)0, &timeout); - if (status == SOCKET_ERROR) { - FPRINTF_S(stderr, - " ERROR socket select,WSAErr=%d", - WSAGetLastError()); - QF_stop(); // <== stop and exit the application - } - else if (FD_ISSET(l_sock, &readSet)) { // socket ready? - status = recv(l_sock, - (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { // any data received? - QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = (QSCtr)status; // # bytes received - QS_rxParse(); // parse all received bytes - } - } - - QS_onFlush(); - } - // set inTestLoop to true in case calls to QS_onTestLoop() nest, - // which can happen through the calls to QS_TEST_PAUSE(). - QS_rxPriv_.inTestLoop = true; -} - -//............................................................................ -void QS_onIntDisable(void) { - if (QS_tstPriv_.intLock != 0U) { - Q_onError(&Q_this_module_[0], 998); - } - ++QS_tstPriv_.intLock; -} -//............................................................................ -void QS_onIntEnable(void) { - --QS_tstPriv_.intLock; - if (QS_tstPriv_.intLock != 0U) { - Q_onError(&Q_this_module_[0], 999); - } -} diff --git a/ports/win32-qutest/safe_std.h b/ports/win32-qutest/safe_std.h deleted file mode 100644 index c752662c..00000000 --- a/ports/win32-qutest/safe_std.h +++ /dev/null @@ -1,106 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities -#ifndef SAFE_STD_H -#define SAFE_STD_H - -#include -#include - -// portable "safe" facilities from and ................ -#ifdef _WIN32 // Windows OS? - -#define MEMMOVE_S(dest_, num_, src_, count_) \ - memmove_s(dest_, num_, src_, count_) - -#define STRNCPY_S(dest_, destsiz_, src_) \ - strncpy_s(dest_, destsiz_, src_, _TRUNCATE) - -#define STRCAT_S(dest_, destsiz_, src_) \ - strcat_s(dest_, destsiz_, src_) - -#define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, __VA_ARGS__) - -#define PRINTF_S(format_, ...) \ - printf_s(format_, __VA_ARGS__) - -#define FPRINTF_S(fp_, format_, ...) \ - fprintf_s(fp_, format_, __VA_ARGS__) - -#ifdef _MSC_VER -#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ - fread_s(buf_, bufsiz_, elsiz_, count_, fp_) -#else -#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ - fread(buf_, elsiz_, count_, fp_) -#endif // _MSC_VER - -#define FOPEN_S(fp_, fName_, mode_) \ -if (fopen_s(&fp_, fName_, mode_) != 0) { \ - fp_ = (FILE *)0; \ -} else (void)0 - -#define LOCALTIME_S(tm_, time_) \ - localtime_s(tm_, time_) - -#else // other OS (Linux, MacOS, etc.) ..................................... - -#define MEMMOVE_S(dest_, num_, src_, count_) \ - memmove(dest_, src_, count_) - -#define STRNCPY_S(dest_, destsiz_, src_) do { \ - strncpy(dest_, src_, destsiz_); \ - dest_[(destsiz_) - 1] = '\0'; \ -} while (false) - -#define STRCAT_S(dest_, destsiz_, src_) \ - strcat(dest_, src_) - -#define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - snprintf(buf_, bufsiz_, format_, __VA_ARGS__) - -#define PRINTF_S(format_, ...) \ - printf(format_, __VA_ARGS__) - -#define FPRINTF_S(fp_, format_, ...) \ - fprintf(fp_, format_, __VA_ARGS__) - -#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ - fread(buf_, elsiz_, count_, fp_) - -#define FOPEN_S(fp_, fName_, mode_) \ - (fp_ = fopen(fName_, mode_)) - -#define LOCALTIME_S(tm_, time_) \ - memcpy(tm_, localtime(time_), sizeof(struct tm)) - -#endif // _WIN32 - -#endif // SAFE_STD_H diff --git a/ports/win32-qv/qf_port.c b/ports/win32-qv/qf_port.c index 434b7062..d5e87cbb 100644 --- a/ports/win32-qv/qf_port.c +++ b/ports/win32-qv/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-19 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C port to Win32-QV (single-threaded) @@ -108,13 +108,7 @@ void QF_init(void) { QPSet_update_(&QF_readySet_, &QF_readySet_dis_); #endif - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) - { - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, Q_USER_SIG, tickRate); - } + QTimeEvt_init(); // initialize QTimeEvts } //............................................................................ @@ -129,17 +123,21 @@ int QF_run(void) { // create the ticker thread... HANDLE ticker = CreateThread(NULL, 1024, &ticker_thread, (void *)0, 0U, NULL); +#ifndef Q_UNSAFE QF_CRIT_ENTRY(); Q_ASSERT_INCRIT(310, ticker != 0); // thread must be created QF_CRIT_EXIT(); +#else + Q_UNUSED_PAR(ticker); +#endif } // the combined event-loop and background-loop of the QV kernel QF_CRIT_ENTRY(); // produce the QS_QF_RUN trace record - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() while (l_isRunning) { Q_ASSERT_INCRIT(300, QPSet_verify_(&QF_readySet_, &QF_readySet_dis_)); @@ -237,7 +235,7 @@ int QF_consoleWaitForKey(void) { void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { diff --git a/ports/win32-qv/qp_port.h b/ports/win32-qv/qp_port.h index f47fd6a6..19931f23 100644 --- a/ports/win32-qv/qp_port.h +++ b/ports/win32-qv/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-02-15 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to Win32-QV (single-threaded) with GNU or Visual C/C++ @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application #ifdef __GNUC__ @@ -130,8 +127,7 @@ void QF_onClockTick(void); #define QF_SCHED_UNLOCK_() ((void)0) // QF event queue customization for Win32-QV... - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) #ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ diff --git a/ports/win32-qv/qs_port.c b/ports/win32-qv/qs_port.c index 344d8762..daeee934 100644 --- a/ports/win32-qv/qs_port.c +++ b/ports/win32-qv/qs_port.c @@ -23,7 +23,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port for Win32 API @@ -286,10 +286,10 @@ void QS_output(void) { //............................................................................ void QS_rx_input(void) { int status = recv(l_sock, - (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); + (char *)QS_rxPriv_->buf, (int)QS_rxPriv_->end, 0); if (status > 0) { // any data received? - QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; // # bytes received + QS_rxPriv_->tail = 0U; + QS_rxPriv_->head = status; // # bytes received QS_rxParse(); // parse all received bytes } } diff --git a/ports/win32-qv/qs_port.h b/ports/win32-qv/qs_port.h index abe0298b..3454f604 100644 --- a/ports/win32-qv/qs_port.h +++ b/ports/win32-qv/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to Win32 with GNU or Visual C++ compilers diff --git a/ports/win32/qf_port.c b/ports/win32/qf_port.c index 09507a8a..0fb7f955 100644 --- a/ports/win32/qf_port.c +++ b/ports/win32/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-19 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C port to Win32 (multithreaded) @@ -75,14 +75,7 @@ void QF_leaveCriticalSection_(void) { void QF_init(void) { InitializeCriticalSection(&l_win32CritSect); - - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) - { - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, Q_USER_SIG, tickRate); - } + QTimeEvt_init(); // initialize QTimeEvts // initialize and enter the startup critical section object to block // any active objects started before calling QF_run() @@ -96,8 +89,8 @@ int QF_run(void) { QF_onStartup(); // application-specific startup callback // produce the QS_QF_RUN trace record - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() // leave the startup critical section to unblock any active objects // started before calling QF_run() @@ -167,7 +160,7 @@ int QF_consoleWaitForKey(void) { void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { diff --git a/ports/win32/qp_port.h b/ports/win32/qp_port.h index 550b836f..01a994f6 100644 --- a/ports/win32/qp_port.h +++ b/ports/win32/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-02-15 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to Win32 (multithreaded) with GNU or Visual C/C++ @@ -36,12 +36,9 @@ #ifndef QP_PORT_H_ #define QP_PORT_H_ -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -#ifdef QP_CONFIG -#include "qp_config.h" // external QP configuration -#endif +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application #ifdef __GNUC__ diff --git a/ports/win32/qs_port.c b/ports/win32/qs_port.c index 344d8762..daeee934 100644 --- a/ports/win32/qs_port.c +++ b/ports/win32/qs_port.c @@ -23,7 +23,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port for Win32 API @@ -286,10 +286,10 @@ void QS_output(void) { //............................................................................ void QS_rx_input(void) { int status = recv(l_sock, - (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); + (char *)QS_rxPriv_->buf, (int)QS_rxPriv_->end, 0); if (status > 0) { // any data received? - QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; // # bytes received + QS_rxPriv_->tail = 0U; + QS_rxPriv_->head = status; // # bytes received QS_rxParse(); // parse all received bytes } } diff --git a/ports/win32/qs_port.h b/ports/win32/qs_port.h index abe0298b..3454f604 100644 --- a/ports/win32/qs_port.h +++ b/ports/win32/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to Win32 with GNU or Visual C++ compilers diff --git a/qpc.qm b/qpc.qm index d27f88ef..40a513f4 100644 --- a/qpc.qm +++ b/qpc.qm @@ -1,36 +1,9 @@ - + QP/C Real-Time Embedded Framework (RTEF) This model is used to generate the whole QP/C source code. -Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>. - -SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial - -This software is dual-licensed under the terms of the open source GNU -General Public License version 3 (or any later version), or alternatively, -under the terms of one of the closed source Quantum Leaps commercial -licenses. - -The terms of the open source GNU General Public License version 3 -can be found at: <www.gnu.org/licenses/gpl-3.0> - -The terms of the closed source Quantum Leaps commercial licenses -can be found at: <www.state-machine.com/licensing> - -Redistributions in source code must retain this copyright notice. -Plagiarizing this software to sidestep the license obligations is illegal. - -Contact information: -<www.state-machine.com/licensing> -<info@state-machine.com> - - - Any user of the QP/C real-time embedded framework -qpc -2025-12-31 - -Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>. +Copyright (c) 2005 Quantum Leaps, LLC. All rights reserved. Q u a n t u m L e a P s ------------------------ @@ -38,24 +11,53 @@ Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>. SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -This software is dual-licensed under the terms of the open source GNU -General Public License version 3 (or any later version), or alternatively, -under the terms of one of the closed source Quantum Leaps commercial -licenses. - -The terms of the open source GNU General Public License version 3 -can be found at: <www.gnu.org/licenses/gpl-3.0> - -The terms of the closed source Quantum Leaps commercial licenses -can be found at: <www.state-machine.com/licensing> +The QP/C software is dual-licensed under the terms of the open-source GNU +General Public License (GPL) or under the terms of one of the closed- +source Quantum Leaps commercial licenses. Redistributions in source code must retain this top-level comment block. Plagiarizing this software to sidestep the license obligations is illegal. -Contact information: +NOTE: +The GPL (see <www.gnu.org/licenses/gpl-3.0>) does NOT permit the +incorporation of the QP/C software into proprietary programs. Please +contact Quantum Leaps for commercial licensing options, which expressly +supersede the GPL and are designed explicitly for licensees interested +in using QP/C in closed-source proprietary applications. + +Quantum Leaps contact information: +<www.state-machine.com/licensing> +<info@state-machine.com> + + + public +qpc +2025-12-31 +Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. + + Q u a n t u m L e a P s + ------------------------ + Modern Embedded Software + +SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial + +The QP/C software is dual-licensed under the terms of the open-source GNU +General Public License (GPL) or under the terms of one of the closed- +source Quantum Leaps commercial licenses. + +Redistributions in source code must retain this top-level comment block. +Plagiarizing this software to sidestep the license obligations is illegal. + +NOTE: +The GPL does NOT permit the incorporation of this code into proprietary +programs. Please contact Quantum Leaps for commercial licensing options, +which expressly supersede the GPL and are designed explicitly for +closed-source distribution. + +Quantum Leaps contact information: <www.state-machine.com/licensing> <info@state-machine.com> -#BC89496843DE5343CECA990E1370BDD6F9ACDC56 +#2BACD81DCE8ED122C193E4F48A14170D660DFF1E @@ -275,14 +277,6 @@ Contact information: - - - 0xE0U - - - - 0U - //! @class QEvt @@ -290,14 +284,14 @@ Contact information: //! @public @memberof QEvt - - - //! @private @memberof QEvt - //! @private @memberof QEvt + + + //! @private @memberof QEvt + = { @@ -315,8 +309,8 @@ Contact information: me->sig = (QSignal)sig; -me->refCtr_ = 0U; -me->evtTag_ = QEVT_MARKER; +me->evtTag_ = 0x0FU; +me->refCtr_ = 0U; @@ -329,13 +323,14 @@ me->evtTag_ = QEVT_MARKER; return me; - + const //! @private @memberof QEvt //! @private @memberof QEvt - return (me != (QEvt const *)0) - && ((me->evtTag_ & 0xF0U) == QEVT_MARKER); + uint8_t rc = me->refCtr_; +return (rc <= 2U*QF_MAX_ACTIVE) + && (((me->evtTag_ ^ rc) & 0x0FU) == 0x0FU); @@ -343,7 +338,7 @@ return me; //! @private @memberof QEvt //! @private @memberof QEvt - return (uint_fast8_t)me->evtTag_ & 0x0FU; + return (uint_fast8_t)(me->evtTag_ >> 4U); @@ -354,7 +349,6 @@ return me; { // unhandled and need to "bubble up" Q_RET_SUPER, //!< event passed to superstate to handle - Q_RET_SUPER_SUB, //!< event passed to submachine superstate Q_RET_UNHANDLED, //!< event unhandled due to guard // handled and do not need to "bubble up" @@ -370,12 +364,10 @@ return me; // transitions need to execute transition-action table in ::QMsm Q_RET_TRAN, //!< regular transition - Q_RET_TRAN_INIT, //!< initial transition in a state or submachine - Q_RET_TRAN_EP, //!< entry-point transition into a submachine + Q_RET_TRAN_INIT, //!< initial transition in a state // transitions that additionally clobber me->state Q_RET_TRAN_HIST, //!< transition to history of a given state - Q_RET_TRAN_XP //!< exit-point transition out of a submachine }; @@ -412,17 +404,6 @@ return me; QMState const *target; //!< @private @memberof QMTranActTable QActionHandler const act[1]; //!< @private @memberof QMTranActTable } QMTranActTable; - - - - //! Reserved signals by the QHsm-style state machine implementation - { - Q_EMPTY_SIG, //!< signal to execute the default case - Q_ENTRY_SIG, //!< signal for coding entry actions - Q_EXIT_SIG, //!< signal for coding exit actions - Q_INIT_SIG, //!< signal for coding initial transitions - Q_USER_SIG //!< offset for the user signals (QP Application) -}; @@ -516,44 +497,49 @@ me->super.temp.fun = initial; QF_CRIT_STAT +QState r; + +// produce QS dictionary for QHsm_top() #ifdef Q_SPY QS_CRIT_ENTRY(); QS_MEM_SYS(); if ((QS_priv_.flags & 0x01U) == 0U) { QS_priv_.flags |= 0x01U; - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_FUN_DICTIONARY(&QHsm_top); + r = Q_RET_HANDLED; } else { - QS_MEM_APP(); - QS_CRIT_EXIT(); + r = Q_RET_IGNORED; +} +QS_MEM_APP(); +QS_CRIT_EXIT(); +if (r == Q_RET_HANDLED) { + QS_FUN_DICTIONARY(&QHsm_top); } #else Q_UNUSED_PAR(qsId); -#endif +#endif // def Q_SPY QStateHandler t = me->state.fun; QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) - && (me->temp.fun != Q_STATE_CAST(0)) - && (t == Q_STATE_CAST(&QHsm_top))); + && (me->temp.fun != Q_STATE_CAST(0)) + && (t == Q_STATE_CAST(&QHsm_top))); QF_CRIT_EXIT(); // execute the top-most initial tran. -QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); +r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); QF_CRIT_ENTRY(); // the top-most initial tran. must be taken Q_ASSERT_INCRIT(210, r == Q_RET_TRAN); QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source state - QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. -QS_END_PRE_() +QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the source state + QS_FUN_PRE(me->temp.fun); // the target of the initial tran. +QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -598,11 +584,11 @@ do { if (r == Q_RET_TRAN) { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source state - QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the source state + QS_FUN_PRE(me->temp.fun); // the target of the initial tran. + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -612,11 +598,11 @@ do { QF_CRIT_ENTRY(); QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the new active state -QS_END_PRE_() +QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the new active state +QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -646,17 +632,21 @@ QStateHandler t = s; QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); -Q_INVARIANT_INCRIT(302, (s != Q_STATE_CAST(0)) +Q_REQUIRE_INCRIT(300, + (e != (QEvt *)0) + && (s != Q_STATE_CAST(0)) && (me->state.uint == (uintptr_t)(~me->temp.uint))); +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +#endif QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the current state -QS_END_PRE_() +QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the current state +QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -673,11 +663,11 @@ do { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the current state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -691,9 +681,22 @@ QF_CRIT_ENTRY(); Q_ENSURE_INCRIT(310, ip > 0); QF_CRIT_EXIT(); -if (r >= Q_RET_TRAN) { // regular tran. taken? - QStateHandler path[QHSM_MAX_NEST_DEPTH_]; +if (r >= Q_RET_TRAN) { // tran. (regular or history) taken? +#ifdef Q_SPY + if (r == Q_RET_TRAN_HIST) { // tran. to history? + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // tran. to history source + QS_FUN_PRE(me->temp.fun); // tran. to history target + QS_END_PRE() + QS_MEM_APP(); + QS_CRIT_EXIT(); + } +#endif // Q_SPY + QStateHandler path[QHSM_MAX_NEST_DEPTH_]; path[0] = me->temp.fun; // tran. target path[1] = t; // current state path[2] = s; // tran. source @@ -715,20 +718,6 @@ if (r >= Q_RET_TRAN) { // regular tran. taken? ip = QHsm_tran_(me, path, qsId); // take the tran. -#ifdef Q_SPY - if (r == Q_RET_TRAN_HIST) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source of the tran. - QS_FUN_PRE_(path[0]); // the target of the tran. to history - QS_END_PRE_() - QS_MEM_APP(); - QS_CRIT_EXIT(); - } -#endif // Q_SPY - // execute state entry actions in the desired order... // note: ip is the fixed upper loop bound for (; ip >= 0; --ip) { @@ -747,11 +736,11 @@ if (r >= Q_RET_TRAN) { // regular tran. taken? QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source (pseudo)state - QS_FUN_PRE_(me->temp.fun); // the target of the tran. - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the source (pseudo)state + QS_FUN_PRE(me->temp.fun); // the target of the tran. + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -792,13 +781,13 @@ if (r >= Q_RET_TRAN) { // regular tran. taken? QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the source of the tran. - QS_FUN_PRE_(t); // the new active state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the source of the tran. + QS_FUN_PRE(t); // the new active state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -807,24 +796,24 @@ if (r >= Q_RET_TRAN) { // regular tran. taken? else if (r == Q_RET_HANDLED) { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the source state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the source state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } else { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.fun); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->state.fun); // the current state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -855,8 +844,8 @@ me->temp.uint = ~me->state.uint; QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_INVARIANT_INCRIT(602, me->state.uint - == (uintptr_t)(~me->temp.uint)); +Q_INVARIANT_INCRIT(602, + me->state.uint == (uintptr_t)(~me->temp.uint)); QF_CRIT_EXIT(); bool inState = false; // assume that this HSM is not in 'state' @@ -1168,11 +1157,11 @@ QF_CRIT_ENTRY(); Q_ASSERT_INCRIT(210, r == Q_RET_TRAN_INIT); QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.obj->stateHandler); // source state - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target state -QS_END_PRE_() +QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->state.obj->stateHandler); // source state + QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target state +QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -1192,11 +1181,11 @@ QF_CRIT_ENTRY(); Q_ENSURE_INCRIT(290, lbound > 0); QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.obj->stateHandler); // the new current state -QS_END_PRE_() +QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->state.obj->stateHandler); // the new current state +QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -1225,17 +1214,21 @@ QMState const *t = s; QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); -Q_INVARIANT_INCRIT(302, (s != (QMState *)0) +Q_REQUIRE_INCRIT(300, + (e != (QEvt *)0) + && (s != (QMState *)0) && (me->state.uint == (uintptr_t)(~me->temp.uint))); +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +#endif QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s->stateHandler); // the current state handler -QS_END_PRE_() +QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s->stateHandler); // the current state handler +QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -1254,21 +1247,17 @@ do { else if (r == Q_RET_SUPER) { t = t->superstate; // advance to the superstate } - // event unhandled and passed to a submachine superstate? - else if (r == Q_RET_SUPER_SUB) { - t = me->temp.obj; // current host state of the submachine - } else { // event unhandled due to a guard QF_CRIT_ENTRY(); // event must be unhandled due to a guard evaluating to 'false' Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t->stateHandler); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t->stateHandler); // the current state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -1282,94 +1271,62 @@ Q_ENSURE_INCRIT(320, lbound > 0); QF_CRIT_EXIT(); if (r >= Q_RET_TRAN) { // any kind of tran. taken? -#ifdef Q_SPY - QMState const * const ts = t; // tran. source for QS tracing - QF_CRIT_ENTRY(); // the tran. source state must not be NULL - Q_ASSERT_INCRIT(330, ts != (QMState *)0); + Q_ASSERT_INCRIT(330, t != (QMState *)0); QF_CRIT_EXIT(); + +#ifdef Q_SPY + QMState const * const ts = t; // tran. source for QS tracing #endif // Q_SPY + struct QMTranActTable const *tatbl; // for saving tran. table + + if (r == Q_RET_TRAN_HIST) { // was it tran. to history? + QMState const * const hist = me->state.obj; // save history + me->state.obj = s; // restore the original state + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t->stateHandler); // source state handler + QS_FUN_PRE(hist->stateHandler); // target state handler + QS_END_PRE() + QS_MEM_APP(); + QS_CRIT_EXIT(); + + // save the tran-action table before it gets clobbered + tatbl = me->temp.tatbl; + QMsm_exitToTranSource_(me, s, t, qsId); + (void)QMsm_execTatbl_(me, tatbl, qsId); + r = QMsm_enterHistory_(me, hist, qsId); + s = me->state.obj; + t = s; // set target to the current state + } lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - do { + while ((r >= Q_RET_TRAN) && (lbound > 0)) { // save the tran-action table before it gets clobbered - struct QMTranActTable const * const tatbl = me->temp.tatbl; - union QAsmAttr tmp; // temporary to save intermediate values - - // was TRAN, TRAN_INIT, or TRAN_EP taken? - if (r <= Q_RET_TRAN_EP) { - me->temp.obj = (QMState *)0; // clear - QMsm_exitToTranSource_(me, s, t, qsId); - r = QMsm_execTatbl_(me, tatbl, qsId); - s = me->state.obj; - } - // was a tran. segment to history taken? - else if (r == Q_RET_TRAN_HIST) { - tmp.obj = me->state.obj; // save history - me->state.obj = s; // restore the original state - QMsm_exitToTranSource_(me, s, t, qsId); - (void)QMsm_execTatbl_(me, tatbl, qsId); - r = QMsm_enterHistory_(me, tmp.obj, qsId); - s = me->state.obj; - } - else { - QF_CRIT_ENTRY(); - // must be tran. to exit point - Q_ASSERT_INCRIT(340, r == Q_RET_TRAN_XP); - QF_CRIT_EXIT(); - - tmp.act = me->state.act; // save XP action - me->state.obj = s; // restore the original state - r = (*tmp.act)(me); // execute the XP action - if (r == Q_RET_TRAN) { // XP -> TRAN ? -#ifdef Q_SPY - tmp.tatbl = me->temp.tatbl; // save me->temp -#endif // Q_SPY - QMsm_exitToTranSource_(me, s, t, qsId); - // take the tran-to-XP segment inside submachine - (void)QMsm_execTatbl_(me, tatbl, qsId); - s = me->state.obj; -#ifdef Q_SPY - me->temp.tatbl = tmp.tatbl; // restore me->temp -#endif // Q_SPY - } - else if (r == Q_RET_TRAN_HIST) { // XP -> HIST ? - tmp.obj = me->state.obj; // save the history - me->state.obj = s; // restore the original state - s = me->temp.obj; // save me->temp - QMsm_exitToTranSource_(me, me->state.obj, t, qsId); - // take the tran-to-XP segment inside submachine - (void)QMsm_execTatbl_(me, tatbl, qsId); -#ifdef Q_SPY - me->temp.obj = s; // restore me->temp -#endif // Q_SPY - s = me->state.obj; - me->state.obj = tmp.obj; // restore the history - } - else { - QF_CRIT_ENTRY(); - // TRAN_XP must NOT be followed by any other tran. type - Q_ASSERT_INCRIT(350, r < Q_RET_TRAN); - QF_CRIT_EXIT(); - } - } - + tatbl = me->temp.tatbl; + me->temp.obj = (QMState *)0; // clear + QMsm_exitToTranSource_(me, s, t, qsId); + r = QMsm_execTatbl_(me, tatbl, qsId); + s = me->state.obj; t = s; // set target to the current state - --lbound; - } while ((r >= Q_RET_TRAN) && (lbound > 0)); + --lbound; + } QF_CRIT_ENTRY(); Q_ENSURE_INCRIT(360, lbound > 0); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(ts->stateHandler); // the tran. source - QS_FUN_PRE_(s->stateHandler); // the new active state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(ts->stateHandler); // the tran. source + QS_FUN_PRE(s->stateHandler); // the new active state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -1383,12 +1340,12 @@ else if (r == Q_RET_HANDLED) { Q_ASSERT_INCRIT(380, t != (QMState *)0); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t->stateHandler); // the source state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t->stateHandler); // the source state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -1396,16 +1353,13 @@ else if (r == Q_RET_HANDLED) { // event bubbled to the 'top' state? else if (t == (QMState *)0) { QS_CRIT_ENTRY(); - // current state can't be NULL - Q_ASSERT_INCRIT(390, s != (QMState *)0); - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s->stateHandler); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s->stateHandler); // the current state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -1553,37 +1507,23 @@ for (; (*a != Q_ACTION_CAST(0)) && (lbound > 0); ++a) { QS_CRIT_ENTRY(); QS_MEM_SYS(); if (r == Q_RET_ENTRY) { - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->temp.obj->stateHandler); // entered state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->temp.obj->stateHandler); // entered state + QS_END_PRE() } else if (r == Q_RET_EXIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->temp.obj->stateHandler); // exited state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->temp.obj->stateHandler); // exited state + QS_END_PRE() } else if (r == Q_RET_TRAN_INIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(tatbl->target->stateHandler); // source - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE_() - } - else if (r == Q_RET_TRAN_EP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_EP, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(tatbl->target->stateHandler); // source - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE_() - } - else if (r == Q_RET_TRAN_XP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_XP, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(tatbl->target->stateHandler); // source - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(tatbl->target->stateHandler); // source + QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target + QS_END_PRE() } else { // empty @@ -1633,22 +1573,15 @@ for (; (s != ts) && (lbound > 0); --lbound) { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s->stateHandler); // the exited state handler - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s->stateHandler); // the exited state handler + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } s = s->superstate; // advance to the superstate - - if (s == (QMState *)0) { // reached the top of a submachine? - s = me->temp.obj; // the superstate from QM_SM_EXIT() - QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(880, s != (QMState *)0); // must be valid - QF_CRIT_EXIT(); - } } QF_CRIT_ENTRY(); Q_ENSURE_INCRIT(890, lbound > 0); @@ -1669,35 +1602,20 @@ QF_CRIT_EXIT(); Q_UNUSED_PAR(qsId); #endif -QMState const *s = hist; -QMState const *ts = me->state.obj; // tran. source +// record the entry path from current state to history QMState const *epath[QMSM_MAX_ENTRY_DEPTH_]; - -QF_CRIT_STAT - -QS_CRIT_ENTRY(); -QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(ts->stateHandler); // source state handler - QS_FUN_PRE_(hist->stateHandler); // target state handler -QS_END_PRE_() -QS_MEM_APP(); -QS_CRIT_EXIT(); - +QMState const *s = hist; int_fast8_t i = 0; // tran. entry path index -while ((s != ts) && (i < QMSM_MAX_ENTRY_DEPTH_)) { +while ((s != me->state.obj) && (i < (QMSM_MAX_ENTRY_DEPTH_ - 1))) { if (s->entryAction != Q_ACTION_CAST(0)) { epath[i] = s; ++i; } s = s->superstate; - if (s == (QMState *)0) { - ts = s; // force exit from the for-loop - } } +QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_ASSERT_INCRIT(910, s == ts); +Q_ASSERT_INCRIT(910, s == me->state.obj); QF_CRIT_EXIT(); // retrace the entry path in reverse (desired) order... @@ -1707,10 +1625,10 @@ while (i > 0) { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE_(me); - QS_FUN_PRE_(epath[i]->stateHandler); // entered state handler - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) + QS_OBJ_PRE(me); + QS_FUN_PRE(epath[i]->stateHandler); // entered state handler + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -1721,6 +1639,15 @@ me->state.obj = hist; // set current state to the tran. target QState r; if (hist->initAction != Q_ACTION_CAST(0)) { r = (*hist->initAction)(me); // execute the tran. action + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(hist->stateHandler); // source + QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target + QS_END_PRE() + QS_MEM_APP(); + QS_CRIT_EXIT(); } else { r = Q_RET_NULL; @@ -1736,8 +1663,12 @@ return r; - { (QSignal)(sig_), 0U, QEVT_MARKER } + { (QSignal)(sig_), 0x01U, 0x0EU } + + + ((uint8_t)0) + @@ -1813,6 +1744,26 @@ return r; ((QMsm *)(ptr_)) + + + ((QSignal)0) + + + + ((QSignal)1) + + + + ((QSignal)2) + + + + ((QSignal)3) + + + + ((enum_t)4) + @@ -1952,26 +1903,6 @@ return r; (struct QMTranActTable const *)(tatbl_))), \ (QState)Q_RET_TRAN_HIST) - - - - - ((Q_ASM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), \ - (QState)Q_RET_TRAN_EP) - - - - - - - - \ - ((((Q_ASM_UPCAST(me))->state.act = (xp_)), \ - ((Q_ASM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - (QState)Q_RET_TRAN_XP) - ((QState)Q_RET_HANDLED) @@ -1984,14 +1915,6 @@ return r; ((QState)Q_RET_SUPER) - - - - - \ - ((Q_ASM_UPCAST(me))->temp.obj = (host_), \ - (QState)Q_RET_SUPER_SUB) - ((QMState *)0) @@ -2196,7 +2119,7 @@ return (me->bits[0] == (QPSetBits)(~dis->bits[0])) - // @struct QSubscrList + //! @struct QSubscrList //! @private @memberof QSubscrList @@ -2206,6 +2129,8 @@ return (me->bits[0] == (QPSetBits)(~dis->bits[0])) //! @private @memberof QSubscrList + + @@ -2303,7 +2228,7 @@ me->super.vptr = &vtable; // hook vptr to QActive vtable - + @@ -2404,46 +2329,49 @@ Q_UNUSED_PAR(sender); #endif #ifdef Q_UTEST // test? -#if Q_UTEST != 0 // testing QP-stub? +#if (Q_UTEST != 0) // testing QP-stub? if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? return QActiveDummy_fakePost_(me, e, margin, sender); } -#endif -#endif +#endif // (Q_UTEST != 0) +#endif // def Q_UTEST QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); +Q_REQUIRE_INCRIT(200, e != (QEvt *)0); + +QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary #ifndef Q_UNSAFE -Q_REQUIRE_INCRIT(100, QEvt_verify_(e)); - -uint8_t const pcopy = (uint8_t)(~me->prio_dis); -Q_INVARIANT_INCRIT(102, me->prio == pcopy); -#endif - -QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary +QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; +Q_INVARIANT_INCRIT(201, (QEvt_verify_(e)) && (tmp == dis)); +#endif // ndef Q_UNSAFE // test-probe#1 for faking queue overflow QS_TEST_PROBE_DEF(&QActive_post_) QS_TEST_PROBE_ID(1, - nFree = 0U; + tmp = 0U; // fake no free events ) +// required margin available? bool status; if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { + if (tmp > 0U) { // free entries available in the queue? status = true; // can post } - else { + else { // no free entries available status = false; // cannot post - Q_ERROR_INCRIT(110); // must be able to post the event + + // The queue overflows, but QF_NO_MARGIN indicates that + // the "event delivery guarantee" is required. + Q_ERROR_INCRIT(210); // must be able to post the event } } -else if (nFree > (QEQueueCtr)margin) { +else if (tmp > (QEQueueCtr)margin) { // enough free entries? status = true; // can post } -else { +else { // the # free entries below the requested margin status = false; // cannot post, but don't assert } @@ -2453,22 +2381,30 @@ if (QEvt_getPoolNum_(e) != 0U) { } if (status) { // can post the event? + --tmp; // one free entry just used up - --nFree; // one free entry just used up - me->eQueue.nFree = nFree; // update the original - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; // increase minimum so far + me->eQueue.nFree = tmp; // update the original +#ifndef Q_UNSAFE + me->eQueue.nFree_dis = (QEQueueCtr)~tmp; // update the DIS + + if (me->eQueue.nMin > tmp) { + me->eQueue.nMin = tmp; // update minimum so far } +#endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->eQueue.nMin); // min # free entries - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries +#ifndef Q_UNSAFE + QS_EQC_PRE(me->eQueue.nMin); // min # free entries +#else + QS_EQC_PRE(0U); // min # free entries +#endif + QS_END_PRE() #ifdef Q_UTEST // callback to examine the posted event under the same conditions @@ -2483,47 +2419,60 @@ if (status) { // can post the event? QF_CRIT_ENTRY(); QF_MEM_SYS(); } -#endif +#endif // def Q_UTEST - if (me->eQueue.frontEvt == (QEvt *)0) { // empty queue? + if (me->eQueue.frontEvt == (QEvt *)0) { // is the queue empty? me->eQueue.frontEvt = e; // deliver event directly +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(211, me->eQueue.frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); +#endif // ndef Q_UNSAFE #ifdef QXK_H_ if (me->super.state.act == Q_ACTION_CAST(0)) { // eXtended? - QXTHREAD_EQUEUE_SIGNAL_(me); // signal the event queue + QXTHREAD_EQUEUE_SIGNAL_(me); // signal eXtended Thread } else { - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue + QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object } #else - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue -#endif + QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object +#endif // def QXK_H_ } - // queue is not empty, insert event into the ring-buffer - else { - // insert event into the ring buffer (FIFO) - me->eQueue.ring[me->eQueue.head] = e; + else { // queue was not empty, insert event into the ring-buffer + tmp = me->eQueue.head; // get volatile into temporary +#ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->eQueue.head_dis; + Q_INVARIANT_INCRIT(212, tmp == dis); +#endif // ndef Q_UNSAFE + me->eQueue.ring[tmp] = e; // insert e into buffer - if (me->eQueue.head == 0U) { // need to wrap head? - me->eQueue.head = me->eQueue.end; // wrap around + if (tmp == 0U) { // need to wrap the head? + tmp = me->eQueue.end; } - --me->eQueue.head; // advance the head (counter clockwise) + --tmp; // advance the head (counter-clockwise) + + me->eQueue.head = tmp; // update the original +#ifndef Q_UNSAFE + me->eQueue.head_dis = (QEQueueCtr)~tmp; +#endif // ndef Q_UNSAFE } QF_MEM_APP(); QF_CRIT_EXIT(); } -else { // cannot post the event +else { // event cannot be posted - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() #ifdef Q_UTEST // callback to examine the posted event under the same conditions @@ -2538,14 +2487,14 @@ else { // cannot post the event QF_CRIT_ENTRY(); QF_MEM_SYS(); } -#endif +#endif // def Q_USTEST QF_MEM_APP(); QF_CRIT_EXIT(); #if (QF_MAX_EPOOL > 0U) QF_gc(e); // recycle the event to avoid a leak -#endif +#endif // (QF_MAX_EPOOL > 0U) } return status; @@ -2558,57 +2507,63 @@ return status; #ifdef Q_UTEST // test? -#if Q_UTEST != 0 // testing QP-stub? +#if (Q_UTEST != 0) // testing QP-stub? if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? QActiveDummy_fakePostLIFO_(me, e); return; } -#endif -#endif +#endif // (Q_UTEST != 0) +#endif // def Q_UTEST QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); +// the posted event must be be valid (which includes not NULL) +Q_REQUIRE_INCRIT(300, e != (QEvt *)0); + +QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary #ifndef Q_UNSAFE -Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); - -uint8_t const pcopy = (uint8_t)(~me->prio_dis); -Q_INVARIANT_INCRIT(202, me->prio == pcopy); -#endif - -#ifdef QXK_H_ -Q_REQUIRE_INCRIT(200, me->super.state.act != Q_ACTION_CAST(0)); -#endif - -QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary +QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; +Q_INVARIANT_INCRIT(301, (QEvt_verify_(e)) && (tmp == dis)); +#endif // ndef Q_UNSAFE // test-probe#1 for faking queue overflow QS_TEST_PROBE_DEF(&QActive_postLIFO_) QS_TEST_PROBE_ID(1, - nFree = 0U; + tmp = 0U; // fake no free events ) -Q_REQUIRE_INCRIT(201, nFree != 0U); +// The queue must NOT overflow for the LIFO posting policy. +Q_REQUIRE_INCRIT(310, tmp != 0U); if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? QEvt_refCtr_inc_(e); // increment the reference counter } ---nFree; // one free entry just used up -me->eQueue.nFree = nFree; // update the original -if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; // update minimum so far -} +--tmp; // one free entry just used up -QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->eQueue.nMin); // min # free entries -QS_END_PRE_() +me->eQueue.nFree = tmp; // update the original +#ifndef Q_UNSAFE +me->eQueue.nFree_dis = (QEQueueCtr)~tmp; + +if (me->eQueue.nMin > tmp) { + me->eQueue.nMin = tmp; // update minimum so far +} +#endif // ndef Q_UNSAFE + +QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries +#ifndef Q_UNSAFE + QS_EQC_PRE(me->eQueue.nMin); // min # free entries +#else + QS_EQC_PRE(0U); // min # free entries +#endif +QS_END_PRE() #ifdef Q_UTEST // callback to examine the posted event under the same conditions @@ -2623,21 +2578,32 @@ if (QS_LOC_CHECK_(me->prio)) { QF_CRIT_ENTRY(); QF_MEM_SYS(); } -#endif +#endif // def Q_UTEST QEvt const * const frontEvt = me->eQueue.frontEvt; me->eQueue.frontEvt = e; // deliver the event directly to the front +#ifndef Q_UNSAFE +me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); +#endif // ndef Q_UNSAFE -if (frontEvt == (QEvt *)0) { // was the queue empty? - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue -} -else { // queue was not empty, leave the event in the ring-buffer - ++me->eQueue.tail; - if (me->eQueue.tail == me->eQueue.end) { // need to wrap the tail? - me->eQueue.tail = 0U; // wrap around +if (frontEvt != (QEvt *)0) { // was the queue NOT empty? + tmp = me->eQueue.tail; // get volatile into temporary; +#ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(311, tmp == dis); +#endif // ndef Q_UNSAFE + ++tmp; + if (tmp == me->eQueue.end) { // need to wrap the tail? + tmp = 0U; // wrap around } - - me->eQueue.ring[me->eQueue.tail] = frontEvt; + me->eQueue.tail = tmp; +#ifndef Q_UNSAFE + me->eQueue.tail_dis = (QEQueueCtr)~tmp; +#endif // ndef Q_UNSAFE + me->eQueue.ring[tmp] = frontEvt; +} +else { // queue was empty + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } QF_MEM_APP(); @@ -2652,43 +2618,77 @@ QF_CRIT_EXIT(); QF_CRIT_ENTRY(); QF_MEM_SYS(); -QACTIVE_EQUEUE_WAIT_(me); // wait for event to arrive directly +// wait for event to arrive directly (depends on QP port) +// NOTE: might use assertion-IDs 400-409 +QACTIVE_EQUEUE_WAIT_(me); // always remove event from the front QEvt const * const e = me->eQueue.frontEvt; -Q_INVARIANT_INCRIT(312, QEvt_verify_(e)); +QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary -QEQueueCtr const nFree = me->eQueue.nFree + 1U; // get volatile into tmp -me->eQueue.nFree = nFree; // update the # free +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(410, e != (QEvt *)0); // queue must NOT be empty +Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) + == (uintptr_t)~me->eQueue.frontEvt_dis); +QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; +Q_INVARIANT_INCRIT(412, tmp == dis); +#endif // ndef Q_UNSAFE + +++tmp; // one more free event in the queue + +me->eQueue.nFree = tmp; // update the # free +#ifndef Q_UNSAFE +me->eQueue.nFree_dis = (QEQueueCtr)~tmp; +#endif // ndef Q_UNSAFE + +if (tmp <= me->eQueue.end) { // any events in the ring buffer? + + QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_END_PRE() -if (nFree <= me->eQueue.end) { // any events in the ring buffer? // remove event from the tail - me->eQueue.frontEvt = me->eQueue.ring[me->eQueue.tail]; - if (me->eQueue.tail == 0U) { // need to wrap the tail? - me->eQueue.tail = me->eQueue.end; // wrap around - } - --me->eQueue.tail; + tmp = me->eQueue.tail; // get volatile into temporary +#ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(420, tmp == dis); +#endif // ndef Q_UNSAFE + QEvt const * const frontEvt = me->eQueue.ring[tmp]; +#ifndef Q_UNSAFE + Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); +#endif // ndef Q_UNSAFE + me->eQueue.frontEvt = frontEvt; // update the original - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_END_PRE_() + if (tmp == 0U) { // need to wrap the tail? + tmp = me->eQueue.end; + } + --tmp; // advance the tail (counter-clockwise) + + me->eQueue.tail = tmp; // update the original +#ifndef Q_UNSAFE + me->eQueue.tail_dis = (QEQueueCtr)~tmp; +#endif // ndef Q_UNSAFE } else { me->eQueue.frontEvt = (QEvt *)0; // queue becomes empty +#ifndef Q_UNSAFE + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); +#endif // ndef Q_UNSAFE // all entries in the queue must be free (+1 for fronEvt) - Q_ASSERT_INCRIT(310, nFree == (me->eQueue.end + 1U)); + Q_ASSERT_INCRIT(440, tmp == (me->eQueue.end + 1U)); - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_GET_LAST, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() } QF_MEM_APP(); @@ -2743,12 +2743,12 @@ Q_INVARIANT_INCRIT(202, QPSet_verify_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis)); -QS_BEGIN_PRE_(QS_QF_PUBLISH, qsId) - QS_TIME_PRE_(); // the timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_PUBLISH, qsId) + QS_TIME_PRE(); // the timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(sig); // the signal of the event + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); +QS_END_PRE() // is it a mutable event? if (QEvt_getPoolNum_(e) != 0U) { @@ -2839,7 +2839,7 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(300, ((enum_t)Q_USER_SIG <= sig) +Q_REQUIRE_INCRIT(300, (Q_USER_SIG <= sig) && (sig < QActive_maxPubSignal_) && (0U < p) && (p <= QF_MAX_ACTIVE) && (QActive_registry_[p] == me)); @@ -2847,11 +2847,11 @@ Q_INVARIANT_INCRIT(302, QPSet_verify_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis)); -QS_BEGIN_PRE_(QS_QF_ACTIVE_SUBSCRIBE, p) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_ACTIVE_SUBSCRIBE, p) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(sig); // the signal of this event + QS_OBJ_PRE(me); // this active object +QS_END_PRE() // insert the prio. into the subscriber set QPSet_insert(&QActive_subscrList_[sig].set, p); @@ -2877,7 +2877,7 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(400, ((enum_t)Q_USER_SIG <= sig) +Q_REQUIRE_INCRIT(400, (Q_USER_SIG <= sig) && (sig < QActive_maxPubSignal_) && (0U < p) && (p <= QF_MAX_ACTIVE) && (QActive_registry_[p] == me)); @@ -2885,11 +2885,11 @@ Q_INVARIANT_INCRIT(402, QPSet_verify_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis)); -QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(sig); // the signal of this event + QS_OBJ_PRE(me); // this active object +QS_END_PRE() // remove the prio. from the subscriber set QPSet_remove(&QActive_subscrList_[sig].set, p); @@ -2920,7 +2920,7 @@ enum_t const maxPubSig = QActive_maxPubSignal_; QF_MEM_APP(); QF_CRIT_EXIT(); -for (enum_t sig = (enum_t)Q_USER_SIG; sig < maxPubSig; ++sig) { +for (enum_t sig = Q_USER_SIG; sig < maxPubSig; ++sig) { QF_CRIT_ENTRY(); QF_MEM_SYS(); @@ -2930,11 +2930,11 @@ for (enum_t sig = (enum_t)Q_USER_SIG; sig < maxPubSig; ++sig) { QPSet_update_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis); #endif - QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_END_PRE() } QF_MEM_APP(); QF_CRIT_EXIT(); @@ -2957,13 +2957,13 @@ for (enum_t sig = (enum_t)Q_USER_SIG; sig < maxPubSig; ++sig) { QS_CRIT_STAT QS_CRIT_ENTRY(); QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QF_ACTIVE_DEFER, me->prio) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this active object - QS_OBJ_PRE_(eq); // the deferred queue - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_ACTIVE_DEFER, me->prio) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this active object + QS_OBJ_PRE(eq); // the deferred queue + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); +QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -2999,13 +2999,13 @@ if (e != (QEvt *)0) { // event available? QEvt_refCtr_dec_(e); // decrement the reference counter } - QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL, me->prio) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this active object - QS_OBJ_PRE_(eq); // the deferred queue - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL, me->prio) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this active object + QS_OBJ_PRE(eq); // the deferred queue + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -3016,11 +3016,11 @@ else { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this active object - QS_OBJ_PRE_(eq); // the deferred queue - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this active object + QS_OBJ_PRE(eq); // the deferred queue + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -3105,22 +3105,42 @@ me->super.super.vptr = &vtable; // hook vptr to QMActive vtable //! @private @memberof QTimeEvt + + + //! @private @memberof QTimeEvt + - + //! @private @memberof QTimeEvt //! @private @memberof QTimeEvt + + + //! @private @memberof QTimeEvt + //! @private @memberof QTimeEvt + + + //! @private @memberof QTimeEvt + + + + //! @private @memberof QTimeEvt + //! @static @private @memberof QTimeEvt + + + //! @static @private @memberof QTimeEvt + //! @public @memberof QTimeEvt @@ -3138,18 +3158,19 @@ Q_REQUIRE_INCRIT(300, (sig != 0) && (tickRate < QF_MAX_TICK_RATE)); QF_CRIT_EXIT(); -// Initialize the QEvt superclass: -// NOTE: The refCtr_ attribute is not used in time events, -// so it is reused to hold the tickRate as well as other -// information about the status of the time event. -me->super.sig = (QSignal)sig; -me->super.refCtr_ = (uint8_t)tickRate; -me->super.evtTag_ = QEVT_MARKER; +QEvt_ctor(&me->super, sig); me->next = (QTimeEvt *)0; me->act = act; me->ctr = 0U; -me->interval = 0U; +me->interval = 0U; +me->tickRate = (uint8_t)tickRate; +me->flags = 0U; + +#ifndef Q_UNSAFE +me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); +me->ctr_dis = (QTimeEvtCtr)~me->ctr; +#endif // ndef Q_UNSAFE @@ -3157,58 +3178,86 @@ me->interval = 0U; //! @public @memberof QTimeEvt - + - - uint_fast8_t const tickRate - = ((uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE); + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// dynamic range checks +#if (QF_TIMEEVT_CTR_SIZE == 1U) +Q_REQUIRE_INCRIT(400, (nTicks < 0xFFU) && (interval < 0xFFU)); +#elif (QF_TIMEEVT_CTR_SIZE == 2U) +Q_REQUIRE_INCRIT(400, (nTicks < 0xFFFFU) && (interval < 0xFFFFU)); +#endif + +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(401, QEvt_verify_(&me->super)); +#endif + QTimeEvtCtr const ctr = me->ctr; +uint8_t const tickRate = me->tickRate; #ifdef Q_SPY uint_fast8_t const qsId = ((QActive *)(me->act))->prio; #endif -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(400, (me->act != (void *)0) +Q_REQUIRE_INCRIT(410, + (nTicks != 0U) && (ctr == 0U) - && (nTicks != 0U) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) - && (me->super.sig >= (QSignal)Q_USER_SIG)); -#ifdef Q_UNSAFE -Q_UNUSED_PAR(ctr); -#endif + && (me->act != (void *)0) + && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE)); -me->ctr = nTicks; -me->interval = interval; +#ifndef Q_UNSAFE +QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; +Q_INVARIANT_INCRIT(411, ctr == dis); +#else +Q_UNUSED_PAR(ctr); +#endif // ndef Q_UNSAFE + +me->ctr = (QTimeEvtCtr)nTicks; +me->interval = (QTimeEvtCtr)interval; +#ifndef Q_UNSAFE +me->ctr_dis = (QTimeEvtCtr)~nTicks; +#endif // ndef Q_UNSAFE // is the time event unlinked? // NOTE: For the duration of a single clock tick of the specified tick // rate a time event can be disarmed and yet still linked into the list // because un-linking is performed exclusively in QTimeEvt_tick_(). -if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - // mark as linked - me->super.refCtr_ |= QTE_IS_LINKED; +if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { + me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - // The time event is initially inserted into the separate - // "freshly armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly armed" - // list is appended to the main list of armed time events based on - // QTimeEvt_timeEvtHead_[tickRate].next. Again, this is to keep any - // changes to the main list exclusively inside the QTimeEvt_tick_(). + // The time event is initially inserted into the separate "freshly + // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly + // armed" list is appended to the main list of armed time events + // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is + // to keep any changes to the main list exclusively inside the + // QTimeEvt_tick_(). +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(420, + Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); + Q_INVARIANT_INCRIT(421, + Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == + (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); +#endif me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; +#ifndef Q_UNSAFE + me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); + QTimeEvt_timeEvtHead_dis_[tickRate] = (uintptr_t)~Q_PTR2UINT_CAST_(me); +#endif // ndef Q_UNSAFE } -QS_BEGIN_PRE_(QS_QF_TIMEEVT_ARM, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the active object - QS_TEC_PRE_(nTicks); // the # ticks - QS_TEC_PRE_(interval); // the interval - QS_U8_PRE_(tickRate); // tick rate -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_TIMEEVT_ARM, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the active object + QS_TEC_PRE(nTicks); // the # ticks + QS_TEC_PRE(interval); // the interval + QS_U8_PRE(tickRate); // tick rate +QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -3218,41 +3267,51 @@ QF_CRIT_EXIT(); //! @public @memberof QTimeEvt //! @public @memberof QTimeEvt - #ifdef Q_SPY -uint_fast8_t const qsId = QACTIVE_CAST_(me->act)->prio; -#endif - -QF_CRIT_STAT + QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -// is the time event actually armed? +QTimeEvtCtr const ctr = me->ctr; + +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(500, QEvt_verify_(&me->super)); +QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; +Q_INVARIANT_INCRIT(501, ctr == dis); +#endif // ndef Q_UNSAFE + +#ifdef Q_SPY +uint_fast8_t const qsId = QACTIVE_CAST_(me->act)->prio; +#endif + +// was the time event actually armed? bool wasArmed; -if (me->ctr != 0U) { +if (ctr != 0U) { wasArmed = true; - me->super.refCtr_ |= QTE_WAS_DISARMED; - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the target AO - QS_TEC_PRE_(me->ctr); // the # ticks - QS_TEC_PRE_(me->interval); // the interval - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate - QS_END_PRE_() - + me->flags |= QTE_FLAG_WAS_DISARMED; me->ctr = 0U; // schedule removal from the list +#ifndef Q_UNSAFE + me->ctr_dis = (QTimeEvtCtr)~0U; +#endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the target AO + QS_TEC_PRE(ctr); // the # ticks + QS_TEC_PRE(me->interval); // the interval + QS_U8_PRE(me->tickRate); // tick rate + QS_END_PRE() } else { // the time event was already disarmed automatically wasArmed = false; - me->super.refCtr_ &= (uint8_t)(~QTE_WAS_DISARMED & 0xFFU); + me->flags &= (uint8_t)(~QTE_FLAG_WAS_DISARMED & 0xFFU); - QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the target AO - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the target AO + QS_U8_PRE(me->tickRate); // tick rate + QS_END_PRE() } QF_MEM_APP(); @@ -3266,25 +3325,44 @@ return wasArmed; //! @public @memberof QTimeEvt - - uint_fast8_t const tickRate - = (uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE; + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// dynamic range checks +#if (QF_TIMEEVT_CTR_SIZE == 1U) +Q_REQUIRE_INCRIT(600, nTicks < 0xFFU); +#elif (QF_TIMEEVT_CTR_SIZE == 2U) +Q_REQUIRE_INCRIT(600, nTicks < 0xFFFFU); +#endif + +uint8_t const tickRate = me->tickRate; +QTimeEvtCtr const ctr = me->ctr; + +Q_REQUIRE_INCRIT(600, + (nTicks != 0U) + && (me->act != (void *)0) + && (tickRate < QF_MAX_TICK_RATE)); + +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(601, QEvt_verify_(&me->super)); +QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; +Q_INVARIANT_INCRIT(602, ctr == dis); +#endif // ndef Q_UNSAFE + #ifdef Q_SPY uint_fast8_t const qsId = ((QActive *)(me->act))->prio; #endif -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); +me->ctr = (QTimeEvtCtr)nTicks; +#ifndef Q_UNSAFE +me->ctr_dis = (QTimeEvtCtr)~nTicks; +#endif // ndef Q_UNSAFE -Q_REQUIRE_INCRIT(600, (me->act != (void *)0) - && (tickRate < QF_MAX_TICK_RATE) - && (nTicks != 0U) - && (me->super.sig >= (QSignal)Q_USER_SIG)); - -// is the time evt not running? +// was the time evt not running? bool wasArmed; -if (me->ctr == 0U) { +if (ctr == 0U) { wasArmed = false; // NOTE: For the duration of a single clock tick of the specified @@ -3293,34 +3371,44 @@ if (me->ctr == 0U) { // QTimeEvt_tick_() function. // is the time event unlinked? - if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - // mark as linked - me->super.refCtr_ |= QTE_IS_LINKED; + if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { + me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - // The time event is initially inserted into the separate - // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. + // The time event is initially inserted into the separate "freshly + // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. // Only later, inside the QTimeEvt_tick_() function, the "freshly // armed" list is appended to the main list of armed time events // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside the + // to keep any changes to the main list exclusively inside // QTimeEvt_tick_(). +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(620, + Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); + Q_INVARIANT_INCRIT(621, + Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == + (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); +#endif me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; +#ifndef Q_UNSAFE + me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); + QTimeEvt_timeEvtHead_dis_[tickRate] = + (uintptr_t)~Q_PTR2UINT_CAST_(me); +#endif // ndef Q_UNSAFE } } else { // the time event was armed wasArmed = true; } -me->ctr = nTicks; // re-load the tick counter (shift the phasing) -QS_BEGIN_PRE_(QS_QF_TIMEEVT_REARM, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the target AO - QS_TEC_PRE_(me->ctr); // the # ticks - QS_TEC_PRE_(me->interval); // the interval - QS_2U8_PRE_(tickRate, (wasArmed ? 1U : 0U)); -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_TIMEEVT_REARM, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the target AO + QS_TEC_PRE(nTicks); // the # ticks + QS_TEC_PRE(me->interval); // the interval + QS_2U8_PRE(tickRate, (wasArmed ? 1U : 0U)); +QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -3336,13 +3424,13 @@ return wasArmed; QF_CRIT_ENTRY(); QF_MEM_SYS(); -uint8_t const wasDisarmed = (me->super.refCtr_ & QTE_WAS_DISARMED); -me->super.refCtr_ |= QTE_WAS_DISARMED; // mark as disarmed +bool const wasDisarmed = (me->flags & QTE_FLAG_WAS_DISARMED) != 0U; +me->flags |= QTE_FLAG_WAS_DISARMED; // mark as disarmed QF_MEM_APP(); QF_CRIT_EXIT(); -return wasDisarmed != 0U; +return wasDisarmed; @@ -3356,6 +3444,23 @@ QTimeEvtCtr const ctr = me->ctr; QF_CRIT_EXIT(); return ctr; + + + + //! @static @private @memberof QTimeEvt + +//! @static @private @memberof QTimeEvt + for (uint_fast8_t tickRate = 0U; + tickRate < Q_DIM(QTimeEvt_timeEvtHead_); + ++tickRate) +{ + QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], + (QActive *)0, Q_USER_SIG, tickRate); +#ifndef Q_UNSAFE + QTimeEvt_timeEvtHead_dis_[tickRate] = + (uintptr_t)~Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act); +#endif +} @@ -3374,44 +3479,70 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(100, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); +Q_REQUIRE_INCRIT(800, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; -QS_BEGIN_PRE_(QS_QF_TICK, 0U) +QS_BEGIN_PRE(QS_QF_TICK, 0U) ++prev->ctr; - QS_TEC_PRE_(prev->ctr); // tick ctr - QS_U8_PRE_(tickRate); // tick rate -QS_END_PRE_() + QS_TEC_PRE(prev->ctr); // tick ctr + QS_U8_PRE(tickRate); // tick rate +QS_END_PRE() // scan the linked-list of time events at this rate... uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound for (; lbound > 0U; --lbound) { - QTimeEvt *e = prev->next; // advance down the time evt. list + Q_ASSERT_INCRIT(810, prev != (QTimeEvt *)0); // sanity check - if (e == (QTimeEvt *)0) { // end of the list? + QTimeEvt *te = prev->next; // advance down the time evt. list +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(811, + Q_PTR2UINT_CAST_(te) == (uintptr_t)~prev->next_dis); +#endif // ndef Q_UNSAFE + + if (te == (QTimeEvt *)0) { // end of the list? // any new time events armed since the last QTimeEvt_tick_()? if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - - // sanity check - Q_ASSERT_INCRIT(110, prev != (QTimeEvt *)0); - prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(812, + Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) + == (uintptr_t)~QTimeEvt_timeEvtHead_dis_[tickRate]); +#endif // ndef Q_UNSAFE + prev->next = (QTimeEvt*)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - e = prev->next; // switch to the new list +#ifndef Q_UNSAFE + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(prev->next); + QTimeEvt_timeEvtHead_dis_[tickRate] = + (uintptr_t)~Q_PTR2UINT_CAST_((void *)0); +#endif // ndef Q_UNSAFE + + te = prev->next; // switch to the new list } else { // all currently armed time events are processed break; // terminate the for-loop } } - // the time event 'e' must be valid - Q_INVARIANT_INCRIT(112, QEvt_verify_(Q_EVT_CAST(QEvt))); + // the time event 'te' must be valid + Q_ASSERT_INCRIT(820, te != (QTimeEvt *)0); + + QTimeEvtCtr ctr = te->ctr; +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(821, QEvt_verify_(&te->super)); + QTimeEvtCtr const dis = (QTimeEvtCtr)~te->ctr_dis; + Q_INVARIANT_INCRIT(822, ctr == dis); +#endif // ndef Q_UNSAFE + + if (ctr == 0U) { // time event scheduled for removal? + prev->next = te->next; +#ifndef Q_UNSAFE + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); +#endif // ndef Q_UNSAFE + + // mark time event 'te' as NOT linked + te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - if (e->ctr == 0U) { // time event scheduled for removal? - prev->next = e->next; - // mark time event 'e' as NOT linked - e->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); // do NOT advance the prev pointer QF_MEM_APP(); QF_CRIT_EXIT(); // exit crit. section to reduce latency @@ -3426,74 +3557,83 @@ for (; lbound > 0U; --lbound) { // of critical sections in QF ports, in which it can occur. QF_CRIT_EXIT_NOP(); } - else { - --e->ctr; + else if (ctr == 1U) { // is time event about to expire? + QActive * const act = (QActive *)te->act; + if (te->interval != 0U) { // periodic time evt? + te->ctr = te->interval; // rearm the time event +#ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~te->interval; +#endif // ndef Q_UNSAFE + prev = te; // advance to this time event + } + else { // one-shot time event: automatically disarm + te->ctr = 0U; + prev->next = te->next; +#ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~0U; + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); +#endif // ndef Q_UNSAFE - if (e->ctr == 0U) { // is time event about to expire? - QActive * const act = (QActive *)e->act; + // mark time event 'te' as NOT linked + te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer - if (e->interval != 0U) { // periodic time evt? - e->ctr = e->interval; // rearm the time event - prev = e; // advance to this time event - } - else { // one-shot time event: automatically disarm - prev->next = e->next; + QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE(te); // this time event object + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() + } - // mark time event 'e' as NOT linked - e->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); - // do NOT advance the prev pointer - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(e); // this time event object - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - } - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(e); // the time event object - QS_SIG_PRE_(e->super.sig); // signal of this time event - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(te); // the time event object + QS_SIG_PRE(te->super.sig);// signal of this time event + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() #ifdef QXK_H_ - if (e->super.sig < Q_USER_SIG) { - QXThread_timeout_(act); - QF_MEM_APP(); - QF_CRIT_EXIT(); - } - else { - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section before posting - - // QACTIVE_POST() asserts if the queue overflows - QACTIVE_POST(act, &e->super, sender); - } -#else + if ((enum_t)te->super.sig < Q_USER_SIG) { + QXThread_timeout_(act); + QF_MEM_APP(); + QF_CRIT_EXIT(); + } + else { QF_MEM_APP(); QF_CRIT_EXIT(); // exit crit. section before posting // QACTIVE_POST() asserts if the queue overflows - QACTIVE_POST(act, &e->super, sender); + QACTIVE_POST(act, &te->super, sender); + } +#else + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section before posting + + // QACTIVE_POST() asserts if the queue overflows + QACTIVE_POST(act, &te->super, sender); #endif - } - else { - prev = e; // advance to this time event + } + else { // time event keeps timing out + --ctr; // decrement the tick counter + te->ctr = ctr; // update the original +#ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~ctr; +#endif // ndef Q_UNSAFE - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section to reduce latency + prev = te; // advance to this time event - // prevent merging critical sections, see NOTE above - QF_CRIT_EXIT_NOP(); - } + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section to reduce latency + + // prevent merging critical sections, see NOTE above + QF_CRIT_EXIT_NOP(); } QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop QF_MEM_SYS(); } -Q_ENSURE_INCRIT(190, lbound > 0U); +Q_ENSURE_INCRIT(890, lbound > 0U); QF_MEM_APP(); QF_CRIT_EXIT(); @@ -3516,7 +3656,7 @@ QF_CRIT_EXIT(); QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(800, tickRate < QF_MAX_TICK_RATE); +Q_REQUIRE_INCRIT(900, tickRate < QF_MAX_TICK_RATE); QF_CRIT_EXIT(); bool inactive; @@ -3556,7 +3696,10 @@ static struct QAsmVtable const vtable = { // QTicker virtual table me->super.super.vptr = &vtable; // hook the vptr // reuse eQueue.head for tick-rate -me->super.eQueue.head = (QEQueueCtr)tickRate; +me->super.eQueue.head = (QEQueueCtr)tickRate; +#ifndef Q_UNSAFE +me->super.eQueue.head_dis = (QEQueueCtr)~tickRate; +#endif // ndef Q_UNSAFE @@ -3578,6 +3721,9 @@ QF_CRIT_ENTRY(); QF_MEM_SYS(); QACTIVE_CAST_(me)->eQueue.tail = 0U; +#ifndef Q_UNSAFE +QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; +#endif // ndef Q_UNSAFE QF_MEM_APP(); QF_CRIT_EXIT(); @@ -3600,14 +3746,28 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; // save # of ticks +// get volatile into temporaries +QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; +QEQueueCtr const tickRate = QACTIVE_CAST_(me)->eQueue.head; + +#ifndef Q_UNSAFE +Q_REQUIRE_INCRIT(700, nTicks > 0U); +QEQueueCtr dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.tail_dis; +Q_INVARIANT_INCRIT(701, nTicks == dis); +dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.head_dis; +Q_INVARIANT_INCRIT(702, tickRate == dis); +#endif // ndef Q_UNSAFE + QACTIVE_CAST_(me)->eQueue.tail = 0U; // clear # ticks +#ifndef Q_UNSAFE +QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; +#endif // ndef Q_UNSAFE QF_MEM_APP(); QF_CRIT_EXIT(); for (; nTicks > 0U; --nTicks) { - QTimeEvt_tick_((uint_fast8_t)QACTIVE_CAST_(me)->eQueue.head, me); + QTimeEvt_tick_((uint_fast8_t)tickRate, me); } @@ -3623,30 +3783,64 @@ for (; nTicks > 0U; --nTicks) { Q_UNUSED_PAR(sender); #endif +static QEvt const tickEvt = QEVT_INITIALIZER(0); + QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -if (me->eQueue.frontEvt == (QEvt *)0) { +QEQueueCtr nTicks = me->eQueue.tail; // get volatile into temporary + +if (me->eQueue.frontEvt == (QEvt *)0) { // no tick events? +#ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(800, nTicks == 0U); + Q_REQUIRE_INCRIT(801, me->eQueue.nFree == 1U); + Q_INVARIANT_INCRIT(802, me->eQueue.frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); + QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; + Q_INVARIANT_INCRIT(803, 1U == dis); + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(804, 0U == dis); +#endif // ndef Q_UNSAFE - static QEvt const tickEvt = QEVT_INITIALIZER(0); me->eQueue.frontEvt = &tickEvt; // deliver event directly - --me->eQueue.nFree; // one less free event + me->eQueue.nFree = 0U; +#ifndef Q_UNSAFE + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt); + me->eQueue.nFree_dis = (QEQueueCtr)~0U; +#endif // ndef Q_UNSAFE QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } +else { +#ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(810, (nTicks > 0U) && (nTicks < 0xFFU)); + Q_REQUIRE_INCRIT(811, me->eQueue.nFree == 0U); + Q_INVARIANT_INCRIT(812, me->eQueue.frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt)); + QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; + Q_INVARIANT_INCRIT(813, 0U == dis); + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(814, nTicks == dis); +#endif // ndef Q_UNSAFE +} -++me->eQueue.tail; // account for one more tick event +++nTicks; // account for one more tick event -QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(0U); // the signal of the event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(0U, 0U); // poolNum & refCtr - QS_EQC_PRE_(0U); // # free entries - QS_EQC_PRE_(0U); // min # free entries -QS_END_PRE_() +me->eQueue.tail = nTicks; // update the original +#ifndef Q_UNSAFE +me->eQueue.tail_dis = (QEQueueCtr)~nTicks; +#endif // ndef Q_UNSAFE + +QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(0U); // the signal of the event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(0U, 0U); // poolNum & refCtr + QS_EQC_PRE(0U); // # free entries + QS_EQC_PRE(0U); // min # free entries +QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -3660,7 +3854,7 @@ QF_CRIT_EXIT(); //! @private @memberof QEQueue - + //! @private @memberof QEQueue @@ -3679,14 +3873,29 @@ QF_CRIT_EXIT(); //! @private @memberof QEQueue + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + - + //! @private @memberof QEQueue - - dummy static member to force generation of -'struct QEQueue' + + // dummy static member to force generating 'struct QEQueue {...}' @@ -3694,7 +3903,7 @@ QF_CRIT_EXIT(); //! @public @memberof QEQueue - + QF_CRIT_STAT @@ -3708,12 +3917,19 @@ Q_REQUIRE_INCRIT(100, qLen < 0xFFU); me->frontEvt = (QEvt *)0; // no events in the queue me->ring = qSto; // the beginning of the ring buffer me->end = (QEQueueCtr)qLen; -if (qLen != 0U) { +if (qLen > 0U) { me->head = 0U; me->tail = 0U; } me->nFree = (QEQueueCtr)(qLen + 1U); // +1 for frontEvt -me->nMin = me->nFree; + +#ifndef Q_UNSAFE +me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->frontEvt); +me->head_dis = (QEQueueCtr)~me->head; +me->tail_dis = (QEQueueCtr)~me->tail; +me->nFree_dis = (QEQueueCtr)~me->nFree; +me->nMin = me->nFree; +#endif QF_MEM_APP(); QF_CRIT_EXIT(); @@ -3737,46 +3953,81 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); +Q_REQUIRE_INCRIT(200, e != (QEvt *)0); -QEQueueCtr nFree = me->nFree; // get volatile into temporary +QEQueueCtr tmp = me->nFree; // get volatile into temporary + +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); +QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; +Q_INVARIANT_INCRIT(202, tmp == dis); +#endif // ndef Q_UNSAFE + +// test-probe#1 for faking queue overflow +QS_TEST_PROBE_DEF(&QEQueue_post) +QS_TEST_PROBE_ID(1, + tmp = 0U; // fake no free events +) // required margin available? bool status; -if (((margin == QF_NO_MARGIN) && (nFree > 0U)) - || (nFree > (QEQueueCtr)margin)) +if (((margin == QF_NO_MARGIN) && (tmp > 0U)) + || (tmp > (QEQueueCtr)margin)) { // is it a mutable event? if (QEvt_getPoolNum_(e) != 0U) { QEvt_refCtr_inc_(e); // increment the reference counter } - --nFree; // one free entry just used up - me->nFree = nFree; // update the original - if (me->nMin > nFree) { - me->nMin = nFree; // update minimum so far + --tmp; // one free entry just used up + + me->nFree = tmp; // update the original +#ifndef Q_UNSAFE + me->nFree_dis = (QEQueueCtr)~tmp; + + if (me->nMin > tmp) { + me->nMin = tmp; // update minimum so far } +#endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_EQUEUE_POST, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->nMin); // min # free entries - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_POST, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries +#ifndef Q_UNSAFE + QS_EQC_PRE(me->nMin); // min # free entries +#else + QS_EQC_PRE(0U); // min # free entries +#endif + QS_END_PRE() - if (me->frontEvt == (QEvt *)0) { // was the queue empty? + if (me->frontEvt == (QEvt *)0) { // is the queue empty? me->frontEvt = e; // deliver event directly +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(211, me->frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); +#endif // ndef Q_UNSAFE } else { // queue was not empty, insert event into the ring-buffer - // insert event into the ring buffer (FIFO)... - me->ring[me->head] = e; // insert e into buffer - // need to wrap the head? - if (me->head == 0U) { - me->head = me->end; // wrap around + tmp = me->head; // get volatile into temporary +#ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->head_dis; + Q_INVARIANT_INCRIT(212, tmp == dis); +#endif // ndef Q_UNSAFE + me->ring[tmp] = e; // insert e into buffer + + if (tmp == 0U) { // need to wrap the head? + tmp = me->end; } - --me->head; + --tmp; // advance head (counter-clockwise) + + me->head = tmp; // update the original +#ifndef Q_UNSAFE + me->head_dis = (QEQueueCtr)~tmp; +#endif // ndef Q_UNSAFE } status = true; // event posted successfully } @@ -3784,14 +4035,14 @@ else { // event cannot be posted // dropping events must be acceptable Q_ASSERT_INCRIT(210, margin != QF_NO_MARGIN); - QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_ATTEMPT, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_POST_ATTEMPT, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() status = false; // event not posted } @@ -3818,39 +4069,74 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); +Q_REQUIRE_INCRIT(300, e != (QEvt *)0); -QEQueueCtr nFree = me->nFree; // get volatile into temporary -Q_REQUIRE_INCRIT(301, nFree != 0U); +QEQueueCtr tmp = me->nFree; // get volatile into temporary + +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; +Q_INVARIANT_INCRIT(302, tmp == dis); +#endif // ndef Q_UNSAFE + +// test-probe#1 for faking queue overflow +QS_TEST_PROBE_DEF(&QEQueue_postLIFO) +QS_TEST_PROBE_ID(1, + tmp = 0U; // fake no free events +) + +// must be able to LIFO-post the event +Q_REQUIRE_INCRIT(310, tmp != 0U); if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? QEvt_refCtr_inc_(e); // increment the reference counter } ---nFree; // one free entry just used up -me->nFree = nFree; // update the original -if (me->nMin > nFree) { - me->nMin = nFree; // update minimum so far +--tmp; // one free entry just used up + +me->nFree = tmp; // update the original +#ifndef Q_UNSAFE +me->nFree_dis = (QEQueueCtr)~tmp; + +if (me->nMin > tmp) { + me->nMin = tmp; // update minimum so far } +#endif // ndef Q_UNSAFE -QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_LIFO, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->nMin); // min # free entries -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_EQUEUE_POST_LIFO, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries +#ifndef Q_UNSAFE + QS_EQC_PRE(me->nMin); // min # free entries +#else + QS_EQC_PRE(0U); // min # free entries +#endif +QS_END_PRE() -QEvt const * const frontEvt = me->frontEvt; // read into temporary -me->frontEvt = e; // deliver event directly to the front of the queue +QEvt const * const frontEvt = me->frontEvt; +me->frontEvt = e; // deliver the event directly to the front +#ifndef Q_UNSAFE +me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); +#endif // ndef Q_UNSAFE -if (frontEvt != (QEvt *)0) { // was the queue not empty? - ++me->tail; - if (me->tail == me->end) { // need to wrap the tail? - me->tail = 0U; // wrap around +if (frontEvt != (QEvt *)0) { // was the queue NOT empty? + tmp = me->tail; // get volatile into temporary; +#ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->tail_dis; + Q_INVARIANT_INCRIT(311, tmp == dis); +#endif // ndef Q_UNSAFE + ++tmp; + if (tmp == me->end) { // need to wrap the tail? + tmp = 0U; // wrap around } - me->ring[me->tail] = frontEvt; // save old front evt + me->tail = tmp; +#ifndef Q_UNSAFE + me->tail_dis = (QEQueueCtr)~tmp; +#endif + me->ring[tmp] = frontEvt; } QF_MEM_APP(); @@ -3872,42 +4158,68 @@ QF_CRIT_ENTRY(); QF_MEM_SYS(); QEvt const * const e = me->frontEvt; // always remove evt from the front +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) + == (uintptr_t)~me->frontEvt_dis); +#endif // ndef Q_UNSAFE if (e != (QEvt *)0) { // was the queue not empty? - Q_INVARIANT_INCRIT(412, QEvt_verify_(e)); + QEQueueCtr tmp = me->nFree; // get volatile into temporary +#ifndef Q_UNSAFE + QEQueueCtr const dis = (QEQueueCtr)~me->nFree_dis; + Q_INVARIANT_INCRIT(412, tmp == dis); +#endif // ndef Q_UNSAFE - // use a temporary variable to increment me->nFree - QEQueueCtr const nFree = me->nFree + 1U; - me->nFree = nFree; // update the # free + ++tmp; // one more free event in the queue + + me->nFree = tmp; // update the # free +#ifndef Q_UNSAFE + me->nFree_dis = (QEQueueCtr)~tmp; +#endif // ndef Q_UNSAFE // any events in the ring buffer? - if (nFree <= me->end) { - me->frontEvt = me->ring[me->tail]; // get from tail - if (me->tail == 0U) { // need to wrap the tail? - me->tail = me->end; // wrap around - } - --me->tail; + if (tmp <= me->end) { - QS_BEGIN_PRE_(QS_QF_EQUEUE_GET, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_GET, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_END_PRE() + + tmp = me->tail; // get volatile into temporary + QEvt const * const frontEvt = me->ring[tmp]; +#ifndef Q_UNSAFE + Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); +#endif // ndef Q_UNSAFE + me->frontEvt = frontEvt; // update the original + + if (tmp == 0U) { // need to wrap the tail? + tmp = me->end; + } + --tmp; // advance the tail (counter-clockwise) + me->tail = tmp; // update the original +#ifndef Q_UNSAFE + me->tail_dis = (QEQueueCtr)~tmp; +#endif // ndef Q_UNSAFE } else { me->frontEvt = (QEvt *)0; // queue becomes empty +#ifndef Q_UNSAFE + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); +#endif // ndef Q_UNSAFE - // all entries in the queue must be free (+1 for fronEvt) - Q_INVARIANT_INCRIT(420, nFree == (me->end + 1U)); + // all entries in the queue must be free (+1 for frontEvt) + Q_INVARIANT_INCRIT(440, tmp == (me->end + 1U)); - QS_BEGIN_PRE_(QS_QF_EQUEUE_GET_LAST, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_GET_LAST, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() } } @@ -3930,7 +4242,11 @@ return e; //! @public @memberof QEQueue //! @public @memberof QEQueue - return me->nMin; + #ifndef Q_UNSAFE +return me->nMin; +#else +return 0U; +#endif @@ -3981,7 +4297,15 @@ return e; //! @private @memberof QMPool - + + //! @private @memberof QMPool + + + + //! @private @memberof QMPool + + + //! @private @memberof QMPool @@ -3999,14 +4323,15 @@ return e; QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(100, (poolSto != (void *)0) - && (poolSize >= (uint_fast32_t)sizeof(QFreeBlock)) - && ((uint_fast16_t)(blockSize + sizeof(QFreeBlock)) > blockSize)); +Q_REQUIRE_INCRIT(100, poolSto != (void *)0); +Q_REQUIRE_INCRIT(101, poolSize >= (uint_fast32_t)sizeof(QFreeBlock)); +Q_REQUIRE_INCRIT(102, (uint_fast16_t)(blockSize + sizeof(QFreeBlock)) + > blockSize); me->free_head = (QFreeBlock *)poolSto; // find # free blocks in a memory block, NO DIVISION -me->blockSize = (QMPoolSize)sizeof(QFreeBlock); +me->blockSize = (QMPoolSize)(2U * sizeof(void *)); uint_fast16_t nblocks = 1U; while (me->blockSize < (QMPoolSize)blockSize) { me->blockSize += (QMPoolSize)sizeof(QFreeBlock); @@ -4027,10 +4352,10 @@ for (uint_fast32_t size = poolSize - me->blockSize; { fb->next = &fb[nblocks]; // point next link to next block #ifndef Q_UNSAFE - fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); + fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); #endif - fb = fb->next; // advance to the next block - ++nTot; // one more free block in the pool + fb = fb->next; // advance to the next block + ++nTot; // one more free block in the pool } // dynamic range check @@ -4041,16 +4366,19 @@ Q_ENSURE_INCRIT(190, nTot < 0xFFFFU); #endif fb->next = (QFreeBlock *)0; // the last link points to NULL -#ifndef Q_UNSAFE -fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); -#endif me->nTot = (QMPoolCtr)nTot; me->nFree = me->nTot; // all blocks are free -me->nMin = me->nTot; // the minimum # free blocks me->start = (QFreeBlock *)poolSto; // the original start this pool buffer me->end = fb; // the last block in this pool +#ifndef Q_UNSAFE +me->free_head_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->free_head); +me->nFree_dis = (QMPoolCtr)~me->nFree; +me->nMin = me->nTot; // the minimum # free blocks +fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); +#endif + QF_MEM_APP(); QF_CRIT_EXIT(); @@ -4071,62 +4399,82 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -// have more free blocks than the requested margin? -QFreeBlock *fb; -if (me->nFree > (QMPoolCtr)margin) { - fb = me->free_head; // get a free block +// get volatile into temporaries +QFreeBlock *fb = me->free_head; +QMPoolCtr nFree = me->nFree; - // a free block must be valid - Q_ASSERT_INCRIT(300, fb != (QFreeBlock *)0); +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(301, Q_PTR2UINT_CAST_(fb) + == (uintptr_t)~me->free_head_dis); +QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; +Q_INVARIANT_INCRIT(302, nFree == dis); +#endif // ndef Q_UNSAFE + +// have more free blocks than the requested margin? +if (nFree > (QMPoolCtr)margin) { + Q_ASSERT_INCRIT(310, fb != (QFreeBlock *)0); QFreeBlock * const fb_next = fb->next; // fast temporary +#ifndef Q_UNSAFE // the free block must have integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(302, Q_UINTPTR_CAST_(fb_next) - == (uintptr_t)~fb->next_dis); + Q_INVARIANT_INCRIT(311, Q_PTR2UINT_CAST_(fb_next) + == (uintptr_t)~fb->next_dis); +#endif // ndef Q_UNSAFE - --me->nFree; // one less free block - if (me->nFree == 0U) { // is the pool becoming empty? + --nFree; // one less free block + if (nFree == 0U) { // is the pool becoming empty? // pool is becoming empty, so the next free block must be NULL Q_ASSERT_INCRIT(320, fb_next == (QFreeBlock *)0); + me->nFree = 0U; +#ifndef Q_UNSAFE + me->nFree_dis = (QMPoolCtr)~0U; me->nMin = 0U; // remember that the pool got empty +#endif // ndef Q_UNSAFE } else { - // invariant: - // The pool is not empty, so the next free-block pointer, - // so the next free block must be in range. + me->nFree = nFree; // update the original +#ifndef Q_UNSAFE + me->nFree_dis = (QMPoolCtr)~nFree; - // NOTE: The next free block pointer can fall out of range - // when the client code writes past the memory block, thus - // corrupting the next block. - Q_ASSERT_INCRIT(330, + // The pool is not empty, so the next free-block pointer + // must be in range. + Q_INVARIANT_INCRIT(330, (me->start <= fb_next) && (fb_next <= me->end)); // is the # free blocks the new minimum so far? - if (me->nMin > me->nFree) { - me->nMin = me->nFree; // remember the new minimum + if (me->nMin > nFree) { + me->nMin = nFree; // remember the minimum so far } +#endif // ndef Q_UNSAFE } me->free_head = fb_next; // set the head to the next free block +#ifndef Q_UNSAFE + me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb_next)); +#endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // # of free blocks in the pool - QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // # of free blocks in the pool +#ifndef Q_UNSAFE + QS_MPC_PRE(me->nMin); // min # free blocks ever in the pool +#else + QS_MPC_PRE(0U); // min # free blocks (not available) +#endif // ndef Q_UNSAFE + QS_END_PRE() } else { // don't have enough free blocks at this point fb = (QFreeBlock *)0; - QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // # of free blocks in the pool - QS_MPC_PRE_(margin); // the requested margin - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // # of free blocks in the pool + QS_MPC_PRE(margin); // the requested margin + QS_END_PRE() } QF_MEM_APP(); @@ -4153,24 +4501,40 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(200, (me->nFree < me->nTot) - && (me->start <= fb) && (fb <= me->end)); +// get volatile into temporaries +QFreeBlock * const free_head = me->free_head; +QMPoolCtr nFree = me->nFree; -fb->next = me->free_head; // link into list #ifndef Q_UNSAFE -fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); +Q_INVARIANT_INCRIT(401, Q_PTR2UINT_CAST_(free_head) + == (uintptr_t)~me->free_head_dis); +QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; +Q_INVARIANT_INCRIT(402, nFree == dis); + +Q_REQUIRE_INCRIT(410, nFree < me->nTot); +Q_REQUIRE_INCRIT(411, (me->start <= fb) && (fb <= me->end)); + +// the block must not be in the pool already +Q_REQUIRE_INCRIT(412, Q_PTR2UINT_CAST_(fb->next) + != (uintptr_t)~fb->next_dis); +#endif // ndef Q_UNSAFE + +++nFree; // one more free block in this pool + +me->free_head = fb; // set as new head of the free list +me->nFree = nFree; +fb->next = free_head; // link into the list +#ifndef Q_UNSAFE +me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb)); +me->nFree_dis = (QMPoolCtr)~nFree; +fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(free_head)); #endif -// set as new head of the free list -me->free_head = fb; - -++me->nFree; // one more free block in this pool - -QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // the # free blocks in the pool -QS_END_PRE_() +QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // the # free blocks in the pool +QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -4245,8 +4609,12 @@ for (uint_fast16_t n = len; n > 0U; --n) { QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(400, (prio <= QF_MAX_ACTIVE) && (QActive_registry_[prio] != (QActive *)0)); +#ifndef Q_UNSAFE uint_fast16_t const min = (uint_fast16_t)QActive_registry_[prio]->eQueue.nMin; +#else +uint_fast16_t const min = 0U; +#endif QF_CRIT_EXIT(); return min; @@ -4345,7 +4713,11 @@ QF_MEM_SYS(); Q_REQUIRE_INCRIT(400, (poolNum <= QF_MAX_EPOOL) && (0U < poolNum) && (poolNum <= QF_priv_.maxPool_)); +#ifndef Q_UNSAFE uint_fast16_t const min = (uint_fast16_t)QF_priv_.ePool_[poolNum - 1U].nMin; +#else +uint_fast16_t const min = 0U; +#endif QF_MEM_APP(); QF_CRIT_EXIT(); @@ -4398,16 +4770,16 @@ QF_EPOOL_GET_(QF_priv_.ePool_[poolNum - 1U], e, if (e != (QEvt *)0) { // was e allocated correctly? e->sig = (QSignal)sig; // set the signal e->refCtr_ = 0U; // initialize the reference counter to 0 - e->evtTag_ = (uint8_t)(QEVT_MARKER | poolNum); + e->evtTag_ = (uint8_t)((poolNum << 4U) | 0x0FU); QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_NEW, + QS_BEGIN_PRE(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_EVS_PRE_(evtSize); // the size of the event - QS_SIG_PRE_(sig); // the signal of the event - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_EVS_PRE(evtSize); // the size of the event + QS_SIG_PRE(sig); // the signal of the event + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -4420,12 +4792,12 @@ else { // event was not allocated Q_ASSERT_INCRIT(320, margin != QF_NO_MARGIN); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, + QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_EVS_PRE_(evtSize); // the size of the event - QS_SIG_PRE_(sig); // the signal of the event - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_EVS_PRE(evtSize); // the size of the event + QS_SIG_PRE(sig); // the signal of the event + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -4444,7 +4816,12 @@ return e; QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(400, QEvt_verify_(e)); + +Q_REQUIRE_INCRIT(400, e != (QEvt *)0); + +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(401, QEvt_verify_(e)); +#endif uint_fast8_t const poolNum = QEvt_getPoolNum_(e); @@ -4453,12 +4830,12 @@ if (poolNum != 0U) { // is it a pool event (mutable)? if (e->refCtr_ > 1U) { // isn't this the last reference? - QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT, + QS_BEGIN_PRE(QS_QF_GC_ATTEMPT, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() QEvt_refCtr_dec_(e); // decrement the ref counter @@ -4467,12 +4844,12 @@ if (poolNum != 0U) { // is it a pool event (mutable)? } else { // this is the last reference to this event, recycle it - QS_BEGIN_PRE_(QS_QF_GC, + QS_BEGIN_PRE(QS_QF_GC, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() // pool number must be in range Q_ASSERT_INCRIT(410, (poolNum <= QF_priv_.maxPool_) @@ -4511,23 +4888,26 @@ Q_UNUSED_PAR(evtRef); QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(500, QEvt_verify_(e)); +Q_REQUIRE_INCRIT(500, e != (QEvt *)0); +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(501, QEvt_verify_(e)); +#endif uint_fast8_t const poolNum = QEvt_getPoolNum_(e); Q_UNUSED_PAR(poolNum); // might be unused -Q_REQUIRE_INCRIT(501, (poolNum != 0U) +Q_REQUIRE_INCRIT(510, (poolNum != 0U) && (evtRef == (void *)0)); QEvt_refCtr_inc_(e); // increments the ref counter QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QF_NEW_REF, +QS_BEGIN_PRE(QS_QF_NEW_REF, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr -QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); +QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -4545,20 +4925,22 @@ return e; QF_CRIT_ENTRY(); QEvt const * const e = (QEvt const *)evtRef; -Q_REQUIRE_INCRIT(600, QEvt_verify_(e)); +Q_REQUIRE_INCRIT(600, e != (QEvt *)0); +#ifndef Q_UNSAFE +Q_INVARIANT_INCRIT(601, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE #ifdef Q_SPY uint_fast8_t const poolNum = QEvt_getPoolNum_(e); -#endif - QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QF_DELETE_REF, +QS_BEGIN_PRE(QS_QF_DELETE_REF, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr -QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); +QS_END_PRE() QS_MEM_APP(); +#endif // def Q_SPY QF_CRIT_EXIT(); @@ -4905,12 +5287,12 @@ Q_INVARIANT_INCRIT(102, QV_priv_.schedCeil if (ceiling > QV_priv_.schedCeil) { // raising the scheduler ceiling? - QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_LOCK, 0U) + QS_TIME_PRE(); // timestamp // the previous sched ceiling & new sched ceiling - QS_2U8_PRE_((uint8_t)QV_priv_.schedCeil, + QS_2U8_PRE((uint8_t)QV_priv_.schedCeil, (uint8_t)ceiling); - QS_END_PRE_() + QS_END_PRE() QV_priv_.schedCeil = ceiling; #ifndef Q_UNSAFE @@ -4934,11 +5316,11 @@ Q_INVARIANT_INCRIT(202, QV_priv_.schedCeil if (QV_priv_.schedCeil != 0U) { // actually enabling the scheduler? - QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE(); // timestamp // current sched ceiling (old), previous sched ceiling (new) - QS_2U8_PRE_((uint8_t)QV_priv_.schedCeil, 0U); - QS_END_PRE_() + QS_2U8_PRE((uint8_t)QV_priv_.schedCeil, 0U); + QS_END_PRE() QV_priv_.schedCeil = 0U; #ifndef Q_UNSAFE @@ -4971,13 +5353,7 @@ QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U); #endif -for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) -{ - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, (enum_t)Q_USER_SIG, tickRate); -} +QTimeEvt_init(); // initialize QTimeEvts #ifdef QV_INIT QV_INIT(); // port-specific initialization of the QV kernel @@ -5017,7 +5393,13 @@ QV_START(); // port-specific startup of the QV kernel #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) uint_fast8_t pprev = 0U; // previously used prio. -#endif + +#ifdef QF_ON_CONTEXT_SW +// officially switch to the idle cotext +QF_onContextSw((QActive *)0, (QActive *)0); +#endif // def QF_ON_CONTEXT_SW + +#endif // def (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) for (;;) { // QV event loop... @@ -5037,11 +5419,11 @@ for (;;) { // QV event loop... QActive * const a = QActive_registry_[p]; #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QS_BEGIN_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_((uint8_t)p, + QS_BEGIN_PRE(QS_SCHED_NEXT, p) + QS_TIME_PRE(); // timestamp + QS_2U8_PRE((uint8_t)p, (uint8_t)pprev); - QS_END_PRE_() + QS_END_PRE() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(((pprev != 0U) @@ -5076,10 +5458,10 @@ for (;;) { // QV event loop... else { // no AO ready to run --> idle #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (pprev != 0U) { - QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_((uint8_t)pprev); // previous prio - QS_END_PRE_() + QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) + QS_TIME_PRE(); // timestamp + QS_U8_PRE((uint8_t)pprev); // previous prio + QS_END_PRE() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(QActive_registry_[pprev], (QActive *)0); @@ -5119,7 +5501,7 @@ return 0; - + @@ -5166,8 +5548,7 @@ QS_FLUSH(); // flush the trace buffer to the host - \ - Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) + ((void)0) @@ -5270,11 +5651,11 @@ Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil // first store the previous lock prio QSchedStatus stat; if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling? - QS_BEGIN_PRE_(QS_SCHED_LOCK, QK_priv_.actPrio) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_LOCK, QK_priv_.actPrio) + QS_TIME_PRE(); // timestamp // the previous lock ceiling & new lock ceiling - QS_2U8_PRE_((uint8_t)QK_priv_.lockCeil, (uint8_t)ceiling); - QS_END_PRE_() + QS_2U8_PRE((uint8_t)QK_priv_.lockCeil, (uint8_t)ceiling); + QS_END_PRE() // previous status of the lock stat = (QSchedStatus)QK_priv_.lockCeil; @@ -5312,11 +5693,11 @@ if (prevCeil != 0xFFU) { Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_()) && (QK_priv_.lockCeil > prevCeil)); - QS_BEGIN_PRE_(QS_SCHED_UNLOCK, QK_priv_.actPrio) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_UNLOCK, QK_priv_.actPrio) + QS_TIME_PRE(); // timestamp // current lock ceiling (old), previous lock ceiling (new) - QS_2U8_PRE_((uint8_t)QK_priv_.lockCeil, (uint8_t)prevCeil); - QS_END_PRE_() + QS_2U8_PRE((uint8_t)QK_priv_.lockCeil, (uint8_t)prevCeil); + QS_END_PRE() // restore the previous lock ceiling QK_priv_.lockCeil = prevCeil; @@ -5442,11 +5823,11 @@ do { #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (p != pprev) { // changing threads? - QS_BEGIN_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_(p, // prio. of the scheduled AO + QS_BEGIN_PRE(QS_SCHED_NEXT, p) + QS_TIME_PRE(); // timestamp + QS_2U8_PRE(p, // prio. of the scheduled AO pprev); // previous prio. - QS_END_PRE_() + QS_END_PRE() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(QActive_registry_[pprev], a); @@ -5521,19 +5902,19 @@ QK_priv_.actThre_dis = (uint_fast8_t)(~QK_priv_.actThre); if (prio_in != 0U) { // resuming an active object? a = QActive_registry_[prio_in]; // pointer to preempted AO - QS_BEGIN_PRE_(QS_SCHED_NEXT, prio_in) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_NEXT, prio_in) + QS_TIME_PRE(); // timestamp // prio. of the resumed AO, previous prio. - QS_2U8_PRE_(prio_in, pprev); - QS_END_PRE_() + QS_2U8_PRE(prio_in, pprev); + QS_END_PRE() } else { // resuming prio.==0 --> idle a = (QActive *)0; // QK idle loop - QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(pprev); // previous prio. - QS_END_PRE_() + QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) + QS_TIME_PRE(); // timestamp + QS_U8_PRE(pprev); // previous prio. + QS_END_PRE() } #ifdef QF_ON_CONTEXT_SW @@ -5565,13 +5946,7 @@ QK_priv_.actThre_dis = (uint_fast8_t)(~0U); QK_priv_.lockCeil_dis = (uint_fast8_t)(~QK_priv_.lockCeil); #endif -for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) -{ - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, (enum_t)Q_USER_SIG, tickRate); -} +QTimeEvt_init(); // initialize QTimeEvts #ifdef QK_INIT QK_INIT(); // port-specific initialization of the QK kernel @@ -5614,6 +5989,11 @@ QK_priv_.lockCeil = 0U; // unlock the QK scheduler QK_priv_.lockCeil_dis = (uint_fast8_t)(~0U); #endif +#ifdef QF_ON_CONTEXT_SW +// officially switch to the idle context +QF_onContextSw((QActive *)0, QActive_registry_[QK_priv_.nextPrio]); +#endif + // activate AOs to process events posted so far if (QK_sched_() != 0U) { QK_activate_(); @@ -5642,7 +6022,7 @@ return 0; - + @@ -5714,8 +6094,7 @@ QF_CRIT_EXIT(); - \ - Q_ASSERT_INCRIT(320, (me_)->eQueue.frontEvt != (QEvt *)0) + ((void)0) @@ -5745,3216 +6124,6 @@ QF_CRIT_EXIT(); } while (false) - - - - - //! @class QXK - { - //! @cond INTERNAL - uint8_t dummy; - //! @endcond -} QXK; - - - - - - ((QTimeEvtCtr)0) - - - - - - //! @class QXK_Attr - - - //! @memberof QXK_Attr - - - - //! @memberof QXK_Attr - - - - //! @memberof QXK_Attr - - - - //! @memberof QXK_Attr - - - - //! @memberof QXK_Attr - - - - //! @memberof QXK_Attr - - - - //! @memberof QXK_Attr - - - - //! @memberof QXK_Attr - - - - - //! @static @private @memberof QXK - - - - //! @static @public @memberof QXK - -//! @static @public @memberof QXK - - - - //! @static @public @memberof QXK - -//! @static @public @memberof QXK - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(100, !QXK_ISR_CONTEXT_()); - -QSchedStatus stat; // saved lock status to be returned - -// is the lock ceiling being raised? -if (ceiling > QXK_priv_.lockCeil) { - QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); // timestamp - // the previous lock ceiling & new lock ceiling - QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)ceiling); - QS_END_PRE_() - - // previous status of the lock - stat = (QSchedStatus)QXK_priv_.lockHolder; - stat |= (QSchedStatus)QXK_priv_.lockCeil << 8U; - - // new status of the lock - QXK_priv_.lockHolder = (QXK_priv_.curr != (QActive *)0) - ? (uint_fast8_t)QXK_priv_.curr->prio - : 0U; - QXK_priv_.lockCeil = ceiling; -} -else { - stat = 0xFFU; // scheduler not locked -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return stat; // return the status to be saved in a stack variable - - - - //! @static @public @memberof QXK - -//! @static @public @memberof QXK - - - // has the scheduler been actually locked by the last QXK_schedLock()? -if (stat != 0xFFU) { - uint8_t const prevCeil = (uint8_t)(stat >> 8U); - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_REQUIRE_INCRIT(200, !QXK_ISR_CONTEXT_()); - Q_REQUIRE_INCRIT(201, QXK_priv_.lockCeil > prevCeil); - - QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); // timestamp - // ceiling before unlocking & prio after unlocking - QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)prevCeil); - QS_END_PRE_() - - // restore the previous lock ceiling and lock holder - QXK_priv_.lockCeil = prevCeil; - QXK_priv_.lockHolder = (stat & 0xFFU); - - // find if any threads should be run after unlocking the scheduler - if (QXK_sched_() != 0U) { // activation needed? - QXK_activate_(); // synchronously activate basic-thread(s) - } - - QF_MEM_APP(); - QF_CRIT_EXIT(); -} - - - - //! @static @public @memberof QXK - -//! @static @public @memberof QXK - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(600, QXK_priv_.lockCeil <= QF_MAX_ACTIVE); - -struct QActive *curr = QXK_priv_.curr; -if (curr == (QActive *)0) { // basic thread? - curr = QActive_registry_[QXK_priv_.actPrio]; -} - -Q_ASSERT_INCRIT(690, curr != (QActive *)0); - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return curr; - - - - //! @static @private @memberof QXK - -//! @static @private @memberof QXK - Q_INVARIANT_INCRIT(402, QPSet_verify_(&QXK_priv_.readySet, - &QXK_priv_.readySet_dis)); - -QActive const * const curr = QXK_priv_.curr; -uint_fast8_t p; -if (QPSet_isEmpty(&QXK_priv_.readySet)) { - p = 0U; // no activation needed -} -else { - // find the highest-prio thread ready to run - p = QPSet_findMax(&QXK_priv_.readySet); - if (p <= QXK_priv_.lockCeil) { - p = (uint_fast8_t)QActive_registry_[QXK_priv_.lockHolder]->prio; - if (p != 0U) { - Q_ASSERT_INCRIT(410, - QPSet_hasElement(&QXK_priv_.readySet, p)); - } - } -} -QActive * const next = QActive_registry_[p]; - -// is the current thread a basic-thread? -if (curr == (QActive *)0) { - - // is the next prio. above the active prio.? - if (p > QXK_priv_.actPrio) { - QXK_priv_.next = next; // set the next AO to activate - - if (next->osObject != (void *)0) { // is next extended? - QXK_CONTEXT_SWITCH_(); - p = 0U; // no activation needed - } - } - else { // below the active prio. - QXK_priv_.next = (QActive *)0; - p = 0U; // no activation needed - } -} -else { // currently executing an extended-thread - // is the current thread different from the next? - if (curr != next) { - QXK_priv_.next = next; - QXK_CONTEXT_SWITCH_(); - } - else { // current is the same as next - QXK_priv_.next = (QActive *)0; // no need to context-switch - } - p = 0U; // no activation needed -} -return p; - - - - //! @static @private @memberof QXK - -//! @static @private @memberof QXK - uint_fast8_t const prio_in = QXK_priv_.actPrio; -QActive *next = QXK_priv_.next; // the next AO (basic-thread) to run - -Q_REQUIRE_INCRIT(500, (next != (QActive *)0) - && (prio_in <= QF_MAX_ACTIVE)); - -// QXK Context switch callback defined or QS tracing enabled? -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -QXK_contextSw_(next); -#endif // QF_ON_CONTEXT_SW || Q_SPY - -QXK_priv_.next = (QActive *)0; // clear the next AO -QXK_priv_.curr = (QActive *)0; // current is basic-thread - -// prio. of the next thread -uint_fast8_t p = (uint_fast8_t)next->prio; - -// loop until no more ready-to-run AOs of higher prio than the initial -do { - QXK_priv_.actPrio = p; // next active prio - - QF_MEM_APP(); - QF_INT_ENABLE(); // unconditionally enable interrupts - - QEvt const * const e = QActive_get_(next); - // NOTE QActive_get_() performs QS_MEM_APP() before return - - // dispatch event (virtual call) - (*next->super.vptr->dispatch)(&next->super, e, p); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - - QF_INT_DISABLE(); // unconditionally disable interrupts - QF_MEM_SYS(); - - // check internal integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(502, QPSet_verify_(&QXK_priv_.readySet, - &QXK_priv_.readySet_dis)); - - if (next->eQueue.frontEvt == (QEvt *)0) { // empty queue? - QPSet_remove(&QXK_priv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - } - - if (QPSet_isEmpty(&QXK_priv_.readySet)) { - QXK_priv_.next = (QActive *)0; - next = QActive_registry_[0]; - p = 0U; // no activation needed - } - else { - // find next highest-prio below the lock ceiling - p = (uint8_t)QPSet_findMax(&QXK_priv_.readySet); - if (p <= QXK_priv_.lockCeil) { - p = QXK_priv_.lockHolder; // thread holding lock - if (p != 0U) { - Q_ASSERT_INCRIT(510, - QPSet_hasElement(&QXK_priv_.readySet, p)); - } - } - - // set the next thread and ensure that it is registered - next = QActive_registry_[p]; - Q_ASSERT_INCRIT(520, next != (QActive *)0); - - // is next a basic thread? - if (next->osObject == (void *)0) { - // is the next prio. above the initial prio.? - if (p > QActive_registry_[prio_in]->prio) { -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (p != QXK_priv_.actPrio) { // changing threads? - QXK_contextSw_(next); - } -#endif // QF_ON_CONTEXT_SW || Q_SPY - QXK_priv_.next = next; - } - else { - QXK_priv_.next = (QActive *)0; - p = 0U; // no activation needed - } - } - else { // next is the extended-thread - QXK_priv_.next = next; - QXK_CONTEXT_SWITCH_(); - p = 0U; // no activation needed - } - } -} while (p != 0U); // while activation needed - -// restore the active prio. -QXK_priv_.actPrio = prio_in; - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -if (next->osObject == (void *)0) { - QXK_contextSw_((prio_in == 0U) - ? (QActive *)0 - : QActive_registry_[prio_in]); -} -#endif // QF_ON_CONTEXT_SW || Q_SPY - - - - __attribute__(( used )) - //! @static @public @memberof QXK - -//! @static @public @memberof QXK - - - #ifdef Q_SPY -uint8_t const prev_prio = (QXK_priv_.prev != (QActive *)0) - ? QXK_priv_.prev->prio - : 0U; -if (next != (QActive *)0) { // next is NOT idle? - QS_BEGIN_PRE_(QS_SCHED_NEXT, next->prio) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_(next->prio, prev_prio); - QS_END_PRE_() -} -else { // going to idle - QS_BEGIN_PRE_(QS_SCHED_IDLE, prev_prio) - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(prev_prio); - QS_END_PRE_() -} -#endif // Q_SPY - -#ifdef QF_ON_CONTEXT_SW -QF_onContextSw(QXK_priv_.prev, next); -#endif // QF_ON_CONTEXT_SW - -QXK_priv_.prev = next; // update the previous thread - - - - //! @static @private @memberof QXK - -//! @static @private @memberof QXK - QF_CRIT_STAT -QF_CRIT_ENTRY(); - -QXThread const * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - -Q_REQUIRE_INCRIT(900, (!QXK_ISR_CONTEXT_()) - && (thr != (QXThread *)0)); // current thread must be extended -Q_REQUIRE_INCRIT(901, - QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - -uint_fast8_t const p = (uint_fast8_t)thr->super.prio; - -QF_MEM_SYS(); -QActive_registry_[p] = (QActive *)0; -QPSet_remove(&QXK_priv_.readySet, p); -#ifndef Q_UNSAFE -QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - -(void)QXK_sched_(); // schedule other threads - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - QF_bzero_(&QF_priv_, sizeof(QF_priv_)); -QF_bzero_(&QXK_priv_, sizeof(QXK_priv_)); -QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - -// setup the QXK scheduler as initially locked and not running -QXK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked - -#ifndef Q_UNSAFE -QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - -for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) -{ - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, (enum_t)Q_USER_SIG, tickRate); -} - -// QXK idle AO object (const in ROM) -static QActive const idle_ao = { (struct QAsmVtable const *)0 }; - -// register the idle AO object (cast 'const' away) -QActive_registry_[0] = QACTIVE_CAST_(&idle_ao); -QXK_priv_.prev = QActive_registry_[0]; - -#ifdef QXK_INIT -QXK_INIT(); // port-specific initialization of the QXK kernel -#endif - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - QF_onCleanup(); // application-specific cleanup callback -// nothing else to do for the dual-mode QXK kernel - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - #ifdef Q_SPY -QS_SIG_DICTIONARY(QXK_DELAY_SIG, (void *)0); -QS_SIG_DICTIONARY(QXK_TIMEOUT_SIG, (void *)0); - -// produce the QS_QF_RUN trace record -QF_INT_DISABLE(); -QF_MEM_SYS(); -QS_beginRec_((uint_fast8_t)QS_QF_RUN); -QS_endRec_(); -QF_MEM_APP(); -QF_INT_ENABLE(); -#endif // Q_SPY - -QF_onStartup(); // application-specific startup callback - -QF_INT_DISABLE(); -QF_MEM_SYS(); - -#ifdef QXK_START -QXK_START(); // port-specific startup of the QXK kernel -#endif - -QXK_priv_.lockCeil = 0U; // unlock the QXK scheduler - -// activate AOs to process events posted so far -if (QXK_sched_() != 0U) { - QXK_activate_(); -} - -QF_MEM_APP(); -QF_INT_ENABLE(); - -for (;;) { // QXK idle loop... - QXK_onIdle(); // application-specific QXK idle callback -} - -#ifdef __GNUC__ // GNU compiler? -return 0; -#endif - - - - - // QActive active object class customization for QK - - - //! @public @memberof QActive - -//! @public @memberof QActive - - - - - - - - - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) - && ((prioSpec & 0xFF00U) == 0U)); -QF_CRIT_EXIT(); - -me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO -me->pthre = 0U; // not used -QActive_register_(me); // make QF aware of this active object - -if (stkSto == (void *)0) { // starting basic thread (AO)? - - QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue - me->osObject = (void *)0; // no private stack for AO - - // top-most initial tran. (virtual call) - (*me->super.vptr->init)(&me->super, par, me->prio); - QS_FLUSH(); // flush the trace buffer to the host - - // see if this AO needs to be scheduled if QXK is already running - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { // scheduler running? - if (QXK_sched_() != 0U) { // activation needed? - QXK_activate_(); // synchronously activate basic-thread(s) - } - } - QF_MEM_APP(); - QF_CRIT_EXIT(); -} -else { // starting QXThread - - // is storage for the queue buffer provided? - if (qSto != (QEvt const **)0) { - QEQueue_init(&me->eQueue, qSto, qLen); - } - - // extended thread constructor puts the thread handler in place of - // the top-most initial tran. 'me->super.temp.act' - QXThread_stackInit_(me, me->super.temp.thr, stkSto, stkSize); - - // the new thread is not blocked on any object - me->super.temp.obj = (QMState *)0; - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // extended-thread becomes ready immediately - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - // see if this thread needs to be scheduled in case QXK is running - if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { - (void)QXK_sched_(); // schedule other threads - } - QF_MEM_APP(); - QF_CRIT_EXIT(); -} - - - - - //! @class QXThread -//! @extends QActive - - - //! @private @memberof QXThread - - - - //! @static @private @memberof QXThread -//! dummy static member to force QM to generate 'struct QXThread' - - - - //! @public @memberof QXThread - -//! @public @memberof QXThread - - - - - union QAsmAttr tmp; -tmp.thr = handler; -QActive_ctor(&me->super, tmp.fun); // superclass' ctor - -me->super.super.state.act = Q_ACTION_CAST(0); // mark as extended thread - -// instantiate the time-event member in the QXThread class -QTimeEvt_ctorX(&me->timeEvt, &me->super, - (enum_t)QXK_DELAY_SIG, tickRate); - - - - //! @public @memberof QXThread - -//! @public @memberof QXThread - - - - - - - - - - - - - QActive_start(&me->super, prioSpec, qSto, qLen, stkSto, stkSize, par); - - - - //! @public @memberof QXThread - -//! @public @memberof QXThread - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - -// precondition, this function: -// - must NOT be called from an ISR; -// - number of ticks cannot be zero -// - be called from an extended thread; -// - the thread must NOT be already blocked on any object. -Q_REQUIRE_INCRIT(800, (!QXK_ISR_CONTEXT_()) - && (nTicks != 0U) - && (thr != (QXThread *)0) - && (thr->super.super.temp.obj == (QMState *)0)); -// - the thread must NOT be holding a scheduler lock. -Q_REQUIRE_INCRIT(801, - QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - -// remember the blocking object -thr->super.super.temp.obj = QXK_PTR_CAST_(QMState const*, &thr->timeEvt); -QXThread_teArm_(thr, (enum_t)QXK_DELAY_SIG, nTicks); -QXThread_block_(thr); - -QF_MEM_APP(); -QF_CRIT_EXIT(); -QF_CRIT_EXIT_NOP(); // BLOCK here - -// after unblocking... -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// the blocking object must be the time event -Q_ASSERT_INCRIT(890, thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState const*, &thr->timeEvt)); -thr->super.super.temp.obj = (QMState *)0; // clear - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -// signal of zero means that the time event was posted without -// being canceled. -return thr->timeEvt.super.sig == 0U; - - - - //! @public @memberof QXThread - -//! @public @memberof QXThread - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -bool wasArmed; -if (me->super.super.temp.obj == QXK_PTR_CAST_(QMState*, &me->timeEvt)) { - wasArmed = QXThread_teDisarm_(me); - QXThread_unblock_(me); -} -else { - wasArmed = false; -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return wasArmed; - - - - //! @static @public @memberof QXThread - -//! @static @public @memberof QXThread - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - -// precondition, this function: -// - must NOT be called from an ISR; -// - be called from an extended thread; -// - the thread must NOT be already blocked on any object. -Q_REQUIRE_INCRIT(500, (!QXK_ISR_CONTEXT_()) - && (thr != (QXThread *)0) - && (thr->super.super.temp.obj == (QMState *)0)); -// - the thread must NOT be holding a scheduler lock. -Q_REQUIRE_INCRIT(501, - QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - -// is the queue empty? -if (thr->super.eQueue.frontEvt == (QEvt *)0) { - - // remember the blocking object (the thread's queue) - thr->super.super.temp.obj - = QXK_PTR_CAST_(QMState const*, &thr->super.eQueue); - - QXThread_teArm_(thr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)thr->super.prio); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - - (void)QXK_sched_(); // schedule other threads - - QF_MEM_APP(); - QF_CRIT_EXIT(); - QF_CRIT_EXIT_NOP(); // BLOCK here - - // after unblocking... - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // the blocking object must be this queue - Q_ASSERT_INCRIT(510, thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState const*, &thr->super.eQueue)); - thr->super.super.temp.obj = (QMState *)0; // clear -} - -// is the queue not empty? -QEvt const *e; -if (thr->super.eQueue.frontEvt != (QEvt *)0) { - e = thr->super.eQueue.frontEvt; // remove from the front - QEQueueCtr const nFree= thr->super.eQueue.nFree + 1U; - thr->super.eQueue.nFree = nFree; // update the # free - - // any events in the ring buffer? - if (nFree <= thr->super.eQueue.end) { - - // remove event from the tail - thr->super.eQueue.frontEvt = - thr->super.eQueue.ring[thr->super.eQueue.tail]; - if (thr->super.eQueue.tail == 0U) { // need to wrap? - thr->super.eQueue.tail = thr->super.eQueue.end; // wrap - } - --thr->super.eQueue.tail; - - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(&thr->super); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_END_PRE_() - } - else { - thr->super.eQueue.frontEvt = (QEvt *)0; // empty queue - - // all entries in the queue must be free (+1 for fronEvt) - Q_ASSERT_INCRIT(520, nFree == (thr->super.eQueue.end + 1U)); - - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(&thr->super); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() - } -} -else { // the queue is still empty -- the timeout must have fired - e = (QEvt *)0; -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return e; - - - - const - //! @private @memberof QXThread - -//! @private @memberof QXThread - // NOTE: must be called IN a critical section - -Q_REQUIRE_INCRIT(600, - QXK_priv_.lockHolder != (uint_fast8_t)me->super.prio); - -QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); -#ifndef Q_UNSAFE -QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - -(void)QXK_sched_(); // schedule other threads - - - - const - //! @private @memberof QXThread - -//! @private @memberof QXThread - // NOTE: must be called IN a critical section - -QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); -#ifndef Q_UNSAFE -QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - -if ((!QXK_ISR_CONTEXT_()) // not inside ISR? - && (QActive_registry_[0] != (QActive *)0)) // kernel started? -{ - (void)QXK_sched_(); // schedule other threads -} - - - - //! @private @memberof QXThread - -//! @private @memberof QXThread - - - // NOTE: must be called IN a critical section - -// the private time event is now disarmed and not in any queue, -// so it is safe to change its signal. The signal of 0 means -// that the time event has expired. -QXTHREAD_CAST_(act)->timeEvt.super.sig = 0U; - -QXThread_unblock_(QXTHREAD_CAST_(act)); - - - - //! @private @memberof QXThread - -//! @private @memberof QXThread - - - - - // NOTE: must be called IN a critical section - -// precondition: -// - the time event must be unused -Q_REQUIRE_INCRIT(700, me->timeEvt.ctr == 0U); - -me->timeEvt.super.sig = (QSignal)sig; - -if (nTicks != QXTHREAD_NO_TIMEOUT) { - me->timeEvt.ctr = (QTimeEvtCtr)nTicks; - me->timeEvt.interval = 0U; - - // is the time event unlinked? - // NOTE: For the duration of a single clock tick of the specified tick - // rate a time event can be disarmed and yet still linked in the list, - // because un-linking is performed exclusively in QTimeEvt_tick_(). - if ((me->timeEvt.super.refCtr_ & QTE_IS_LINKED) == 0U) { - uint_fast8_t const tickRate - = ((uint_fast8_t)me->timeEvt.super.refCtr_ & QTE_TICK_RATE); - Q_ASSERT_INCRIT(710, tickRate < QF_MAX_TICK_RATE); - - // mark as linked - me->timeEvt.super.refCtr_ |= QTE_IS_LINKED; - - // The time event is initially inserted into the separate - // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly - // armed" list is appended to the main list of armed time events - // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside - // QTimeEvt_tick_(). - me->timeEvt.next - = QXK_PTR_CAST_(QTimeEvt*, QTimeEvt_timeEvtHead_[tickRate].act); - QTimeEvt_timeEvtHead_[tickRate].act = &me->timeEvt; - } -} - - - - //! @private @memberof QXThread - -//! @private @memberof QXThread - // NOTE: must be called IN a critical section - -bool wasArmed; -// is the time evt running? -if (me->timeEvt.ctr != 0U) { - wasArmed = true; - me->timeEvt.ctr = 0U; // schedule removal from list -} -// the time event was already automatically disarmed -else { - wasArmed = false; -} -return wasArmed; - - - - //! @private @memberof QXThread - -//! @private @memberof QXThread - - - - - - - - - - - - - //! @class QXSemaphore - - - //! @private @memberof QXSemaphore - - - - //! @private @memberof QXSemaphore - - - - //! @private @memberof QXSemaphore - - - - //! @public @memberof QXSemaphore - -//! @public @memberof QXSemaphore - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(100, (count <= max_count) - && (0U < max_count) && (max_count <= 0xFFU)); - -me->count = (uint8_t)count; -me->max_count = (uint8_t)max_count; -QPSet_setEmpty(&me->waitSet); - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @public @memberof QXSemaphore - -//! @public @memberof QXSemaphore - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); - -// precondition, this function: -// - must NOT be called from an ISR; -// - the semaphore must be initialized -// - be called from an extended thread; -// - the thread must NOT be already blocked on any object. -Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) - && (me->max_count > 0U) - && (curr != (QXThread *)0) - && (curr->super.super.temp.obj == (QMState *)0)); -// - the thread must NOT be holding a scheduler lock. -Q_REQUIRE_INCRIT(201, - QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); - -bool taken = true; // assume that the semaphore will be signaled -if (me->count > 0U) { - --me->count; // semaphore taken: decrement the count - - QS_BEGIN_PRE_(QS_SEM_TAKE, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->super.prio, me->count); - QS_END_PRE_() -} -else { // semaphore not available -- BLOCK the thread - uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - // remove the curr prio from the ready set (will block) - // and insert to the waiting set on this semaphore - QPSet_remove(&QXK_priv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - QPSet_insert(&me->waitSet, p); - - // remember the blocking object (this semaphore) - curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); - QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - - QS_BEGIN_PRE_(QS_SEM_BLOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->super.prio, me->count); - QS_END_PRE_() - - // schedule the next thread if multitasking started - (void)QXK_sched_(); // schedule other threads - - QF_MEM_APP(); - QF_CRIT_EXIT(); - QF_CRIT_EXIT_NOP(); // BLOCK here !!! - - QF_CRIT_ENTRY(); // AFTER unblocking... - QF_MEM_SYS(); - - // the blocking object must be this semaphore - Q_ASSERT_INCRIT(240, curr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me)); - - // did the blocking time-out? (signal of zero means that it did) - if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? - QPSet_remove(&me->waitSet, p); // remove unblocked thread - taken = false; // the semaphore was NOT taken - } - } - else { // blocking did NOT time out - // the thread must NOT be waiting on this semaphore - Q_ASSERT_INCRIT(250, !QPSet_hasElement(&me->waitSet, p)); - } - curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return taken; - - - - //! @public @memberof QXSemaphore - -//! @public @memberof QXSemaphore - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// precondition: -// - the semaphore must be initialized -Q_REQUIRE_INCRIT(300, me->max_count > 0U); - -#ifdef Q_SPY -QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_priv_.curr); -#endif // Q_SPY - -bool taken; -// is the semaphore available? -if (me->count > 0U) { - --me->count; - taken = true; - - QS_BEGIN_PRE_(QS_SEM_TAKE, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->prio, me->count); - QS_END_PRE_() -} -else { // the semaphore is NOT available (would block) - taken = false; - - QS_BEGIN_PRE_(QS_SEM_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->prio, me->count); - QS_END_PRE_() -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return taken; - - - - //! @public @memberof QXSemaphore - -//! @public @memberof QXSemaphore - bool signaled = true; // assume that the semaphore will be signaled - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// precondition: -// - the semaphore must be initialized -Q_REQUIRE_INCRIT(400, me->max_count > 0U); - -// any threads blocked on this semaphore? -if (QPSet_notEmpty(&me->waitSet)) { - // find the highest-prio. thread waiting on this semaphore - uint_fast8_t const p = QPSet_findMax(&me->waitSet); - QXThread * const thr = - QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - - // assert that the thread: - // - must be registered in QF; - // - must be extended; and - // - must be blocked on this semaphore; - Q_ASSERT_INCRIT(410, (thr != (QXThread *)0) - && (thr->super.osObject != (void *)0) - && (thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me))); - - // disarm the internal time event - (void)QXThread_teDisarm_(thr); - - // make the thread ready to run and remove from the wait-list - QPSet_insert(&QXK_priv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - QPSet_remove(&me->waitSet, p); - - QS_BEGIN_PRE_(QS_SEM_TAKE, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(thr->super.prio, me->count); - QS_END_PRE_() - - if (!QXK_ISR_CONTEXT_()) { // not inside ISR? - (void)QXK_sched_(); // schedule other threads - } -} -else if (me->count < me->max_count) { - ++me->count; // increment the semaphore count - - QS_BEGIN_PRE_(QS_SEM_SIGNAL, 0U) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(0U, me->count); - QS_END_PRE_() -} -else { - signaled = false; // semaphore NOT signaled -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return signaled; - - - - - //! @class QXMutex - - - //! @private @memberof QXMutex - - - - //! @private @memberof QXMutex - - - - //! @public @memberof QXMutex - -//! @public @memberof QXMutex - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(100, (prioSpec & 0xFF00U) == 0U); - -me->ao.prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. -me->ao.pthre = 0U; // preemption-threshold (not used) -QActive * const ao = &me->ao; - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -QActive_register_(ao); // register this mutex as AO - - - - //! @public @memberof QXMutex - -//! @public @memberof QXMutex - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); - -// precondition, this mutex operation must: -// - NOT be called from an ISR; -// - be called from an eXtended thread; -// - the mutex-prio. must be in range; -// - the thread must NOT be already blocked on any object. -Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) - && (curr != (QXThread *)0) - && (me->ao.prio <= QF_MAX_ACTIVE) - && (curr->super.super.temp.obj == (QMState *)0)); -// also: the thread must NOT be holding a scheduler lock. -Q_REQUIRE_INCRIT(201, - QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); - -// is the mutex available? -bool locked = true; // assume that the mutex will be locked -if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; // mutex lock nesting - - // also: the newly locked mutex must have no holder yet - Q_REQUIRE_INCRIT(203, me->ao.osObject == (void *)0); - - // set the new mutex holder to the curr thread and - // save the thread's prio in the mutex - // NOTE: reuse the otherwise unused eQueue data member. - me->ao.osObject = curr; - me->ao.eQueue.head = (QEQueueCtr)curr->super.prio; - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the holder prio. must be lower than that of the mutex - // and the prio. slot must be occupied by this mutex - Q_ASSERT_INCRIT(210, (curr->super.prio < me->ao.prio) - && (QActive_registry_[me->ao.prio] == &me->ao)); - - // remove the thread's original prio from the ready set - // and insert the mutex's prio into the ready set - QPSet_remove(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.prio); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - // put the thread into the AO registry in place of the mutex - QActive_registry_[me->ao.prio] = &curr->super; - - // set thread's prio to that of the mutex - curr->super.prio = me->ao.prio; -#ifndef Q_UNSAFE - curr->super.prio_dis = (uint8_t)(~curr->super.prio); -#endif - } -} -// is the mutex locked by this thread already (nested locking)? -else if (me->ao.osObject == &curr->super) { - - // the nesting level beyond the arbitrary but high bound - // most likely means cyclic or recursive locking of a mutex. - Q_ASSERT_INCRIT(220, me->ao.eQueue.nFree < 0xFFU); - - ++me->ao.eQueue.nFree; // lock one more level - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() -} -else { // the mutex is already locked by a different thread - // the mutex holder must be valid - Q_ASSERT_INCRIT(230, me->ao.osObject != (void *)0); - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the prio slot must be occupied by the thr. holding the mutex - Q_ASSERT_INCRIT(240, QActive_registry_[me->ao.prio] - == QACTIVE_CAST_(me->ao.osObject)); - } - - // remove the curr thread's prio from the ready set (will block) - // and insert it to the waiting set on this mutex - uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - QPSet_remove(&QXK_priv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - QPSet_insert(&me->waitSet, p); - - // set the blocking object (this mutex) - curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); - QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - - QS_BEGIN_PRE_(QS_MTX_BLOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio - curr->super.prio); // blocked thread prio - QS_END_PRE_() - - // schedule the next thread if multitasking started - (void)QXK_sched_(); // schedule other threads - - QF_MEM_APP(); - QF_CRIT_EXIT(); - QF_CRIT_EXIT_NOP(); // BLOCK here !!! - - // AFTER unblocking... - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - // the blocking object must be this mutex - Q_ASSERT_INCRIT(250, curr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me)); - - // did the blocking time-out? (signal of zero means that it did) - if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? - QPSet_remove(&me->waitSet, p); // remove unblocked thread - locked = false; // the mutex was NOT locked - } - } - else { // blocking did NOT time out - // the thread must NOT be waiting on this mutex - Q_ASSERT_INCRIT(260, !QPSet_hasElement(&me->waitSet, p)); - } - curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return locked; - - - - //! @public @memberof QXMutex - -//! @public @memberof QXMutex - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QActive *curr = QXK_priv_.curr; -if (curr == (QActive *)0) { // called from a basic thread? - curr = QActive_registry_[QXK_priv_.actPrio]; -} - -// precondition, this mutex must: -// - NOT be called from an ISR; -// - the calling thread must be valid; -// - the mutex-prio. must be in range -Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) - && (curr != (QActive *)0) - && (me->ao.prio <= QF_MAX_ACTIVE)); -// also: the thread must NOT be holding a scheduler lock. -Q_REQUIRE_INCRIT(301, - QXK_priv_.lockHolder != (uint_fast8_t)curr->prio); - -// is the mutex available? -if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; // mutex lock nesting - - // also the newly locked mutex must have no holder yet - Q_REQUIRE_INCRIT(303, me->ao.osObject == (void *)0); - - // set the new mutex holder to the curr thread and - // save the thread's prio in the mutex - // NOTE: reuse the otherwise unused eQueue data member. - me->ao.osObject = curr; - me->ao.eQueue.head = (QEQueueCtr)curr->prio; - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the holder prio. must be lower than that of the mutex - // and the prio. slot must be occupied by this mutex - Q_ASSERT_INCRIT(310, (curr->prio < me->ao.prio) - && (QActive_registry_[me->ao.prio] == &me->ao)); - - // remove the thread's original prio from the ready set - // and insert the mutex's prio into the ready set - QPSet_remove(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.prio); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - // put the thread into the AO registry in place of the mutex - QActive_registry_[me->ao.prio] = curr; - - // set thread's prio to that of the mutex - curr->prio = me->ao.prio; -#ifndef Q_UNSAFE - curr->prio_dis = (uint8_t)(~curr->prio); -#endif - } -} -// is the mutex locked by this thread already (nested locking)? -else if (me->ao.osObject == curr) { - // the nesting level must not exceed the specified bound - Q_ASSERT_INCRIT(320, me->ao.eQueue.nFree < 0xFFU); - - ++me->ao.eQueue.nFree; // lock one more level - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() -} -else { // the mutex is already locked by a different thread - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the prio slot must be occupied by the thr. holding the mutex - Q_ASSERT_INCRIT(330, QActive_registry_[me->ao.prio] - == QACTIVE_CAST_(me->ao.osObject)); - } - - QS_BEGIN_PRE_(QS_MTX_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio - curr->prio); // trying thread prio - QS_END_PRE_() - - curr = (QActive *)0; // means that mutex is NOT available -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return curr != (QActive *)0; - - - - //! @public @memberof QXMutex - -//! @public @memberof QXMutex - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QActive *curr = QXK_priv_.curr; -if (curr == (QActive *)0) { // called from a basic thread? - curr = QActive_registry_[QXK_priv_.actPrio]; -} - -Q_REQUIRE_INCRIT(400, (!QXK_ISR_CONTEXT_()) - && (curr != (QActive *)0)); -Q_REQUIRE_INCRIT(401, me->ao.eQueue.nFree > 0U); -Q_REQUIRE_INCRIT(403, me->ao.osObject == curr); - -// is this the last nesting level? -if (me->ao.eQueue.nFree == 1U) { - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // prio. must be in range - Q_ASSERT_INCRIT(410, me->ao.prio < QF_MAX_ACTIVE); - - // restore the holding thread's prio from the mutex - curr->prio = (uint8_t)me->ao.eQueue.head; -#ifndef Q_UNSAFE - curr->prio_dis = (uint8_t)(~curr->prio); -#endif - - // put the mutex back into the AO registry - QActive_registry_[me->ao.prio] = &me->ao; - - // remove the mutex' prio from the ready set - // and insert the original thread's prio. - QPSet_remove(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.prio); - QPSet_insert(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.eQueue.head); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - } - - QS_BEGIN_PRE_(QS_MTX_UNLOCK, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio - 0U); // nesting - QS_END_PRE_() - - // are any other threads waiting on this mutex? - if (QPSet_notEmpty(&me->waitSet)) { - // find the highest-prio. thread waiting on this mutex - uint_fast8_t const p = QPSet_findMax(&me->waitSet); - - // remove this thread from waiting on the mutex - // and insert it into the ready set. - QPSet_remove(&me->waitSet, p); - QPSet_insert(&QXK_priv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); -#endif - - QXThread * const thr = - QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - - // the waiting thread must: - // - be registered in QF - // - have the prio. corresponding to the registration - // - be an extended thread - // - be blocked on this mutex - Q_ASSERT_INCRIT(420, (thr != (QXThread *)0) - && (thr->super.prio == (uint8_t)p) - && (thr->super.super.state.act == Q_ACTION_CAST(0)) - && (thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me))); - - // disarm the internal time event - (void)QXThread_teDisarm_(thr); - - // set the new mutex holder to the curr thread and - // save the thread's prio in the mutex - // NOTE: reuse the otherwise unused eQueue data member. - me->ao.osObject = thr; - me->ao.eQueue.head = (QEQueueCtr)thr->super.prio; - - QS_BEGIN_PRE_(QS_MTX_LOCK, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the holder prio. must be lower than that of the mutex - Q_ASSERT_INCRIT(430, (me->ao.prio < QF_MAX_ACTIVE) - && (thr->super.prio < me->ao.prio)); - - // put the thread into AO registry in place of the mutex - QActive_registry_[me->ao.prio] = &thr->super; - } - } - else { // no threads are waiting for this mutex - me->ao.eQueue.nFree = 0U; // free up the nesting count - - // the mutex no longer held by any thread - me->ao.osObject = (void *)0; - me->ao.eQueue.head = 0U; - me->ao.eQueue.tail = 0U; - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // put the mutex back at the original mutex slot - QActive_registry_[me->ao.prio] = - QXK_PTR_CAST_(QActive*, me); - } - } - - // schedule the next thread if multitasking started - if (QXK_sched_() != 0U) { // activation needed? - QXK_activate_(); // synchronously activate basic-thread(s) - } -} -else { // releasing one level of nested mutex lock - --me->ao.eQueue.nFree; // unlock one level - - QS_BEGIN_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - - - - - - - - - - - - - \ - QACTIVE_POST_X(&(me_)->super, (e_), (margin_), (sender_)) - - - - - - - QSchedStatus lockStat_; - - - - - - do { \ - if (QXK_ISR_CONTEXT_()) { \ - lockStat_ = 0xFFU; \ - } else { \ - lockStat_ = QXK_schedLock((ceil_)); \ - } \ -} while (false) - - - - do { \ - if (lockStat_ != 0xFFU) { \ - QXK_schedUnlock(lockStat_); \ - } \ -} while (false) - - - - - - \ - Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) - - - - - - do { \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ - if (!QXK_ISR_CONTEXT_()) { \ - if (QXK_sched_() != 0U) { \ - QXK_activate_(); \ - } \ - } \ -} while (false) - - - - - - do { \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - if (!QXK_ISR_CONTEXT_()) { \ - if (QXK_sched_() != 0U) { \ - QXK_activate_(); \ - } \ - } \ -} while (false) - - - - - - do { \ - if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ - (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ - if (!QXK_ISR_CONTEXT_()) { \ - (void)QXK_sched_(); \ - } \ - } \ -} while (false) - - - - - - do { \ - if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ - (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ - if (!QXK_ISR_CONTEXT_()) { \ - (void)QXK_sched_(); \ - } \ - } \ -} while (false) - - - - <type_> - - - - - ((type_)(ptr_)) - - - - - - ((QXThread *)(ptr_)) - - - - - - - - - //! @class QS - { - //! @cond INTERNAL - uint8_t dummy; - //! @endcond -} QS; - - - - //! @static @public @memberof QS -//! pre-defined QS record IDs - { - // [0] QS session (not maskable) - QS_EMPTY, //!< QS record for cleanly starting a session - - // [1] SM records - QS_QEP_STATE_ENTRY, //!< a state was entered - QS_QEP_STATE_EXIT, //!< a state was exited - QS_QEP_STATE_INIT, //!< an initial transition was taken in a state - QS_QEP_INIT_TRAN, //!< the top-most initial transition was taken - QS_QEP_INTERN_TRAN, //!< an internal transition was taken - QS_QEP_TRAN, //!< a regular transition was taken - QS_QEP_IGNORED, //!< an event was ignored (silently discarded) - QS_QEP_DISPATCH, //!< an event was dispatched (begin of RTC step) - QS_QEP_UNHANDLED, //!< an event was un-handled due to a guard - - // [10] Active Object (AO) records - QS_QF_ACTIVE_DEFER, //!< AO deferred an event - QS_QF_ACTIVE_RECALL, //!< AO recalled an event - QS_QF_ACTIVE_SUBSCRIBE, //!< an AO subscribed to an event - QS_QF_ACTIVE_UNSUBSCRIBE, //!< an AO unsubscribed to an event - QS_QF_ACTIVE_POST, //!< an event was posted (FIFO) directly to AO - QS_QF_ACTIVE_POST_LIFO, //!< an event was posted (LIFO) directly to AO - QS_QF_ACTIVE_GET, //!< AO got an event and its queue is not empty - QS_QF_ACTIVE_GET_LAST,//!< AO got an event and its queue is empty - QS_QF_ACTIVE_RECALL_ATTEMPT, //!< AO attempted to recall an event - - // [19] Event Queue (EQ) records - QS_QF_EQUEUE_POST, //!< an event was posted (FIFO) to a raw queue - QS_QF_EQUEUE_POST_LIFO, //!< an event was posted (LIFO) to a raw queue - QS_QF_EQUEUE_GET, //!< get an event and queue still not empty - QS_QF_EQUEUE_GET_LAST,//!< get the last event from the queue - - // [23] Framework (QF) records - QS_QF_NEW_ATTEMPT, //!< an attempt to allocate an event failed - - // [24] Memory Pool (MP) records - QS_QF_MPOOL_GET, //!< a memory block was removed from memory pool - QS_QF_MPOOL_PUT, //!< a memory block was returned to memory pool - - // [26] Additional Framework (QF) records - QS_QF_PUBLISH, //!< an event was published to active objects - QS_QF_NEW_REF, //!< new event reference was created - QS_QF_NEW, //!< new event was created - QS_QF_GC_ATTEMPT, //!< garbage collection attempt - QS_QF_GC, //!< garbage collection - QS_QF_TICK, //!< QTimeEvt tick was called - - // [32] Time Event (TE) records - QS_QF_TIMEEVT_ARM, //!< a time event was armed - QS_QF_TIMEEVT_AUTO_DISARM, //!< a time event expired and was disarmed - QS_QF_TIMEEVT_DISARM_ATTEMPT,//!< attempt to disarm a disarmed QTimeEvt - QS_QF_TIMEEVT_DISARM, //!< true disarming of an armed time event - QS_QF_TIMEEVT_REARM, //!< rearming of a time event - QS_QF_TIMEEVT_POST, //!< a time event posted itself directly to an AO - - // [38] Additional Framework (QF) records - QS_QF_DELETE_REF, //!< an event reference is about to be deleted - QS_QF_CRIT_ENTRY, //!< critical section was entered - QS_QF_CRIT_EXIT, //!< critical section was exited - QS_QF_ISR_ENTRY, //!< an ISR was entered - QS_QF_ISR_EXIT, //!< an ISR was exited - QS_QF_INT_DISABLE, //!< interrupts were disabled - QS_QF_INT_ENABLE, //!< interrupts were enabled - - // [45] Additional Active Object (AO) records - QS_QF_ACTIVE_POST_ATTEMPT,//!< attempt to post an evt to AO failed - - // [46] Additional Event Queue (EQ) records - QS_QF_EQUEUE_POST_ATTEMPT,//!< attempt to post evt to QEQueue failed - - // [47] Additional Memory Pool (MP) records - QS_QF_MPOOL_GET_ATTEMPT, //!< attempt to get a memory block failed - - // [48] Scheduler (SC) records - QS_SCHED_PREEMPT, //!< scheduler asynchronously preempted a task - QS_SCHED_RESTORE, //!< scheduler restored preempted task - QS_SCHED_LOCK, //!< scheduler was locked - QS_SCHED_UNLOCK, //!< scheduler was unlocked - QS_SCHED_NEXT, //!< scheduler started next task - QS_SCHED_IDLE, //!< scheduler restored the idle task - - // [54] Miscellaneous QS records (not maskable) - QS_ENUM_DICT, //!< enumeration dictionary entry - - // [55] Additional QEP records - QS_QEP_TRAN_HIST, //!< a tran. to history was taken - QS_QEP_TRAN_EP, //!< a tran. to entry point into a submachine - QS_QEP_TRAN_XP, //!< a tran. to exit point out of a submachine - - // [58] Miscellaneous QS records (not maskable) - QS_TEST_PAUSED, //!< test has been paused - QS_TEST_PROBE_GET, //!< reports that Test-Probe has been used - QS_SIG_DICT, //!< signal dictionary entry - QS_OBJ_DICT, //!< object dictionary entry - QS_FUN_DICT, //!< function dictionary entry - QS_USR_DICT, //!< user QS record dictionary entry - QS_TARGET_INFO, //!< reports the Target information - QS_TARGET_DONE, //!< reports completion of a user callback - QS_RX_STATUS, //!< reports QS data receive status - QS_QUERY_DATA, //!< reports the data from "current object" query - QS_PEEK_DATA, //!< reports the data from the PEEK query - QS_ASSERT_FAIL, //!< assertion failed in the code - QS_QF_RUN, //!< QF_run() was entered - - // [71] Semaphore (SEM) records - QS_SEM_TAKE, //!< a semaphore was taken by a thread - QS_SEM_BLOCK, //!< a semaphore blocked a thread - QS_SEM_SIGNAL, //!< a semaphore was signaled - QS_SEM_BLOCK_ATTEMPT, //!< a semaphore blocked was attempted - - // [75] Mutex (MTX) records - QS_MTX_LOCK, //!< a mutex was locked - QS_MTX_BLOCK, //!< a mutex blocked a thread - QS_MTX_UNLOCK, //!< a mutex was unlocked - QS_MTX_LOCK_ATTEMPT, //!< a mutex lock was attempted - QS_MTX_BLOCK_ATTEMPT, //!< a mutex blocking was attempted - QS_MTX_UNLOCK_ATTEMPT,//!< a mutex unlock was attempted - - // [81] - QS_PRE_MAX //!< the # predefined signals -}; - - - - //! @static @public @memberof QS -//! QS-TX record groups for QS_GLB_FILTER() - { - QS_ALL_RECORDS = 0xF0,//!< all maskable QS records - QS_SM_RECORDS, //!< State Machine QS records - QS_AO_RECORDS, //!< Active Object QS records - QS_EQ_RECORDS, //!< Event Queues QS records - QS_MP_RECORDS, //!< Memory Pools QS records - QS_TE_RECORDS, //!< Time Events QS records - QS_QF_RECORDS, //!< QF QS records - QS_SC_RECORDS, //!< Scheduler QS records - QS_SEM_RECORDS, //!< Semaphore QS records - QS_MTX_RECORDS, //!< Mutex QS records - QS_U0_RECORDS, //!< User Group 100-104 records - QS_U1_RECORDS, //!< User Group 105-109 records - QS_U2_RECORDS, //!< User Group 110-114 records - QS_U3_RECORDS, //!< User Group 115-119 records - QS_U4_RECORDS, //!< User Group 120-124 records - QS_UA_RECORDS //!< All User records -}; - - - - //! @static @public @memberof QS -//! QS user record group offsets for QS_GLB_FILTER() - { - QS_USER = 100, //!< the first record available to QS users - QS_USER0 = QS_USER, //!< offset for User Group 0 - QS_USER1 = (enum_t)QS_USER0 + 5, //!< offset for User Group 1 - QS_USER2 = (enum_t)QS_USER1 + 5, //!< offset for User Group 2 - QS_USER3 = (enum_t)QS_USER2 + 5, //!< offset for User Group 3 - QS_USER4 = (enum_t)QS_USER3 + 5 //!< offset for User Group 4 -}; - - - - //! @static @public @memberof QS -//! QS ID offsets for QS_LOC_FILTER() - { - QS_AO_ID = 0, //!< offset for AO priorities - QS_EP_ID = 64, //!< offset for event-pool IDs - QS_EQ_ID = 80, //!< offset for event-queue IDs - QS_AP_ID = 96 //!< offset for Application-specific IDs -}; - - - - //! @static @public @memberof QS -//! QS ID groups for QS_LOC_FILTER() - { - QS_ALL_IDS = 0xF0, //!< all QS IDs - QS_AO_IDS = 0x80 + (enum_t)QS_AO_ID, //!< AO IDs (priorities) - QS_EP_IDS = 0x80 + (enum_t)QS_EP_ID, //!< event-pool IDs - QS_EQ_IDS = 0x80 + (enum_t)QS_EQ_ID, //!< event-queue IDs - QS_AP_IDS = 0x80 + (enum_t)QS_AP_ID //!< Application-specific IDs -}; - - - - //! @struct QSpyId - - - - - - - - - - - - - - - - //! @static @private @memberof QS - )(void); - - - - - - - - - - - - - - - //! @struct QS_Filter - - - - - - - - //! @static @private @memberof QS - -//! @static @private @memberof QS - - - - - - - //! Enumerates data elements for app-specific trace records - { - QS_I8_ENUM_T, //!< signed 8-bit integer or enum format - QS_U8_T, //!< unsigned 8-bit integer format - QS_I16_T, //!< signed 16-bit integer format - QS_U16_T, //!< unsigned 16-bit integer format - QS_I32_T, //!< signed 32-bit integer format - QS_U32_T, //!< unsigned 32-bit integer format - QS_F32_T, //!< 32-bit floating point format - QS_F64_T, //!< 64-bit floating point format - QS_STR_T, //!< zero-terminated ASCII string format - QS_MEM_T, //!< up to 255-bytes memory block format - QS_SIG_T, //!< event signal format - QS_OBJ_T, //!< object pointer format - QS_FUN_T, //!< function pointer format - QS_I64_T, //!< signed 64-bit integer format - QS_U64_T //!< unsigned 64-bit integer format -}; - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - QS_priv_.buf = &sto[0]; -QS_priv_.end = (QSCtr)stoSize; -QS_priv_.head = 0U; -QS_priv_.tail = 0U; -QS_priv_.used = 0U; -QS_priv_.seq = 0U; -QS_priv_.chksum = 0U; -QS_priv_.critNest = 0U; - -QS_glbFilter_(-(int_fast16_t)QS_ALL_RECORDS); // all global filters OFF -QS_locFilter_((int_fast16_t)QS_ALL_IDS); // all local filters ON -QS_priv_.locFilter_AP = (void *)0; // deprecated "AP-filter" - -// produce an empty record to "flush" the QS trace buffer -QS_beginRec_((uint_fast8_t)QS_EMPTY); -QS_endRec_(); - -// produce the reset record to inform QSPY of a new session -QS_target_info_pre_(0xFFU); - -// hold off flushing after successful initialization (see QS_INIT()) - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - uint16_t ret; -if (QS_priv_.used == 0U) { - ret = QS_EOD; // set End-Of-Data -} -else { - uint8_t const * const buf = QS_priv_.buf; // put in a temporary - QSCtr tail = QS_priv_.tail; // put in a temporary (register) - ret = (uint16_t)buf[tail]; // set the byte to return - ++tail; // advance the tail - if (tail == QS_priv_.end) { // tail wrap around? - tail = 0U; - } - QS_priv_.tail = tail; // update the tail - --QS_priv_.used; // one less byte used -} -return ret; // return the byte or EOD - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - QSCtr const used = QS_priv_.used; // put in a temporary (register) -uint8_t const *buf; - -// any bytes used in the ring buffer? -if (used != 0U) { - QSCtr tail = QS_priv_.tail; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - QSCtr n = (QSCtr)(end - tail); - if (n > used) { - n = used; - } - if (n > (QSCtr)(*pNbytes)) { - n = (QSCtr)(*pNbytes); - } - *pNbytes = (uint16_t)n; // n-bytes available - buf = &QS_priv_.buf[tail]; // the bytes are at the tail - - QS_priv_.used = (QSCtr)(used - n); - tail += n; - if (tail == end) { - tail = 0U; - } - QS_priv_.tail = tail; -} -else { // no bytes available - *pNbytes = 0U; // no bytes available right now - buf = (uint8_t *)0; // no bytes available right now -} -return buf; - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - - - //! @static @public @memberof QS -//! Kinds of objects used in QS-RX - { - SM_OBJ, //!< state machine object - AO_OBJ, //!< active object - MP_OBJ, //!< event pool object - EQ_OBJ, //!< raw queue object - TE_OBJ, //!< time event object - AP_OBJ, //!< generic Application-specific object - MAX_OBJ -}; - - - - //! @static @public @memberof QS -//! Object combinations for QS-RX - { - SM_AO_OBJ = (enum_t)MAX_OBJ //!< combination of SM and AO -}; - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - QS_rxPriv_.buf = &sto[0]; -QS_rxPriv_.end = (QSCtr)stoSize; -QS_rxPriv_.head = 0U; -QS_rxPriv_.tail = 0U; - -QS_rxPriv_.currObj[SM_OBJ] = (void *)0; -QS_rxPriv_.currObj[AO_OBJ] = (void *)0; -QS_rxPriv_.currObj[MP_OBJ] = (void *)0; -QS_rxPriv_.currObj[EQ_OBJ] = (void *)0; -QS_rxPriv_.currObj[TE_OBJ] = (void *)0; -QS_rxPriv_.currObj[AP_OBJ] = (void *)0; - -QS_RX_TRAN_(WAIT4_SEQ); -QS_rxPriv_.esc = 0U; -QS_rxPriv_.seq = 0U; -QS_rxPriv_.chksum = 0U; - -QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); - QS_OBJ_PRE_(&QS_rxPriv_); - QS_STR_PRE_("QS_RX"); -QS_endRec_(); -// no QS_REC_DONE(), because QS is not running yet - -#ifdef Q_UTEST -QS_tstPriv_.tpNum = 0U; -QS_tstPriv_.testTime = 0U; -#endif // Q_UTEST - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - // NOTE: does not need critical section -// But requires system-level memory access (QF_MEM_SYS()). - -QSCtr head = QS_rxPriv_.head + 1U; -if (head == QS_rxPriv_.end) { - head = 0U; -} -if (head != QS_rxPriv_.tail) { // buffer NOT full? - QS_rxPriv_.buf[QS_rxPriv_.head] = b; - QS_rxPriv_.head = head; // update the head to a *valid* index - return true; // byte placed in the buffer -} -else { - return false; // byte NOT placed in the buffer -} - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - QSCtr tail = QS_rxPriv_.tail; -while (QS_rxPriv_.head != tail) { // QS-RX buffer NOT empty? - uint8_t b = QS_rxPriv_.buf[tail]; - - ++tail; - if (tail == QS_rxPriv_.end) { - tail = 0U; - } - QS_rxPriv_.tail = tail; // update the tail to a *valid* index - - if (QS_rxPriv_.esc != 0U) { // escaped byte arrived? - QS_rxPriv_.esc = 0U; - b ^= QS_ESC_XOR; - - QS_rxPriv_.chksum += b; - QS_rxParseData_(b); - } - else if (b == QS_ESC) { - QS_rxPriv_.esc = 1U; - } - else if (b == QS_FRAME) { - // get ready for the next frame - b = QS_rxPriv_.state; // save the current state in b - QS_rxPriv_.esc = 0U; - QS_RX_TRAN_(WAIT4_SEQ); - - if (QS_rxPriv_.chksum == QS_GOOD_CHKSUM) { - QS_rxPriv_.chksum = 0U; - QS_rxHandleGoodFrame_(b); - } - else { // bad checksum - QS_rxPriv_.chksum = 0U; - QS_rxReportError_(0x41); - QS_rxHandleBadFrame_(b); - } - } - else { - QS_rxPriv_.chksum += b; - QS_rxParseData_(b); - } -} - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - QS_CRIT_STAT -QS_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, obj_kind < Q_DIM(QS_rxPriv_.currObj)); - -QS_MEM_SYS(); - -QS_rxPriv_.currObj[obj_kind] = obj_ptr; - -QS_MEM_APP(); -QS_CRIT_EXIT(); - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - // NOTE: Must be called IN critical section. -// Also requires system-level memory access (QF_MEM_SYS()). - -QSCtr const head = QS_rxPriv_.head; -uint16_t nFree; -if (head == QS_rxPriv_.tail) { // buffer empty? - nFree = (uint16_t)(QS_rxPriv_.end - 1U); -} -else if (head < QS_rxPriv_.tail) { - nFree = (uint16_t)(QS_rxPriv_.tail - (head + 1U)); -} -else { - nFree = (uint16_t)((head + 1U) - QS_rxPriv_.tail); - nFree = (uint16_t)(QS_rxPriv_.end - nFree); -} -return nFree; - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - - - - - - - - - - - // @struct TProbe - { - QSFun addr; - uint32_t data; - uint8_t idx; -}; - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - - - - - - - - //! @static @public @memberof QS - -//! @static @public @memberof QS - - - - - - - - - //! QF_init() stub for QUTest - // Clear the internal QF variables, so that the framework can start -// correctly even if the startup code fails to clear the uninitialized -// data (as is required by the C Standard). -QF_bzero_(&QF_priv_, sizeof(QF_priv_)); -QF_bzero_(&QS_tstPriv_, sizeof(QS_tstPriv_)); -QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - -#ifndef Q_UNSAFE -QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); -#endif - - - - //! QF_stop() stub for QUTest - QS_onReset(); - - - - //! QF_run() stub for QUTest - // function dictionaries for the standard API -QS_FUN_DICTIONARY(&QActive_post_); -QS_FUN_DICTIONARY(&QActive_postLIFO_); -QS_FUN_DICTIONARY(&QS_processTestEvts_); - -QS_CRIT_STAT -QS_CRIT_ENTRY(); -QS_MEM_SYS(); - -// produce the QS_QF_RUN trace record -QS_BEGIN_PRE_(QS_QF_RUN, 0U) -QS_END_PRE_() - -QS_MEM_APP(); -QS_CRIT_EXIT(); - -QS_processTestEvts_(); // process all events posted so far -QS_onTestLoop(); // run the test loop -QS_onCleanup(); // application cleanup -return 0; // return no error - - - - - // QActive stub for QUTest - - - //! @private @memberof QActive - -//! @private @memberof QActive - - - - - - - - - - - - - Q_UNUSED_PAR(stkSto); -Q_UNUSED_PAR(stkSize); - -me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO -me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold -QActive_register_(me); // make QF aware of this active object - -QEQueue_init(&me->eQueue, qSto, qLen); - -// top-most initial tran. (virtual call) -(*me->super.vptr->init)(&me->super, par, me->prio); - - - - //! @protected @memberof QActive - -//! @protected @memberof QActive - QActive_unsubscribeAll(me); // unsubscribe from all events -QActive_unregister_(me); // un-register this active object - - - - - // QTimeEvt stub for QUTest - - - //! @private @memberof QTimeEvt - -//! @private @memberof QTimeEvt - - - - - QS_CRIT_STAT -QS_CRIT_ENTRY(); -QS_MEM_SYS(); - -QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - -QS_BEGIN_PRE_(QS_QF_TICK, 0U) - ++prev->ctr; - QS_TEC_PRE_(prev->ctr); // tick ctr - QS_U8_PRE_(tickRate); // tick rate -QS_END_PRE_() - -// is current Time Event object provided? -QTimeEvt *t = (QTimeEvt *)QS_rxPriv_.currObj[TE_OBJ]; -if (t != (QTimeEvt *)0) { - - // the time event must be armed - Q_ASSERT_INCRIT(810, t->ctr != 0U); - - QActive * const act = (QActive *)(t->act); - - // the recipient AO must be provided - Q_ASSERT_INCRIT(820, act != (QActive *)0); - - // periodic time evt? - if (t->interval != 0U) { - t->ctr = t->interval; // rearm the time event - } - else { // one-shot time event: automatically disarm - t->ctr = 0U; // auto-disarm - // mark time event 't' as NOT linked - t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); // this time event object - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - } - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(t); // the time event object - QS_SIG_PRE_(t->super.sig); // signal of this time event - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - QS_MEM_APP(); - QS_CRIT_EXIT(); // exit critical section before posting - - QACTIVE_POST(act, &t->super, sender); // asserts if queue overflows - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); -} - -// update the linked list of time events -for (;;) { - t = prev->next; // advance down the time evt. list - - // end of the list? - if (t == (QTimeEvt *)0) { - - // any new time events armed since the last QTimeEvt_tick_()? - if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - - // sanity check - Q_ASSERT_INCRIT(830, prev != (QTimeEvt *)0); - prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; // switch to the new list - } - else { - break; // all currently armed time evts. processed - } - } - - // time event scheduled for removal? - if (t->ctr == 0U) { - prev->next = t->next; - // mark time event 't' as NOT linked - t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - // do NOT advance the prev pointer - QS_MEM_APP(); - QS_CRIT_EXIT(); // exit crit. section to reduce latency - } - else { - prev = t; // advance to this time event - QS_MEM_APP(); - QS_CRIT_EXIT(); // exit crit. section to reduce latency - } - QS_CRIT_ENTRY(); // re-enter crit. section to continue - QS_MEM_SYS(); -} - -QS_MEM_APP(); -QS_CRIT_EXIT(); - - - - - //! @class QHsmDummy -//! @extends QAsm - - - //! @public @memberof QHsmDummy - -//! @public @memberof QHsmDummy - static struct QAsmVtable const vtable = { - &QHsmDummy_init_, - &QHsmDummy_dispatch_, - &QHsm_isIn_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif -}; -me->super.vptr = &vtable; // hook the vptr - - - - //! @private @memberof QHsmDummy - -//! @private @memberof QHsmDummy - - - - - - - Q_UNUSED_PAR(par); - -#ifdef Q_SPY -if ((QS_priv_.flags & 0x01U) == 0U) { - QS_priv_.flags |= 0x01U; - QS_FUN_DICTIONARY(&QHsm_top); -} -#endif - -QS_CRIT_STAT -QS_CRIT_ENTRY(); -QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.fun); // the source state - QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. -QS_END_PRE_() -QS_MEM_APP(); -QS_CRIT_EXIT(); - - - - //! @private @memberof QHsmDummy - -//! @private @memberof QHsmDummy - - - - - - - QS_CRIT_STAT -QS_CRIT_ENTRY(); -QS_MEM_SYS(); -QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.fun); // the current state -QS_END_PRE_() -QS_MEM_APP(); -QS_CRIT_EXIT(); - - - - - //! @class QActiveDummy -//! @extends QActive - - - //! @public @memberof QActiveDummy - -//! @public @memberof QActiveDummy - // superclass' ctor -QActive_ctor(&me->super, Q_STATE_CAST(0)); - -static struct QAsmVtable const vtable = { - &QActiveDummy_init_, - &QActiveDummy_dispatch_, - &QHsm_isIn_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif -}; -me->super.super.vptr = &vtable; // hook the vptr - - - - //! @private @memberof QActiveDummy - -//! @private @memberof QActiveDummy - - - - - - - Q_UNUSED_PAR(qsId); - -QHsmDummy_init_(me, par, ((QActive const *)me)->prio); - - - - //! @private @memberof QActiveDummy - -//! @private @memberof QActiveDummy - - - - - - - Q_UNUSED_PAR(qsId); - -QHsmDummy_dispatch_(me, e, ((QActive const *)me)->prio); - - - - //! @private @memberof QActiveDummy - -//! @private @memberof QActiveDummy - - - - - - - - - QS_TEST_PROBE_DEF(&QActive_post_) - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// test-probe#1 for faking queue overflow -bool status = true; -QS_TEST_PROBE_ID(1, - status = false; - if (margin == QF_NO_MARGIN) { - // fake assertion Mod=qf_actq,Loc=110 - Q_onError("qf_actq", 110); - } -) - -// is it a mutable event? -if (QEvt_getPoolNum_(e) != 0U) { - QEvt_refCtr_inc_(e); -} - -uint_fast8_t const rec = (status ? (uint_fast8_t)QS_QF_ACTIVE_POST - : (uint_fast8_t)QS_QF_ACTIVE_POST_ATTEMPT); -QS_BEGIN_PRE_(rec, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(0U); // # free entries - QS_EQC_PRE_(margin); // margin requested -QS_END_PRE_() - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -// callback to examine the posted event under the same conditions -// as producing the #QS_QF_ACTIVE_POST trace record, which are: -// the local filter for this AO ('me->prio') is set -if (QS_LOC_CHECK_(me->prio)) { - QS_onTestPost(sender, me, e, status); -} - -// recycle the event immediately, because it was not really posted -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); -#endif - -return status; // the event is "posted" correctly - - - - //! @private @memberof QActiveDummy - -//! @private @memberof QActiveDummy - - - - - QS_TEST_PROBE_DEF(&QActive_postLIFO_) - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// test-probe#1 for faking queue overflow -QS_TEST_PROBE_ID(1, - // fake assertion Mod=qf_actq,Loc=210 - Q_onError("qf_actq", 210); -) - -// is it a mutable event? -if (QEvt_getPoolNum_(e) != 0U) { - QEvt_refCtr_inc_(e); -} - -QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(0U); // # free entries - QS_EQC_PRE_(0U); // min # free entries -QS_END_PRE_() - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -// callback to examine the posted event under the same conditions -// as producing the #QS_QF_ACTIVE_POST trace record, which are: -// the local filter for this AO ('me->prio') is set -if (QS_LOC_CHECK_(me->prio)) { - QS_onTestPost((QActive *)0, me, e, true); -} -// recycle the event immediately, because it was not really posted -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); -#endif - - - - - - - - - - - (QS_onStartup(arg_)) - - - - (QS_onCleanup()) - - - - (QS_output()) - - - - (QS_rx_input()) - - - - - - (QS_glbFilter_((int_fast16_t)(rec_))) - - - - - - (QS_locFilter_((int_fast16_t)(qsId_))) - - - - - - - - \ -if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \ - QS_CRIT_STAT \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - - - - } \ - QS_endRec_(); \ - QS_MEM_APP(); \ - QS_CRIT_EXIT(); \ -} - - - - (QS_onFlush()) - - - - - - - - \ -if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - - - - } \ - QS_endRec_(); \ -} - - - - - - \ - (((uint_fast8_t)QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ - & ((uint_fast8_t)1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) - - - - - - \ - (((uint_fast8_t)QS_filt_.loc[(uint_fast8_t)(qsId_) >> 3U] \ - & ((uint_fast8_t)1U << ((uint_fast8_t)(qsId_) & 7U))) != 0U) - - - - ((void)0) - - - - - - - - \ - (QS_u8_fmt_((uint8_t)(((width_) << 4U) & 0x7U) | (uint8_t)QS_I8_ENUM_T, \ - (data_))) - - - - - - - - \ - (QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_))) - - - - - - - - \ - (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_))) - - - - - - - - \ - (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_))) - - - - - - - - \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_))) - - - - - - - - \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_))) - - - - - - - - \ - (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_))) - - - - - - - - \ - (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_))) - - - - - - - - \ - (QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_))) - - - - - - - - \ - (QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_))) - - - - - - (QS_str_fmt_((str_))) - - - - - - - - (QS_mem_fmt_((mem_), (size_))) - - - - - - - - \ - (QS_u8_fmt_((uint8_t)(0x80U | ((group_) << 4U)) | (uint8_t)QS_I8_ENUM_T,\ - (uint8_t)(value_))) - - - - (QS_u16_raw_(QS_onGetTime())) - - - - (QS_u32_raw_(QS_onGetTime())) - - - - - - (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_))) - - - - - - (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) - - - - - - (QS_u64_fmt_(QS_OBJ_T, (uint64_t)(obj_))) - - - - - - (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_))) - - - - - - (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) - - - - - - (QS_u64_fmt_(QS_FUN_T, (uint64_t)(fun_))) - - - - - - - - \ - QS_u8_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) - - - - - - - - \ - QS_u16_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) - - - - - - - - \ - QS_u32_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) - - - - - - - - \ - (QS_sig_dict_pre_((QSignal)(sig_), (obj_), #sig_)) - - - - - - \ - (QS_obj_dict_pre_((obj_), #obj_)) - - - - - - - - \ - (QS_obj_arr_dict_pre_((obj_), (idx_), #obj_)) - - - - - - \ - (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_)) - - - - - - \ - (QS_usr_dict_pre_((rec_), #rec_)) - - - - - - - - \ - (QS_enum_dict_pre_((value_), (group_), #value_)) - - - - - - (QS_rxPut((b_))) - - - - - - - - - - - - do { \ - QS_BEGIN_PRE_(QS_QF_ISR_ENTRY, 0U) \ - QS_TIME_PRE_(); \ - QS_2u8_raw_(isrnest, prio); \ - QS_END_PRE_() \ -} - - - - - - - - do { \ - QS_BEGIN_PRE_(QS_QF_ISR_EXIT, 0U) \ - QS_TIME_PRE_(); \ - QS_2u8_raw_(isrnest, prio); \ - QS_END_PRE_() \ -} while (false) - - - - - - (code_) - - - - - - - - - - \ - (QS_assertion_pre_((module_), (id_), (delay_))) - - - - ((uint16_t)0xFFFFU) - - - - ((uint8_t)7U) - - - - ((uint8_t)0x0FU) - - - - QF_CRIT_STAT - - - - QF_CRIT_ENTRY() - - - - QF_CRIT_EXIT() - - - - QF_MEM_SYS() - - - - QF_MEM_APP() - - @@ -9003,9 +6172,9 @@ $declare1 ${QP-FuSa} #define QP_H_ //============================================================================ -#define QP_VERSION_STR "7.4.0-rc.3" -#define QP_VERSION 740U -#define QP_RELEASE 0x7092C3BBU +#define QP_VERSION_STR "8.0.0" +#define QP_VERSION 800U +#define QP_RELEASE 0x7055936FU //============================================================================ //! @cond INTERNAL @@ -9088,24 +6257,30 @@ $declare ${QF-macros} $declare ${QF::QF-pkg} -// Bitmasks are for the QTimeEvt::refCtr_ attribute (inherited from ::QEvt). -// In ::QTimeEvt this attribute is NOT used for reference counting. -#define QTE_IS_LINKED (1U << 7U) -#define QTE_WAS_DISARMED (1U << 6U) -#define QTE_TICK_RATE 0x0FU +// Bitmasks are for the QTimeEvt::flags attribute +#define QTE_FLAG_IS_LINKED (1U << 7U) +#define QTE_FLAG_WAS_DISARMED (1U << 6U) //! @private @memberof QEvt static inline void QEvt_refCtr_inc_(QEvt const *me) { - ++((QEvt *)me)->refCtr_; + uint8_t rc = me->refCtr_ + 1U; + ((QEvt *)me)->refCtr_ = rc; // cast away 'const' +#ifndef Q_UNSAFE + ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); +#endif // ndef Q_UNSAFE } //! @private @memberof QEvt static inline void QEvt_refCtr_dec_(QEvt const *me) { - --((QEvt *)me)->refCtr_; + uint8_t rc = me->refCtr_ - 1U; + ((QEvt *)me)->refCtr_ = rc; // cast away 'const' +#ifndef Q_UNSAFE + ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); +#endif // ndef Q_UNSAFE } -#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) -#define Q_UINTPTR_CAST_(ptr_) ((uintptr_t)(ptr_)) +#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) +#define Q_PTR2UINT_CAST_(ptr_) ((uintptr_t)(ptr_)) #endif // QP_PKG_H_ @@ -9122,13 +6297,11 @@ static inline void QEvt_refCtr_dec_(QEvt const *me) { typedef uint8_t QEQueueCtr; #elif (QF_EQUEUE_CTR_SIZE == 2U) typedef uint16_t QEQueueCtr; -#elif (QF_EQUEUE_CTR_SIZE == 4U) - typedef uint32_t QEQueueCtr; #else - #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" + #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U" #endif -struct QEvt; // forward declaration +struct QEvt; // forward declartion $declare ${QF::QEQueue} @@ -9167,8 +6340,8 @@ $declare ${QF::QEQueue} #endif #define QF_MPOOL_EL(evType_) struct { \ - QFreeBlock sto_[((sizeof(evType_) - 1U) \ - / sizeof(QFreeBlock)) + 1U]; } + QFreeBlock sto_[((sizeof(evType_) - 1U) / (2U * sizeof(void *))) + 1U]; \ +} $declare ${QF::QFreeBlock} @@ -9219,515 +6392,6 @@ $declare ${QF_EPOOL-impl} #endif // QP_IMPL #endif // QK_H_ - - - - #ifndef QXK_H_ -#define QXK_H_ - -$declare ${QXK::QXK} - -$declare ${QXK::QSchedStatus} - -$declare ${QXK::QXTHREAD_NO_TIMEOUT} - -$declare ${QXK::QXK-base} - -$declare ${QXK::QXThread} - -$declare ${QXK::QXSemaphore} - -$declare ${QXK::QXMutex} - -$declare ${QXK-macros} - -//============================================================================ -// interface used only for internal implementation, but not in applications -#ifdef QP_IMPL - -$declare ${QXK-impl} - -$declare ${QF_EPOOL-impl} - -enum QXK_TimeoutSigs { - QXK_DELAY_SIG = 1, - QXK_TIMEOUT_SIG -}; - -#endif // QP_IMPL - -#endif // QXK_H_ - - - - #ifndef QS_H_ -#define QS_H_ - -#ifndef Q_SPY -#error "Q_SPY must be defined to include qs.h" -#endif - -//============================================================================ -//! @cond INTERNAL - -#ifndef QS_CTR_SIZE -#define QS_CTR_SIZE 2U -#endif - -#ifndef QS_TIME_SIZE -#define QS_TIME_SIZE 4U -#endif - -//! @endcond -//============================================================================ - -$declare ${QS::types} -$declare ${QS::filters} -$declare ${QS-macros} - -//============================================================================ -//! @cond INTERNAL - -typedef struct { - void const * locFilter_AP; //!< @deprecated - uint8_t * buf; - QSCtr end; - QSCtr volatile head; - QSCtr volatile tail; - QSCtr volatile used; - uint8_t volatile seq; - uint8_t volatile chksum; - uint8_t volatile critNest; - uint8_t flags; -} QS_Attr; - -extern QS_Attr QS_priv_; - -void QS_glbFilter_(int_fast16_t const filter); -void QS_locFilter_(int_fast16_t const filter); - -void QS_beginRec_(uint_fast8_t const rec); -void QS_endRec_(void); - -void QS_u8_raw_(uint8_t const d); -void QS_2u8_raw_(uint8_t const d1, uint8_t const d2); -void QS_u16_raw_(uint16_t const d); -void QS_u32_raw_(uint32_t const d); -void QS_u64_raw_(uint64_t const d); -void QS_obj_raw_(void const * const obj); -void QS_str_raw_(char const * const str); - -void QS_u8_fmt_(uint8_t const format, uint8_t const d); -void QS_u16_fmt_(uint8_t const format, uint16_t const d); -void QS_u32_fmt_(uint8_t const format, uint32_t const d); -void QS_u64_fmt_(uint8_t const format, uint64_t const d); -void QS_f32_fmt_(uint8_t const format, float32_t const f); -void QS_f64_fmt_(uint8_t const format, float64_t const d); -void QS_str_fmt_(char const * const str); -void QS_mem_fmt_(uint8_t const * const blk, uint8_t const size); - -void QS_sig_dict_pre_(QSignal const sig, void const * const obj, - char const * const name); -void QS_obj_dict_pre_(void const * const obj, char const * const name); -void QS_obj_arr_dict_pre_(void const * const obj, uint_fast16_t const idx, - char const * const name); -void QS_fun_dict_pre_(QSpyFunPtr const fun, char const * const name); -void QS_usr_dict_pre_(enum_t const rec, char const * const name); -void QS_enum_dict_pre_(enum_t const value, uint8_t const group, - char const * const name); - -void QS_assertion_pre_(char const * const module, int_t const id, - uint32_t const delay); - -void QS_target_info_pre_(uint8_t const isReset); - -//! @endcond -//============================================================================ - -$declare ${QS::QS-TX} - -//============================================================================ -#ifdef Q_UTEST - -$declare ${QS::QUTest} - -#define QUTEST_ON_POST 124 - -//============================================================================ -//! @cond INTERNAL - -typedef struct { - struct QS_TProbe tpBuf[16]; - uint8_t tpNum; - QSTimeCtr testTime; - QPSet readySet; - QPSet readySet_dis; - uint_fast8_t intLock; -} QSTestAttr; - -extern QSTestAttr QS_tstPriv_; - -void QS_test_pause_(void); -uint32_t QS_getTestProbe_(QSpyFunPtr const api); - -//! @endcond -//============================================================================ - -// QP-stub for QUTest -// NOTE: The QP-stub is needed for unit testing QP applications, -// but might NOT be needed for testing QP itself. -#if (Q_UTEST != 0) - -$declare ${QS::QUTest-stub::QHsmDummy} -$declare ${QS::QUTest-stub::QActiveDummy} - -#endif // Q_UTEST != 0 - -#define QS_TEST_PROBE_DEF(fun_) \ - uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_)); - -#define QS_TEST_PROBE(code_) \ - if (qs_tp_ != 0U) { code_ } - -#define QS_TEST_PROBE_ID(id_, code_) \ - if (qs_tp_ == (uint32_t)(id_)) { code_ } - -#define QS_TEST_PAUSE() (QS_test_pause_()) - -#else // Q_UTEST not defined - -// dummy definitions when not building for QUTEST -#define QS_TEST_PROBE_DEF(fun_) -#define QS_TEST_PROBE(code_) -#define QS_TEST_PROBE_ID(id_, code_) -#define QS_TEST_PAUSE() ((void)0) - -#endif // Q_UTEST - -//============================================================================ -//! @cond INTERNAL - -typedef struct { - uint32_t param1; - uint32_t param2; - uint32_t param3; - uint8_t idx; - uint8_t cmdId; -} CmdVar; - -typedef struct { - uint_fast8_t rate; -} TickVar; - -typedef struct { - uint16_t offs; - uint8_t size; - uint8_t num; - uint8_t idx; -} PeekVar; - -typedef struct { - uint32_t data; - uint16_t offs; - uint8_t size; - uint8_t num; - uint8_t idx; - uint8_t fill; -} PokeVar; - -typedef struct { - uint8_t data[16]; - uint8_t idx; - int8_t recId; // global/local -} FltVar; - -typedef struct { - QSObj addr; - uint8_t idx; - uint8_t kind; // see qs.h, enum QSpyObjKind - int8_t recId; -} ObjVar; - -typedef struct { - QEvt *e; - uint8_t *p; - QSignal sig; - uint16_t len; - uint8_t prio; - uint8_t idx; -} EvtVar; - -typedef struct { - void * currObj[8]; - uint8_t * buf; - QSCtr end; - QSCtr volatile head; - QSCtr volatile tail; - uint8_t state; - uint8_t esc; - uint8_t seq; - uint8_t chksum; -#ifdef Q_UTEST - bool inTestLoop; -#endif - union Variant { - CmdVar cmd; - TickVar tick; - PeekVar peek; - PokeVar poke; - FltVar flt; - ObjVar obj; - EvtVar evt; -#ifdef Q_UTEST - struct QS_TProbe tp; -#endif // Q_UTEST - } var; -} QS_RxAttr; - -//! @endcond - -//! @static @private @memberof QS -extern QS_RxAttr QS_rxPriv_; - -//============================================================================ - -$declare ${QS::QS-RX} - -#endif // QS_H_ - - - - #ifndef QS_DUMMY_H_ -#define QS_DUMMY_H_ - -#ifdef Q_SPY - #error "Q_SPY must NOT be defined to include qs_dummy.h" -#endif - -#ifdef Q_UTEST - #error "Q_UTEST must NOT be defined to include qs_dummy.h" -#endif - -#define QS_INIT(arg_) ((uint8_t)1U) -#define QS_EXIT() ((void)0) -#define QS_DUMP() ((void)0) -#define QS_GLB_FILTER(rec_) ((void)0) -#define QS_LOC_FILTER(qsId_) ((void)0) - -#define QS_GET_BYTE(pByte_) ((uint16_t)0xFFFFU) -#define QS_GET_BLOCK(pSize_) ((uint8_t *)0) - -#define QS_BEGIN_ID(rec_, qsId_) if (false) { -#define QS_END() } -#define QS_BEGIN_INCRIT(rec_, qsId_) if (false) { -#define QS_END_INCRIT() } - -#define QS_I8(width_, data_) ((void)0) -#define QS_U8(width_, data_) ((void)0) -#define QS_I16(width_, data_) ((void)0) -#define QS_U16(width_, data_) ((void)0) -#define QS_I32(width_, data_) ((void)0) -#define QS_U32(width_, data_) ((void)0) -#define QS_F32(width_, data_) ((void)0) -#define QS_F64(width_, data_) ((void)0) -#define QS_I64(width_, data_) ((void)0) -#define QS_U64(width_, data_) ((void)0) -#define QS_ENUM(group_, value_) ((void)0) -#define QS_STR(str_) ((void)0) -#define QS_MEM(mem_, size_) ((void)0) -#define QS_SIG(sig_, obj_) ((void)0) -#define QS_OBJ(obj_) ((void)0) -#define QS_FUN(fun_) ((void)0) - -#define QS_SIG_DICTIONARY(sig_, obj_) ((void)0) -#define QS_OBJ_DICTIONARY(obj_) ((void)0) -#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) ((void)0) -#define QS_FUN_DICTIONARY(fun_) ((void)0) -#define QS_USR_DICTIONARY(rec_) ((void)0) -#define QS_ENUM_DICTIONARY(value_, group_) ((void)0) -#define QS_ASSERTION(module_, loc_, delay_) ((void)0) -#define QS_FLUSH() ((void)0) - -#define QS_TEST_PROBE_DEF(fun_) -#define QS_TEST_PROBE(code_) -#define QS_TEST_PROBE_ID(id_, code_) -#define QS_TEST_PAUSE() ((void)0) - -#define QS_OUTPUT() ((void)0) -#define QS_RX_INPUT() ((void)0) -#define QS_ONLY(code_) ((void)0) - -//============================================================================ -// interface used only for internal implementation, but not in applications -#ifdef QP_IMPL - // predefined QS trace records - #define QS_BEGIN_PRE_(rec_, qsId_) if (false) { - #define QS_END_PRE_() } - #define QS_U8_PRE_(data_) ((void)0) - #define QS_2U8_PRE_(data1_, data2_) ((void)0) - #define QS_U16_PRE_(data_) ((void)0) - #define QS_U32_PRE_(data_) ((void)0) - #define QS_TIME_PRE_() ((void)0) - #define QS_SIG_PRE_(sig_) ((void)0) - #define QS_EVS_PRE_(size_) ((void)0) - #define QS_OBJ_PRE_(obj_) ((void)0) - #define QS_FUN_PRE_(fun_) ((void)0) - #define QS_EQC_PRE_(ctr_) ((void)0) - #define QS_MPC_PRE_(ctr_) ((void)0) - #define QS_MPS_PRE_(size_) ((void)0) - #define QS_TEC_PRE_(ctr_) ((void)0) - - #define QS_CRIT_STAT - #define QS_CRIT_ENTRY() ((void)0) - #define QS_CRIT_EXIT() ((void)0) - - #define QS_MEM_SYS() ((void)0) - #define QS_MEM_APP() ((void)0) - - #define QS_TR_CRIT_ENTRY() ((void)0) - #define QS_TR_CRIT_EXIT() ((void)0) - #define QS_TR_ISR_ENTRY(isrnest_, prio_) ((void)0) - #define QS_TR_ISR_EXIT(isrnest_, prio_) ((void)0) -#endif // QP_IMPL - -#endif // QS_DUMMY_H_ - - - - #ifndef QS_PKG_H_ -#define QS_PKG_H_ - -//============================================================================ -//! @cond INTERNAL - -//! QS received record types (RX channel) -enum QSpyRxRecords { - QS_RX_INFO, //!< query Target info (ver, config, tstamp) - QS_RX_COMMAND, //!< execute a user-defined command in the Target - QS_RX_RESET, //!< reset the Target - QS_RX_TICK, //!< call system clock tick in the Target - QS_RX_PEEK, //!< peek Target memory - QS_RX_POKE, //!< poke Target memory - QS_RX_FILL, //!< fill Target memory - QS_RX_TEST_SETUP, //!< test setup - QS_RX_TEST_TEARDOWN, //!< test teardown - QS_RX_TEST_PROBE, //!< set a Test-Probe in the Target - QS_RX_GLB_FILTER, //!< set global filters in the Target - QS_RX_LOC_FILTER, //!< set local filters in the Target - QS_RX_AO_FILTER, //!< set local AO filter in the Target - QS_RX_CURR_OBJ, //!< set the "current-object" in the Target - QS_RX_TEST_CONTINUE, //!< continue a test after QS_TEST_PAUSE() - QS_RX_QUERY_CURR, //!< query the "current object" in the Target - QS_RX_EVENT //!< inject an event to the Target -}; - -//---------------------------------------------------------------------------- -#define QS_FRAME 0x7EU -#define QS_ESC 0x7DU -#define QS_ESC_XOR 0x20U -#define QS_GOOD_CHKSUM 0xFFU - -//---------------------------------------------------------------------------- -#define QS_BEGIN_PRE_(rec_, qsId_) \ - if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \ - QS_beginRec_((uint_fast8_t)(rec_)); -#define QS_END_PRE_() QS_endRec_(); } - -#define QS_U8_PRE_(data_) (QS_u8_raw_((uint8_t)(data_))) -#define QS_2U8_PRE_(data1_, data2_) \ - (QS_2u8_raw_((uint8_t)(data1_), (uint8_t)(data2_))) -#define QS_U16_PRE_(data_) (QS_u16_raw_((uint16_t)(data_))) -#define QS_U32_PRE_(data_) (QS_u32_raw_((uint32_t)(data_))) -#define QS_STR_PRE_(msg_) (QS_str_raw_((msg_))) -#define QS_OBJ_PRE_(obj_) (QS_obj_raw_(obj_)) - -#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U)) - #define QS_SIG_PRE_(sig_) (QS_u8_raw_((uint8_t)sig_)) -#elif (Q_SIGNAL_SIZE == 2U) - #define QS_SIG_PRE_(sig_) (QS_u16_raw_((uint16_t)sig_)) -#elif (Q_SIGNAL_SIZE == 4U) - #define QS_SIG_PRE_(sig_) (QS_u32_raw_((uint32_t)sig_)) -#endif - -#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 2U)) - #define QS_FUN_PRE_(fun_) (QS_u16_raw_((uint16_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 4U) - #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 8U) - #define QS_FUN_PRE_(fun_) (QS_u64_raw_((uint64_t)(fun_))) -#else - #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) -#endif - -//---------------------------------------------------------------------------- -#if (!defined QF_EQUEUE_CTR_SIZE || (QF_EQUEUE_CTR_SIZE == 1U)) - #define QS_EQC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_EQUEUE_CTR_SIZE == 2U) - #define QS_EQC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_EQUEUE_CTR_SIZE == 4U) - #define QS_EQC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) -#endif - -#if (!defined QF_EVENT_SIZ_SIZE || (QF_EVENT_SIZ_SIZE == 1U)) - #define QS_EVS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) -#elif (QF_EVENT_SIZ_SIZE == 2U) - #define QS_EVS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) -#elif (QF_EVENT_SIZ_SIZE == 4U) - #define QS_EVS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) -#endif - -#if (!defined QF_MPOOL_SIZ_SIZE || (QF_MPOOL_SIZ_SIZE == 1U)) - #define QS_MPS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) -#elif (QF_MPOOL_SIZ_SIZE == 2U) - #define QS_MPS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) -#elif (QF_MPOOL_SIZ_SIZE == 4U) - #define QS_MPS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) -#endif - -#if (!defined QF_MPOOL_CTR_SIZE || (QF_MPOOL_CTR_SIZE == 1U)) - #define QS_MPC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_MPOOL_CTR_SIZE == 2U) - #define QS_MPC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_MPOOL_CTR_SIZE == 4U) - #define QS_MPC_PRE_(ctr_) QS_u32_raw_((uint16_t)(ctr_)) -#endif - -#if (!defined QF_TIMEEVT_CTR_SIZE || (QF_TIMEEVT_CTR_SIZE == 1U)) - #define QS_TEC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_TIMEEVT_CTR_SIZE == 2U) - #define QS_TEC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_TIMEEVT_CTR_SIZE == 4U) - #define QS_TEC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) -#endif - -//---------------------------------------------------------------------------- -#define QS_INSERT_BYTE_(b_) \ - buf[head] = (b_); \ - ++head; \ - if (head == end) { \ - head = 0U; \ - } - -#define QS_INSERT_ESC_BYTE_(b_) \ - chksum = (uint8_t)(chksum + (b_)); \ - if (((b_) != QS_FRAME) && ((b_) != QS_ESC)) { \ - QS_INSERT_BYTE_(b_) \ - } \ - else { \ - QS_INSERT_BYTE_(QS_ESC) \ - QS_INSERT_BYTE_((uint8_t)((b_) ^ QS_ESC_XOR))\ - ++QS_priv_.used; \ - } - -//---------------------------------------------------------------------------- -#if (defined Q_UTEST) && (Q_UTEST != 0) -void QS_processTestEvts_(void); -#endif // Q_UTEST != 0 - -//! @endcond -//============================================================================ - -#endif // QS_PKG_H_ @@ -9744,26 +6408,25 @@ extern char const Q_BUILD_TIME[9]; #ifndef QPC_H_ #define QPC_H_ -//============================================================================ #include "qp_port.h" // QP port from the port directory #include "qsafe.h" // QP Functional Safety (FuSa) Subsystem #ifdef Q_SPY // software tracing enabled? #include "qs_port.h" // QS/C port from the port directory #else - #include "qs_dummy.h" // QS/C dummy (inactive) interface + #include "qs_dummy.h" // QS/C dummy interface (inactive) #endif -//============================================================================ #ifndef QP_API_VERSION - -#define QP_API_VERSION 0 - + #define QP_API_VERSION 0 #endif // #ifndef QP_API_VERSION -//============================================================================ // QP API compatibility layer... +//============================================================================ +#if (QP_API_VERSION < 800) -#if (QP_API_VERSION < 740) +#define QM_SUPER_SUB(host_) error "submachines no longer supported" +#define QM_TRAN_EP(tatbl_) error "submachines no longer supported" +#define QM_TRAN_XP(xp_, tatbl_) error "submachines no longer supported" #ifdef QEVT_DYN_CTOR //! @deprecated #QEVT_DYN_CTOR, please use #QEVT_PAR_INIT @@ -9799,6 +6462,12 @@ typedef char char_t; //! number that **always** evaluates the `expr_` expression. #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) +#elif defined Q_UNSAFE + + //! @deprecated general purpose assertion with user-specified ID + //! number that **always** evaluates the `expr_` expression. + #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) + #else // QP FuSa Subsystem enabled //! @deprecated general purpose assertion with user-specified ID @@ -9845,79 +6514,7 @@ static inline void QF_psInit( //! @deprecated instead use: QASM_IS_IN() #define QHsm_isIn(me_, state_) QASM_IS_IN((QAsm *)(me_), (state_)) -//============================================================================ -#if (QP_API_VERSION < 691) - -//! @deprecated enable the QS global filter -#define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_)) - -//! @deprecated disable the QS global filter -#define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_)) - -//! @deprecated enable the QS local filter for SM (state machine) object -#define QS_FILTER_SM_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for AO (active objects) -#define QS_FILTER_AO_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for MP (memory pool) object -#define QS_FILTER_MP_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for EQ (event queue) object -#define QS_FILTER_EQ_OBJ(obj_) ((void)0) - -//! @deprecated enable the QS local filter for TE (time event) object -#define QS_FILTER_TE_OBJ(obj_) ((void)0) - -#ifdef Q_SPY - -//! @deprecated local Filter for a generic application object `obj_`. -#define QS_FILTER_AP_OBJ(obj_) (QS_filt_.loc_AP = (obj_)) - -//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID() -#define QS_BEGIN(rec_, obj_) \ - if (((QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ - & (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \ - && ((QS_priv_.locFilter_AP == (void *)0) \ - || (QS_priv_.locFilter_AP == (obj_)))) \ - { \ - QS_CRIT_STAT \ - QS_CRIT_ENTRY(); \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - -//! @deprecated Output formatted uint32_t to the QS record -#define QS_U32_HEX(width_, data_) \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | QS_HEX_FMT, (data_))) - -#else - -#define QS_FILTER_AP_OBJ(obj_) ((void)0) -#define QS_BEGIN(rec_, obj_) if (false) { -#define QS_U32_HEX(width_, data_) ((void)0) - -#endif - -//============================================================================ -#if (QP_API_VERSION < 660) - -//! @deprecated casting to QXThreadHandler -//! instead use: the new signature of QXThreadHandler and don't cast -#define Q_XTHREAD_CAST(handler_) ((QXThreadHandler)(handler_)) - -//============================================================================ -#if (QP_API_VERSION < 580) - -//! @deprecated instead use: QASM_INIT() -#define QMSM_INIT(me_, par_, qsId_) QASM_INIT((me_), (par_), (qsId_)) - -//! @deprecated instead use: QASM_DISPATCH() -#define QMSM_DISPATCH(me_, e_, qsId_) QASM_DISPATCH((me_), (e_), (qsId_)) - -#endif // QP_API_VERSION < 580 -#endif // QP_API_VERSION < 660 -#endif // QP_API_VERSION < 691 -#endif // QP_API_VERSION < 700 +#endif // QP_API_VERSION < 800 #endif // QPC_H_ @@ -9953,25 +6550,25 @@ $define ${QEP::QEvt::reserved_[4]} ((*(state_))(me, &QEvt_reserved_[(sig_)])) // helper macro to trace state entry -#define QS_STATE_ENTRY_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, (qsId_)) \ - QS_OBJ_PRE_(me); \ - QS_FUN_PRE_(state_); \ - QS_END_PRE_() \ - QS_MEM_APP(); \ +#define QS_STATE_ENTRY_(state_, qsId_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, (qsId_)) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(state_); \ + QS_END_PRE() \ + QS_MEM_APP(); \ QS_CRIT_EXIT() // helper macro to trace state exit -#define QS_STATE_EXIT_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, (qsId_)) \ - QS_OBJ_PRE_(me); \ - QS_FUN_PRE_(state_); \ - QS_END_PRE_() \ - QS_MEM_APP(); \ +#define QS_STATE_EXIT_(state_, qsId_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE(QS_QEP_STATE_EXIT, (qsId_)) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(state_); \ + QS_END_PRE() \ + QS_MEM_APP(); \ QS_CRIT_EXIT() //! @endcond @@ -10288,2246 +6885,13 @@ $define ${QK::QF-cust} $define ${QK::QActive} - - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk") - -$define ${QXK::QXK-base} - -$define ${QXK::QF-cust} - -$define ${QXK::QActive} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk_mutex") - -$define ${QXK::QXMutex} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk_sema") - -$define ${QXK::QXSemaphore} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk_xthr") - -$define ${QXK::QXThread} - - - - - #define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope interface -#include "qstamp.h" // QP time-stamp -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem - -Q_DEFINE_THIS_MODULE("qs") - -// ensure that the predefined records don't overlap the -// user records (application-specific). -Q_ASSERT_STATIC((enum_t)QS_PRE_MAX <= (enum_t)QS_USER); - -$define ${QS::QS-TX} - -#ifndef QF_MEM_ISOLATE -$define ${QS::filters} -#endif - -//============================================================================ -//! @cond INTERNAL - -//! @static @private @memberof QS -QS_Attr QS_priv_; - -//............................................................................ -void QS_glbFilter_(int_fast16_t const filter) { - bool const isRemove = (filter < 0); - uint8_t const rec = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; - switch (rec) { - case (uint8_t)QS_ALL_RECORDS: { - uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); - - // set all global filters (partially unrolled loop) - for (uint_fast8_t i = 0U; - i < Q_DIM(QS_filt_.glb); - i += 4U) - { - QS_filt_.glb[i ] = tmp; - QS_filt_.glb[i + 1U] = tmp; - QS_filt_.glb[i + 2U] = tmp; - QS_filt_.glb[i + 3U] = tmp; - } - if (isRemove) { - // leave the "not maskable" filters enabled, - // see qs.h, Miscellaneous QS records (not maskable) - QS_filt_.glb[0] = 0x01U; - QS_filt_.glb[6] = 0x40U; - QS_filt_.glb[7] = 0xFCU; - QS_filt_.glb[8] = 0x7FU; - } - else { - // never turn the last 3 records on (0x7D, 0x7E, 0x7F) - QS_filt_.glb[15] = 0x1FU; - } - break; - } - case (uint8_t)QS_SM_RECORDS: - if (isRemove) { - QS_filt_.glb[0] &= (uint8_t)(~0xFEU & 0xFFU); - QS_filt_.glb[1] &= (uint8_t)(~0x03U & 0xFFU); - QS_filt_.glb[6] &= (uint8_t)(~0x80U & 0xFFU); - QS_filt_.glb[7] &= (uint8_t)(~0x03U & 0xFFU); - } - else { - QS_filt_.glb[0] |= 0xFEU; - QS_filt_.glb[1] |= 0x03U; - QS_filt_.glb[6] |= 0x80U; - QS_filt_.glb[7] |= 0x03U; - } - break; - case (uint8_t)QS_AO_RECORDS: - if (isRemove) { - QS_filt_.glb[1] &= (uint8_t)(~0xFCU & 0xFFU); - QS_filt_.glb[2] &= (uint8_t)(~0x07U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x20U & 0xFFU); - } - else { - QS_filt_.glb[1] |= 0xFCU; - QS_filt_.glb[2] |= 0x07U; - QS_filt_.glb[5] |= 0x20U; - } - break; - case (uint8_t)QS_EQ_RECORDS: - if (isRemove) { - QS_filt_.glb[2] &= (uint8_t)(~0x78U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x40U & 0xFFU); - } - else { - QS_filt_.glb[2] |= 0x78U; - QS_filt_.glb[5] |= 0x40U; - } - break; - case (uint8_t)QS_MP_RECORDS: - if (isRemove) { - QS_filt_.glb[3] &= (uint8_t)(~0x03U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x80U & 0xFFU); - } - else { - QS_filt_.glb[3] |= 0x03U; - QS_filt_.glb[5] |= 0x80U; - } - break; - case (uint8_t)QS_QF_RECORDS: - if (isRemove) { - QS_filt_.glb[2] &= (uint8_t)(~0x80U & 0xFFU); - QS_filt_.glb[3] &= (uint8_t)(~0xFCU & 0xFFU); - QS_filt_.glb[4] &= (uint8_t)(~0xC0U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_filt_.glb[2] |= 0x80U; - QS_filt_.glb[3] |= 0xFCU; - QS_filt_.glb[4] |= 0xC0U; - QS_filt_.glb[5] |= 0x1FU; - } - break; - case (uint8_t)QS_TE_RECORDS: - if (isRemove) { - QS_filt_.glb[4] &= (uint8_t)(~0x3FU & 0xFFU); - } - else { - QS_filt_.glb[4] |= 0x3FU; - } - break; - case (uint8_t)QS_SC_RECORDS: - if (isRemove) { - QS_filt_.glb[6] &= (uint8_t)(~0x3FU & 0xFFU); - } - else { - QS_filt_.glb[6] |= 0x3FU; - } - break; - case (uint8_t)QS_SEM_RECORDS: - if (isRemove) { - QS_filt_.glb[8] &= (uint8_t)(~0x80U & 0xFFU); - QS_filt_.glb[9] &= (uint8_t)(~0x07U & 0xFFU); - } - else { - QS_filt_.glb[8] |= 0x80U; - QS_filt_.glb[9] |= 0x07U; - } - break; - case (uint8_t)QS_MTX_RECORDS: - if (isRemove) { - QS_filt_.glb[9] &= (uint8_t)(~0xF8U & 0xFFU); - QS_filt_.glb[10] &= (uint8_t)(~0x01U & 0xFFU); - } - else { - QS_filt_.glb[9] |= 0xF8U; - QS_filt_.glb[10] |= 0x01U; - } - break; - case (uint8_t)QS_U0_RECORDS: - if (isRemove) { - QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_filt_.glb[13] &= (uint8_t)(~0x01U & 0xFFU); - } - else { - QS_filt_.glb[12] |= 0xF0U; - QS_filt_.glb[13] |= 0x01U; - } - break; - case (uint8_t)QS_U1_RECORDS: - if (isRemove) { - QS_filt_.glb[13] &= (uint8_t)(~0x3EU & 0xFFU); - } - else { - QS_filt_.glb[13] |= 0x3EU; - } - break; - case (uint8_t)QS_U2_RECORDS: - if (isRemove) { - QS_filt_.glb[13] &= (uint8_t)(~0xC0U & 0xFFU); - QS_filt_.glb[14] &= (uint8_t)(~0x07U & 0xFFU); - } - else { - QS_filt_.glb[13] |= 0xC0U; - QS_filt_.glb[14] |= 0x07U; - } - break; - case (uint8_t)QS_U3_RECORDS: - if (isRemove) { - QS_filt_.glb[14] &= (uint8_t)(~0xF8U & 0xFFU); - } - else { - QS_filt_.glb[14] |= 0xF8U; - } - break; - case (uint8_t)QS_U4_RECORDS: - if (isRemove) { - QS_filt_.glb[15] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_filt_.glb[15] |= 0x1FU; - } - break; - case (uint8_t)QS_UA_RECORDS: - if (isRemove) { - QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_filt_.glb[13] = 0U; - QS_filt_.glb[14] = 0U; - QS_filt_.glb[15] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_filt_.glb[12] |= 0xF0U; - QS_filt_.glb[13] |= 0xFFU; - QS_filt_.glb[14] |= 0xFFU; - QS_filt_.glb[15] |= 0x1FU; - } - break; - default: { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - // QS rec number must be below 0x7D, so no need for escaping - Q_ASSERT_INCRIT(210, rec < 0x7DU); - QS_CRIT_EXIT(); - - if (isRemove) { - QS_filt_.glb[rec >> 3U] - &= (uint8_t)(~(1U << (rec & 7U)) & 0xFFU); - } - else { - QS_filt_.glb[rec >> 3U] - |= (1U << (rec & 7U)); - // never turn the last 3 records on (0x7D, 0x7E, 0x7F) - QS_filt_.glb[15] &= 0x1FU; - } - break; - } - } -} - -//............................................................................ -void QS_locFilter_(int_fast16_t const filter) { - bool const isRemove = (filter < 0); - uint8_t const qsId = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; - uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); - uint_fast8_t i; - switch (qsId) { - case (uint8_t)QS_ALL_IDS: - // set all local filters (partially unrolled loop) - for (i = 0U; i < Q_DIM(QS_filt_.loc); i += 4U) { - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - QS_filt_.loc[i + 2U] = tmp; - QS_filt_.loc[i + 3U] = tmp; - } - break; - case (uint8_t)QS_AO_IDS: - for (i = 0U; i < 8U; i += 4U) { - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - QS_filt_.loc[i + 2U] = tmp; - QS_filt_.loc[i + 3U] = tmp; - } - break; - case (uint8_t)QS_EP_IDS: - i = 8U; - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - break; - case (uint8_t)QS_AP_IDS: - i = 12U; - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - QS_filt_.loc[i + 2U] = tmp; - QS_filt_.loc[i + 3U] = tmp; - break; - default: { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - // qsId must be in range - Q_ASSERT_INCRIT(310, qsId < 0x7FU); - QS_CRIT_EXIT(); - if (isRemove) { - QS_filt_.loc[qsId >> 3U] - &= (uint8_t)(~(1U << (qsId & 7U)) & 0xFFU); - } - else { - QS_filt_.loc[qsId >> 3U] - |= (1U << (qsId & 7U)); - } - break; - } - } - QS_filt_.loc[0] |= 0x01U; // leave QS_ID == 0 always on -} - -//............................................................................ -void QS_beginRec_(uint_fast8_t const rec) { - uint8_t const b = (uint8_t)(QS_priv_.seq + 1U); - uint8_t chksum = 0U; // reset the checksum - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.seq = b; // store the incremented sequence num - QS_priv_.used += 2U; // 2 bytes about to be added - - QS_INSERT_ESC_BYTE_(b) - - chksum = (uint8_t)(chksum + rec); // update checksum - QS_INSERT_BYTE_((uint8_t)rec) // rec byte does not need escaping - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_endRec_(void) { - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - uint8_t b = QS_priv_.chksum; - b ^= 0xFFU; // invert the bits in the checksum - - QS_priv_.used += 2U; // 2 bytes about to be added - - if ((b != QS_FRAME) && (b != QS_ESC)) { - QS_INSERT_BYTE_(b) - } - else { - QS_INSERT_BYTE_(QS_ESC) - QS_INSERT_BYTE_(b ^ QS_ESC_XOR) - ++QS_priv_.used; // account for the ESC byte - } - - QS_INSERT_BYTE_(QS_FRAME) // do not escape this QS_FRAME - - QS_priv_.head = head; // save the head - - // overrun over the old data? - if (QS_priv_.used > end) { - QS_priv_.used = end; // the whole buffer is used - QS_priv_.tail = head; // shift the tail to the old data - } -} - -//............................................................................ -void QS_u8_raw_(uint8_t const d) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.used += 1U; // 1 byte about to be added - QS_INSERT_ESC_BYTE_(d) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_2u8_raw_( - uint8_t const d1, - uint8_t const d2) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.used += 2U; // 2 bytes are about to be added - QS_INSERT_ESC_BYTE_(d1) - QS_INSERT_ESC_BYTE_(d2) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u16_raw_(uint16_t const d) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint16_t x = d; - - QS_priv_.used += 2U; // 2 bytes are about to be added - - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; - QS_INSERT_ESC_BYTE_((uint8_t)x) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u32_raw_(uint32_t const d) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint32_t x = d; - - QS_priv_.used += 4U; // 4 bytes are about to be added - for (uint_fast8_t i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_obj_raw_(void const * const obj) { - #if (QS_OBJ_PTR_SIZE == 1U) - QS_u8_raw_((uint8_t)obj); - #elif (QS_OBJ_PTR_SIZE == 2U) - QS_u16_raw_((uint16_t)obj); - #elif (QS_OBJ_PTR_SIZE == 4U) - QS_u32_raw_((uint32_t)obj); - #elif (QS_OBJ_PTR_SIZE == 8U) - QS_u64_raw_((uint64_t)obj); - #else - QS_u32_raw_((uint32_t)obj); - #endif -} - -//............................................................................ -void QS_str_raw_(char const * const str) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - QSCtr used = QS_priv_.used; // put in a temporary (register) - - for (char const *s = str; *s != '\0'; ++s) { - chksum += (uint8_t)*s; // update checksum - QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping - ++used; - } - QS_INSERT_BYTE_((uint8_t)'\0') // zero-terminate the string - ++used; - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum - QS_priv_.used = used; // save # of used buffer space -} - -//............................................................................ -void QS_u8_fmt_( - uint8_t const format, - uint8_t const d) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.used += 2U; // 2 bytes about to be added - - QS_INSERT_ESC_BYTE_(format) - QS_INSERT_ESC_BYTE_(d) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u16_fmt_( - uint8_t const format, - uint16_t const d) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint8_t b = (uint8_t)d; - - QS_priv_.used += 3U; // 3 bytes about to be added - - QS_INSERT_ESC_BYTE_(format) - QS_INSERT_ESC_BYTE_(b) - b = (uint8_t)(d >> 8U); - QS_INSERT_ESC_BYTE_(b) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u32_fmt_( - uint8_t const format, - uint32_t const d) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint32_t x = d; - - QS_priv_.used += 5U; // 5 bytes about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // insert 4 bytes... - for (uint_fast8_t i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_str_fmt_(char const * const str) { - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - QSCtr used = QS_priv_.used; // put in a temporary (register) - - used += 2U; // account for the format byte and the terminating-0 - QS_INSERT_BYTE_((uint8_t)QS_STR_T) - chksum += (uint8_t)QS_STR_T; - - for (char const *s = str; *s != '\0'; ++s) { - QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping - chksum += (uint8_t)*s; // update checksum - ++used; - } - QS_INSERT_BYTE_(0U) // zero-terminate the string - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum - QS_priv_.used = used; // save # of used buffer space -} - -//............................................................................ -void QS_mem_fmt_( - uint8_t const * const blk, - uint8_t const size) -{ - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint8_t const *pb = blk; - - QS_priv_.used += ((QSCtr)size + 2U); // size+2 bytes to be added - - QS_INSERT_BYTE_((uint8_t)QS_MEM_T) - chksum += (uint8_t)QS_MEM_T; - - QS_INSERT_ESC_BYTE_(size) - // output the 'size' # bytes - for (uint8_t len = size; len > 0U; --len) { - QS_INSERT_ESC_BYTE_(*pb) - ++pb; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_sig_dict_pre_( - QSignal const sig, - void const * const obj, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_SIG_DICT); - QS_SIG_PRE_(sig); - QS_OBJ_PRE_(obj); - QS_STR_PRE_((*name == '&') ? &name[1] : name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_obj_dict_pre_( - void const * const obj, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); - QS_OBJ_PRE_(obj); - QS_STR_PRE_((*name == '&') ? &name[1] : name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_obj_arr_dict_pre_( - void const * const obj, - uint_fast16_t const idx, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(400, idx < 1000U); - QS_CRIT_EXIT(); - - // format idx into a char buffer as "xxx\0" - uint8_t idx_str[4]; - uint_fast16_t tmp = idx; - uint8_t i; - idx_str[3] = 0U; // zero-terminate - idx_str[2] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); - tmp /= 10U; - idx_str[1] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); - if (idx_str[1] == (uint8_t)'0') { - i = 2U; - } - else { - tmp /= 10U; - idx_str[0] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); - if (idx_str[0] == (uint8_t)'0') { - i = 1U; - } - else { - i = 0U; - } - } - - uint8_t j = ((*name == '&') ? 1U : 0U); - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); - QS_OBJ_PRE_(obj); - for (; name[j] != '\0'; ++j) { - QS_U8_PRE_(name[j]); - if (name[j] == '[') { - ++j; - break; - } - } - for (; idx_str[i] != 0U; ++i) { - QS_U8_PRE_(idx_str[i]); - } - // skip chars until ']' - for (; name[j] != '\0'; ++j) { - if (name[j] == ']') { - break; - } - } - for (; name[j] != '\0'; ++j) { - QS_U8_PRE_(name[j]); - } - QS_U8_PRE_(0U); // zero-terminate - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_fun_dict_pre_( - QSpyFunPtr const fun, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_FUN_DICT); - QS_FUN_PRE_(fun); - QS_STR_PRE_((*name == '&') ? &name[1] : name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_usr_dict_pre_( - enum_t const rec, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_USR_DICT); - QS_U8_PRE_(rec); - QS_STR_PRE_(name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_enum_dict_pre_( - enum_t const value, - uint8_t const group, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_ENUM_DICT); - QS_2U8_PRE_(value, group); - QS_STR_PRE_(name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_assertion_pre_( - char const * const module, - int_t const id, - uint32_t const delay) -{ - // NOTE: called in a critical section - - QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); - QS_TIME_PRE_(); - QS_U16_PRE_(id); - QS_STR_PRE_((module != (char *)0) ? module : "?"); - QS_endRec_(); - QS_onFlush(); - - // busy-wait until all QS data makes it over to the host - for (uint32_t volatile delay_ctr = delay; - delay_ctr > 0U; --delay_ctr) - {} - QS_onCleanup(); -} - -//............................................................................ -void QS_target_info_pre_(uint8_t const isReset) { - // NOTE: called in a critical section - - static uint8_t const ZERO = (uint8_t)'0'; - static uint8_t const * const TIME = (uint8_t const *)&Q_BUILD_TIME[0]; - static uint8_t const * const DATE = (uint8_t const *)&Q_BUILD_DATE[0]; - static union { - uint16_t u16; - uint8_t u8[2]; - } endian_test; - - endian_test.u16 = 0x0102U; - QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); - QS_U8_PRE_(isReset); - QS_U16_PRE_(((endian_test.u8[0] == 0x01U) // big endian? - ? (0x8000U | QP_VERSION) - : QP_VERSION)); // target endianness + version number - - // send the object sizes... - QS_U8_PRE_(Q_SIGNAL_SIZE | (QF_EVENT_SIZ_SIZE << 4U)); - -#ifdef QF_EQUEUE_CTR_SIZE - QS_U8_PRE_(QF_EQUEUE_CTR_SIZE | (QF_TIMEEVT_CTR_SIZE << 4U)); -#else - QS_U8_PRE_(QF_TIMEEVT_CTR_SIZE << 4U); -#endif // QF_EQUEUE_CTR_SIZE - -#ifdef QF_MPOOL_CTR_SIZE - QS_U8_PRE_(QF_MPOOL_SIZ_SIZE | (QF_MPOOL_CTR_SIZE << 4U)); -#else - QS_U8_PRE_(0U); -#endif // QF_MPOOL_CTR_SIZE - - QS_U8_PRE_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U)); - QS_U8_PRE_(QS_TIME_SIZE); - - // send the bounds... - QS_U8_PRE_(QF_MAX_ACTIVE); - QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U)); - - // send the build time in three bytes (sec, min, hour)... - QS_U8_PRE_((10U * (uint8_t)(TIME[6] - ZERO)) - + (uint8_t)(TIME[7] - ZERO)); - QS_U8_PRE_((10U * (uint8_t)(TIME[3] - ZERO)) - + (uint8_t)(TIME[4] - ZERO)); - if (Q_BUILD_TIME[0] == ' ') { - QS_U8_PRE_(TIME[1] - ZERO); - } - else { - QS_U8_PRE_((10U * (uint8_t)(TIME[0] - ZERO)) - + (uint8_t)(TIME[1] - ZERO)); - } - - // send the build date in three bytes (day, month, year) ... - if (Q_BUILD_DATE[4] == ' ') { - QS_U8_PRE_(DATE[5] - ZERO); - } - else { - QS_U8_PRE_((10U * (uint8_t)(DATE[4] - ZERO)) - + (uint8_t)(DATE[5] - ZERO)); - } - // convert the 3-letter month to a number 1-12 ... - uint8_t b; - switch ((int_t)DATE[0] + (int_t)DATE[1] + (int_t)DATE[2]) { - case (int_t)'J' + (int_t)'a' + (int_t)'n': - b = 1U; - break; - case (int_t)'F' + (int_t)'e' + (int_t)'b': - b = 2U; - break; - case (int_t)'M' + (int_t)'a' + (int_t)'r': - b = 3U; - break; - case (int_t)'A' + (int_t)'p' + (int_t)'r': - b = 4U; - break; - case (int_t)'M' + (int_t)'a' + (int_t)'y': - b = 5U; - break; - case (int_t)'J' + (int_t)'u' + (int_t)'n': - b = 6U; - break; - case (int_t)'J' + (int_t)'u' + (int_t)'l': - b = 7U; - break; - case (int_t)'A' + (int_t)'u' + (int_t)'g': - b = 8U; - break; - case (int_t)'S' + (int_t)'e' + (int_t)'p': - b = 9U; - break; - case (int_t)'O' + (int_t)'c' + (int_t)'t': - b = 10U; - break; - case (int_t)'N' + (int_t)'o' + (int_t)'v': - b = 11U; - break; - case (int_t)'D' + (int_t)'e' + (int_t)'c': - b = 12U; - break; - default: - b = 0U; - break; - } - QS_U8_PRE_(b); // store the month - QS_U8_PRE_((10U * (uint8_t)(DATE[9] - ZERO)) - + (uint8_t)(DATE[10] - ZERO)); - QS_endRec_(); -} - -//! @endcond - - - - #define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope internal interface - -//============================================================================ -//! @cond INTERNAL - -//! @static @private @memberof QS -void QS_u64_raw_(uint64_t const d) { - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - - QS_priv_.used += 8U; // 8 bytes are about to be added - uint64_t u64 = d; - for (uint_fast8_t i = 8U; i != 0U; --i) { - uint8_t const b = (uint8_t)u64; - QS_INSERT_ESC_BYTE_(b) - u64 >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @static @private @memberof QS -void QS_u64_fmt_( - uint8_t const format, - uint64_t const d) -{ - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - - QS_priv_.used += 9U; // 9 bytes are about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // output 8 bytes of data... - uint64_t u64 = d; - for (uint_fast8_t i = 8U; i != 0U; --i) { - uint8_t const b = (uint8_t)u64; - QS_INSERT_ESC_BYTE_(b) - u64 >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @endcond - - - - #define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope internal interface - -//============================================================================ -//! @cond INTERNAL - -//! @static @private @memberof QS -void QS_f32_fmt_( - uint8_t const format, - float32_t const f) -{ - union F32Rep { - float32_t f; - uint32_t u; - } fu32; // the internal binary representation - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - uint_fast8_t i; - - fu32.f = f; // assign the binary representation - - QS_priv_.used += 5U; // 5 bytes about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // insert 4 bytes... - for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu32.u) - fu32.u >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @static @private @memberof QS -void QS_f64_fmt_( - uint8_t const format, - float64_t const d) -{ - union F64Rep { - float64_t d; - uint32_t u[2]; - } fu64; // the internal binary representation - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - uint32_t i; - - // static constant union to detect endianness of the machine - static union U32Rep { - uint32_t u32; - uint8_t u8; - } const endian = { 1U }; - - fu64.d = d; // assign the binary representation - - // is this a big-endian machine? - if (endian.u8 == 0U) { - // swap fu64.u[0] <-> fu64.u[1]... - i = fu64.u[0]; - fu64.u[0] = fu64.u[1]; - fu64.u[1] = i; - } - - QS_priv_.used += 9U; // 9 bytes about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // output 4 bytes from fu64.u[0]... - for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[0]) - fu64.u[0] >>= 8U; - } - - // output 4 bytes from fu64.u[1]... - for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[1]) - fu64.u[1] >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @endcond - - - - #define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem - -//============================================================================ -//! @cond INTERNAL - -Q_DEFINE_THIS_MODULE("qs_rx") - -enum { - ERROR_STATE, - WAIT4_SEQ, - WAIT4_REC, - WAIT4_INFO_FRAME, - WAIT4_CMD_ID, - WAIT4_CMD_PARAM1, - WAIT4_CMD_PARAM2, - WAIT4_CMD_PARAM3, - WAIT4_CMD_FRAME, - WAIT4_RESET_FRAME, - WAIT4_TICK_RATE, - WAIT4_TICK_FRAME, - WAIT4_PEEK_OFFS, - WAIT4_PEEK_SIZE, - WAIT4_PEEK_NUM, - WAIT4_PEEK_FRAME, - WAIT4_POKE_OFFS, - WAIT4_POKE_SIZE, - WAIT4_POKE_NUM, - WAIT4_POKE_DATA, - WAIT4_POKE_FRAME, - WAIT4_FILL_DATA, - WAIT4_FILL_FRAME, - WAIT4_FILTER_LEN, - WAIT4_FILTER_DATA, - WAIT4_FILTER_FRAME, - WAIT4_OBJ_KIND, - WAIT4_OBJ_ADDR, - WAIT4_OBJ_FRAME, - WAIT4_QUERY_KIND, - WAIT4_QUERY_FRAME, - WAIT4_EVT_PRIO, - WAIT4_EVT_SIG, - WAIT4_EVT_LEN, - WAIT4_EVT_PAR, - WAIT4_EVT_FRAME - -#ifdef Q_UTEST - , - WAIT4_TEST_SETUP_FRAME, - WAIT4_TEST_TEARDOWN_FRAME, - WAIT4_TEST_PROBE_DATA, - WAIT4_TEST_PROBE_ADDR, - WAIT4_TEST_PROBE_FRAME, - WAIT4_TEST_CONTINUE_FRAME -#endif // Q_UTEST -}; - -// static helper functions... -static void QS_rxParseData_(uint8_t const b); -static void QS_rxHandleGoodFrame_(uint8_t const state); -static void QS_rxHandleBadFrame_(uint8_t const state); -static void QS_rxReportAck_(int8_t const recId); -static void QS_rxReportError_(int8_t const code); -static void QS_rxReportDone_(int8_t const recId); -static void QS_queryCurrObj(uint8_t const obj_kind); -static void QS_rxPoke_(void); - -//! Internal QS-RX macro to encapsulate tran. in the QS-RX FSM -#define QS_RX_TRAN_(target_) (QS_rxPriv_.state = (uint8_t)(target_)) - -#ifndef QF_MEM_ISOLATE -//! @static @private @memberof QS -QS_RxAttr QS_rxPriv_; -#endif // QF_MEM_ISOLATE - -//! @endcond -//============================================================================ - -$define ${QS::QS-RX} - -//============================================================================ -//! @cond INTERNAL - -static void QS_rxParseData_(uint8_t const b) { - switch (QS_rxPriv_.state) { - case (uint8_t)WAIT4_SEQ: { - ++QS_rxPriv_.seq; - if (QS_rxPriv_.seq != b) { - QS_rxReportError_(0x42); - QS_rxPriv_.seq = b; // update the sequence - } - QS_RX_TRAN_(WAIT4_REC); - break; - } - case (uint8_t)WAIT4_REC: { - switch (b) { - case (uint8_t)QS_RX_INFO: - QS_RX_TRAN_(WAIT4_INFO_FRAME); - break; - case (uint8_t)QS_RX_COMMAND: - QS_RX_TRAN_(WAIT4_CMD_ID); - break; - case (uint8_t)QS_RX_RESET: - QS_RX_TRAN_(WAIT4_RESET_FRAME); - break; - case (uint8_t)QS_RX_TICK: - QS_RX_TRAN_(WAIT4_TICK_RATE); - break; - case (uint8_t)QS_RX_PEEK: - if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { - QS_rxPriv_.var.peek.offs = 0U; - QS_rxPriv_.var.peek.idx = 0U; - QS_RX_TRAN_(WAIT4_PEEK_OFFS); - } - else { - QS_rxReportError_((int8_t)QS_RX_PEEK); - QS_RX_TRAN_(ERROR_STATE); - } - break; - case (uint8_t)QS_RX_POKE: // intentionally fall-through - case (uint8_t)QS_RX_FILL: - QS_rxPriv_.var.poke.fill = - ((b == (uint8_t)QS_RX_FILL) ? 1U : 0U); - if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { - QS_rxPriv_.var.poke.offs = 0U; - QS_rxPriv_.var.poke.idx = 0U; - QS_RX_TRAN_(WAIT4_POKE_OFFS); - } - else { - QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - case (uint8_t)QS_RX_GLB_FILTER: // intentionally fall-through - case (uint8_t)QS_RX_LOC_FILTER: - QS_rxPriv_.var.flt.recId = (int8_t)b; - QS_RX_TRAN_(WAIT4_FILTER_LEN); - break; - case (uint8_t)QS_RX_AO_FILTER: // intentionally fall-through - case (uint8_t)QS_RX_CURR_OBJ: - QS_rxPriv_.var.obj.recId = (int8_t)b; - QS_RX_TRAN_(WAIT4_OBJ_KIND); - break; - case (uint8_t)QS_RX_QUERY_CURR: - QS_rxPriv_.var.obj.recId = (int8_t)QS_RX_QUERY_CURR; - QS_RX_TRAN_(WAIT4_QUERY_KIND); - break; - case (uint8_t)QS_RX_EVENT: - QS_RX_TRAN_(WAIT4_EVT_PRIO); - break; - -#ifdef Q_UTEST - case (uint8_t)QS_RX_TEST_SETUP: - QS_RX_TRAN_(WAIT4_TEST_SETUP_FRAME); - break; - case (uint8_t)QS_RX_TEST_TEARDOWN: - QS_RX_TRAN_(WAIT4_TEST_TEARDOWN_FRAME); - break; - case (uint8_t)QS_RX_TEST_CONTINUE: - QS_RX_TRAN_(WAIT4_TEST_CONTINUE_FRAME); - break; - case (uint8_t)QS_RX_TEST_PROBE: - if (QS_tstPriv_.tpNum - < (uint8_t)(sizeof(QS_tstPriv_.tpBuf) - / sizeof(QS_tstPriv_.tpBuf[0]))) - { - QS_rxPriv_.var.tp.data = 0U; - QS_rxPriv_.var.tp.idx = 0U; - QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA); - } - else { // the # Test-Probes exceeded - QS_rxReportError_((int8_t)QS_RX_TEST_PROBE); - QS_RX_TRAN_(ERROR_STATE); - } - break; -#endif // Q_UTEST - - default: - QS_rxReportError_(0x43); - QS_RX_TRAN_(ERROR_STATE); - break; - } - break; - } - case (uint8_t)WAIT4_INFO_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_CMD_ID: { - QS_rxPriv_.var.cmd.cmdId = b; - QS_rxPriv_.var.cmd.idx = 0U; - QS_rxPriv_.var.cmd.param1 = 0U; - QS_rxPriv_.var.cmd.param2 = 0U; - QS_rxPriv_.var.cmd.param3 = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM1); - break; - } - case (uint8_t)WAIT4_CMD_PARAM1: { - QS_rxPriv_.var.cmd.param1 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx); - QS_rxPriv_.var.cmd.idx += 8U; - if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) { - QS_rxPriv_.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM2); - } - break; - } - case (uint8_t)WAIT4_CMD_PARAM2: { - QS_rxPriv_.var.cmd.param2 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx); - QS_rxPriv_.var.cmd.idx += 8U; - if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) { - QS_rxPriv_.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM3); - } - break; - } - case (uint8_t)WAIT4_CMD_PARAM3: { - QS_rxPriv_.var.cmd.param3 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx); - QS_rxPriv_.var.cmd.idx += 8U; - if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) { - QS_rxPriv_.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_FRAME); - } - break; - } - case (uint8_t)WAIT4_CMD_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_RESET_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TICK_RATE: { - QS_rxPriv_.var.tick.rate = (uint_fast8_t)b; - QS_RX_TRAN_(WAIT4_TICK_FRAME); - break; - } - case (uint8_t)WAIT4_TICK_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_PEEK_OFFS: { - if (QS_rxPriv_.var.peek.idx == 0U) { - QS_rxPriv_.var.peek.offs = (uint16_t)b; - QS_rxPriv_.var.peek.idx += 8U; - } - else { - QS_rxPriv_.var.peek.offs |= (uint16_t)((uint16_t)b << 8U); - QS_RX_TRAN_(WAIT4_PEEK_SIZE); - } - break; - } - case (uint8_t)WAIT4_PEEK_SIZE: { - if ((b == 1U) || (b == 2U) || (b == 4U)) { - QS_rxPriv_.var.peek.size = b; - QS_RX_TRAN_(WAIT4_PEEK_NUM); - } - else { - QS_rxReportError_((int8_t)QS_RX_PEEK); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_PEEK_NUM: { - QS_rxPriv_.var.peek.num = b; - QS_RX_TRAN_(WAIT4_PEEK_FRAME); - break; - } - case (uint8_t)WAIT4_PEEK_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_POKE_OFFS: { - if (QS_rxPriv_.var.poke.idx == 0U) { - QS_rxPriv_.var.poke.offs = (uint16_t)b; - QS_rxPriv_.var.poke.idx = 1U; - } - else { - QS_rxPriv_.var.poke.offs |= (uint16_t)((uint16_t)b << 8U); - QS_RX_TRAN_(WAIT4_POKE_SIZE); - } - break; - } - case (uint8_t)WAIT4_POKE_SIZE: { - if ((b == 1U) || (b == 2U) || (b == 4U)) { - QS_rxPriv_.var.poke.size = b; - QS_RX_TRAN_(WAIT4_POKE_NUM); - } - else { - QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_POKE_NUM: { - if (b > 0U) { - QS_rxPriv_.var.poke.num = b; - QS_rxPriv_.var.poke.data = 0U; - QS_rxPriv_.var.poke.idx = 0U; - QS_RX_TRAN_((QS_rxPriv_.var.poke.fill != 0U) - ? WAIT4_FILL_DATA - : WAIT4_POKE_DATA); - } - else { - QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_FILL_DATA: { - QS_rxPriv_.var.poke.data |= ((uint32_t)b << QS_rxPriv_.var.poke.idx); - QS_rxPriv_.var.poke.idx += 8U; - if ((uint8_t)(QS_rxPriv_.var.poke.idx >> 3U) == QS_rxPriv_.var.poke.size) { - QS_RX_TRAN_(WAIT4_FILL_FRAME); - } - break; - } - case (uint8_t)WAIT4_POKE_DATA: { - QS_rxPriv_.var.poke.data |= ((uint32_t)b << QS_rxPriv_.var.poke.idx); - QS_rxPriv_.var.poke.idx += 8U; - if ((uint8_t)(QS_rxPriv_.var.poke.idx >> 3U) == QS_rxPriv_.var.poke.size) { - QS_rxPoke_(); - --QS_rxPriv_.var.poke.num; - if (QS_rxPriv_.var.poke.num == 0U) { - QS_RX_TRAN_(WAIT4_POKE_FRAME); - } - } - break; - } - case (uint8_t)WAIT4_FILL_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case WAIT4_POKE_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_FILTER_LEN: { - if (b == sizeof(QS_rxPriv_.var.flt.data)) { - QS_rxPriv_.var.flt.idx = 0U; - QS_RX_TRAN_(WAIT4_FILTER_DATA); - } - else { - QS_rxReportError_(QS_rxPriv_.var.flt.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_FILTER_DATA: { - QS_rxPriv_.var.flt.data[QS_rxPriv_.var.flt.idx] = b; - ++QS_rxPriv_.var.flt.idx; - if (QS_rxPriv_.var.flt.idx == sizeof(QS_rxPriv_.var.flt.data)) { - QS_RX_TRAN_(WAIT4_FILTER_FRAME); - } - break; - } - case (uint8_t)WAIT4_FILTER_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_OBJ_KIND: { - if (b <= (uint8_t)SM_AO_OBJ) { - QS_rxPriv_.var.obj.kind = b; - QS_rxPriv_.var.obj.addr = 0U; - QS_rxPriv_.var.obj.idx = 0U; - QS_RX_TRAN_(WAIT4_OBJ_ADDR); - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_OBJ_ADDR: { - QS_rxPriv_.var.obj.addr |= ((QSObj)b << QS_rxPriv_.var.obj.idx); - QS_rxPriv_.var.obj.idx += 8U; - if (QS_rxPriv_.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) { - QS_RX_TRAN_(WAIT4_OBJ_FRAME); - } - break; - } - case (uint8_t)WAIT4_OBJ_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_QUERY_KIND: { - if (b < (uint8_t)MAX_OBJ) { - QS_rxPriv_.var.obj.kind = b; - QS_RX_TRAN_(WAIT4_QUERY_FRAME); - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_QUERY_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_EVT_PRIO: { - QS_rxPriv_.var.evt.prio = b; - QS_rxPriv_.var.evt.sig = 0U; - QS_rxPriv_.var.evt.idx = 0U; - QS_RX_TRAN_(WAIT4_EVT_SIG); - break; - } - case (uint8_t)WAIT4_EVT_SIG: { - QS_rxPriv_.var.evt.sig |= (QSignal)((uint32_t)b << QS_rxPriv_.var.evt.idx); - QS_rxPriv_.var.evt.idx += 8U; - if (QS_rxPriv_.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) { - QS_rxPriv_.var.evt.len = 0U; - QS_rxPriv_.var.evt.idx = 0U; - QS_RX_TRAN_(WAIT4_EVT_LEN); - } - break; - } - case (uint8_t)WAIT4_EVT_LEN: { - QS_rxPriv_.var.evt.len |= (uint16_t)((uint32_t)b << QS_rxPriv_.var.evt.idx); - QS_rxPriv_.var.evt.idx += 8U; - if (QS_rxPriv_.var.evt.idx == (8U * 2U)) { - if ((QS_rxPriv_.var.evt.len + sizeof(QEvt)) - <= QF_poolGetMaxBlockSize()) - { - // report Ack before generating any other QS records - QS_rxReportAck_((int8_t)QS_RX_EVENT); - - QS_rxPriv_.var.evt.e = QF_newX_( - ((uint_fast16_t)QS_rxPriv_.var.evt.len + sizeof(QEvt)), - 0U, // margin - (enum_t)QS_rxPriv_.var.evt.sig); - if (QS_rxPriv_.var.evt.e != (QEvt *)0) { // evt allocated? - QS_rxPriv_.var.evt.p = (uint8_t *)QS_rxPriv_.var.evt.e; - QS_rxPriv_.var.evt.p = &QS_rxPriv_.var.evt.p[sizeof(QEvt)]; - if (QS_rxPriv_.var.evt.len > 0U) { - QS_RX_TRAN_(WAIT4_EVT_PAR); - } - else { - QS_RX_TRAN_(WAIT4_EVT_FRAME); - } - } - else { - QS_rxReportError_((int8_t)QS_RX_EVENT); - QS_RX_TRAN_(ERROR_STATE); - } - } - else { - QS_rxReportError_((int8_t)QS_RX_EVENT); - QS_RX_TRAN_(ERROR_STATE); - } - } - break; - } - case (uint8_t)WAIT4_EVT_PAR: { // event parameters - *QS_rxPriv_.var.evt.p = b; - ++QS_rxPriv_.var.evt.p; - --QS_rxPriv_.var.evt.len; - if (QS_rxPriv_.var.evt.len == 0U) { - QS_RX_TRAN_(WAIT4_EVT_FRAME); - } - break; - } - case (uint8_t)WAIT4_EVT_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - -#ifdef Q_UTEST - case (uint8_t)WAIT4_TEST_SETUP_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TEST_TEARDOWN_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TEST_CONTINUE_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TEST_PROBE_DATA: { - QS_rxPriv_.var.tp.data |= ((uint32_t)b << QS_rxPriv_.var.tp.idx); - QS_rxPriv_.var.tp.idx += 8U; - if (QS_rxPriv_.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) { - QS_rxPriv_.var.tp.addr = 0U; - QS_rxPriv_.var.tp.idx = 0U; - QS_RX_TRAN_(WAIT4_TEST_PROBE_ADDR); - } - break; - } - case (uint8_t)WAIT4_TEST_PROBE_ADDR: { - QS_rxPriv_.var.tp.addr |= ((QSFun)b << QS_rxPriv_.var.tp.idx); - QS_rxPriv_.var.tp.idx += 8U; - if (QS_rxPriv_.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) { - QS_RX_TRAN_(WAIT4_TEST_PROBE_FRAME); - } - break; - } - case (uint8_t)WAIT4_TEST_PROBE_FRAME: { - // keep ignoring the data until a frame is collected - break; - } -#endif // Q_UTEST - - case (uint8_t)ERROR_STATE: { - // keep ignoring the data until a good frame is collected - break; - } - default: { // unexpected or unimplemented state - QS_rxReportError_(0x45); - QS_RX_TRAN_(ERROR_STATE); - break; - } - } -} - -//............................................................................ -static void QS_rxHandleGoodFrame_(uint8_t const state) { - uint8_t i; - uint8_t *ptr; - QS_CRIT_STAT - - switch (state) { - case WAIT4_INFO_FRAME: { - // no need to report Ack or Done - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_target_info_pre_(0U); // send only Target info - QS_MEM_APP(); - QS_CRIT_EXIT(); - break; - } - case WAIT4_RESET_FRAME: { - // no need to report Ack or Done, because Target resets - QS_onReset(); // reset the Target - break; - } - case WAIT4_CMD_PARAM1: // intentionally fall-through - case WAIT4_CMD_PARAM2: // intentionally fall-through - case WAIT4_CMD_PARAM3: // intentionally fall-through - case WAIT4_CMD_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_COMMAND); - QS_onCommand(QS_rxPriv_.var.cmd.cmdId, QS_rxPriv_.var.cmd.param1, - QS_rxPriv_.var.cmd.param2, QS_rxPriv_.var.cmd.param3); -#ifdef Q_UTEST - #if Q_UTEST != 0 - QS_processTestEvts_(); // process all events produced - #endif // Q_UTEST != 0 -#endif // Q_UTEST - QS_rxReportDone_((int8_t)QS_RX_COMMAND); - break; - } - case WAIT4_TICK_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TICK); -#ifdef Q_UTEST - QTimeEvt_tick1_((uint_fast8_t)QS_rxPriv_.var.tick.rate, &QS_rxPriv_); - #if Q_UTEST != 0 - QS_processTestEvts_(); // process all events produced - #endif // Q_UTEST != 0 -#else - QTimeEvt_tick_((uint_fast8_t)QS_rxPriv_.var.tick.rate, &QS_rxPriv_); -#endif // Q_UTEST - QS_rxReportDone_((int8_t)QS_RX_TICK); - break; - } - case WAIT4_PEEK_FRAME: { - // no need to report Ack or Done - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_PEEK_DATA); - ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[QS_rxPriv_.var.peek.offs]; - QS_TIME_PRE_(); // timestamp - QS_U16_PRE_(QS_rxPriv_.var.peek.offs); // data offset - QS_U8_PRE_(QS_rxPriv_.var.peek.size); // data size - QS_U8_PRE_(QS_rxPriv_.var.peek.num); // # data items - for (i = 0U; i < QS_rxPriv_.var.peek.num; ++i) { - switch (QS_rxPriv_.var.peek.size) { - case 1: - QS_U8_PRE_(ptr[i]); - break; - case 2: - QS_U16_PRE_(((uint16_t *)ptr)[i]); - break; - case 4: - QS_U32_PRE_(((uint32_t *)ptr)[i]); - break; - default: - // intentionally empty - break; - } - } - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - - QS_REC_DONE(); // user callback (if defined) - break; - } - case WAIT4_POKE_DATA: { - // received less than expected poke data items - QS_rxReportError_((int8_t)QS_RX_POKE); - break; - } - case WAIT4_POKE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_POKE); - // no need to report done - break; - } - case WAIT4_FILL_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_FILL); - ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[QS_rxPriv_.var.poke.offs]; - for (i = 0U; i < QS_rxPriv_.var.poke.num; ++i) { - switch (QS_rxPriv_.var.poke.size) { - case 1: - ptr[i] = (uint8_t)QS_rxPriv_.var.poke.data; - break; - case 2: - ((uint16_t *)ptr)[i] - = (uint16_t)QS_rxPriv_.var.poke.data; - break; - case 4: - ((uint32_t *)ptr)[i] = QS_rxPriv_.var.poke.data; - break; - default: - // intentionally empty - break; - } - } - break; - } - case WAIT4_FILTER_FRAME: { - QS_rxReportAck_(QS_rxPriv_.var.flt.recId); - - // apply the received filters - if (QS_rxPriv_.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) { - for (i = 0U; i < Q_DIM(QS_filt_.glb); ++i) { - QS_filt_.glb[i] = QS_rxPriv_.var.flt.data[i]; - } - // leave the "not maskable" filters enabled, - // see qs.h, Miscellaneous QS records (not maskable) - QS_filt_.glb[0] |= 0x01U; - QS_filt_.glb[7] |= 0xFCU; - QS_filt_.glb[8] |= 0x7FU; - - // never enable the last 3 records (0x7D, 0x7E, 0x7F) - QS_filt_.glb[15] &= 0x1FU; - } - else if (QS_rxPriv_.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) { - for (i = 0U; i < Q_DIM(QS_filt_.loc); ++i) { - QS_filt_.loc[i] = QS_rxPriv_.var.flt.data[i]; - } - // leave QS_ID == 0 always on - QS_filt_.loc[0] |= 0x01U; - } - else { - QS_rxReportError_(QS_rxPriv_.var.flt.recId); - } - // no need to report Done - break; - } - case WAIT4_OBJ_FRAME: { - i = QS_rxPriv_.var.obj.kind; - if (i < (uint8_t)MAX_OBJ) { - if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { - QS_rxPriv_.currObj[i] = (void *)QS_rxPriv_.var.obj.addr; - QS_rxReportAck_((int8_t)QS_RX_CURR_OBJ); - } - else if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_AO_FILTER) { - if (QS_rxPriv_.var.obj.addr != 0U) { - int_fast16_t const filter = - (int_fast16_t)((QActive *)QS_rxPriv_.var.obj.addr)->prio; - QS_locFilter_((i == 0U) ? filter :-filter); - QS_rxReportAck_((int8_t)QS_RX_AO_FILTER); - } - else { - QS_rxReportError_((int8_t)QS_RX_AO_FILTER); - } - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - } - } - // both SM and AO - else if (i == (uint8_t)SM_AO_OBJ) { - if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { - QS_rxPriv_.currObj[SM_OBJ] = (void *)QS_rxPriv_.var.obj.addr; - QS_rxPriv_.currObj[AO_OBJ] = (void *)QS_rxPriv_.var.obj.addr; - } - QS_rxReportAck_(QS_rxPriv_.var.obj.recId); - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - } - break; - } - case WAIT4_QUERY_FRAME: { - QS_queryCurrObj(QS_rxPriv_.var.obj.kind); - break; - } - case WAIT4_EVT_FRAME: { - // NOTE: Ack was already reported in the WAIT4_EVT_LEN state -#ifdef Q_UTEST - QS_onTestEvt(QS_rxPriv_.var.evt.e); // adjust the event, if needed -#endif // Q_UTEST - i = 0U; // use 'i' as status, 0 == success,no-recycle - - if (QS_rxPriv_.var.evt.prio == 0U) { // publish - QActive_publish_(QS_rxPriv_.var.evt.e, &QS_rxPriv_, 0U); - } - else if (QS_rxPriv_.var.evt.prio < QF_MAX_ACTIVE) { - if (!QACTIVE_POST_X(QActive_registry_[QS_rxPriv_.var.evt.prio], - QS_rxPriv_.var.evt.e, - 0U, // margin - &QS_rxPriv_)) - { - // failed QACTIVE_POST() recycles the event - i = 0x80U; // failure status, no recycle - } - } - else if (QS_rxPriv_.var.evt.prio == 255U) { // special prio - // dispatch to the current SM object - if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - // increment the ref-ctr to simulate the situation - // when the event is just retrieved from a queue. - // This is expected for the following QF_gc() call. - ++QS_rxPriv_.var.evt.e->refCtr_; - - QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; - (*sm->vptr->dispatch)(sm, QS_rxPriv_.var.evt.e, 0U); - i = 0x01U; // success status, recycle needed - } - else { - i = 0x81U; // failure status, recycle needed - } - } - else if (QS_rxPriv_.var.evt.prio == 254U) { // special prio - // init the current SM object" - if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - // increment the ref-ctr to simulate the situation - // when the event is just retrieved from a queue. - // This is expected for the following QF_gc() call. - ++QS_rxPriv_.var.evt.e->refCtr_; - - QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; - (*sm->vptr->init)(sm, QS_rxPriv_.var.evt.e, 0U); - i = 0x01U; // success status, recycle needed - } - else { - i = 0x81U; // failure status, recycle needed - } - } - else if (QS_rxPriv_.var.evt.prio == 253U) { // special prio - // post to the current AO - if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) { - if (!QACTIVE_POST_X( - (QActive *)QS_rxPriv_.currObj[AO_OBJ], - QS_rxPriv_.var.evt.e, - 0U, // margin - &QS_rxPriv_)) - { - // failed QACTIVE_POST() recycles the event - i = 0x80U; // failure status, no recycle - } - } - else { - i = 0x81U; // failure status, recycle needed - } - } - else { - i = 0x81U; // failure status, recycle needed - } - -#if (QF_MAX_EPOOL > 0U) - if ((i & 0x01U) != 0U) { // recycle needed? - QF_gc(QS_rxPriv_.var.evt.e); - } -#endif - if ((i & 0x80U) != 0U) { // failure? - QS_rxReportError_((int8_t)QS_RX_EVENT); - } - else { -#ifdef Q_UTEST - #if Q_UTEST != 0 - QS_processTestEvts_(); // process all events produced - #endif // Q_UTEST != 0 -#endif // Q_UTEST - QS_rxReportDone_((int8_t)QS_RX_EVENT); - } - break; - } - -#ifdef Q_UTEST - case WAIT4_TEST_SETUP_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_SETUP); - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_tstPriv_.tpNum = 0U; // clear the Test-Probes - QS_tstPriv_.testTime = 0U; // clear the time tick - QS_MEM_APP(); - QS_CRIT_EXIT(); - // don't clear current objects - QS_onTestSetup(); // application-specific test setup - // no need to report Done - break; - } - case WAIT4_TEST_TEARDOWN_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_TEARDOWN); - QS_onTestTeardown(); // application-specific test teardown - // no need to report Done - break; - } - case WAIT4_TEST_CONTINUE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_CONTINUE); - QS_rxPriv_.inTestLoop = false; // exit the QUTest loop - // no need to report Done - break; - } - case WAIT4_TEST_PROBE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_PROBE); - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - Q_ASSERT_INCRIT(815, QS_tstPriv_.tpNum - < (sizeof(QS_tstPriv_.tpBuf) / sizeof(QS_tstPriv_.tpBuf[0]))); - QS_tstPriv_.tpBuf[QS_tstPriv_.tpNum] = QS_rxPriv_.var.tp; - ++QS_tstPriv_.tpNum; - QS_MEM_APP(); - QS_CRIT_EXIT(); - // no need to report Done - break; - } -#endif // Q_UTEST - - case ERROR_STATE: { - // keep ignoring all bytes until new frame - break; - } - default: { - QS_rxReportError_(0x47); - break; - } - } -} - -//............................................................................ -static void QS_rxHandleBadFrame_(uint8_t const state) { - QS_rxReportError_(0x50); // report error for all bad frames - - switch (state) { - case WAIT4_EVT_FRAME: { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - Q_ASSERT_INCRIT(910, QS_rxPriv_.var.evt.e != (QEvt *)0); - QS_CRIT_EXIT(); -#if (QF_MAX_EPOOL > 0U) - QF_gc(QS_rxPriv_.var.evt.e); // don't leak allocated evt -#endif - break; - } - default: { - // intentionally empty - break; - } - } -} - -//............................................................................ -static void QS_rxReportAck_(int8_t const recId) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(recId); // record ID - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) -} - -//............................................................................ -static void QS_rxReportError_(int8_t const code) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(0x80U | (uint8_t)code); // error code - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) -} - -//............................................................................ -static void QS_rxReportDone_(int8_t const recId) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_TARGET_DONE); - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(recId); // record ID - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) -} - -//............................................................................ -static void QS_queryCurrObj(uint8_t const obj_kind) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(800, obj_kind < Q_DIM(QS_rxPriv_.currObj)); - QS_CRIT_EXIT(); - - if (QS_rxPriv_.currObj[obj_kind] != (void *)0) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_QUERY_DATA); - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(obj_kind); // object kind - QS_OBJ_PRE_(QS_rxPriv_.currObj[obj_kind]); - switch (obj_kind) { - case (uint8_t)SM_OBJ: // intentionally fall through - case (uint8_t)AO_OBJ: - QS_FUN_PRE_((*((QAsm *)QS_rxPriv_.currObj[obj_kind])->vptr - ->getStateHandler)( - ((QAsm *)QS_rxPriv_.currObj[obj_kind]))); - break; - case (uint8_t)MP_OBJ: - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case (uint8_t)EQ_OBJ: - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case (uint8_t)TE_OBJ: - QS_OBJ_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->act); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->ctr); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->interval); - QS_SIG_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.sig); - QS_U8_PRE_ (((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.refCtr_); - break; - default: - // intentionally empty - break; - } - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) - } - else { - QS_rxReportError_((int8_t)QS_RX_QUERY_CURR); - } -} - -//............................................................................ -static void QS_rxPoke_(void) { - uint8_t *ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[QS_rxPriv_.var.poke.offs]; - switch (QS_rxPriv_.var.poke.size) { - case 1: - *ptr = (uint8_t)QS_rxPriv_.var.poke.data; - break; - case 2: - *(uint16_t *)ptr = (uint16_t)QS_rxPriv_.var.poke.data; - break; - case 4: - *(uint32_t *)ptr = QS_rxPriv_.var.poke.data; - break; - default: { - Q_ERROR_INCRIT(900); - break; - } - } - - QS_rxPriv_.var.poke.data = 0U; - QS_rxPriv_.var.poke.idx = 0U; - QS_rxPriv_.var.poke.offs += (uint16_t)QS_rxPriv_.var.poke.size; -} - -//! @endcond - - - - // only build when Q_UTEST is defined -#ifdef Q_UTEST - -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#include "qs_port.h" // include QS port -#include "qs_pkg.h" // QS facilities for pre-defined trace records - -//============================================================================ -// QUTest unit testing harness -$define ${QS::QUTest} - -//============================================================================ -//! @cond INTERNAL - -QSTestAttr QS_tstPriv_; - -//............................................................................ -void QS_test_pause_(void) { - QS_beginRec_((uint_fast8_t)QS_TEST_PAUSED); - QS_endRec_(); - QS_onTestLoop(); -} - -//............................................................................ -uint32_t QS_getTestProbe_(QSpyFunPtr const api) { - uint32_t data = 0U; - for (uint_fast8_t i = 0U; i < QS_tstPriv_.tpNum; ++i) { - if (QS_tstPriv_.tpBuf[i].addr == (QSFun)api) { - data = QS_tstPriv_.tpBuf[i].data; - - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_TEST_PROBE_GET); - QS_TIME_PRE_(); // timestamp - QS_FUN_PRE_(api); // the calling API - QS_U32_PRE_(data); // the Test-Probe data - QS_endRec_(); - - QS_REC_DONE(); // user callback (if defined) - - --QS_tstPriv_.tpNum; // one less Test-Probe - // move all remaining entries in the buffer up by one - for (uint_fast8_t j = i; j < QS_tstPriv_.tpNum; ++j) { - QS_tstPriv_.tpBuf[j] = QS_tstPriv_.tpBuf[j + 1U]; - } - QS_MEM_APP(); - QS_CRIT_EXIT(); - break; // we are done (Test-Probe retrieved) - } - } - return data; -} - -//............................................................................ -QSTimeCtr QS_onGetTime(void) { - return (++QS_tstPriv_.testTime); -} - -//............................................................................ -Q_NORETURN Q_onError( - char const * const module, - int_t const id) -{ - // NOTE: called in a critical section - - QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); - QS_TIME_PRE_(); - QS_U16_PRE_(id); - QS_STR_PRE_((module != (char *)0) ? module : "?"); - QS_endRec_(); - QS_onFlush(); // flush the assertion record to the host - - QS_onCleanup(); // cleanup before resetting - QS_onReset(); // reset the target to prevent the code from continuing - for (;;) { // QS_onReset() should not return, but to ensure no-return - } -} - -//! @endcond -//============================================================================ - -// QP-stub for QUTest -// NOTE: The QP-stub is needed for unit testing QP applications, but might -// NOT be needed for testing QP itself. In that case, the build process -// can define Q_UTEST=0 to exclude the QP-stub from the build. -#if (Q_UTEST != 0) - -Q_DEFINE_THIS_MODULE("qutest") - -//............................................................................ -void QS_processTestEvts_(void) { - QS_TEST_PROBE_DEF(&QS_processTestEvts_) - - // return immediately (do nothing) for Test Probe != 0 - QS_TEST_PROBE(return;) - - while (QPSet_notEmpty(&QS_tstPriv_.readySet)) { - uint_fast8_t const p = QPSet_findMax(&QS_tstPriv_.readySet); - QActive * const a = QActive_registry_[p]; - - QEvt const * const e = QActive_get_(a); - QASM_DISPATCH(a, e, a->prio); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? - QPSet_remove(&QS_tstPriv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); -#endif - } - } -} - -$define ${QS::QUTest-stub} - -#endif // Q_UTEST != 0 - -#endif // Q_UTEST - #include "qstamp.h" -//! the calendar date of the last translation of the form: "Mmm dd yyyy" char const Q_BUILD_DATE[12] = __DATE__; - -//! the time of the last translation of the form: "hh:mm:ss" char const Q_BUILD_TIME[9] = __TIME__; diff --git a/qpc.sha1 b/qpc.sha1 index 89b5d324..df959ca8 100644 --- a/qpc.sha1 +++ b/qpc.sha1 @@ -1,174 +1,131 @@ -d875de4b3adef10ad05ff11713bed330be048922 *qpc.qm -4905c5e1a7afeafb9b644ca8ff0c7bd8b6d956ec *include/qequeue.h -80349c00631173d87bf4b98fddc7ccc417561d10 *include/qk.h -f131ada80744965bc27f5d31c43ee8a5edac63fd *include/qmpool.h -e112ab5915f12deef350c75ef9e9ec69f7b8c59f *include/qp.h -a9e58ddcc2185a56d79cad7dc5f31f7e5f5c89a3 *include/qp_pkg.h -270513305e374cec84fed74979299835f4ae3246 *include/qpc.h -d72b80d37040e1c428e38fba5a6880f76962a4f3 *include/qs.h -815d4314cf8ff757d2dfe160b5f4689ee22729a3 *include/qs_dummy.h -abb43eb6d5ae56106b137a284f024bc5a03b20e0 *include/qs_pkg.h -68f55b6ffb4192d3a37508ddef694bef7e8adb2d *include/qsafe.h -c7e98c8ea5989ddb53af1ed87283ebed2bf50c6d *include/qstamp.h -4c6a9b6c757448bc3d838f1c293d07bbb76617d6 *include/qv.h -4b229ebf5b2109147940f00e8b46a629ea5a29ba *include/qxk.h +7177cfc37bca450ea06ffc6afe31a61c0008304f *qpc.qm +e3c60b712a27e8f8c11e38711e785ffc4006cda5 *include/qequeue.h +a0d30600da64ec7aaadc6b9bd268c217930c3e60 *include/qk.h +84c8c1036c38f0f1646cc60e4813a7c8fb89f2d2 *include/qmpool.h +080b5860668af8dc54cd429268c24f5629fbe074 *include/qp.h +7a909dd01c0aa3fd7d74b4a4c88b930eeb0b815e *include/qp_pkg.h +0a3323af546e1b2320e6745e8e0effa837abdc53 *include/qpc.h +5a0c927370d332fc170e84650d980173da2102ae *include/qs_dummy.h +7458d62031562c2517577b258d47249b7b900dd7 *include/qsafe.h +2e0a56edcf460fcd82f6d7277e5fc0876325efeb *include/qstamp.h +d0199c9094039e672d85e9198ccff0d4ed9128cc *include/qv.h +5886c3a0831996cfbf7141255efb4e9f5b4d8254 *include/README.md 7f54a0933a9dc2fcaca475919fa0067667ed99ed *src/qf/CMakeLists.txt -125ad159841f3290be4c1a1708641099101afc46 *src/qf/qep_hsm.c -edac47d01b0d24636c312a4b85813e7d7af3fdfb *src/qf/qep_msm.c -8e366a46d0e9fd5580ec1a052b9bf54d322409fb *src/qf/qf_act.c -b2ef0d4ea8d62bab84ff674c9037db35609c35fd *src/qf/qf_actq.c -8f1af64278e070f94a791bee8747eb2c8f8eaf42 *src/qf/qf_defer.c -e8c4578918a78aa80639dc74e474ebf88983497b *src/qf/qf_dyn.c -7bfaf319d2d84144c69942da765f728f47241597 *src/qf/qf_mem.c -eab3084e49a9ac674f898a038c1c61e17b86db34 *src/qf/qf_ps.c -5e2687fbbc2e5a4d9ea1c15eb146aa78144042b0 *src/qf/qf_qact.c -5abf85ddb3b120fd148bdfbd662aa3578c01f993 *src/qf/qf_qeq.c -c0265928351e6d891277d05aab1aeac20534c5a8 *src/qf/qf_qmact.c -390f03c5899d3657066bb7335905f9e44793236d *src/qf/qf_time.c +d6aa00cb34e553e951df726fc5db39a6d16bc891 *src/qf/qep_hsm.c +67d6f8351a0e9a1df311be681083c73ecf63ea61 *src/qf/qep_msm.c +733bc8bf8e08014c20d8354efb98729857edb4cd *src/qf/qf_act.c +90e27f32bc8862946bfe4c6c376bf03327de25f7 *src/qf/qf_actq.c +8b58d43c5b8fe3b1b846392d1f7d99d5720428d9 *src/qf/qf_defer.c +eba579d6183310d9d0d07a14f28691b41ebaa921 *src/qf/qf_dyn.c +d263e3b91f9e5c61d6a458b5c6023ac68eb07a13 *src/qf/qf_mem.c +47ae6dfca8c983839aa6a58a8afdc819f2d3b1e2 *src/qf/qf_ps.c +2ed707166ca625a684c93147aec772dd568e5d9f *src/qf/qf_qact.c +e6e7dd46ed4ab7fb3ecd781ca29ea141d13f49d9 *src/qf/qf_qeq.c +f975ffcfadfed6856a41587b8275e0ea3bbe63a3 *src/qf/qf_qmact.c +b888e05e67e1259ee96d29b244aa8a2a68d0f904 *src/qf/qf_time.c 878a737efe234f40dc8c9374acc351e510b4da1e *src/qk/CMakeLists.txt -144e820821d5676d6bbbacac028acb8ea50de0a7 *src/qk/qk.c -4e7914a38bc70dc9032ed7e74e3b49b13a80112c *src/qs/CMakeLists.txt -fd621e42816352285008e72ca0b714e8d3bb5bd3 *src/qs/qs.c -96f2c2dee49009beeea2149c1ed71c8c53b6df01 *src/qs/qs_64bit.c -9f4e31b2ab70d6003737832bdaecedfab10ba04b *src/qs/qs_fp.c -fd1c77d97cfd166a377139553a85b635135ad566 *src/qs/qs_rx.c -aed0252b6ee3637bdfef31767a85e626a72a8226 *src/qs/qstamp.c -b9309c48a98f04639c03ad9e363a46f031fe02c3 *src/qs/qutest.c +5f092f2dc82962633e8ff32f736baaf04ef4c5da *src/qk/qk.c +68c99a2991d25df7486e57edadaa955b2bda396d *src/qs/CMakeLists.txt +f055d938dd53c9baf7f5e04ad1bc4f4ec40044e9 *src/qs/qstamp.c b1d2def9b8f6cde464170af7682ab0f01f4f40f6 *src/qv/CMakeLists.txt -b6577263b393a83197f9383f4576dbd870ec1511 *src/qv/qv.c -4cb0461eeec92f5a2e0c5b8ec41da409c5958193 *src/qxk/CMakeLists.txt -bb8f6d1e612a39e40e3f780ec1a678ee75a1a0d8 *src/qxk/qxk.c -a67a1aec687cb3f692dc5d49bec6e7460a38bbd0 *src/qxk/qxk_mutex.c -81b8a5c73f7c918fecd6e67969c9f625d9db408f *src/qxk/qxk_sema.c -abd65424ec87f9ad930f141bffd83d6ddeb619e5 *src/qxk/qxk_xthr.c -96494a3063233afd366fa3b0662e5206e3fe1b03 *ports/lint-plus/au-barr.lnt -4558a0e1e95b69c7de9820bca7df5344fde67008 *ports/lint-plus/au-ds.lnt -b2a4134f9a46ba33adea43faafa0ea0d6c2dac22 *ports/lint-plus/au-misra4.lnt -0e2fbbc6a6a53414919daf0ec89c2812e151165f *ports/lint-plus/au-ql-c99.lnt -e09e52aca80043e1a3365756c8ccccf708289bde *ports/lint-plus/options.lnt -9929081c14ef7784fed31a61d2d5676f6ba46cef *ports/lint-plus/ql-style.lnt -697518fede974485d34ddcdc1819be1304a5ce0a *ports/lint-plus/qpc.lnt -742acb5e8187254dc321b7c1a4b973d4af34775f *ports/lint-plus/std.lnt -ed03ed27328a0a87a9f490dea797dfd9d8c00097 *ports/arm-cm/qk/armclang/qk_port.c -466037f0da0fdd5124bd45bc4bb7dd0cee73a8f3 *ports/arm-cm/qk/armclang/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qk/armclang/qs_port.h -6efc7ba56de01629de2a7c64e04aa7fb18680eb1 *ports/arm-cm/qk/config/qp_config.h -11168cb0b412aeed04a1b02f2cab8cd86184df6d *ports/arm-cm/qk/gnu/qk_port.c -01992d44f4e14a593979f13db974f42edc84287d *ports/arm-cm/qk/gnu/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qk/gnu/qs_port.h -9d0345156894db34f0dca00bbe730bad30699d89 *ports/arm-cm/qk/iar/qk_port.c -d54bbf1d649139c4096d93e32849fecd1a29ee04 *ports/arm-cm/qk/iar/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qk/iar/qs_port.h -da4b65d3ee3b1d02b7bdf5125492d93ec2f3546c *ports/arm-cm/qv/armclang/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qv/armclang/qs_port.h -95f317c5328aafb1396740a83514ed965c0d13c4 *ports/arm-cm/qv/armclang/qv_port.c -80d697feff43f8bebaa1143e2ea316d4d064b802 *ports/arm-cm/qv/config/qp_config.h -215d226380da844642f5e96ed0ebc6b9f6fd2bfc *ports/arm-cm/qv/gnu/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qv/gnu/qs_port.h -10084951ab49c6a632641b82d102dc0df44c9edd *ports/arm-cm/qv/gnu/qv_port.c -08bb668de09851a81ad6b8d101e8116be638c638 *ports/arm-cm/qv/iar/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qv/iar/qs_port.h -d2d6726cfc560f9ed301bbb6b214991997daa107 *ports/arm-cm/qv/iar/qv_port.c -6f54f449bad8f3263a25d2885ae2310c48eaf085 *ports/arm-cm/qxk/armclang/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qxk/armclang/qs_port.h -4aee8cf7691c7e628e67f0208d33c5b9e6bebf25 *ports/arm-cm/qxk/armclang/qxk_port.c -0ac4f86f279638431bb7a12d8b3e8fb5bfd9ad33 *ports/arm-cm/qxk/config/qp_config.h -36bb14cd9579ee7c4b074cdd921ec99cf408ea0c *ports/arm-cm/qxk/gnu/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qxk/gnu/qs_port.h -335abfde3ed62a37e67e30d2cbe1bce29f83b88e *ports/arm-cm/qxk/gnu/qxk_port.c -02505aae407cdbdeb079eebfb5f73b96d2f492a2 *ports/arm-cm/qxk/iar/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qxk/iar/qs_port.h -3d83983a358cf7cb813490c556fec3c63ba8e1d9 *ports/arm-cm/qxk/iar/qxk_port.c -f9da74ed234d38423c412dd831b4dcbd9a10c978 *ports/arm-cm/qutest/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cm/qutest/qs_port.h -791a13c3bdf0646860b2e366acace9413f29a341 *ports/arm-cr/qk/config/qp_config.h -4d79ce35280c25da8f61c90a371b24c9770c1e39 *ports/arm-cr/qk/gnu/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cr/qk/gnu/qs_port.h -3fe18d672bb906d5be90efe6886a6d2de5f1ebcb *ports/arm-cr/qk/iar/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cr/qk/iar/qs_port.h -45f2b8f6565d0d98a97058489cda04e16fce3102 *ports/arm-cr/qk/ti/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cr/qk/ti/qs_port.h -9b9723802d3d2229af7cf810d2d94145679b2428 *ports/arm-cr/qv/gnu/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cr/qv/gnu/qs_port.h -a1b7f30c8c2fa66951e8f5518a8c4c930466db49 *ports/arm-cr/qv/iar/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cr/qv/iar/qs_port.h -d6389431a053fd6fc8f83b1585ecd628618eb5e6 *ports/arm-cr/qv/ti/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/arm-cr/qv/ti/qs_port.h -0a37d137f3fea038fedd602b2ea1870114295a9b *ports/msp430/qk/qp_port.h -7c5e810cf497ef306c2160a21e12bcd2fcd26583 *ports/msp430/qk/qs_port.h -97b7170961a9ec6bef2eff12fb3c640d392bf22c *ports/msp430/qv/qp_port.h -7c5e810cf497ef306c2160a21e12bcd2fcd26583 *ports/msp430/qv/qs_port.h -4af1c8f956dda650dc16ea9041c834fa72b9d42d *ports/msp430/qutest/qp_port.h -7c5e810cf497ef306c2160a21e12bcd2fcd26583 *ports/msp430/qutest/qs_port.h -9d2c612b3954999eda20d12e13657e9205b8c972 *ports/config/qp_config.h +f77a3c93938c5ff9a37214bdfe1c7c255f9eed6e *src/qv/qv.c +5a77be9e96ab536754188a32a6b6f99b8db9f2ff *ports/arm-cm/qk/armclang/qk_port.c +dc00b85b62f9d3dce9c4f0073b9e0c1b0d96d652 *ports/arm-cm/qk/armclang/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qk/armclang/qs_port.h +e27abe98e61b175634d3ef10f0b137a2c183b235 *ports/arm-cm/qk/config/qp_config.h +404046a50f5c970986b23f9ded48b3aed37738e5 *ports/arm-cm/qk/gnu/qk_port.c +1a1c683b243e48651427751f54752ce6f6ee60b0 *ports/arm-cm/qk/gnu/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qk/gnu/qs_port.h +ba447b9e250b96a4cc5caf901a8643df40737966 *ports/arm-cm/qk/iar/qk_port.c +2e4ad9ed30bdec6728a1e1b4cfe52ca96668fb70 *ports/arm-cm/qk/iar/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qk/iar/qs_port.h +06909bcb51e7c1dd28e666a12a885500db74c052 *ports/arm-cm/qv/armclang/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qv/armclang/qs_port.h +1caea977419fbbf8eff95cb4a7a695b168b14bda *ports/arm-cm/qv/armclang/qv_port.c +651dedf7266e0da44ce45ddd3cced3782eccda17 *ports/arm-cm/qv/config/qp_config.h +0427fc5ce0d727350d39b1bc9dcb081172865be4 *ports/arm-cm/qv/gnu/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qv/gnu/qs_port.h +6dad2e9e8a929e4477f6b071cc05d70638fbb356 *ports/arm-cm/qv/gnu/qv_port.c +c63708c0d86bfefb58bf60917fd428dbf29a0a31 *ports/arm-cm/qv/iar/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qv/iar/qs_port.h +9386d798e1989ff6789f54f5ae33741aad4b1b07 *ports/arm-cm/qv/iar/qv_port.c +623d43a6e15634e9c61434625486cd24aaaa949b *ports/arm-cr/qk/config/qp_config.h +38e441bb971501ba5118cbd5782b394eee80e660 *ports/arm-cr/qk/gnu/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qk/gnu/qs_port.h +88d3ed754f05c43609ecf52767c270fa438ecd03 *ports/arm-cr/qk/iar/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qk/iar/qs_port.h +e03d1c780c764e2a323b8423ae5045e226ee98c6 *ports/arm-cr/qk/ti/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qk/ti/qs_port.h +84b6adb5703d24e41f5c19982fe797b9a79b38a8 *ports/arm-cr/qv/gnu/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qv/gnu/qs_port.h +da079ffa59b518ead25ed8aed82adc1535fc0280 *ports/arm-cr/qv/iar/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qv/iar/qs_port.h +b6a6e866be5f4ac5bfc961aee3c466a755b9cd03 *ports/arm-cr/qv/ti/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qv/ti/qs_port.h +68b3a558e7e3e22477abf917ef5f87f1b424f9e5 *ports/msp430/qk/qp_port.h +a99dfb36c107e6c1b2fcc345792130bbc1ebcc4f *ports/msp430/qk/qs_port.h +39dceae58da3feab8f34e4597d63e72e4f8084e2 *ports/msp430/qv/qp_port.h +a99dfb36c107e6c1b2fcc345792130bbc1ebcc4f *ports/msp430/qv/qs_port.h +1459908255dbdd581cd38bd5ea33a121fce496b7 *ports/msp430/qutest/qp_port.h +a99dfb36c107e6c1b2fcc345792130bbc1ebcc4f *ports/msp430/qutest/qs_port.h +77bb26f94e1e9ce0ba617f5a6cc2b921c4b283c7 *ports/config/qp_config.h 2ee7f5594f6121705bbc57145175b5c5867e0070 *ports/embos/CMakeLists.txt -05944870ca5f75d0942a2a65e32c4a9fc9ea4f9e *ports/embos/qf_port.c -301919d0bdfe1b9bc12639f3394f59c4e43d0b66 *ports/embos/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/embos/qs_port.h +7cfd0e233fc7ee4c73cccaa58f769f3643325785 *ports/embos/qf_port.c +a378ac45d230fc61b4462b3cc17a05d018271ea7 *ports/embos/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/embos/qs_port.h e65838e1764bd6b4eb73025be1e8116ac28247b2 *ports/freertos/CMakeLists.txt -6343509d769b420f07cea628c68bec729dfbc942 *ports/freertos/qf_port.c -c4cdfad6a99e8c121b034f74d4d23f2d2a333331 *ports/freertos/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/freertos/qs_port.h +743a22c5deedeca8216fb2109174cc4c81573804 *ports/freertos/qf_port.c +1563d37772cf1cd0bddca356d49ee9805401f2cd *ports/freertos/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/freertos/qs_port.h a01e1f6d49ce056ac4e130d54ae4724fda2ebf32 *ports/threadx/CMakeLists.txt -fb18ebe253666180094170817e6453bcc3dcf386 *ports/threadx/qf_port.c -6792ed70d78732ad942fb99cb55194eacb23df37 *ports/threadx/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/threadx/qs_port.h +be313a1d4350f28274fcb6b0dcdebf5279f40c71 *ports/threadx/qf_port.c +0aeea704b1cfac4e956e14e529dddf7759acde04 *ports/threadx/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/threadx/qs_port.h 847cd324346d1d6c9c81422e99045442edcc7f64 *ports/threadx/README.md d9b6e1ca7a0215a3e141ae43970781d0f4d0d08f *ports/uc-os2/CMakeLists.txt -85f46dc50c923694206f88f310c76083ff34ad2f *ports/uc-os2/qf_port.c -284ad7ebeb68aedf94e2fabba81b3787e9978ad9 *ports/uc-os2/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *ports/uc-os2/qs_port.h +30411991988667532a2432a80fa25aff2c451384 *ports/uc-os2/qf_port.c +6223846204fb35ba9c9da56bb7d686fbf19d375c *ports/uc-os2/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/uc-os2/qs_port.h 4a5da9508e2012b2ca3943b87134163e558964cc *ports/qep-only/CMakeLists.txt -1199ebd523ea4f24e1f7c43238018f64b923ff1d *ports/qep-only/qp_port.h +cdb7c42a17fb3c5f282a55e08f99678e1cd56c0e *ports/qep-only/qp_port.h 5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/qep-only/safe_std.h 5d7914dfaf44a9c2552afdd5d8de4cfc3ebbc22a *ports/posix/CMakeLists.txt -e4eb61f17c387d6a3f0986384ea2d321f96a20c9 *ports/posix/qf_port.c -9e6f98ae930242a4889e1a257c5c20bdbf2e6aab *ports/posix/qp_port.h -243f5fdf73141276dc8b90ec55c09e672d54c540 *ports/posix/qs_port.c -a06f0f49fb35c21bb2c7df9b0cb66f7cff16c530 *ports/posix/qs_port.h +6b9d862537f4823ca83c81d2e8892da9711a69cd *ports/posix/qf_port.c +c99d7d3ca180a3f7903fe6948d5cffaf7e8f1996 *ports/posix/qp_port.h +51d89a3fa8c7a6c5858f6354ea8cc350e42a9d30 *ports/posix/qs_port.c +d05889780d358bb1fe02ffad1a9414332f5eb300 *ports/posix/qs_port.h 6e33b2e5092d117f58c47b632c59420f382ac39f *ports/posix/README.md 5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/posix/safe_std.h 039b1e4066eb7eeac3233070ad6aa2cd9f6d1c69 *ports/posix-qv/CMakeLists.txt -7ad0df4b40d862f22a0781c7c54ac17f38b48cf7 *ports/posix-qv/qf_port.c -dbce975f56b71518ca29f8694a3f67f146f0762c *ports/posix-qv/qp_port.h -243f5fdf73141276dc8b90ec55c09e672d54c540 *ports/posix-qv/qs_port.c -a06f0f49fb35c21bb2c7df9b0cb66f7cff16c530 *ports/posix-qv/qs_port.h +2b432fddb2bb9a9912db1c0f6e1ceada35323365 *ports/posix-qv/qf_port.c +b73738f7297d6c023012d98c59c901a1e8951f02 *ports/posix-qv/qp_port.h +51d89a3fa8c7a6c5858f6354ea8cc350e42a9d30 *ports/posix-qv/qs_port.c +d05889780d358bb1fe02ffad1a9414332f5eb300 *ports/posix-qv/qs_port.h ab829eb3deed2bc84b3581610f1664777afd3841 *ports/posix-qv/README.md 5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/posix-qv/safe_std.h -1ecb2095e8de486c8111a420b5511a4ea0cb097c *ports/posix-qutest/CMakeLists.txt -5b6b5b3f6ee635c49920b177fd3ee66813d6ba35 *ports/posix-qutest/qp_port.h -a06f0f49fb35c21bb2c7df9b0cb66f7cff16c530 *ports/posix-qutest/qs_port.h -5fc17dbde9691cbebd18c04a6a4cde4789ad1d71 *ports/posix-qutest/qutest_port.c -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/posix-qutest/safe_std.h cfea17ea9ab718e9e4f506e90c4b2fc8c1fea858 *ports/win32/CMakeLists.txt -141eba516d088f91ed5c74968b5863414e8587da *ports/win32/qf_port.c -92e081241e4ce102193246ebe8f95879bd853c09 *ports/win32/qp_port.h -eea30365b6b95a429cb1f1f17136df44d32e62ba *ports/win32/qs_port.c -ff6375dabf341a7869781f82fd7eda32497c4069 *ports/win32/qs_port.h +a99784fa31b0466af740186bbe96f8d78fc7c17a *ports/win32/qf_port.c +d0b7e944e6df828e040ec146f639e42be2c354d5 *ports/win32/qp_port.h +d86809f52df1ab5be11ed12dfb3b8ef4cb4fd6db *ports/win32/qs_port.c +b1a67eb489d35d71cf6fb40fc8f087906839f1a7 *ports/win32/qs_port.h 8d3500b2b8700f5aa925f7020631d7d1415bd028 *ports/win32/qwin_gui.c 04f62b5f1812de29bfb0619af1fc04ec44256802 *ports/win32/qwin_gui.h 3781ccdce31dea9d08493a801926eb278950786f *ports/win32/README.md 5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/win32/safe_std.h 8d589868e287ceb185b4837064c80d4eed8e1a44 *ports/win32-qv/CMakeLists.txt -8c9f5fa1cd43311381c09b17db15b40d883470a6 *ports/win32-qv/qf_port.c -e58272e88511fb06aa77589dd9e39c04e5f3180f *ports/win32-qv/qp_port.h -eea30365b6b95a429cb1f1f17136df44d32e62ba *ports/win32-qv/qs_port.c -ff6375dabf341a7869781f82fd7eda32497c4069 *ports/win32-qv/qs_port.h +d6706afb9a3b11f6aad510f16ec1ed9665b98633 *ports/win32-qv/qf_port.c +20249cc3927858f7d457433e64be963df0baddf7 *ports/win32-qv/qp_port.h +d86809f52df1ab5be11ed12dfb3b8ef4cb4fd6db *ports/win32-qv/qs_port.c +b1a67eb489d35d71cf6fb40fc8f087906839f1a7 *ports/win32-qv/qs_port.h 77d78e462a3ac8fac9c75fd97720500ceb449664 *ports/win32-qv/qwin_gui.c be15234e51b8fe3c295ff644e84fbc1cfca89257 *ports/win32-qv/qwin_gui.h b57cec85e2fe5c261270f68acc3ae440802a62bd *ports/win32-qv/README.md 5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/win32-qv/safe_std.h -a04f13d2d9f24ef71d95f997d87f8a3ba9862e45 *ports/win32-qutest/CMakeLists.txt -eefe47fcb37f794b8d0c68fc6b3331ff78f20a33 *ports/win32-qutest/qp_port.h -ff6375dabf341a7869781f82fd7eda32497c4069 *ports/win32-qutest/qs_port.h -9b9499b5fc28a4e418f048867af33367b9b6f2e0 *ports/win32-qutest/qutest_port.c -7319222937ebd55cb32e1e30abcbc38547419a5c *ports/win32-qutest/README.md -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/win32-qutest/safe_std.h 848a30efa3274ff30fb72059f926fe7963ab2321 *zephyr/CMakeLists.txt 10764710e545dd4d2ce0ddf032711df7f9191937 *zephyr/Kconfig 2eb2a922e18b4760a68151ebee1b6282d20b4692 *zephyr/module.yml -fdae436b2e3b9657bd38a51a6f85482ba2e4c6a8 *zephyr/qf_port.c +c691294aa02303c2d74c0b4fa62c2296491d1d15 *zephyr/qf_port.c 109c291df50110f185adc17bcdf8becc0a79346c *zephyr/qp-zephyr.jpg -ee0f1921d5994717b112b2c933f3c2cc3d690d74 *zephyr/qp_port.h -faf4df1db0c16caa5e84a303ad9a1ecaaa135b78 *zephyr/qs_port.h +abe4afc842977359a1bb63a76b765aed65b64def *zephyr/qp_port.h +e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *zephyr/qs_port.h ab487299b61fea18e2926913048a4498b3bfa4b4 *zephyr/README.md diff --git a/qpc_sha1.bat b/qpc_sha1.bat index 88b94b60..2de6cc1a 100644 --- a/qpc_sha1.bat +++ b/qpc_sha1.bat @@ -4,7 +4,7 @@ @echo Usage: qpc_sha1 [gen] @echo examples: @echo qpc_sha1 : check the sha1 sums in the file qpcp.sha1 -@echo qpc_sha1 gen : generate the sha1 file qpcp.sha1 +@echo qpc_sha1 gen : generate the sha1 file qpc.sha1 @echo. @if NOT "%1"=="gen" ( @@ -16,7 +16,6 @@ goto end @sha1sum qpc.qm ^ include/* ^ src/qf/* src/qk/* src/qs/* src/qv/* src/qxk/* ^ - ports/lint-plus/*.lnt ^ ports/arm-cm/qk/armclang/* ports/arm-cm/qk/config/* ports/arm-cm/qk/gnu/* ports/arm-cm/qk/iar/* ^ ports/arm-cm/qv/armclang/* ports/arm-cm/qv/config/* ports/arm-cm/qv/gnu/* ports/arm-cm/qv/iar/* ^ ports/arm-cm/qxk/armclang/* ports/arm-cm/qxk/config/* ports/arm-cm/qxk/gnu/* ports/arm-cm/qxk/iar/* ^ diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..2c26380d --- /dev/null +++ b/src/README.md @@ -0,0 +1,45 @@ +# Files Missing from the QP/C GPL Distribution +Due to the widespread non-compliance with the GPL, as well as infringement +on the [dual-licensing model of QP frameworks][Lic], the following files +have been **removed from the open-source GPL distribution**: + +``` +qpc +| ++---include +| qs.h +| qs_pkg.h +| qxk.h +| +\---src + | + +---qs + | qs.c + | qs_64bit.c + | qs_fp.c + | qs_rx.c + | qutest.c + | + \---qxk + qxk.c + qxk_mutex.c + qxk_sema.c + qxk_xthr.c +``` + +> NOTE: These files are available to the [commercial licensees][Cust] with +the active Support Term. Please contact [Quantum Leaps technical support][Sup] +to get the complete QP/C framework distribution. + +# QP/C Framework Evaluation +To request **evaluation** of the complete QP/C framework, please contact +Quantum Leaps at: +- https://www.state-machine.com/contact + +# Quantum Leaps Licensing: +To learn more about the open source and commercial licensing options: +- https://www.state-machine.com/licensing + + [Lic]: + [Cust]: + [Sup]: diff --git a/src/qf/qep_hsm.c b/src/qf/qep_hsm.c index 69ac8f3d..104c8492 100644 --- a/src/qf/qep_hsm.c +++ b/src/qf/qep_hsm.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qep_hsm.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -83,25 +75,25 @@ QEvt const QEvt_reserved_[4] = { ((*(state_))(me, &QEvt_reserved_[(sig_)])) // helper macro to trace state entry -#define QS_STATE_ENTRY_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, (qsId_)) \ - QS_OBJ_PRE_(me); \ - QS_FUN_PRE_(state_); \ - QS_END_PRE_() \ - QS_MEM_APP(); \ +#define QS_STATE_ENTRY_(state_, qsId_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, (qsId_)) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(state_); \ + QS_END_PRE() \ + QS_MEM_APP(); \ QS_CRIT_EXIT() // helper macro to trace state exit -#define QS_STATE_EXIT_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, (qsId_)) \ - QS_OBJ_PRE_(me); \ - QS_FUN_PRE_(state_); \ - QS_END_PRE_() \ - QS_MEM_APP(); \ +#define QS_STATE_EXIT_(state_, qsId_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE(QS_QEP_STATE_EXIT, (qsId_)) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(state_); \ + QS_END_PRE() \ + QS_MEM_APP(); \ QS_CRIT_EXIT() //! @endcond @@ -144,44 +136,49 @@ void QHsm_init_( { QF_CRIT_STAT + QState r; + + // produce QS dictionary for QHsm_top() #ifdef Q_SPY QS_CRIT_ENTRY(); QS_MEM_SYS(); if ((QS_priv_.flags & 0x01U) == 0U) { QS_priv_.flags |= 0x01U; - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_FUN_DICTIONARY(&QHsm_top); + r = Q_RET_HANDLED; } else { - QS_MEM_APP(); - QS_CRIT_EXIT(); + r = Q_RET_IGNORED; + } + QS_MEM_APP(); + QS_CRIT_EXIT(); + if (r == Q_RET_HANDLED) { + QS_FUN_DICTIONARY(&QHsm_top); } #else Q_UNUSED_PAR(qsId); - #endif + #endif // def Q_SPY QStateHandler t = me->state.fun; QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) - && (me->temp.fun != Q_STATE_CAST(0)) - && (t == Q_STATE_CAST(&QHsm_top))); + && (me->temp.fun != Q_STATE_CAST(0)) + && (t == Q_STATE_CAST(&QHsm_top))); QF_CRIT_EXIT(); // execute the top-most initial tran. - QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); + r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); QF_CRIT_ENTRY(); // the top-most initial tran. must be taken Q_ASSERT_INCRIT(210, r == Q_RET_TRAN); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source state - QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the source state + QS_FUN_PRE(me->temp.fun); // the target of the initial tran. + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -226,11 +223,11 @@ void QHsm_init_( if (r == Q_RET_TRAN) { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source state - QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the source state + QS_FUN_PRE(me->temp.fun); // the target of the initial tran. + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -240,11 +237,11 @@ void QHsm_init_( QF_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the new active state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the new active state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -271,17 +268,21 @@ void QHsm_dispatch_( QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); - Q_INVARIANT_INCRIT(302, (s != Q_STATE_CAST(0)) + Q_REQUIRE_INCRIT(300, + (e != (QEvt *)0) + && (s != Q_STATE_CAST(0)) && (me->state.uint == (uintptr_t)(~me->temp.uint))); + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); + #endif QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the current state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -298,11 +299,11 @@ void QHsm_dispatch_( QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the current state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -316,9 +317,22 @@ void QHsm_dispatch_( Q_ENSURE_INCRIT(310, ip > 0); QF_CRIT_EXIT(); - if (r >= Q_RET_TRAN) { // regular tran. taken? - QStateHandler path[QHSM_MAX_NEST_DEPTH_]; + if (r >= Q_RET_TRAN) { // tran. (regular or history) taken? + #ifdef Q_SPY + if (r == Q_RET_TRAN_HIST) { // tran. to history? + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // tran. to history source + QS_FUN_PRE(me->temp.fun); // tran. to history target + QS_END_PRE() + QS_MEM_APP(); + QS_CRIT_EXIT(); + } + #endif // Q_SPY + QStateHandler path[QHSM_MAX_NEST_DEPTH_]; path[0] = me->temp.fun; // tran. target path[1] = t; // current state path[2] = s; // tran. source @@ -340,20 +354,6 @@ void QHsm_dispatch_( ip = QHsm_tran_(me, path, qsId); // take the tran. - #ifdef Q_SPY - if (r == Q_RET_TRAN_HIST) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source of the tran. - QS_FUN_PRE_(path[0]); // the target of the tran. to history - QS_END_PRE_() - QS_MEM_APP(); - QS_CRIT_EXIT(); - } - #endif // Q_SPY - // execute state entry actions in the desired order... // note: ip is the fixed upper loop bound for (; ip >= 0; --ip) { @@ -372,11 +372,11 @@ void QHsm_dispatch_( QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t); // the source (pseudo)state - QS_FUN_PRE_(me->temp.fun); // the target of the tran. - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t); // the source (pseudo)state + QS_FUN_PRE(me->temp.fun); // the target of the tran. + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -417,13 +417,13 @@ void QHsm_dispatch_( QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the source of the tran. - QS_FUN_PRE_(t); // the new active state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the source of the tran. + QS_FUN_PRE(t); // the new active state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -432,24 +432,24 @@ void QHsm_dispatch_( else if (r == Q_RET_HANDLED) { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s); // the source state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s); // the source state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } else { QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.fun); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->state.fun); // the current state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -477,8 +477,8 @@ bool QHsm_isIn_( { QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_INVARIANT_INCRIT(602, me->state.uint - == (uintptr_t)(~me->temp.uint)); + Q_INVARIANT_INCRIT(602, + me->state.uint == (uintptr_t)(~me->temp.uint)); QF_CRIT_EXIT(); bool inState = false; // assume that this HSM is not in 'state' diff --git a/src/qf/qep_msm.c b/src/qf/qep_msm.c index 079abaa1..f911fd3a 100644 --- a/src/qf/qep_msm.c +++ b/src/qf/qep_msm.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qep_msm.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -134,11 +126,11 @@ void QMsm_init_( Q_ASSERT_INCRIT(210, r == Q_RET_TRAN_INIT); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.obj->stateHandler); // source state - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->state.obj->stateHandler); // source state + QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -158,11 +150,11 @@ void QMsm_init_( Q_ENSURE_INCRIT(290, lbound > 0); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.obj->stateHandler); // the new current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->state.obj->stateHandler); // the new current state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -188,17 +180,21 @@ void QMsm_dispatch_( QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); - Q_INVARIANT_INCRIT(302, (s != (QMState *)0) + Q_REQUIRE_INCRIT(300, + (e != (QEvt *)0) + && (s != (QMState *)0) && (me->state.uint == (uintptr_t)(~me->temp.uint))); + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); + #endif QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s->stateHandler); // the current state handler - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s->stateHandler); // the current state handler + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -217,21 +213,17 @@ void QMsm_dispatch_( else if (r == Q_RET_SUPER) { t = t->superstate; // advance to the superstate } - // event unhandled and passed to a submachine superstate? - else if (r == Q_RET_SUPER_SUB) { - t = me->temp.obj; // current host state of the submachine - } else { // event unhandled due to a guard QF_CRIT_ENTRY(); // event must be unhandled due to a guard evaluating to 'false' Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t->stateHandler); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t->stateHandler); // the current state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -245,94 +237,62 @@ void QMsm_dispatch_( QF_CRIT_EXIT(); if (r >= Q_RET_TRAN) { // any kind of tran. taken? - #ifdef Q_SPY - QMState const * const ts = t; // tran. source for QS tracing - QF_CRIT_ENTRY(); // the tran. source state must not be NULL - Q_ASSERT_INCRIT(330, ts != (QMState *)0); + Q_ASSERT_INCRIT(330, t != (QMState *)0); QF_CRIT_EXIT(); + + #ifdef Q_SPY + QMState const * const ts = t; // tran. source for QS tracing #endif // Q_SPY + struct QMTranActTable const *tatbl; // for saving tran. table + + if (r == Q_RET_TRAN_HIST) { // was it tran. to history? + QMState const * const hist = me->state.obj; // save history + me->state.obj = s; // restore the original state + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t->stateHandler); // source state handler + QS_FUN_PRE(hist->stateHandler); // target state handler + QS_END_PRE() + QS_MEM_APP(); + QS_CRIT_EXIT(); + + // save the tran-action table before it gets clobbered + tatbl = me->temp.tatbl; + QMsm_exitToTranSource_(me, s, t, qsId); + (void)QMsm_execTatbl_(me, tatbl, qsId); + r = QMsm_enterHistory_(me, hist, qsId); + s = me->state.obj; + t = s; // set target to the current state + } lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - do { + while ((r >= Q_RET_TRAN) && (lbound > 0)) { // save the tran-action table before it gets clobbered - struct QMTranActTable const * const tatbl = me->temp.tatbl; - union QAsmAttr tmp; // temporary to save intermediate values - - // was TRAN, TRAN_INIT, or TRAN_EP taken? - if (r <= Q_RET_TRAN_EP) { - me->temp.obj = (QMState *)0; // clear - QMsm_exitToTranSource_(me, s, t, qsId); - r = QMsm_execTatbl_(me, tatbl, qsId); - s = me->state.obj; - } - // was a tran. segment to history taken? - else if (r == Q_RET_TRAN_HIST) { - tmp.obj = me->state.obj; // save history - me->state.obj = s; // restore the original state - QMsm_exitToTranSource_(me, s, t, qsId); - (void)QMsm_execTatbl_(me, tatbl, qsId); - r = QMsm_enterHistory_(me, tmp.obj, qsId); - s = me->state.obj; - } - else { - QF_CRIT_ENTRY(); - // must be tran. to exit point - Q_ASSERT_INCRIT(340, r == Q_RET_TRAN_XP); - QF_CRIT_EXIT(); - - tmp.act = me->state.act; // save XP action - me->state.obj = s; // restore the original state - r = (*tmp.act)(me); // execute the XP action - if (r == Q_RET_TRAN) { // XP -> TRAN ? - #ifdef Q_SPY - tmp.tatbl = me->temp.tatbl; // save me->temp - #endif // Q_SPY - QMsm_exitToTranSource_(me, s, t, qsId); - // take the tran-to-XP segment inside submachine - (void)QMsm_execTatbl_(me, tatbl, qsId); - s = me->state.obj; - #ifdef Q_SPY - me->temp.tatbl = tmp.tatbl; // restore me->temp - #endif // Q_SPY - } - else if (r == Q_RET_TRAN_HIST) { // XP -> HIST ? - tmp.obj = me->state.obj; // save the history - me->state.obj = s; // restore the original state - s = me->temp.obj; // save me->temp - QMsm_exitToTranSource_(me, me->state.obj, t, qsId); - // take the tran-to-XP segment inside submachine - (void)QMsm_execTatbl_(me, tatbl, qsId); - #ifdef Q_SPY - me->temp.obj = s; // restore me->temp - #endif // Q_SPY - s = me->state.obj; - me->state.obj = tmp.obj; // restore the history - } - else { - QF_CRIT_ENTRY(); - // TRAN_XP must NOT be followed by any other tran. type - Q_ASSERT_INCRIT(350, r < Q_RET_TRAN); - QF_CRIT_EXIT(); - } - } - + tatbl = me->temp.tatbl; + me->temp.obj = (QMState *)0; // clear + QMsm_exitToTranSource_(me, s, t, qsId); + r = QMsm_execTatbl_(me, tatbl, qsId); + s = me->state.obj; t = s; // set target to the current state - --lbound; - } while ((r >= Q_RET_TRAN) && (lbound > 0)); + --lbound; + } QF_CRIT_ENTRY(); Q_ENSURE_INCRIT(360, lbound > 0); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(ts->stateHandler); // the tran. source - QS_FUN_PRE_(s->stateHandler); // the new active state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(ts->stateHandler); // the tran. source + QS_FUN_PRE(s->stateHandler); // the new active state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -346,12 +306,12 @@ void QMsm_dispatch_( Q_ASSERT_INCRIT(380, t != (QMState *)0); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(t->stateHandler); // the source state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(t->stateHandler); // the source state + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -359,16 +319,13 @@ void QMsm_dispatch_( // event bubbled to the 'top' state? else if (t == (QMState *)0) { QS_CRIT_ENTRY(); - // current state can't be NULL - Q_ASSERT_INCRIT(390, s != (QMState *)0); - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s->stateHandler); // the current state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) + QS_TIME_PRE(); // time stamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s->stateHandler); // the current state + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -492,37 +449,23 @@ QState QMsm_execTatbl_( QS_CRIT_ENTRY(); QS_MEM_SYS(); if (r == Q_RET_ENTRY) { - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->temp.obj->stateHandler); // entered state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->temp.obj->stateHandler); // entered state + QS_END_PRE() } else if (r == Q_RET_EXIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->temp.obj->stateHandler); // exited state - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(me->temp.obj->stateHandler); // exited state + QS_END_PRE() } else if (r == Q_RET_TRAN_INIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(tatbl->target->stateHandler); // source - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE_() - } - else if (r == Q_RET_TRAN_EP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_EP, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(tatbl->target->stateHandler); // source - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE_() - } - else if (r == Q_RET_TRAN_XP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_XP, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(tatbl->target->stateHandler); // source - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(tatbl->target->stateHandler); // source + QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target + QS_END_PRE() } else { // empty @@ -568,22 +511,15 @@ void QMsm_exitToTranSource_( QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(s->stateHandler); // the exited state handler - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(s->stateHandler); // the exited state handler + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } s = s->superstate; // advance to the superstate - - if (s == (QMState *)0) { // reached the top of a submachine? - s = me->temp.obj; // the superstate from QM_SM_EXIT() - QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(880, s != (QMState *)0); // must be valid - QF_CRIT_EXIT(); - } } QF_CRIT_ENTRY(); Q_ENSURE_INCRIT(890, lbound > 0); @@ -601,35 +537,20 @@ QState QMsm_enterHistory_( Q_UNUSED_PAR(qsId); #endif - QMState const *s = hist; - QMState const *ts = me->state.obj; // tran. source + // record the entry path from current state to history QMState const *epath[QMSM_MAX_ENTRY_DEPTH_]; - - QF_CRIT_STAT - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(ts->stateHandler); // source state handler - QS_FUN_PRE_(hist->stateHandler); // target state handler - QS_END_PRE_() - QS_MEM_APP(); - QS_CRIT_EXIT(); - + QMState const *s = hist; int_fast8_t i = 0; // tran. entry path index - while ((s != ts) && (i < QMSM_MAX_ENTRY_DEPTH_)) { + while ((s != me->state.obj) && (i < (QMSM_MAX_ENTRY_DEPTH_ - 1))) { if (s->entryAction != Q_ACTION_CAST(0)) { epath[i] = s; ++i; } s = s->superstate; - if (s == (QMState *)0) { - ts = s; // force exit from the for-loop - } } + QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(910, s == ts); + Q_ASSERT_INCRIT(910, s == me->state.obj); QF_CRIT_EXIT(); // retrace the entry path in reverse (desired) order... @@ -639,10 +560,10 @@ QState QMsm_enterHistory_( QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE_(me); - QS_FUN_PRE_(epath[i]->stateHandler); // entered state handler - QS_END_PRE_() + QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) + QS_OBJ_PRE(me); + QS_FUN_PRE(epath[i]->stateHandler); // entered state handler + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -653,6 +574,15 @@ QState QMsm_enterHistory_( QState r; if (hist->initAction != Q_ACTION_CAST(0)) { r = (*hist->initAction)(me); // execute the tran. action + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) + QS_OBJ_PRE(me); // this state machine object + QS_FUN_PRE(hist->stateHandler); // source + QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target + QS_END_PRE() + QS_MEM_APP(); + QS_CRIT_EXIT(); } else { r = Q_RET_NULL; diff --git a/src/qf/qf_act.c b/src/qf/qf_act.c index 4998197c..fa8525ef 100644 --- a/src/qf/qf_act.c +++ b/src/qf/qf_act.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_act.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // diff --git a/src/qf/qf_actq.c b/src/qf/qf_actq.c index 2d0191fb..ec2ad98e 100644 --- a/src/qf/qf_actq.c +++ b/src/qf/qf_actq.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_actq.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -74,46 +66,49 @@ bool QActive_post_(QActive * const me, #endif #ifdef Q_UTEST // test? - #if Q_UTEST != 0 // testing QP-stub? + #if (Q_UTEST != 0) // testing QP-stub? if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? return QActiveDummy_fakePost_(me, e, margin, sender); } - #endif - #endif + #endif // (Q_UTEST != 0) + #endif // def Q_UTEST QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); + + QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary #ifndef Q_UNSAFE - Q_REQUIRE_INCRIT(100, QEvt_verify_(e)); - - uint8_t const pcopy = (uint8_t)(~me->prio_dis); - Q_INVARIANT_INCRIT(102, me->prio == pcopy); - #endif - - QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary + QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; + Q_INVARIANT_INCRIT(201, (QEvt_verify_(e)) && (tmp == dis)); + #endif // ndef Q_UNSAFE // test-probe#1 for faking queue overflow QS_TEST_PROBE_DEF(&QActive_post_) QS_TEST_PROBE_ID(1, - nFree = 0U; + tmp = 0U; // fake no free events ) + // required margin available? bool status; if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { + if (tmp > 0U) { // free entries available in the queue? status = true; // can post } - else { + else { // no free entries available status = false; // cannot post - Q_ERROR_INCRIT(110); // must be able to post the event + + // The queue overflows, but QF_NO_MARGIN indicates that + // the "event delivery guarantee" is required. + Q_ERROR_INCRIT(210); // must be able to post the event } } - else if (nFree > (QEQueueCtr)margin) { + else if (tmp > (QEQueueCtr)margin) { // enough free entries? status = true; // can post } - else { + else { // the # free entries below the requested margin status = false; // cannot post, but don't assert } @@ -123,22 +118,30 @@ bool QActive_post_(QActive * const me, } if (status) { // can post the event? + --tmp; // one free entry just used up - --nFree; // one free entry just used up - me->eQueue.nFree = nFree; // update the original - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; // increase minimum so far + me->eQueue.nFree = tmp; // update the original + #ifndef Q_UNSAFE + me->eQueue.nFree_dis = (QEQueueCtr)~tmp; // update the DIS + + if (me->eQueue.nMin > tmp) { + me->eQueue.nMin = tmp; // update minimum so far } + #endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->eQueue.nMin); // min # free entries - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + #ifndef Q_UNSAFE + QS_EQC_PRE(me->eQueue.nMin); // min # free entries + #else + QS_EQC_PRE(0U); // min # free entries + #endif + QS_END_PRE() #ifdef Q_UTEST // callback to examine the posted event under the same conditions @@ -153,47 +156,60 @@ bool QActive_post_(QActive * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); } - #endif + #endif // def Q_UTEST - if (me->eQueue.frontEvt == (QEvt *)0) { // empty queue? + if (me->eQueue.frontEvt == (QEvt *)0) { // is the queue empty? me->eQueue.frontEvt = e; // deliver event directly + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(211, me->eQueue.frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); + #endif // ndef Q_UNSAFE #ifdef QXK_H_ if (me->super.state.act == Q_ACTION_CAST(0)) { // eXtended? - QXTHREAD_EQUEUE_SIGNAL_(me); // signal the event queue + QXTHREAD_EQUEUE_SIGNAL_(me); // signal eXtended Thread } else { - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue + QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object } #else - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue - #endif + QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object + #endif // def QXK_H_ } - // queue is not empty, insert event into the ring-buffer - else { - // insert event into the ring buffer (FIFO) - me->eQueue.ring[me->eQueue.head] = e; + else { // queue was not empty, insert event into the ring-buffer + tmp = me->eQueue.head; // get volatile into temporary + #ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->eQueue.head_dis; + Q_INVARIANT_INCRIT(212, tmp == dis); + #endif // ndef Q_UNSAFE + me->eQueue.ring[tmp] = e; // insert e into buffer - if (me->eQueue.head == 0U) { // need to wrap head? - me->eQueue.head = me->eQueue.end; // wrap around + if (tmp == 0U) { // need to wrap the head? + tmp = me->eQueue.end; } - --me->eQueue.head; // advance the head (counter clockwise) + --tmp; // advance the head (counter-clockwise) + + me->eQueue.head = tmp; // update the original + #ifndef Q_UNSAFE + me->eQueue.head_dis = (QEQueueCtr)~tmp; + #endif // ndef Q_UNSAFE } QF_MEM_APP(); QF_CRIT_EXIT(); } - else { // cannot post the event + else { // event cannot be posted - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() #ifdef Q_UTEST // callback to examine the posted event under the same conditions @@ -208,14 +224,14 @@ bool QActive_post_(QActive * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); } - #endif + #endif // def Q_USTEST QF_MEM_APP(); QF_CRIT_EXIT(); #if (QF_MAX_EPOOL > 0U) QF_gc(e); // recycle the event to avoid a leak - #endif + #endif // (QF_MAX_EPOOL > 0U) } return status; @@ -229,57 +245,63 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { #ifdef Q_UTEST // test? - #if Q_UTEST != 0 // testing QP-stub? + #if (Q_UTEST != 0) // testing QP-stub? if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? QActiveDummy_fakePostLIFO_(me, e); return; } - #endif - #endif + #endif // (Q_UTEST != 0) + #endif // def Q_UTEST QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); + // the posted event must be be valid (which includes not NULL) + Q_REQUIRE_INCRIT(300, e != (QEvt *)0); + + QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary #ifndef Q_UNSAFE - Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); - - uint8_t const pcopy = (uint8_t)(~me->prio_dis); - Q_INVARIANT_INCRIT(202, me->prio == pcopy); - #endif - - #ifdef QXK_H_ - Q_REQUIRE_INCRIT(200, me->super.state.act != Q_ACTION_CAST(0)); - #endif - - QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary + QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; + Q_INVARIANT_INCRIT(301, (QEvt_verify_(e)) && (tmp == dis)); + #endif // ndef Q_UNSAFE // test-probe#1 for faking queue overflow QS_TEST_PROBE_DEF(&QActive_postLIFO_) QS_TEST_PROBE_ID(1, - nFree = 0U; + tmp = 0U; // fake no free events ) - Q_REQUIRE_INCRIT(201, nFree != 0U); + // The queue must NOT overflow for the LIFO posting policy. + Q_REQUIRE_INCRIT(310, tmp != 0U); if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? QEvt_refCtr_inc_(e); // increment the reference counter } - --nFree; // one free entry just used up - me->eQueue.nFree = nFree; // update the original - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; // update minimum so far - } + --tmp; // one free entry just used up - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->eQueue.nMin); // min # free entries - QS_END_PRE_() + me->eQueue.nFree = tmp; // update the original + #ifndef Q_UNSAFE + me->eQueue.nFree_dis = (QEQueueCtr)~tmp; + + if (me->eQueue.nMin > tmp) { + me->eQueue.nMin = tmp; // update minimum so far + } + #endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + #ifndef Q_UNSAFE + QS_EQC_PRE(me->eQueue.nMin); // min # free entries + #else + QS_EQC_PRE(0U); // min # free entries + #endif + QS_END_PRE() #ifdef Q_UTEST // callback to examine the posted event under the same conditions @@ -294,21 +316,32 @@ void QActive_postLIFO_(QActive * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); } - #endif + #endif // def Q_UTEST QEvt const * const frontEvt = me->eQueue.frontEvt; me->eQueue.frontEvt = e; // deliver the event directly to the front + #ifndef Q_UNSAFE + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); + #endif // ndef Q_UNSAFE - if (frontEvt == (QEvt *)0) { // was the queue empty? - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue - } - else { // queue was not empty, leave the event in the ring-buffer - ++me->eQueue.tail; - if (me->eQueue.tail == me->eQueue.end) { // need to wrap the tail? - me->eQueue.tail = 0U; // wrap around + if (frontEvt != (QEvt *)0) { // was the queue NOT empty? + tmp = me->eQueue.tail; // get volatile into temporary; + #ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(311, tmp == dis); + #endif // ndef Q_UNSAFE + ++tmp; + if (tmp == me->eQueue.end) { // need to wrap the tail? + tmp = 0U; // wrap around } - - me->eQueue.ring[me->eQueue.tail] = frontEvt; + me->eQueue.tail = tmp; + #ifndef Q_UNSAFE + me->eQueue.tail_dis = (QEQueueCtr)~tmp; + #endif // ndef Q_UNSAFE + me->eQueue.ring[tmp] = frontEvt; + } + else { // queue was empty + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } QF_MEM_APP(); @@ -324,43 +357,77 @@ QEvt const * QActive_get_(QActive * const me) { QF_CRIT_ENTRY(); QF_MEM_SYS(); - QACTIVE_EQUEUE_WAIT_(me); // wait for event to arrive directly + // wait for event to arrive directly (depends on QP port) + // NOTE: might use assertion-IDs 400-409 + QACTIVE_EQUEUE_WAIT_(me); // always remove event from the front QEvt const * const e = me->eQueue.frontEvt; - Q_INVARIANT_INCRIT(312, QEvt_verify_(e)); + QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary - QEQueueCtr const nFree = me->eQueue.nFree + 1U; // get volatile into tmp - me->eQueue.nFree = nFree; // update the # free + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(410, e != (QEvt *)0); // queue must NOT be empty + Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) + == (uintptr_t)~me->eQueue.frontEvt_dis); + QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; + Q_INVARIANT_INCRIT(412, tmp == dis); + #endif // ndef Q_UNSAFE + + ++tmp; // one more free event in the queue + + me->eQueue.nFree = tmp; // update the # free + #ifndef Q_UNSAFE + me->eQueue.nFree_dis = (QEQueueCtr)~tmp; + #endif // ndef Q_UNSAFE + + if (tmp <= me->eQueue.end) { // any events in the ring buffer? + + QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_END_PRE() - if (nFree <= me->eQueue.end) { // any events in the ring buffer? // remove event from the tail - me->eQueue.frontEvt = me->eQueue.ring[me->eQueue.tail]; - if (me->eQueue.tail == 0U) { // need to wrap the tail? - me->eQueue.tail = me->eQueue.end; // wrap around - } - --me->eQueue.tail; + tmp = me->eQueue.tail; // get volatile into temporary + #ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(420, tmp == dis); + #endif // ndef Q_UNSAFE + QEvt const * const frontEvt = me->eQueue.ring[tmp]; + #ifndef Q_UNSAFE + Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); + #endif // ndef Q_UNSAFE + me->eQueue.frontEvt = frontEvt; // update the original - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_END_PRE_() + if (tmp == 0U) { // need to wrap the tail? + tmp = me->eQueue.end; + } + --tmp; // advance the tail (counter-clockwise) + + me->eQueue.tail = tmp; // update the original + #ifndef Q_UNSAFE + me->eQueue.tail_dis = (QEQueueCtr)~tmp; + #endif // ndef Q_UNSAFE } else { me->eQueue.frontEvt = (QEvt *)0; // queue becomes empty + #ifndef Q_UNSAFE + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); + #endif // ndef Q_UNSAFE // all entries in the queue must be free (+1 for fronEvt) - Q_ASSERT_INCRIT(310, nFree == (me->eQueue.end + 1U)); + Q_ASSERT_INCRIT(440, tmp == (me->eQueue.end + 1U)); - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_GET_LAST, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() } QF_MEM_APP(); @@ -379,8 +446,12 @@ uint_fast16_t QF_getQueueMin(uint_fast8_t const prio) { QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(400, (prio <= QF_MAX_ACTIVE) && (QActive_registry_[prio] != (QActive *)0)); + #ifndef Q_UNSAFE uint_fast16_t const min = (uint_fast16_t)QActive_registry_[prio]->eQueue.nMin; + #else + uint_fast16_t const min = 0U; + #endif QF_CRIT_EXIT(); return min; @@ -409,6 +480,9 @@ void QTicker_ctor(QTicker * const me, // reuse eQueue.head for tick-rate me->super.eQueue.head = (QEQueueCtr)tickRate; + #ifndef Q_UNSAFE + me->super.eQueue.head_dis = (QEQueueCtr)~tickRate; + #endif // ndef Q_UNSAFE } //${QF::QTicker::init_} ...................................................... @@ -427,6 +501,9 @@ void QTicker_init_( QF_MEM_SYS(); QACTIVE_CAST_(me)->eQueue.tail = 0U; + #ifndef Q_UNSAFE + QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; + #endif // ndef Q_UNSAFE QF_MEM_APP(); QF_CRIT_EXIT(); @@ -446,14 +523,28 @@ void QTicker_dispatch_( QF_CRIT_ENTRY(); QF_MEM_SYS(); - QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; // save # of ticks + // get volatile into temporaries + QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; + QEQueueCtr const tickRate = QACTIVE_CAST_(me)->eQueue.head; + + #ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(700, nTicks > 0U); + QEQueueCtr dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.tail_dis; + Q_INVARIANT_INCRIT(701, nTicks == dis); + dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.head_dis; + Q_INVARIANT_INCRIT(702, tickRate == dis); + #endif // ndef Q_UNSAFE + QACTIVE_CAST_(me)->eQueue.tail = 0U; // clear # ticks + #ifndef Q_UNSAFE + QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; + #endif // ndef Q_UNSAFE QF_MEM_APP(); QF_CRIT_EXIT(); for (; nTicks > 0U; --nTicks) { - QTimeEvt_tick_((uint_fast8_t)QACTIVE_CAST_(me)->eQueue.head, me); + QTimeEvt_tick_((uint_fast8_t)tickRate, me); } } @@ -467,30 +558,64 @@ void QTicker_trig_( Q_UNUSED_PAR(sender); #endif + static QEvt const tickEvt = QEVT_INITIALIZER(0); + QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); - if (me->eQueue.frontEvt == (QEvt *)0) { + QEQueueCtr nTicks = me->eQueue.tail; // get volatile into temporary + + if (me->eQueue.frontEvt == (QEvt *)0) { // no tick events? + #ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(800, nTicks == 0U); + Q_REQUIRE_INCRIT(801, me->eQueue.nFree == 1U); + Q_INVARIANT_INCRIT(802, me->eQueue.frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); + QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; + Q_INVARIANT_INCRIT(803, 1U == dis); + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(804, 0U == dis); + #endif // ndef Q_UNSAFE - static QEvt const tickEvt = QEVT_INITIALIZER(0); me->eQueue.frontEvt = &tickEvt; // deliver event directly - --me->eQueue.nFree; // one less free event + me->eQueue.nFree = 0U; + #ifndef Q_UNSAFE + me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt); + me->eQueue.nFree_dis = (QEQueueCtr)~0U; + #endif // ndef Q_UNSAFE QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } + else { + #ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(810, (nTicks > 0U) && (nTicks < 0xFFU)); + Q_REQUIRE_INCRIT(811, me->eQueue.nFree == 0U); + Q_INVARIANT_INCRIT(812, me->eQueue.frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt)); + QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; + Q_INVARIANT_INCRIT(813, 0U == dis); + dis = (QEQueueCtr)~me->eQueue.tail_dis; + Q_INVARIANT_INCRIT(814, nTicks == dis); + #endif // ndef Q_UNSAFE + } - ++me->eQueue.tail; // account for one more tick event + ++nTicks; // account for one more tick event - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(0U); // the signal of the event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(0U, 0U); // poolNum & refCtr - QS_EQC_PRE_(0U); // # free entries - QS_EQC_PRE_(0U); // min # free entries - QS_END_PRE_() + me->eQueue.tail = nTicks; // update the original + #ifndef Q_UNSAFE + me->eQueue.tail_dis = (QEQueueCtr)~nTicks; + #endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(0U); // the signal of the event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(0U, 0U); // poolNum & refCtr + QS_EQC_PRE(0U); // # free entries + QS_EQC_PRE(0U); // min # free entries + QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); diff --git a/src/qf/qf_defer.c b/src/qf/qf_defer.c index e7d7dd15..28c0fe68 100644 --- a/src/qf/qf_defer.c +++ b/src/qf/qf_defer.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_defer.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -72,13 +64,13 @@ bool QActive_defer(QActive const * const me, QS_CRIT_STAT QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_DEFER, me->prio) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this active object - QS_OBJ_PRE_(eq); // the deferred queue - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_DEFER, me->prio) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this active object + QS_OBJ_PRE(eq); // the deferred queue + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); @@ -115,13 +107,13 @@ bool QActive_recall(QActive * const me, QEvt_refCtr_dec_(e); // decrement the reference counter } - QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL, me->prio) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this active object - QS_OBJ_PRE_(eq); // the deferred queue - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL, me->prio) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this active object + QS_OBJ_PRE(eq); // the deferred queue + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -132,11 +124,11 @@ bool QActive_recall(QActive * const me, QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) - QS_TIME_PRE_(); // time stamp - QS_OBJ_PRE_(me); // this active object - QS_OBJ_PRE_(eq); // the deferred queue - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) + QS_TIME_PRE(); // time stamp + QS_OBJ_PRE(me); // this active object + QS_OBJ_PRE(eq); // the deferred queue + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); diff --git a/src/qf/qf_dyn.c b/src/qf/qf_dyn.c index 2b4fe93f..fc172386 100644 --- a/src/qf/qf_dyn.c +++ b/src/qf/qf_dyn.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_dyn.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -124,7 +116,11 @@ uint_fast16_t QF_getPoolMin(uint_fast8_t const poolNum) { Q_REQUIRE_INCRIT(400, (poolNum <= QF_MAX_EPOOL) && (0U < poolNum) && (poolNum <= QF_priv_.maxPool_)); + #ifndef Q_UNSAFE uint_fast16_t const min = (uint_fast16_t)QF_priv_.ePool_[poolNum - 1U].nMin; + #else + uint_fast16_t const min = 0U; + #endif QF_MEM_APP(); QF_CRIT_EXIT(); @@ -174,16 +170,16 @@ QEvt * QF_newX_( if (e != (QEvt *)0) { // was e allocated correctly? e->sig = (QSignal)sig; // set the signal e->refCtr_ = 0U; // initialize the reference counter to 0 - e->evtTag_ = (uint8_t)(QEVT_MARKER | poolNum); + e->evtTag_ = (uint8_t)((poolNum << 4U) | 0x0FU); QS_CRIT_ENTRY(); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_NEW, + QS_BEGIN_PRE(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_EVS_PRE_(evtSize); // the size of the event - QS_SIG_PRE_(sig); // the signal of the event - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_EVS_PRE(evtSize); // the size of the event + QS_SIG_PRE(sig); // the signal of the event + QS_END_PRE() QS_MEM_APP(); QS_CRIT_EXIT(); } @@ -196,12 +192,12 @@ QEvt * QF_newX_( Q_ASSERT_INCRIT(320, margin != QF_NO_MARGIN); QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, + QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_EVS_PRE_(evtSize); // the size of the event - QS_SIG_PRE_(sig); // the signal of the event - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_EVS_PRE(evtSize); // the size of the event + QS_SIG_PRE(sig); // the signal of the event + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -217,7 +213,12 @@ QEvt * QF_newX_( void QF_gc(QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(400, QEvt_verify_(e)); + + Q_REQUIRE_INCRIT(400, e != (QEvt *)0); + + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(401, QEvt_verify_(e)); + #endif uint_fast8_t const poolNum = QEvt_getPoolNum_(e); @@ -226,12 +227,12 @@ void QF_gc(QEvt const * const e) { if (e->refCtr_ > 1U) { // isn't this the last reference? - QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT, + QS_BEGIN_PRE(QS_QF_GC_ATTEMPT, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() QEvt_refCtr_dec_(e); // decrement the ref counter @@ -240,12 +241,12 @@ void QF_gc(QEvt const * const e) { } else { // this is the last reference to this event, recycle it - QS_BEGIN_PRE_(QS_QF_GC, + QS_BEGIN_PRE(QS_QF_GC, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() // pool number must be in range Q_ASSERT_INCRIT(410, (poolNum <= QF_priv_.maxPool_) @@ -282,23 +283,26 @@ QEvt const * QF_newRef_( QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(500, QEvt_verify_(e)); + Q_REQUIRE_INCRIT(500, e != (QEvt *)0); + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(501, QEvt_verify_(e)); + #endif uint_fast8_t const poolNum = QEvt_getPoolNum_(e); Q_UNUSED_PAR(poolNum); // might be unused - Q_REQUIRE_INCRIT(501, (poolNum != 0U) + Q_REQUIRE_INCRIT(510, (poolNum != 0U) && (evtRef == (void *)0)); QEvt_refCtr_inc_(e); // increments the ref counter QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_NEW_REF, + QS_BEGIN_PRE(QS_QF_NEW_REF, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() QS_MEM_APP(); QF_CRIT_EXIT(); @@ -313,20 +317,22 @@ void QF_deleteRef_(void const * const evtRef) { QF_CRIT_ENTRY(); QEvt const * const e = (QEvt const *)evtRef; - Q_REQUIRE_INCRIT(600, QEvt_verify_(e)); + Q_REQUIRE_INCRIT(600, e != (QEvt *)0); + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(601, QEvt_verify_(e)); + #endif // ndef Q_UNSAFE #ifdef Q_SPY uint_fast8_t const poolNum = QEvt_getPoolNum_(e); - #endif - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QF_DELETE_REF, + QS_BEGIN_PRE(QS_QF_DELETE_REF, (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_2U8_PRE_(poolNum, e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_2U8_PRE(poolNum, e->refCtr_); + QS_END_PRE() QS_MEM_APP(); + #endif // def Q_SPY QF_CRIT_EXIT(); diff --git a/src/qf/qf_mem.c b/src/qf/qf_mem.c index 7732a87e..fa12c8de 100644 --- a/src/qf/qf_mem.c +++ b/src/qf/qf_mem.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_mem.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -74,14 +66,15 @@ void QMPool_init(QMPool * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(100, (poolSto != (void *)0) - && (poolSize >= (uint_fast32_t)sizeof(QFreeBlock)) - && ((uint_fast16_t)(blockSize + sizeof(QFreeBlock)) > blockSize)); + Q_REQUIRE_INCRIT(100, poolSto != (void *)0); + Q_REQUIRE_INCRIT(101, poolSize >= (uint_fast32_t)sizeof(QFreeBlock)); + Q_REQUIRE_INCRIT(102, (uint_fast16_t)(blockSize + sizeof(QFreeBlock)) + > blockSize); me->free_head = (QFreeBlock *)poolSto; // find # free blocks in a memory block, NO DIVISION - me->blockSize = (QMPoolSize)sizeof(QFreeBlock); + me->blockSize = (QMPoolSize)(2U * sizeof(void *)); uint_fast16_t nblocks = 1U; while (me->blockSize < (QMPoolSize)blockSize) { me->blockSize += (QMPoolSize)sizeof(QFreeBlock); @@ -102,10 +95,10 @@ void QMPool_init(QMPool * const me, { fb->next = &fb[nblocks]; // point next link to next block #ifndef Q_UNSAFE - fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); + fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); #endif - fb = fb->next; // advance to the next block - ++nTot; // one more free block in the pool + fb = fb->next; // advance to the next block + ++nTot; // one more free block in the pool } // dynamic range check @@ -116,16 +109,19 @@ void QMPool_init(QMPool * const me, #endif fb->next = (QFreeBlock *)0; // the last link points to NULL - #ifndef Q_UNSAFE - fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); - #endif me->nTot = (QMPoolCtr)nTot; me->nFree = me->nTot; // all blocks are free - me->nMin = me->nTot; // the minimum # free blocks me->start = (QFreeBlock *)poolSto; // the original start this pool buffer me->end = fb; // the last block in this pool + #ifndef Q_UNSAFE + me->free_head_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->free_head); + me->nFree_dis = (QMPoolCtr)~me->nFree; + me->nMin = me->nTot; // the minimum # free blocks + fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); + #endif + QF_MEM_APP(); QF_CRIT_EXIT(); } @@ -144,62 +140,82 @@ void * QMPool_get(QMPool * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - // have more free blocks than the requested margin? - QFreeBlock *fb; - if (me->nFree > (QMPoolCtr)margin) { - fb = me->free_head; // get a free block + // get volatile into temporaries + QFreeBlock *fb = me->free_head; + QMPoolCtr nFree = me->nFree; - // a free block must be valid - Q_ASSERT_INCRIT(300, fb != (QFreeBlock *)0); + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, Q_PTR2UINT_CAST_(fb) + == (uintptr_t)~me->free_head_dis); + QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; + Q_INVARIANT_INCRIT(302, nFree == dis); + #endif // ndef Q_UNSAFE + + // have more free blocks than the requested margin? + if (nFree > (QMPoolCtr)margin) { + Q_ASSERT_INCRIT(310, fb != (QFreeBlock *)0); QFreeBlock * const fb_next = fb->next; // fast temporary + #ifndef Q_UNSAFE // the free block must have integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(302, Q_UINTPTR_CAST_(fb_next) - == (uintptr_t)~fb->next_dis); + Q_INVARIANT_INCRIT(311, Q_PTR2UINT_CAST_(fb_next) + == (uintptr_t)~fb->next_dis); + #endif // ndef Q_UNSAFE - --me->nFree; // one less free block - if (me->nFree == 0U) { // is the pool becoming empty? + --nFree; // one less free block + if (nFree == 0U) { // is the pool becoming empty? // pool is becoming empty, so the next free block must be NULL Q_ASSERT_INCRIT(320, fb_next == (QFreeBlock *)0); + me->nFree = 0U; + #ifndef Q_UNSAFE + me->nFree_dis = (QMPoolCtr)~0U; me->nMin = 0U; // remember that the pool got empty + #endif // ndef Q_UNSAFE } else { - // invariant: - // The pool is not empty, so the next free-block pointer, - // so the next free block must be in range. + me->nFree = nFree; // update the original + #ifndef Q_UNSAFE + me->nFree_dis = (QMPoolCtr)~nFree; - // NOTE: The next free block pointer can fall out of range - // when the client code writes past the memory block, thus - // corrupting the next block. - Q_ASSERT_INCRIT(330, + // The pool is not empty, so the next free-block pointer + // must be in range. + Q_INVARIANT_INCRIT(330, (me->start <= fb_next) && (fb_next <= me->end)); // is the # free blocks the new minimum so far? - if (me->nMin > me->nFree) { - me->nMin = me->nFree; // remember the new minimum + if (me->nMin > nFree) { + me->nMin = nFree; // remember the minimum so far } + #endif // ndef Q_UNSAFE } me->free_head = fb_next; // set the head to the next free block + #ifndef Q_UNSAFE + me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb_next)); + #endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // # of free blocks in the pool - QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // # of free blocks in the pool + #ifndef Q_UNSAFE + QS_MPC_PRE(me->nMin); // min # free blocks ever in the pool + #else + QS_MPC_PRE(0U); // min # free blocks (not available) + #endif // ndef Q_UNSAFE + QS_END_PRE() } else { // don't have enough free blocks at this point fb = (QFreeBlock *)0; - QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // # of free blocks in the pool - QS_MPC_PRE_(margin); // the requested margin - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // # of free blocks in the pool + QS_MPC_PRE(margin); // the requested margin + QS_END_PRE() } QF_MEM_APP(); @@ -224,24 +240,40 @@ void QMPool_put(QMPool * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(200, (me->nFree < me->nTot) - && (me->start <= fb) && (fb <= me->end)); + // get volatile into temporaries + QFreeBlock * const free_head = me->free_head; + QMPoolCtr nFree = me->nFree; - fb->next = me->free_head; // link into list #ifndef Q_UNSAFE - fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); + Q_INVARIANT_INCRIT(401, Q_PTR2UINT_CAST_(free_head) + == (uintptr_t)~me->free_head_dis); + QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; + Q_INVARIANT_INCRIT(402, nFree == dis); + + Q_REQUIRE_INCRIT(410, nFree < me->nTot); + Q_REQUIRE_INCRIT(411, (me->start <= fb) && (fb <= me->end)); + + // the block must not be in the pool already + Q_REQUIRE_INCRIT(412, Q_PTR2UINT_CAST_(fb->next) + != (uintptr_t)~fb->next_dis); + #endif // ndef Q_UNSAFE + + ++nFree; // one more free block in this pool + + me->free_head = fb; // set as new head of the free list + me->nFree = nFree; + fb->next = free_head; // link into the list + #ifndef Q_UNSAFE + me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb)); + me->nFree_dis = (QMPoolCtr)~nFree; + fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(free_head)); #endif - // set as new head of the free list - me->free_head = fb; - - ++me->nFree; // one more free block in this pool - - QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this memory pool - QS_MPC_PRE_(me->nFree); // the # free blocks in the pool - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this memory pool + QS_MPC_PRE(nFree); // the # free blocks in the pool + QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); diff --git a/src/qf/qf_ps.c b/src/qf/qf_ps.c index 49331948..ff7ee56a 100644 --- a/src/qf/qf_ps.c +++ b/src/qf/qf_ps.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_ps.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -113,12 +105,12 @@ void QActive_publish_( QPSet_verify_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis)); - QS_BEGIN_PRE_(QS_QF_PUBLISH, qsId) - QS_TIME_PRE_(); // the timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(sig); // the signal of the event - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_PUBLISH, qsId) + QS_TIME_PRE(); // the timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(sig); // the signal of the event + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() // is it a mutable event? if (QEvt_getPoolNum_(e) != 0U) { @@ -210,7 +202,7 @@ void QActive_subscribe(QActive const * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(300, ((enum_t)Q_USER_SIG <= sig) + Q_REQUIRE_INCRIT(300, (Q_USER_SIG <= sig) && (sig < QActive_maxPubSignal_) && (0U < p) && (p <= QF_MAX_ACTIVE) && (QActive_registry_[p] == me)); @@ -218,11 +210,11 @@ void QActive_subscribe(QActive const * const me, QPSet_verify_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis)); - QS_BEGIN_PRE_(QS_QF_ACTIVE_SUBSCRIBE, p) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_SUBSCRIBE, p) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_END_PRE() // insert the prio. into the subscriber set QPSet_insert(&QActive_subscrList_[sig].set, p); @@ -249,7 +241,7 @@ void QActive_unsubscribe(QActive const * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(400, ((enum_t)Q_USER_SIG <= sig) + Q_REQUIRE_INCRIT(400, (Q_USER_SIG <= sig) && (sig < QActive_maxPubSignal_) && (0U < p) && (p <= QF_MAX_ACTIVE) && (QActive_registry_[p] == me)); @@ -257,11 +249,11 @@ void QActive_unsubscribe(QActive const * const me, QPSet_verify_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis)); - QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_END_PRE() // remove the prio. from the subscriber set QPSet_remove(&QActive_subscrList_[sig].set, p); @@ -293,7 +285,7 @@ void QActive_unsubscribeAll(QActive const * const me) { QF_MEM_APP(); QF_CRIT_EXIT(); - for (enum_t sig = (enum_t)Q_USER_SIG; sig < maxPubSig; ++sig) { + for (enum_t sig = Q_USER_SIG; sig < maxPubSig; ++sig) { QF_CRIT_ENTRY(); QF_MEM_SYS(); @@ -303,11 +295,11 @@ void QActive_unsubscribeAll(QActive const * const me) { QPSet_update_(&QActive_subscrList_[sig].set, &QActive_subscrList_[sig].set_dis); #endif - QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_END_PRE() } QF_MEM_APP(); QF_CRIT_EXIT(); diff --git a/src/qf/qf_qact.c b/src/qf/qf_qact.c index 763a0373..24d9f437 100644 --- a/src/qf/qf_qact.c +++ b/src/qf/qf_qact.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_qact.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // diff --git a/src/qf/qf_qeq.c b/src/qf/qf_qeq.c index eabef8af..c800f67e 100644 --- a/src/qf/qf_qeq.c +++ b/src/qf/qf_qeq.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_qeq.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -62,12 +54,11 @@ Q_DEFINE_THIS_MODULE("qf_qeq") //$define${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QF::QEQueue} ............................................................. -QEQueue QEQueue_dummy; //${QF::QEQueue::init} ....................................................... //! @public @memberof QEQueue void QEQueue_init(QEQueue * const me, - struct QEvt const ** const qSto, + struct QEvt const * * const qSto, uint_fast16_t const qLen) { QF_CRIT_STAT @@ -81,12 +72,19 @@ void QEQueue_init(QEQueue * const me, me->frontEvt = (QEvt *)0; // no events in the queue me->ring = qSto; // the beginning of the ring buffer me->end = (QEQueueCtr)qLen; - if (qLen != 0U) { + if (qLen > 0U) { me->head = 0U; me->tail = 0U; } me->nFree = (QEQueueCtr)(qLen + 1U); // +1 for frontEvt - me->nMin = me->nFree; + + #ifndef Q_UNSAFE + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->frontEvt); + me->head_dis = (QEQueueCtr)~me->head; + me->tail_dis = (QEQueueCtr)~me->tail; + me->nFree_dis = (QEQueueCtr)~me->nFree; + me->nMin = me->nFree; + #endif QF_MEM_APP(); QF_CRIT_EXIT(); @@ -107,46 +105,81 @@ bool QEQueue_post(QEQueue * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); - QEQueueCtr nFree = me->nFree; // get volatile into temporary + QEQueueCtr tmp = me->nFree; // get volatile into temporary + + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); + QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; + Q_INVARIANT_INCRIT(202, tmp == dis); + #endif // ndef Q_UNSAFE + + // test-probe#1 for faking queue overflow + QS_TEST_PROBE_DEF(&QEQueue_post) + QS_TEST_PROBE_ID(1, + tmp = 0U; // fake no free events + ) // required margin available? bool status; - if (((margin == QF_NO_MARGIN) && (nFree > 0U)) - || (nFree > (QEQueueCtr)margin)) + if (((margin == QF_NO_MARGIN) && (tmp > 0U)) + || (tmp > (QEQueueCtr)margin)) { // is it a mutable event? if (QEvt_getPoolNum_(e) != 0U) { QEvt_refCtr_inc_(e); // increment the reference counter } - --nFree; // one free entry just used up - me->nFree = nFree; // update the original - if (me->nMin > nFree) { - me->nMin = nFree; // update minimum so far + --tmp; // one free entry just used up + + me->nFree = tmp; // update the original + #ifndef Q_UNSAFE + me->nFree_dis = (QEQueueCtr)~tmp; + + if (me->nMin > tmp) { + me->nMin = tmp; // update minimum so far } + #endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_EQUEUE_POST, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->nMin); // min # free entries - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_POST, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + #ifndef Q_UNSAFE + QS_EQC_PRE(me->nMin); // min # free entries + #else + QS_EQC_PRE(0U); // min # free entries + #endif + QS_END_PRE() - if (me->frontEvt == (QEvt *)0) { // was the queue empty? + if (me->frontEvt == (QEvt *)0) { // is the queue empty? me->frontEvt = e; // deliver event directly + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(211, me->frontEvt_dis + == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); + #endif // ndef Q_UNSAFE } else { // queue was not empty, insert event into the ring-buffer - // insert event into the ring buffer (FIFO)... - me->ring[me->head] = e; // insert e into buffer - // need to wrap the head? - if (me->head == 0U) { - me->head = me->end; // wrap around + tmp = me->head; // get volatile into temporary + #ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->head_dis; + Q_INVARIANT_INCRIT(212, tmp == dis); + #endif // ndef Q_UNSAFE + me->ring[tmp] = e; // insert e into buffer + + if (tmp == 0U) { // need to wrap the head? + tmp = me->end; } - --me->head; + --tmp; // advance head (counter-clockwise) + + me->head = tmp; // update the original + #ifndef Q_UNSAFE + me->head_dis = (QEQueueCtr)~tmp; + #endif // ndef Q_UNSAFE } status = true; // event posted successfully } @@ -154,14 +187,14 @@ bool QEQueue_post(QEQueue * const me, // dropping events must be acceptable Q_ASSERT_INCRIT(210, margin != QF_NO_MARGIN); - QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_ATTEMPT, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_POST_ATTEMPT, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_EQC_PRE(margin); // margin requested + QS_END_PRE() status = false; // event not posted } @@ -186,39 +219,74 @@ void QEQueue_postLIFO(QEQueue * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); + Q_REQUIRE_INCRIT(300, e != (QEvt *)0); - QEQueueCtr nFree = me->nFree; // get volatile into temporary - Q_REQUIRE_INCRIT(301, nFree != 0U); + QEQueueCtr tmp = me->nFree; // get volatile into temporary + + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); + QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; + Q_INVARIANT_INCRIT(302, tmp == dis); + #endif // ndef Q_UNSAFE + + // test-probe#1 for faking queue overflow + QS_TEST_PROBE_DEF(&QEQueue_postLIFO) + QS_TEST_PROBE_ID(1, + tmp = 0U; // fake no free events + ) + + // must be able to LIFO-post the event + Q_REQUIRE_INCRIT(310, tmp != 0U); if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? QEvt_refCtr_inc_(e); // increment the reference counter } - --nFree; // one free entry just used up - me->nFree = nFree; // update the original - if (me->nMin > nFree) { - me->nMin = nFree; // update minimum so far + --tmp; // one free entry just used up + + me->nFree = tmp; // update the original + #ifndef Q_UNSAFE + me->nFree_dis = (QEQueueCtr)~tmp; + + if (me->nMin > tmp) { + me->nMin = tmp; // update minimum so far } + #endif // ndef Q_UNSAFE - QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_LIFO, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_EQC_PRE_(me->nMin); // min # free entries - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_POST_LIFO, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + #ifndef Q_UNSAFE + QS_EQC_PRE(me->nMin); // min # free entries + #else + QS_EQC_PRE(0U); // min # free entries + #endif + QS_END_PRE() - QEvt const * const frontEvt = me->frontEvt; // read into temporary - me->frontEvt = e; // deliver event directly to the front of the queue + QEvt const * const frontEvt = me->frontEvt; + me->frontEvt = e; // deliver the event directly to the front + #ifndef Q_UNSAFE + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); + #endif // ndef Q_UNSAFE - if (frontEvt != (QEvt *)0) { // was the queue not empty? - ++me->tail; - if (me->tail == me->end) { // need to wrap the tail? - me->tail = 0U; // wrap around + if (frontEvt != (QEvt *)0) { // was the queue NOT empty? + tmp = me->tail; // get volatile into temporary; + #ifndef Q_UNSAFE + dis = (QEQueueCtr)~me->tail_dis; + Q_INVARIANT_INCRIT(311, tmp == dis); + #endif // ndef Q_UNSAFE + ++tmp; + if (tmp == me->end) { // need to wrap the tail? + tmp = 0U; // wrap around } - me->ring[me->tail] = frontEvt; // save old front evt + me->tail = tmp; + #ifndef Q_UNSAFE + me->tail_dis = (QEQueueCtr)~tmp; + #endif + me->ring[tmp] = frontEvt; } QF_MEM_APP(); @@ -239,42 +307,68 @@ struct QEvt const * QEQueue_get(QEQueue * const me, QF_MEM_SYS(); QEvt const * const e = me->frontEvt; // always remove evt from the front + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) + == (uintptr_t)~me->frontEvt_dis); + #endif // ndef Q_UNSAFE if (e != (QEvt *)0) { // was the queue not empty? - Q_INVARIANT_INCRIT(412, QEvt_verify_(e)); + QEQueueCtr tmp = me->nFree; // get volatile into temporary + #ifndef Q_UNSAFE + QEQueueCtr const dis = (QEQueueCtr)~me->nFree_dis; + Q_INVARIANT_INCRIT(412, tmp == dis); + #endif // ndef Q_UNSAFE - // use a temporary variable to increment me->nFree - QEQueueCtr const nFree = me->nFree + 1U; - me->nFree = nFree; // update the # free + ++tmp; // one more free event in the queue + + me->nFree = tmp; // update the # free + #ifndef Q_UNSAFE + me->nFree_dis = (QEQueueCtr)~tmp; + #endif // ndef Q_UNSAFE // any events in the ring buffer? - if (nFree <= me->end) { - me->frontEvt = me->ring[me->tail]; // get from tail - if (me->tail == 0U) { // need to wrap the tail? - me->tail = me->end; // wrap around - } - --me->tail; + if (tmp <= me->end) { - QS_BEGIN_PRE_(QS_QF_EQUEUE_GET, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_GET, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_END_PRE() + + tmp = me->tail; // get volatile into temporary + QEvt const * const frontEvt = me->ring[tmp]; + #ifndef Q_UNSAFE + Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); + #endif // ndef Q_UNSAFE + me->frontEvt = frontEvt; // update the original + + if (tmp == 0U) { // need to wrap the tail? + tmp = me->end; + } + --tmp; // advance the tail (counter-clockwise) + me->tail = tmp; // update the original + #ifndef Q_UNSAFE + me->tail_dis = (QEQueueCtr)~tmp; + #endif // ndef Q_UNSAFE } else { me->frontEvt = (QEvt *)0; // queue becomes empty + #ifndef Q_UNSAFE + me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); + #endif // ndef Q_UNSAFE - // all entries in the queue must be free (+1 for fronEvt) - Q_INVARIANT_INCRIT(420, nFree == (me->end + 1U)); + // all entries in the queue must be free (+1 for frontEvt) + Q_INVARIANT_INCRIT(440, tmp == (me->end + 1U)); - QS_BEGIN_PRE_(QS_QF_EQUEUE_GET_LAST, qsId) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this queue object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_EQUEUE_GET_LAST, qsId) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this queue object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_END_PRE() } } diff --git a/src/qf/qf_qmact.c b/src/qf/qf_qmact.c index 5d2b1058..2f7b8861 100644 --- a/src/qf/qf_qmact.c +++ b/src/qf/qf_qmact.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_qmact.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // diff --git a/src/qf/qf_time.c b/src/qf/qf_time.c index d65e6ac3..5477e254 100644 --- a/src/qf/qf_time.c +++ b/src/qf/qf_time.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qf::qf_time.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -64,6 +56,10 @@ Q_DEFINE_THIS_MODULE("qf_time") //${QF::QTimeEvt} ............................................................ QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; +#ifndef Q_UNSAFE +uintptr_t QTimeEvt_timeEvtHead_dis_[QF_MAX_TICK_RATE]; +#endif // ndef Q_UNSAFE + //${QF::QTimeEvt::ctorX} ..................................................... //! @public @memberof QTimeEvt void QTimeEvt_ctorX(QTimeEvt * const me, @@ -77,75 +73,104 @@ void QTimeEvt_ctorX(QTimeEvt * const me, && (tickRate < QF_MAX_TICK_RATE)); QF_CRIT_EXIT(); - // Initialize the QEvt superclass: - // NOTE: The refCtr_ attribute is not used in time events, - // so it is reused to hold the tickRate as well as other - // information about the status of the time event. - me->super.sig = (QSignal)sig; - me->super.refCtr_ = (uint8_t)tickRate; - me->super.evtTag_ = QEVT_MARKER; + QEvt_ctor(&me->super, sig); me->next = (QTimeEvt *)0; me->act = act; me->ctr = 0U; me->interval = 0U; + me->tickRate = (uint8_t)tickRate; + me->flags = 0U; + + #ifndef Q_UNSAFE + me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); + me->ctr_dis = (QTimeEvtCtr)~me->ctr; + #endif // ndef Q_UNSAFE } //${QF::QTimeEvt::armX} ...................................................... //! @public @memberof QTimeEvt void QTimeEvt_armX(QTimeEvt * const me, - QTimeEvtCtr const nTicks, - QTimeEvtCtr const interval) + uint32_t const nTicks, + uint32_t const interval) { - uint_fast8_t const tickRate - = ((uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE); - QTimeEvtCtr const ctr = me->ctr; - #ifdef Q_SPY - uint_fast8_t const qsId = ((QActive *)(me->act))->prio; - #endif - QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(400, (me->act != (void *)0) - && (ctr == 0U) - && (nTicks != 0U) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) - && (me->super.sig >= (QSignal)Q_USER_SIG)); - #ifdef Q_UNSAFE - Q_UNUSED_PAR(ctr); + // dynamic range checks + #if (QF_TIMEEVT_CTR_SIZE == 1U) + Q_REQUIRE_INCRIT(400, (nTicks < 0xFFU) && (interval < 0xFFU)); + #elif (QF_TIMEEVT_CTR_SIZE == 2U) + Q_REQUIRE_INCRIT(400, (nTicks < 0xFFFFU) && (interval < 0xFFFFU)); #endif - me->ctr = nTicks; - me->interval = interval; + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(401, QEvt_verify_(&me->super)); + #endif + + QTimeEvtCtr const ctr = me->ctr; + uint8_t const tickRate = me->tickRate; + #ifdef Q_SPY + uint_fast8_t const qsId = ((QActive *)(me->act))->prio; + #endif + + Q_REQUIRE_INCRIT(410, + (nTicks != 0U) + && (ctr == 0U) + && (me->act != (void *)0) + && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE)); + + #ifndef Q_UNSAFE + QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; + Q_INVARIANT_INCRIT(411, ctr == dis); + #else + Q_UNUSED_PAR(ctr); + #endif // ndef Q_UNSAFE + + me->ctr = (QTimeEvtCtr)nTicks; + me->interval = (QTimeEvtCtr)interval; + #ifndef Q_UNSAFE + me->ctr_dis = (QTimeEvtCtr)~nTicks; + #endif // ndef Q_UNSAFE // is the time event unlinked? // NOTE: For the duration of a single clock tick of the specified tick // rate a time event can be disarmed and yet still linked into the list // because un-linking is performed exclusively in QTimeEvt_tick_(). - if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - // mark as linked - me->super.refCtr_ |= QTE_IS_LINKED; + if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { + me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - // The time event is initially inserted into the separate - // "freshly armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly armed" - // list is appended to the main list of armed time events based on - // QTimeEvt_timeEvtHead_[tickRate].next. Again, this is to keep any - // changes to the main list exclusively inside the QTimeEvt_tick_(). + // The time event is initially inserted into the separate "freshly + // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly + // armed" list is appended to the main list of armed time events + // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is + // to keep any changes to the main list exclusively inside the + // QTimeEvt_tick_(). + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(420, + Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); + Q_INVARIANT_INCRIT(421, + Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == + (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); + #endif me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; + #ifndef Q_UNSAFE + me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); + QTimeEvt_timeEvtHead_dis_[tickRate] = (uintptr_t)~Q_PTR2UINT_CAST_(me); + #endif // ndef Q_UNSAFE } - QS_BEGIN_PRE_(QS_QF_TIMEEVT_ARM, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the active object - QS_TEC_PRE_(nTicks); // the # ticks - QS_TEC_PRE_(interval); // the interval - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_TIMEEVT_ARM, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the active object + QS_TEC_PRE(nTicks); // the # ticks + QS_TEC_PRE(interval); // the interval + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -154,41 +179,51 @@ void QTimeEvt_armX(QTimeEvt * const me, //${QF::QTimeEvt::disarm} .................................................... //! @public @memberof QTimeEvt bool QTimeEvt_disarm(QTimeEvt * const me) { - #ifdef Q_SPY - uint_fast8_t const qsId = QACTIVE_CAST_(me->act)->prio; - #endif - QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); - // is the time event actually armed? + QTimeEvtCtr const ctr = me->ctr; + + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(500, QEvt_verify_(&me->super)); + QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; + Q_INVARIANT_INCRIT(501, ctr == dis); + #endif // ndef Q_UNSAFE + + #ifdef Q_SPY + uint_fast8_t const qsId = QACTIVE_CAST_(me->act)->prio; + #endif + + // was the time event actually armed? bool wasArmed; - if (me->ctr != 0U) { + if (ctr != 0U) { wasArmed = true; - me->super.refCtr_ |= QTE_WAS_DISARMED; - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the target AO - QS_TEC_PRE_(me->ctr); // the # ticks - QS_TEC_PRE_(me->interval); // the interval - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate - QS_END_PRE_() - + me->flags |= QTE_FLAG_WAS_DISARMED; me->ctr = 0U; // schedule removal from the list + #ifndef Q_UNSAFE + me->ctr_dis = (QTimeEvtCtr)~0U; + #endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the target AO + QS_TEC_PRE(ctr); // the # ticks + QS_TEC_PRE(me->interval); // the interval + QS_U8_PRE(me->tickRate); // tick rate + QS_END_PRE() } else { // the time event was already disarmed automatically wasArmed = false; - me->super.refCtr_ &= (uint8_t)(~QTE_WAS_DISARMED & 0xFFU); + me->flags &= (uint8_t)(~QTE_FLAG_WAS_DISARMED & 0xFFU); - QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the target AO - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the target AO + QS_U8_PRE(me->tickRate); // tick rate + QS_END_PRE() } QF_MEM_APP(); @@ -200,26 +235,45 @@ bool QTimeEvt_disarm(QTimeEvt * const me) { //${QF::QTimeEvt::rearm} ..................................................... //! @public @memberof QTimeEvt bool QTimeEvt_rearm(QTimeEvt * const me, - QTimeEvtCtr const nTicks) + uint32_t const nTicks) { - uint_fast8_t const tickRate - = (uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE; - #ifdef Q_SPY - uint_fast8_t const qsId = ((QActive *)(me->act))->prio; - #endif - QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(600, (me->act != (void *)0) - && (tickRate < QF_MAX_TICK_RATE) - && (nTicks != 0U) - && (me->super.sig >= (QSignal)Q_USER_SIG)); + // dynamic range checks + #if (QF_TIMEEVT_CTR_SIZE == 1U) + Q_REQUIRE_INCRIT(600, nTicks < 0xFFU); + #elif (QF_TIMEEVT_CTR_SIZE == 2U) + Q_REQUIRE_INCRIT(600, nTicks < 0xFFFFU); + #endif - // is the time evt not running? + uint8_t const tickRate = me->tickRate; + QTimeEvtCtr const ctr = me->ctr; + + Q_REQUIRE_INCRIT(600, + (nTicks != 0U) + && (me->act != (void *)0) + && (tickRate < QF_MAX_TICK_RATE)); + + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(601, QEvt_verify_(&me->super)); + QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; + Q_INVARIANT_INCRIT(602, ctr == dis); + #endif // ndef Q_UNSAFE + + #ifdef Q_SPY + uint_fast8_t const qsId = ((QActive *)(me->act))->prio; + #endif + + me->ctr = (QTimeEvtCtr)nTicks; + #ifndef Q_UNSAFE + me->ctr_dis = (QTimeEvtCtr)~nTicks; + #endif // ndef Q_UNSAFE + + // was the time evt not running? bool wasArmed; - if (me->ctr == 0U) { + if (ctr == 0U) { wasArmed = false; // NOTE: For the duration of a single clock tick of the specified @@ -228,34 +282,44 @@ bool QTimeEvt_rearm(QTimeEvt * const me, // QTimeEvt_tick_() function. // is the time event unlinked? - if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - // mark as linked - me->super.refCtr_ |= QTE_IS_LINKED; + if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { + me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - // The time event is initially inserted into the separate - // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. + // The time event is initially inserted into the separate "freshly + // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. // Only later, inside the QTimeEvt_tick_() function, the "freshly // armed" list is appended to the main list of armed time events // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside the + // to keep any changes to the main list exclusively inside // QTimeEvt_tick_(). + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(620, + Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); + Q_INVARIANT_INCRIT(621, + Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == + (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); + #endif me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; + #ifndef Q_UNSAFE + me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); + QTimeEvt_timeEvtHead_dis_[tickRate] = + (uintptr_t)~Q_PTR2UINT_CAST_(me); + #endif // ndef Q_UNSAFE } } else { // the time event was armed wasArmed = true; } - me->ctr = nTicks; // re-load the tick counter (shift the phasing) - QS_BEGIN_PRE_(QS_QF_TIMEEVT_REARM, qsId) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this time event object - QS_OBJ_PRE_(me->act); // the target AO - QS_TEC_PRE_(me->ctr); // the # ticks - QS_TEC_PRE_(me->interval); // the interval - QS_2U8_PRE_(tickRate, (wasArmed ? 1U : 0U)); - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_TIMEEVT_REARM, qsId) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(me->act); // the target AO + QS_TEC_PRE(nTicks); // the # ticks + QS_TEC_PRE(me->interval); // the interval + QS_2U8_PRE(tickRate, (wasArmed ? 1U : 0U)); + QS_END_PRE() QF_MEM_APP(); QF_CRIT_EXIT(); @@ -270,13 +334,13 @@ bool QTimeEvt_wasDisarmed(QTimeEvt * const me) { QF_CRIT_ENTRY(); QF_MEM_SYS(); - uint8_t const wasDisarmed = (me->super.refCtr_ & QTE_WAS_DISARMED); - me->super.refCtr_ |= QTE_WAS_DISARMED; // mark as disarmed + bool const wasDisarmed = (me->flags & QTE_FLAG_WAS_DISARMED) != 0U; + me->flags |= QTE_FLAG_WAS_DISARMED; // mark as disarmed QF_MEM_APP(); QF_CRIT_EXIT(); - return wasDisarmed != 0U; + return wasDisarmed; } //${QF::QTimeEvt::currCtr} ................................................... @@ -290,6 +354,22 @@ QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me) { return ctr; } +//${QF::QTimeEvt::init} ...................................................... +//! @static @private @memberof QTimeEvt +void QTimeEvt_init(void) { + for (uint_fast8_t tickRate = 0U; + tickRate < Q_DIM(QTimeEvt_timeEvtHead_); + ++tickRate) + { + QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], + (QActive *)0, Q_USER_SIG, tickRate); + #ifndef Q_UNSAFE + QTimeEvt_timeEvtHead_dis_[tickRate] = + (uintptr_t)~Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act); + #endif + } +} + //${QF::QTimeEvt::tick_} ..................................................... //! @static @private @memberof QTimeEvt void QTimeEvt_tick_( @@ -304,44 +384,70 @@ void QTimeEvt_tick_( QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(100, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); + Q_REQUIRE_INCRIT(800, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - QS_BEGIN_PRE_(QS_QF_TICK, 0U) + QS_BEGIN_PRE(QS_QF_TICK, 0U) ++prev->ctr; - QS_TEC_PRE_(prev->ctr); // tick ctr - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() + QS_TEC_PRE(prev->ctr); // tick ctr + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() // scan the linked-list of time events at this rate... uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound for (; lbound > 0U; --lbound) { - QTimeEvt *e = prev->next; // advance down the time evt. list + Q_ASSERT_INCRIT(810, prev != (QTimeEvt *)0); // sanity check - if (e == (QTimeEvt *)0) { // end of the list? + QTimeEvt *te = prev->next; // advance down the time evt. list + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(811, + Q_PTR2UINT_CAST_(te) == (uintptr_t)~prev->next_dis); + #endif // ndef Q_UNSAFE + + if (te == (QTimeEvt *)0) { // end of the list? // any new time events armed since the last QTimeEvt_tick_()? if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - - // sanity check - Q_ASSERT_INCRIT(110, prev != (QTimeEvt *)0); - prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(812, + Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) + == (uintptr_t)~QTimeEvt_timeEvtHead_dis_[tickRate]); + #endif // ndef Q_UNSAFE + prev->next = (QTimeEvt*)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - e = prev->next; // switch to the new list + #ifndef Q_UNSAFE + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(prev->next); + QTimeEvt_timeEvtHead_dis_[tickRate] = + (uintptr_t)~Q_PTR2UINT_CAST_((void *)0); + #endif // ndef Q_UNSAFE + + te = prev->next; // switch to the new list } else { // all currently armed time events are processed break; // terminate the for-loop } } - // the time event 'e' must be valid - Q_INVARIANT_INCRIT(112, QEvt_verify_(Q_EVT_CAST(QEvt))); + // the time event 'te' must be valid + Q_ASSERT_INCRIT(820, te != (QTimeEvt *)0); + + QTimeEvtCtr ctr = te->ctr; + #ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(821, QEvt_verify_(&te->super)); + QTimeEvtCtr const dis = (QTimeEvtCtr)~te->ctr_dis; + Q_INVARIANT_INCRIT(822, ctr == dis); + #endif // ndef Q_UNSAFE + + if (ctr == 0U) { // time event scheduled for removal? + prev->next = te->next; + #ifndef Q_UNSAFE + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); + #endif // ndef Q_UNSAFE + + // mark time event 'te' as NOT linked + te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - if (e->ctr == 0U) { // time event scheduled for removal? - prev->next = e->next; - // mark time event 'e' as NOT linked - e->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); // do NOT advance the prev pointer QF_MEM_APP(); QF_CRIT_EXIT(); // exit crit. section to reduce latency @@ -356,74 +462,83 @@ void QTimeEvt_tick_( // of critical sections in QF ports, in which it can occur. QF_CRIT_EXIT_NOP(); } - else { - --e->ctr; + else if (ctr == 1U) { // is time event about to expire? + QActive * const act = (QActive *)te->act; + if (te->interval != 0U) { // periodic time evt? + te->ctr = te->interval; // rearm the time event + #ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~te->interval; + #endif // ndef Q_UNSAFE + prev = te; // advance to this time event + } + else { // one-shot time event: automatically disarm + te->ctr = 0U; + prev->next = te->next; + #ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~0U; + prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); + #endif // ndef Q_UNSAFE - if (e->ctr == 0U) { // is time event about to expire? - QActive * const act = (QActive *)e->act; + // mark time event 'te' as NOT linked + te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer - if (e->interval != 0U) { // periodic time evt? - e->ctr = e->interval; // rearm the time event - prev = e; // advance to this time event - } - else { // one-shot time event: automatically disarm - prev->next = e->next; + QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE(te); // this time event object + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() + } - // mark time event 'e' as NOT linked - e->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); - // do NOT advance the prev pointer - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(e); // this time event object - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - } - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(e); // the time event object - QS_SIG_PRE_(e->super.sig); // signal of this time event - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(te); // the time event object + QS_SIG_PRE(te->super.sig);// signal of this time event + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() #ifdef QXK_H_ - if (e->super.sig < Q_USER_SIG) { - QXThread_timeout_(act); - QF_MEM_APP(); - QF_CRIT_EXIT(); - } - else { - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section before posting - - // QACTIVE_POST() asserts if the queue overflows - QACTIVE_POST(act, &e->super, sender); - } - #else + if ((enum_t)te->super.sig < Q_USER_SIG) { + QXThread_timeout_(act); + QF_MEM_APP(); + QF_CRIT_EXIT(); + } + else { QF_MEM_APP(); QF_CRIT_EXIT(); // exit crit. section before posting // QACTIVE_POST() asserts if the queue overflows - QACTIVE_POST(act, &e->super, sender); + QACTIVE_POST(act, &te->super, sender); + } + #else + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section before posting + + // QACTIVE_POST() asserts if the queue overflows + QACTIVE_POST(act, &te->super, sender); #endif - } - else { - prev = e; // advance to this time event + } + else { // time event keeps timing out + --ctr; // decrement the tick counter + te->ctr = ctr; // update the original + #ifndef Q_UNSAFE + te->ctr_dis = (QTimeEvtCtr)~ctr; + #endif // ndef Q_UNSAFE - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section to reduce latency + prev = te; // advance to this time event - // prevent merging critical sections, see NOTE above - QF_CRIT_EXIT_NOP(); - } + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section to reduce latency + + // prevent merging critical sections, see NOTE above + QF_CRIT_EXIT_NOP(); } QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop QF_MEM_SYS(); } - Q_ENSURE_INCRIT(190, lbound > 0U); + Q_ENSURE_INCRIT(890, lbound > 0U); QF_MEM_APP(); QF_CRIT_EXIT(); } @@ -433,7 +548,7 @@ void QTimeEvt_tick_( bool QTimeEvt_noActive(uint_fast8_t const tickRate) { QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(800, tickRate < QF_MAX_TICK_RATE); + Q_REQUIRE_INCRIT(900, tickRate < QF_MAX_TICK_RATE); QF_CRIT_EXIT(); bool inactive; diff --git a/src/qk/qk.c b/src/qk/qk.c index 6bae74ae..db312d25 100644 --- a/src/qk/qk.c +++ b/src/qk/qk.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qk::qk.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -83,11 +75,11 @@ QSchedStatus QK_schedLock(uint_fast8_t const ceiling) { // first store the previous lock prio QSchedStatus stat; if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling? - QS_BEGIN_PRE_(QS_SCHED_LOCK, QK_priv_.actPrio) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_LOCK, QK_priv_.actPrio) + QS_TIME_PRE(); // timestamp // the previous lock ceiling & new lock ceiling - QS_2U8_PRE_((uint8_t)QK_priv_.lockCeil, (uint8_t)ceiling); - QS_END_PRE_() + QS_2U8_PRE((uint8_t)QK_priv_.lockCeil, (uint8_t)ceiling); + QS_END_PRE() // previous status of the lock stat = (QSchedStatus)QK_priv_.lockCeil; @@ -122,11 +114,11 @@ void QK_schedUnlock(QSchedStatus const prevCeil) { Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_()) && (QK_priv_.lockCeil > prevCeil)); - QS_BEGIN_PRE_(QS_SCHED_UNLOCK, QK_priv_.actPrio) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_UNLOCK, QK_priv_.actPrio) + QS_TIME_PRE(); // timestamp // current lock ceiling (old), previous lock ceiling (new) - QS_2U8_PRE_((uint8_t)QK_priv_.lockCeil, (uint8_t)prevCeil); - QS_END_PRE_() + QS_2U8_PRE((uint8_t)QK_priv_.lockCeil, (uint8_t)prevCeil); + QS_END_PRE() // restore the previous lock ceiling QK_priv_.lockCeil = prevCeil; @@ -244,11 +236,11 @@ void QK_activate_(void) { #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (p != pprev) { // changing threads? - QS_BEGIN_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_(p, // prio. of the scheduled AO + QS_BEGIN_PRE(QS_SCHED_NEXT, p) + QS_TIME_PRE(); // timestamp + QS_2U8_PRE(p, // prio. of the scheduled AO pprev); // previous prio. - QS_END_PRE_() + QS_END_PRE() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(QActive_registry_[pprev], a); @@ -323,19 +315,19 @@ void QK_activate_(void) { if (prio_in != 0U) { // resuming an active object? a = QActive_registry_[prio_in]; // pointer to preempted AO - QS_BEGIN_PRE_(QS_SCHED_NEXT, prio_in) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_NEXT, prio_in) + QS_TIME_PRE(); // timestamp // prio. of the resumed AO, previous prio. - QS_2U8_PRE_(prio_in, pprev); - QS_END_PRE_() + QS_2U8_PRE(prio_in, pprev); + QS_END_PRE() } else { // resuming prio.==0 --> idle a = (QActive *)0; // QK idle loop - QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(pprev); // previous prio. - QS_END_PRE_() + QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) + QS_TIME_PRE(); // timestamp + QS_U8_PRE(pprev); // previous prio. + QS_END_PRE() } #ifdef QF_ON_CONTEXT_SW @@ -366,13 +358,7 @@ void QF_init(void) { QK_priv_.lockCeil_dis = (uint_fast8_t)(~QK_priv_.lockCeil); #endif - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) - { - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, (enum_t)Q_USER_SIG, tickRate); - } + QTimeEvt_init(); // initialize QTimeEvts #ifdef QK_INIT QK_INIT(); // port-specific initialization of the QK kernel @@ -413,6 +399,11 @@ int_t QF_run(void) { QK_priv_.lockCeil_dis = (uint_fast8_t)(~0U); #endif + #ifdef QF_ON_CONTEXT_SW + // officially switch to the idle context + QF_onContextSw((QActive *)0, QActive_registry_[QK_priv_.nextPrio]); + #endif + // activate AOs to process events posted so far if (QK_sched_() != 0U) { QK_activate_(); @@ -439,7 +430,7 @@ int_t QF_run(void) { //! @public @memberof QActive void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, diff --git a/src/qs/CMakeLists.txt b/src/qs/CMakeLists.txt index 91af88c7..752fead5 100644 --- a/src/qs/CMakeLists.txt +++ b/src/qs/CMakeLists.txt @@ -1,9 +1,15 @@ # ./src/qs -target_sources(qpc PRIVATE - "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_64bit.c>" - "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_fp.c>" - "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_rx.c>" - "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qstamp.c>" - "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs.c>" - "$<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/qutest.c>" -) +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/qs.c) + target_sources(qpc PRIVATE + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_64bit.c>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_fp.c>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_rx.c>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qstamp.c>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs.c>" + "$<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/qutest.c>" + ) +else() + target_sources(qpc PRIVATE + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qstamp.c>" + ) +endif() diff --git a/src/qs/qs.c b/src/qs/qs.c deleted file mode 100644 index 96942c5e..00000000 --- a/src/qs/qs.c +++ /dev/null @@ -1,995 +0,0 @@ -//$file${src::qs::qs.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qs::qs.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qs::qs.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope interface -#include "qstamp.h" // QP time-stamp -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem - -Q_DEFINE_THIS_MODULE("qs") - -// ensure that the predefined records don't overlap the -// user records (application-specific). -Q_ASSERT_STATIC((enum_t)QS_PRE_MAX <= (enum_t)QS_USER); - -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QS::QS-TX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QS-TX::initBuf} ...................................................... -//! @static @public @memberof QS -void QS_initBuf( - uint8_t * const sto, - uint_fast32_t const stoSize) -{ - QS_priv_.buf = &sto[0]; - QS_priv_.end = (QSCtr)stoSize; - QS_priv_.head = 0U; - QS_priv_.tail = 0U; - QS_priv_.used = 0U; - QS_priv_.seq = 0U; - QS_priv_.chksum = 0U; - QS_priv_.critNest = 0U; - - QS_glbFilter_(-(int_fast16_t)QS_ALL_RECORDS); // all global filters OFF - QS_locFilter_((int_fast16_t)QS_ALL_IDS); // all local filters ON - QS_priv_.locFilter_AP = (void *)0; // deprecated "AP-filter" - - // produce an empty record to "flush" the QS trace buffer - QS_beginRec_((uint_fast8_t)QS_EMPTY); - QS_endRec_(); - - // produce the reset record to inform QSPY of a new session - QS_target_info_pre_(0xFFU); - - // hold off flushing after successful initialization (see QS_INIT()) -} - -//${QS::QS-TX::getByte} ...................................................... -//! @static @public @memberof QS -uint16_t QS_getByte(void) { - uint16_t ret; - if (QS_priv_.used == 0U) { - ret = QS_EOD; // set End-Of-Data - } - else { - uint8_t const * const buf = QS_priv_.buf; // put in a temporary - QSCtr tail = QS_priv_.tail; // put in a temporary (register) - ret = (uint16_t)buf[tail]; // set the byte to return - ++tail; // advance the tail - if (tail == QS_priv_.end) { // tail wrap around? - tail = 0U; - } - QS_priv_.tail = tail; // update the tail - --QS_priv_.used; // one less byte used - } - return ret; // return the byte or EOD -} - -//${QS::QS-TX::getBlock} ..................................................... -//! @static @public @memberof QS -uint8_t const * QS_getBlock(uint16_t * const pNbytes) { - QSCtr const used = QS_priv_.used; // put in a temporary (register) - uint8_t const *buf; - - // any bytes used in the ring buffer? - if (used != 0U) { - QSCtr tail = QS_priv_.tail; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - QSCtr n = (QSCtr)(end - tail); - if (n > used) { - n = used; - } - if (n > (QSCtr)(*pNbytes)) { - n = (QSCtr)(*pNbytes); - } - *pNbytes = (uint16_t)n; // n-bytes available - buf = &QS_priv_.buf[tail]; // the bytes are at the tail - - QS_priv_.used = (QSCtr)(used - n); - tail += n; - if (tail == end) { - tail = 0U; - } - QS_priv_.tail = tail; - } - else { // no bytes available - *pNbytes = 0U; // no bytes available right now - buf = (uint8_t *)0; // no bytes available right now - } - return buf; -} -//$enddef${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -#ifndef QF_MEM_ISOLATE -//$define${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::filters::filt_} ...................................................... -//! @static @private @memberof QS -QS_Filter QS_filt_; -//$enddef${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif - -//============================================================================ -//! @cond INTERNAL - -//! @static @private @memberof QS -QS_Attr QS_priv_; - -//............................................................................ -void QS_glbFilter_(int_fast16_t const filter) { - bool const isRemove = (filter < 0); - uint8_t const rec = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; - switch (rec) { - case (uint8_t)QS_ALL_RECORDS: { - uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); - - // set all global filters (partially unrolled loop) - for (uint_fast8_t i = 0U; - i < Q_DIM(QS_filt_.glb); - i += 4U) - { - QS_filt_.glb[i ] = tmp; - QS_filt_.glb[i + 1U] = tmp; - QS_filt_.glb[i + 2U] = tmp; - QS_filt_.glb[i + 3U] = tmp; - } - if (isRemove) { - // leave the "not maskable" filters enabled, - // see qs.h, Miscellaneous QS records (not maskable) - QS_filt_.glb[0] = 0x01U; - QS_filt_.glb[6] = 0x40U; - QS_filt_.glb[7] = 0xFCU; - QS_filt_.glb[8] = 0x7FU; - } - else { - // never turn the last 3 records on (0x7D, 0x7E, 0x7F) - QS_filt_.glb[15] = 0x1FU; - } - break; - } - case (uint8_t)QS_SM_RECORDS: - if (isRemove) { - QS_filt_.glb[0] &= (uint8_t)(~0xFEU & 0xFFU); - QS_filt_.glb[1] &= (uint8_t)(~0x03U & 0xFFU); - QS_filt_.glb[6] &= (uint8_t)(~0x80U & 0xFFU); - QS_filt_.glb[7] &= (uint8_t)(~0x03U & 0xFFU); - } - else { - QS_filt_.glb[0] |= 0xFEU; - QS_filt_.glb[1] |= 0x03U; - QS_filt_.glb[6] |= 0x80U; - QS_filt_.glb[7] |= 0x03U; - } - break; - case (uint8_t)QS_AO_RECORDS: - if (isRemove) { - QS_filt_.glb[1] &= (uint8_t)(~0xFCU & 0xFFU); - QS_filt_.glb[2] &= (uint8_t)(~0x07U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x20U & 0xFFU); - } - else { - QS_filt_.glb[1] |= 0xFCU; - QS_filt_.glb[2] |= 0x07U; - QS_filt_.glb[5] |= 0x20U; - } - break; - case (uint8_t)QS_EQ_RECORDS: - if (isRemove) { - QS_filt_.glb[2] &= (uint8_t)(~0x78U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x40U & 0xFFU); - } - else { - QS_filt_.glb[2] |= 0x78U; - QS_filt_.glb[5] |= 0x40U; - } - break; - case (uint8_t)QS_MP_RECORDS: - if (isRemove) { - QS_filt_.glb[3] &= (uint8_t)(~0x03U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x80U & 0xFFU); - } - else { - QS_filt_.glb[3] |= 0x03U; - QS_filt_.glb[5] |= 0x80U; - } - break; - case (uint8_t)QS_QF_RECORDS: - if (isRemove) { - QS_filt_.glb[2] &= (uint8_t)(~0x80U & 0xFFU); - QS_filt_.glb[3] &= (uint8_t)(~0xFCU & 0xFFU); - QS_filt_.glb[4] &= (uint8_t)(~0xC0U & 0xFFU); - QS_filt_.glb[5] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_filt_.glb[2] |= 0x80U; - QS_filt_.glb[3] |= 0xFCU; - QS_filt_.glb[4] |= 0xC0U; - QS_filt_.glb[5] |= 0x1FU; - } - break; - case (uint8_t)QS_TE_RECORDS: - if (isRemove) { - QS_filt_.glb[4] &= (uint8_t)(~0x3FU & 0xFFU); - } - else { - QS_filt_.glb[4] |= 0x3FU; - } - break; - case (uint8_t)QS_SC_RECORDS: - if (isRemove) { - QS_filt_.glb[6] &= (uint8_t)(~0x3FU & 0xFFU); - } - else { - QS_filt_.glb[6] |= 0x3FU; - } - break; - case (uint8_t)QS_SEM_RECORDS: - if (isRemove) { - QS_filt_.glb[8] &= (uint8_t)(~0x80U & 0xFFU); - QS_filt_.glb[9] &= (uint8_t)(~0x07U & 0xFFU); - } - else { - QS_filt_.glb[8] |= 0x80U; - QS_filt_.glb[9] |= 0x07U; - } - break; - case (uint8_t)QS_MTX_RECORDS: - if (isRemove) { - QS_filt_.glb[9] &= (uint8_t)(~0xF8U & 0xFFU); - QS_filt_.glb[10] &= (uint8_t)(~0x01U & 0xFFU); - } - else { - QS_filt_.glb[9] |= 0xF8U; - QS_filt_.glb[10] |= 0x01U; - } - break; - case (uint8_t)QS_U0_RECORDS: - if (isRemove) { - QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_filt_.glb[13] &= (uint8_t)(~0x01U & 0xFFU); - } - else { - QS_filt_.glb[12] |= 0xF0U; - QS_filt_.glb[13] |= 0x01U; - } - break; - case (uint8_t)QS_U1_RECORDS: - if (isRemove) { - QS_filt_.glb[13] &= (uint8_t)(~0x3EU & 0xFFU); - } - else { - QS_filt_.glb[13] |= 0x3EU; - } - break; - case (uint8_t)QS_U2_RECORDS: - if (isRemove) { - QS_filt_.glb[13] &= (uint8_t)(~0xC0U & 0xFFU); - QS_filt_.glb[14] &= (uint8_t)(~0x07U & 0xFFU); - } - else { - QS_filt_.glb[13] |= 0xC0U; - QS_filt_.glb[14] |= 0x07U; - } - break; - case (uint8_t)QS_U3_RECORDS: - if (isRemove) { - QS_filt_.glb[14] &= (uint8_t)(~0xF8U & 0xFFU); - } - else { - QS_filt_.glb[14] |= 0xF8U; - } - break; - case (uint8_t)QS_U4_RECORDS: - if (isRemove) { - QS_filt_.glb[15] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_filt_.glb[15] |= 0x1FU; - } - break; - case (uint8_t)QS_UA_RECORDS: - if (isRemove) { - QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_filt_.glb[13] = 0U; - QS_filt_.glb[14] = 0U; - QS_filt_.glb[15] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_filt_.glb[12] |= 0xF0U; - QS_filt_.glb[13] |= 0xFFU; - QS_filt_.glb[14] |= 0xFFU; - QS_filt_.glb[15] |= 0x1FU; - } - break; - default: { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - // QS rec number must be below 0x7D, so no need for escaping - Q_ASSERT_INCRIT(210, rec < 0x7DU); - QS_CRIT_EXIT(); - - if (isRemove) { - QS_filt_.glb[rec >> 3U] - &= (uint8_t)(~(1U << (rec & 7U)) & 0xFFU); - } - else { - QS_filt_.glb[rec >> 3U] - |= (1U << (rec & 7U)); - // never turn the last 3 records on (0x7D, 0x7E, 0x7F) - QS_filt_.glb[15] &= 0x1FU; - } - break; - } - } -} - -//............................................................................ -void QS_locFilter_(int_fast16_t const filter) { - bool const isRemove = (filter < 0); - uint8_t const qsId = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; - uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); - uint_fast8_t i; - switch (qsId) { - case (uint8_t)QS_ALL_IDS: - // set all local filters (partially unrolled loop) - for (i = 0U; i < Q_DIM(QS_filt_.loc); i += 4U) { - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - QS_filt_.loc[i + 2U] = tmp; - QS_filt_.loc[i + 3U] = tmp; - } - break; - case (uint8_t)QS_AO_IDS: - for (i = 0U; i < 8U; i += 4U) { - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - QS_filt_.loc[i + 2U] = tmp; - QS_filt_.loc[i + 3U] = tmp; - } - break; - case (uint8_t)QS_EP_IDS: - i = 8U; - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - break; - case (uint8_t)QS_AP_IDS: - i = 12U; - QS_filt_.loc[i ] = tmp; - QS_filt_.loc[i + 1U] = tmp; - QS_filt_.loc[i + 2U] = tmp; - QS_filt_.loc[i + 3U] = tmp; - break; - default: { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - // qsId must be in range - Q_ASSERT_INCRIT(310, qsId < 0x7FU); - QS_CRIT_EXIT(); - if (isRemove) { - QS_filt_.loc[qsId >> 3U] - &= (uint8_t)(~(1U << (qsId & 7U)) & 0xFFU); - } - else { - QS_filt_.loc[qsId >> 3U] - |= (1U << (qsId & 7U)); - } - break; - } - } - QS_filt_.loc[0] |= 0x01U; // leave QS_ID == 0 always on -} - -//............................................................................ -void QS_beginRec_(uint_fast8_t const rec) { - uint8_t const b = (uint8_t)(QS_priv_.seq + 1U); - uint8_t chksum = 0U; // reset the checksum - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.seq = b; // store the incremented sequence num - QS_priv_.used += 2U; // 2 bytes about to be added - - QS_INSERT_ESC_BYTE_(b) - - chksum = (uint8_t)(chksum + rec); // update checksum - QS_INSERT_BYTE_((uint8_t)rec) // rec byte does not need escaping - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_endRec_(void) { - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - uint8_t b = QS_priv_.chksum; - b ^= 0xFFU; // invert the bits in the checksum - - QS_priv_.used += 2U; // 2 bytes about to be added - - if ((b != QS_FRAME) && (b != QS_ESC)) { - QS_INSERT_BYTE_(b) - } - else { - QS_INSERT_BYTE_(QS_ESC) - QS_INSERT_BYTE_(b ^ QS_ESC_XOR) - ++QS_priv_.used; // account for the ESC byte - } - - QS_INSERT_BYTE_(QS_FRAME) // do not escape this QS_FRAME - - QS_priv_.head = head; // save the head - - // overrun over the old data? - if (QS_priv_.used > end) { - QS_priv_.used = end; // the whole buffer is used - QS_priv_.tail = head; // shift the tail to the old data - } -} - -//............................................................................ -void QS_u8_raw_(uint8_t const d) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.used += 1U; // 1 byte about to be added - QS_INSERT_ESC_BYTE_(d) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_2u8_raw_( - uint8_t const d1, - uint8_t const d2) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.used += 2U; // 2 bytes are about to be added - QS_INSERT_ESC_BYTE_(d1) - QS_INSERT_ESC_BYTE_(d2) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u16_raw_(uint16_t const d) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint16_t x = d; - - QS_priv_.used += 2U; // 2 bytes are about to be added - - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; - QS_INSERT_ESC_BYTE_((uint8_t)x) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u32_raw_(uint32_t const d) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint32_t x = d; - - QS_priv_.used += 4U; // 4 bytes are about to be added - for (uint_fast8_t i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_obj_raw_(void const * const obj) { - #if (QS_OBJ_PTR_SIZE == 1U) - QS_u8_raw_((uint8_t)obj); - #elif (QS_OBJ_PTR_SIZE == 2U) - QS_u16_raw_((uint16_t)obj); - #elif (QS_OBJ_PTR_SIZE == 4U) - QS_u32_raw_((uint32_t)obj); - #elif (QS_OBJ_PTR_SIZE == 8U) - QS_u64_raw_((uint64_t)obj); - #else - QS_u32_raw_((uint32_t)obj); - #endif -} - -//............................................................................ -void QS_str_raw_(char const * const str) { - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - QSCtr used = QS_priv_.used; // put in a temporary (register) - - for (char const *s = str; *s != '\0'; ++s) { - chksum += (uint8_t)*s; // update checksum - QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping - ++used; - } - QS_INSERT_BYTE_((uint8_t)'\0') // zero-terminate the string - ++used; - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum - QS_priv_.used = used; // save # of used buffer space -} - -//............................................................................ -void QS_u8_fmt_( - uint8_t const format, - uint8_t const d) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - - QS_priv_.used += 2U; // 2 bytes about to be added - - QS_INSERT_ESC_BYTE_(format) - QS_INSERT_ESC_BYTE_(d) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u16_fmt_( - uint8_t const format, - uint16_t const d) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint8_t b = (uint8_t)d; - - QS_priv_.used += 3U; // 3 bytes about to be added - - QS_INSERT_ESC_BYTE_(format) - QS_INSERT_ESC_BYTE_(b) - b = (uint8_t)(d >> 8U); - QS_INSERT_ESC_BYTE_(b) - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_u32_fmt_( - uint8_t const format, - uint32_t const d) -{ - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint32_t x = d; - - QS_priv_.used += 5U; // 5 bytes about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // insert 4 bytes... - for (uint_fast8_t i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_str_fmt_(char const * const str) { - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - QSCtr used = QS_priv_.used; // put in a temporary (register) - - used += 2U; // account for the format byte and the terminating-0 - QS_INSERT_BYTE_((uint8_t)QS_STR_T) - chksum += (uint8_t)QS_STR_T; - - for (char const *s = str; *s != '\0'; ++s) { - QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping - chksum += (uint8_t)*s; // update checksum - ++used; - } - QS_INSERT_BYTE_(0U) // zero-terminate the string - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum - QS_priv_.used = used; // save # of used buffer space -} - -//............................................................................ -void QS_mem_fmt_( - uint8_t const * const blk, - uint8_t const size) -{ - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) - QSCtr head = QS_priv_.head; // put in a temporary (register) - QSCtr const end = QS_priv_.end; // put in a temporary (register) - uint8_t const *pb = blk; - - QS_priv_.used += ((QSCtr)size + 2U); // size+2 bytes to be added - - QS_INSERT_BYTE_((uint8_t)QS_MEM_T) - chksum += (uint8_t)QS_MEM_T; - - QS_INSERT_ESC_BYTE_(size) - // output the 'size' # bytes - for (uint8_t len = size; len > 0U; --len) { - QS_INSERT_ESC_BYTE_(*pb) - ++pb; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//............................................................................ -void QS_sig_dict_pre_( - QSignal const sig, - void const * const obj, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_SIG_DICT); - QS_SIG_PRE_(sig); - QS_OBJ_PRE_(obj); - QS_STR_PRE_((*name == '&') ? &name[1] : name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_obj_dict_pre_( - void const * const obj, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); - QS_OBJ_PRE_(obj); - QS_STR_PRE_((*name == '&') ? &name[1] : name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_obj_arr_dict_pre_( - void const * const obj, - uint_fast16_t const idx, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(400, idx < 1000U); - QS_CRIT_EXIT(); - - // format idx into a char buffer as "xxx\0" - uint8_t idx_str[4]; - uint_fast16_t tmp = idx; - uint8_t i; - idx_str[3] = 0U; // zero-terminate - idx_str[2] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); - tmp /= 10U; - idx_str[1] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); - if (idx_str[1] == (uint8_t)'0') { - i = 2U; - } - else { - tmp /= 10U; - idx_str[0] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); - if (idx_str[0] == (uint8_t)'0') { - i = 1U; - } - else { - i = 0U; - } - } - - uint8_t j = ((*name == '&') ? 1U : 0U); - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); - QS_OBJ_PRE_(obj); - for (; name[j] != '\0'; ++j) { - QS_U8_PRE_(name[j]); - if (name[j] == '[') { - ++j; - break; - } - } - for (; idx_str[i] != 0U; ++i) { - QS_U8_PRE_(idx_str[i]); - } - // skip chars until ']' - for (; name[j] != '\0'; ++j) { - if (name[j] == ']') { - break; - } - } - for (; name[j] != '\0'; ++j) { - QS_U8_PRE_(name[j]); - } - QS_U8_PRE_(0U); // zero-terminate - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_fun_dict_pre_( - QSpyFunPtr const fun, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_FUN_DICT); - QS_FUN_PRE_(fun); - QS_STR_PRE_((*name == '&') ? &name[1] : name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_usr_dict_pre_( - enum_t const rec, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_USR_DICT); - QS_U8_PRE_(rec); - QS_STR_PRE_(name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_enum_dict_pre_( - enum_t const value, - uint8_t const group, - char const * const name) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_beginRec_((uint_fast8_t)QS_ENUM_DICT); - QS_2U8_PRE_(value, group); - QS_STR_PRE_(name); - QS_endRec_(); - - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_onFlush(); -} - -//............................................................................ -void QS_assertion_pre_( - char const * const module, - int_t const id, - uint32_t const delay) -{ - // NOTE: called in a critical section - - QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); - QS_TIME_PRE_(); - QS_U16_PRE_(id); - QS_STR_PRE_((module != (char *)0) ? module : "?"); - QS_endRec_(); - QS_onFlush(); - - // busy-wait until all QS data makes it over to the host - for (uint32_t volatile delay_ctr = delay; - delay_ctr > 0U; --delay_ctr) - {} - QS_onCleanup(); -} - -//............................................................................ -void QS_target_info_pre_(uint8_t const isReset) { - // NOTE: called in a critical section - - static uint8_t const ZERO = (uint8_t)'0'; - static uint8_t const * const TIME = (uint8_t const *)&Q_BUILD_TIME[0]; - static uint8_t const * const DATE = (uint8_t const *)&Q_BUILD_DATE[0]; - static union { - uint16_t u16; - uint8_t u8[2]; - } endian_test; - - endian_test.u16 = 0x0102U; - QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); - QS_U8_PRE_(isReset); - QS_U16_PRE_(((endian_test.u8[0] == 0x01U) // big endian? - ? (0x8000U | QP_VERSION) - : QP_VERSION)); // target endianness + version number - - // send the object sizes... - QS_U8_PRE_(Q_SIGNAL_SIZE | (QF_EVENT_SIZ_SIZE << 4U)); - -#ifdef QF_EQUEUE_CTR_SIZE - QS_U8_PRE_(QF_EQUEUE_CTR_SIZE | (QF_TIMEEVT_CTR_SIZE << 4U)); -#else - QS_U8_PRE_(QF_TIMEEVT_CTR_SIZE << 4U); -#endif // QF_EQUEUE_CTR_SIZE - -#ifdef QF_MPOOL_CTR_SIZE - QS_U8_PRE_(QF_MPOOL_SIZ_SIZE | (QF_MPOOL_CTR_SIZE << 4U)); -#else - QS_U8_PRE_(0U); -#endif // QF_MPOOL_CTR_SIZE - - QS_U8_PRE_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U)); - QS_U8_PRE_(QS_TIME_SIZE); - - // send the bounds... - QS_U8_PRE_(QF_MAX_ACTIVE); - QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U)); - - // send the build time in three bytes (sec, min, hour)... - QS_U8_PRE_((10U * (uint8_t)(TIME[6] - ZERO)) - + (uint8_t)(TIME[7] - ZERO)); - QS_U8_PRE_((10U * (uint8_t)(TIME[3] - ZERO)) - + (uint8_t)(TIME[4] - ZERO)); - if (Q_BUILD_TIME[0] == ' ') { - QS_U8_PRE_(TIME[1] - ZERO); - } - else { - QS_U8_PRE_((10U * (uint8_t)(TIME[0] - ZERO)) - + (uint8_t)(TIME[1] - ZERO)); - } - - // send the build date in three bytes (day, month, year) ... - if (Q_BUILD_DATE[4] == ' ') { - QS_U8_PRE_(DATE[5] - ZERO); - } - else { - QS_U8_PRE_((10U * (uint8_t)(DATE[4] - ZERO)) - + (uint8_t)(DATE[5] - ZERO)); - } - // convert the 3-letter month to a number 1-12 ... - uint8_t b; - switch ((int_t)DATE[0] + (int_t)DATE[1] + (int_t)DATE[2]) { - case (int_t)'J' + (int_t)'a' + (int_t)'n': - b = 1U; - break; - case (int_t)'F' + (int_t)'e' + (int_t)'b': - b = 2U; - break; - case (int_t)'M' + (int_t)'a' + (int_t)'r': - b = 3U; - break; - case (int_t)'A' + (int_t)'p' + (int_t)'r': - b = 4U; - break; - case (int_t)'M' + (int_t)'a' + (int_t)'y': - b = 5U; - break; - case (int_t)'J' + (int_t)'u' + (int_t)'n': - b = 6U; - break; - case (int_t)'J' + (int_t)'u' + (int_t)'l': - b = 7U; - break; - case (int_t)'A' + (int_t)'u' + (int_t)'g': - b = 8U; - break; - case (int_t)'S' + (int_t)'e' + (int_t)'p': - b = 9U; - break; - case (int_t)'O' + (int_t)'c' + (int_t)'t': - b = 10U; - break; - case (int_t)'N' + (int_t)'o' + (int_t)'v': - b = 11U; - break; - case (int_t)'D' + (int_t)'e' + (int_t)'c': - b = 12U; - break; - default: - b = 0U; - break; - } - QS_U8_PRE_(b); // store the month - QS_U8_PRE_((10U * (uint8_t)(DATE[9] - ZERO)) - + (uint8_t)(DATE[10] - ZERO)); - QS_endRec_(); -} - -//! @endcond diff --git a/src/qs/qs_64bit.c b/src/qs/qs_64bit.c deleted file mode 100644 index e47d6b76..00000000 --- a/src/qs/qs_64bit.c +++ /dev/null @@ -1,94 +0,0 @@ -//$file${src::qs::qs_64bit.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qs::qs_64bit.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qs::qs_64bit.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope internal interface - -//============================================================================ -//! @cond INTERNAL - -//! @static @private @memberof QS -void QS_u64_raw_(uint64_t const d) { - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - - QS_priv_.used += 8U; // 8 bytes are about to be added - uint64_t u64 = d; - for (uint_fast8_t i = 8U; i != 0U; --i) { - uint8_t const b = (uint8_t)u64; - QS_INSERT_ESC_BYTE_(b) - u64 >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @static @private @memberof QS -void QS_u64_fmt_( - uint8_t const format, - uint64_t const d) -{ - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - - QS_priv_.used += 9U; // 9 bytes are about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // output 8 bytes of data... - uint64_t u64 = d; - for (uint_fast8_t i = 8U; i != 0U; --i) { - uint8_t const b = (uint8_t)u64; - QS_INSERT_ESC_BYTE_(b) - u64 >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @endcond diff --git a/src/qs/qs_fp.c b/src/qs/qs_fp.c deleted file mode 100644 index 4f10877b..00000000 --- a/src/qs/qs_fp.c +++ /dev/null @@ -1,130 +0,0 @@ -//$file${src::qs::qs_fp.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qs::qs_fp.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qs::qs_fp.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope internal interface - -//============================================================================ -//! @cond INTERNAL - -//! @static @private @memberof QS -void QS_f32_fmt_( - uint8_t const format, - float32_t const f) -{ - union F32Rep { - float32_t f; - uint32_t u; - } fu32; // the internal binary representation - uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - uint_fast8_t i; - - fu32.f = f; // assign the binary representation - - QS_priv_.used += 5U; // 5 bytes about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // insert 4 bytes... - for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu32.u) - fu32.u >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @static @private @memberof QS -void QS_f64_fmt_( - uint8_t const format, - float64_t const d) -{ - union F64Rep { - float64_t d; - uint32_t u[2]; - } fu64; // the internal binary representation - uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; - QSCtr head = QS_priv_.head; - QSCtr const end = QS_priv_.end; - uint32_t i; - - // static constant union to detect endianness of the machine - static union U32Rep { - uint32_t u32; - uint8_t u8; - } const endian = { 1U }; - - fu64.d = d; // assign the binary representation - - // is this a big-endian machine? - if (endian.u8 == 0U) { - // swap fu64.u[0] <-> fu64.u[1]... - i = fu64.u[0]; - fu64.u[0] = fu64.u[1]; - fu64.u[1] = i; - } - - QS_priv_.used += 9U; // 9 bytes about to be added - QS_INSERT_ESC_BYTE_(format) // insert the format byte - - // output 4 bytes from fu64.u[0]... - for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[0]) - fu64.u[0] >>= 8U; - } - - // output 4 bytes from fu64.u[1]... - for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[1]) - fu64.u[1] >>= 8U; - } - - QS_priv_.head = head; // save the head - QS_priv_.chksum = chksum; // save the checksum -} - -//! @endcond diff --git a/src/qs/qs_rx.c b/src/qs/qs_rx.c deleted file mode 100644 index eca183db..00000000 --- a/src/qs/qs_rx.c +++ /dev/null @@ -1,1169 +0,0 @@ -//$file${src::qs::qs_rx.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qs::qs_rx.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qs::qs_rx.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qs_port.h" // QS port -#include "qs_pkg.h" // QS package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem - -//============================================================================ -//! @cond INTERNAL - -Q_DEFINE_THIS_MODULE("qs_rx") - -enum { - ERROR_STATE, - WAIT4_SEQ, - WAIT4_REC, - WAIT4_INFO_FRAME, - WAIT4_CMD_ID, - WAIT4_CMD_PARAM1, - WAIT4_CMD_PARAM2, - WAIT4_CMD_PARAM3, - WAIT4_CMD_FRAME, - WAIT4_RESET_FRAME, - WAIT4_TICK_RATE, - WAIT4_TICK_FRAME, - WAIT4_PEEK_OFFS, - WAIT4_PEEK_SIZE, - WAIT4_PEEK_NUM, - WAIT4_PEEK_FRAME, - WAIT4_POKE_OFFS, - WAIT4_POKE_SIZE, - WAIT4_POKE_NUM, - WAIT4_POKE_DATA, - WAIT4_POKE_FRAME, - WAIT4_FILL_DATA, - WAIT4_FILL_FRAME, - WAIT4_FILTER_LEN, - WAIT4_FILTER_DATA, - WAIT4_FILTER_FRAME, - WAIT4_OBJ_KIND, - WAIT4_OBJ_ADDR, - WAIT4_OBJ_FRAME, - WAIT4_QUERY_KIND, - WAIT4_QUERY_FRAME, - WAIT4_EVT_PRIO, - WAIT4_EVT_SIG, - WAIT4_EVT_LEN, - WAIT4_EVT_PAR, - WAIT4_EVT_FRAME - -#ifdef Q_UTEST - , - WAIT4_TEST_SETUP_FRAME, - WAIT4_TEST_TEARDOWN_FRAME, - WAIT4_TEST_PROBE_DATA, - WAIT4_TEST_PROBE_ADDR, - WAIT4_TEST_PROBE_FRAME, - WAIT4_TEST_CONTINUE_FRAME -#endif // Q_UTEST -}; - -// static helper functions... -static void QS_rxParseData_(uint8_t const b); -static void QS_rxHandleGoodFrame_(uint8_t const state); -static void QS_rxHandleBadFrame_(uint8_t const state); -static void QS_rxReportAck_(int8_t const recId); -static void QS_rxReportError_(int8_t const code); -static void QS_rxReportDone_(int8_t const recId); -static void QS_queryCurrObj(uint8_t const obj_kind); -static void QS_rxPoke_(void); - -//! Internal QS-RX macro to encapsulate tran. in the QS-RX FSM -#define QS_RX_TRAN_(target_) (QS_rxPriv_.state = (uint8_t)(target_)) - -#ifndef QF_MEM_ISOLATE -//! @static @private @memberof QS -QS_RxAttr QS_rxPriv_; -#endif // QF_MEM_ISOLATE - -//! @endcond -//============================================================================ - -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QS-RX::rxInitBuf} .................................................... -//! @static @public @memberof QS -void QS_rxInitBuf( - uint8_t * const sto, - uint16_t const stoSize) -{ - QS_rxPriv_.buf = &sto[0]; - QS_rxPriv_.end = (QSCtr)stoSize; - QS_rxPriv_.head = 0U; - QS_rxPriv_.tail = 0U; - - QS_rxPriv_.currObj[SM_OBJ] = (void *)0; - QS_rxPriv_.currObj[AO_OBJ] = (void *)0; - QS_rxPriv_.currObj[MP_OBJ] = (void *)0; - QS_rxPriv_.currObj[EQ_OBJ] = (void *)0; - QS_rxPriv_.currObj[TE_OBJ] = (void *)0; - QS_rxPriv_.currObj[AP_OBJ] = (void *)0; - - QS_RX_TRAN_(WAIT4_SEQ); - QS_rxPriv_.esc = 0U; - QS_rxPriv_.seq = 0U; - QS_rxPriv_.chksum = 0U; - - QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); - QS_OBJ_PRE_(&QS_rxPriv_); - QS_STR_PRE_("QS_RX"); - QS_endRec_(); - // no QS_REC_DONE(), because QS is not running yet - - #ifdef Q_UTEST - QS_tstPriv_.tpNum = 0U; - QS_tstPriv_.testTime = 0U; - #endif // Q_UTEST -} - -//${QS::QS-RX::rxParse} ...................................................... -//! @static @public @memberof QS -void QS_rxParse(void) { - QSCtr tail = QS_rxPriv_.tail; - while (QS_rxPriv_.head != tail) { // QS-RX buffer NOT empty? - uint8_t b = QS_rxPriv_.buf[tail]; - - ++tail; - if (tail == QS_rxPriv_.end) { - tail = 0U; - } - QS_rxPriv_.tail = tail; // update the tail to a *valid* index - - if (QS_rxPriv_.esc != 0U) { // escaped byte arrived? - QS_rxPriv_.esc = 0U; - b ^= QS_ESC_XOR; - - QS_rxPriv_.chksum += b; - QS_rxParseData_(b); - } - else if (b == QS_ESC) { - QS_rxPriv_.esc = 1U; - } - else if (b == QS_FRAME) { - // get ready for the next frame - b = QS_rxPriv_.state; // save the current state in b - QS_rxPriv_.esc = 0U; - QS_RX_TRAN_(WAIT4_SEQ); - - if (QS_rxPriv_.chksum == QS_GOOD_CHKSUM) { - QS_rxPriv_.chksum = 0U; - QS_rxHandleGoodFrame_(b); - } - else { // bad checksum - QS_rxPriv_.chksum = 0U; - QS_rxReportError_(0x41); - QS_rxHandleBadFrame_(b); - } - } - else { - QS_rxPriv_.chksum += b; - QS_rxParseData_(b); - } - } -} - -//${QS::QS-RX::setCurrObj} ................................................... -//! @static @public @memberof QS -void QS_setCurrObj( - uint8_t const obj_kind, - void * const obj_ptr) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(300, obj_kind < Q_DIM(QS_rxPriv_.currObj)); - - QS_MEM_SYS(); - - QS_rxPriv_.currObj[obj_kind] = obj_ptr; - - QS_MEM_APP(); - QS_CRIT_EXIT(); -} - -//${QS::QS-RX::rxGetNfree} ................................................... -//! @static @public @memberof QS -uint16_t QS_rxGetNfree(void) { - // NOTE: Must be called IN critical section. - // Also requires system-level memory access (QF_MEM_SYS()). - - QSCtr const head = QS_rxPriv_.head; - uint16_t nFree; - if (head == QS_rxPriv_.tail) { // buffer empty? - nFree = (uint16_t)(QS_rxPriv_.end - 1U); - } - else if (head < QS_rxPriv_.tail) { - nFree = (uint16_t)(QS_rxPriv_.tail - (head + 1U)); - } - else { - nFree = (uint16_t)((head + 1U) - QS_rxPriv_.tail); - nFree = (uint16_t)(QS_rxPriv_.end - nFree); - } - return nFree; -} -//$enddef${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//============================================================================ -//! @cond INTERNAL - -static void QS_rxParseData_(uint8_t const b) { - switch (QS_rxPriv_.state) { - case (uint8_t)WAIT4_SEQ: { - ++QS_rxPriv_.seq; - if (QS_rxPriv_.seq != b) { - QS_rxReportError_(0x42); - QS_rxPriv_.seq = b; // update the sequence - } - QS_RX_TRAN_(WAIT4_REC); - break; - } - case (uint8_t)WAIT4_REC: { - switch (b) { - case (uint8_t)QS_RX_INFO: - QS_RX_TRAN_(WAIT4_INFO_FRAME); - break; - case (uint8_t)QS_RX_COMMAND: - QS_RX_TRAN_(WAIT4_CMD_ID); - break; - case (uint8_t)QS_RX_RESET: - QS_RX_TRAN_(WAIT4_RESET_FRAME); - break; - case (uint8_t)QS_RX_TICK: - QS_RX_TRAN_(WAIT4_TICK_RATE); - break; - case (uint8_t)QS_RX_PEEK: - if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { - QS_rxPriv_.var.peek.offs = 0U; - QS_rxPriv_.var.peek.idx = 0U; - QS_RX_TRAN_(WAIT4_PEEK_OFFS); - } - else { - QS_rxReportError_((int8_t)QS_RX_PEEK); - QS_RX_TRAN_(ERROR_STATE); - } - break; - case (uint8_t)QS_RX_POKE: // intentionally fall-through - case (uint8_t)QS_RX_FILL: - QS_rxPriv_.var.poke.fill = - ((b == (uint8_t)QS_RX_FILL) ? 1U : 0U); - if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { - QS_rxPriv_.var.poke.offs = 0U; - QS_rxPriv_.var.poke.idx = 0U; - QS_RX_TRAN_(WAIT4_POKE_OFFS); - } - else { - QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - case (uint8_t)QS_RX_GLB_FILTER: // intentionally fall-through - case (uint8_t)QS_RX_LOC_FILTER: - QS_rxPriv_.var.flt.recId = (int8_t)b; - QS_RX_TRAN_(WAIT4_FILTER_LEN); - break; - case (uint8_t)QS_RX_AO_FILTER: // intentionally fall-through - case (uint8_t)QS_RX_CURR_OBJ: - QS_rxPriv_.var.obj.recId = (int8_t)b; - QS_RX_TRAN_(WAIT4_OBJ_KIND); - break; - case (uint8_t)QS_RX_QUERY_CURR: - QS_rxPriv_.var.obj.recId = (int8_t)QS_RX_QUERY_CURR; - QS_RX_TRAN_(WAIT4_QUERY_KIND); - break; - case (uint8_t)QS_RX_EVENT: - QS_RX_TRAN_(WAIT4_EVT_PRIO); - break; - -#ifdef Q_UTEST - case (uint8_t)QS_RX_TEST_SETUP: - QS_RX_TRAN_(WAIT4_TEST_SETUP_FRAME); - break; - case (uint8_t)QS_RX_TEST_TEARDOWN: - QS_RX_TRAN_(WAIT4_TEST_TEARDOWN_FRAME); - break; - case (uint8_t)QS_RX_TEST_CONTINUE: - QS_RX_TRAN_(WAIT4_TEST_CONTINUE_FRAME); - break; - case (uint8_t)QS_RX_TEST_PROBE: - if (QS_tstPriv_.tpNum - < (uint8_t)(sizeof(QS_tstPriv_.tpBuf) - / sizeof(QS_tstPriv_.tpBuf[0]))) - { - QS_rxPriv_.var.tp.data = 0U; - QS_rxPriv_.var.tp.idx = 0U; - QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA); - } - else { // the # Test-Probes exceeded - QS_rxReportError_((int8_t)QS_RX_TEST_PROBE); - QS_RX_TRAN_(ERROR_STATE); - } - break; -#endif // Q_UTEST - - default: - QS_rxReportError_(0x43); - QS_RX_TRAN_(ERROR_STATE); - break; - } - break; - } - case (uint8_t)WAIT4_INFO_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_CMD_ID: { - QS_rxPriv_.var.cmd.cmdId = b; - QS_rxPriv_.var.cmd.idx = 0U; - QS_rxPriv_.var.cmd.param1 = 0U; - QS_rxPriv_.var.cmd.param2 = 0U; - QS_rxPriv_.var.cmd.param3 = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM1); - break; - } - case (uint8_t)WAIT4_CMD_PARAM1: { - QS_rxPriv_.var.cmd.param1 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx); - QS_rxPriv_.var.cmd.idx += 8U; - if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) { - QS_rxPriv_.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM2); - } - break; - } - case (uint8_t)WAIT4_CMD_PARAM2: { - QS_rxPriv_.var.cmd.param2 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx); - QS_rxPriv_.var.cmd.idx += 8U; - if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) { - QS_rxPriv_.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM3); - } - break; - } - case (uint8_t)WAIT4_CMD_PARAM3: { - QS_rxPriv_.var.cmd.param3 |= ((uint32_t)b << QS_rxPriv_.var.cmd.idx); - QS_rxPriv_.var.cmd.idx += 8U; - if (QS_rxPriv_.var.cmd.idx == (8U * 4U)) { - QS_rxPriv_.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_FRAME); - } - break; - } - case (uint8_t)WAIT4_CMD_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_RESET_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TICK_RATE: { - QS_rxPriv_.var.tick.rate = (uint_fast8_t)b; - QS_RX_TRAN_(WAIT4_TICK_FRAME); - break; - } - case (uint8_t)WAIT4_TICK_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_PEEK_OFFS: { - if (QS_rxPriv_.var.peek.idx == 0U) { - QS_rxPriv_.var.peek.offs = (uint16_t)b; - QS_rxPriv_.var.peek.idx += 8U; - } - else { - QS_rxPriv_.var.peek.offs |= (uint16_t)((uint16_t)b << 8U); - QS_RX_TRAN_(WAIT4_PEEK_SIZE); - } - break; - } - case (uint8_t)WAIT4_PEEK_SIZE: { - if ((b == 1U) || (b == 2U) || (b == 4U)) { - QS_rxPriv_.var.peek.size = b; - QS_RX_TRAN_(WAIT4_PEEK_NUM); - } - else { - QS_rxReportError_((int8_t)QS_RX_PEEK); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_PEEK_NUM: { - QS_rxPriv_.var.peek.num = b; - QS_RX_TRAN_(WAIT4_PEEK_FRAME); - break; - } - case (uint8_t)WAIT4_PEEK_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_POKE_OFFS: { - if (QS_rxPriv_.var.poke.idx == 0U) { - QS_rxPriv_.var.poke.offs = (uint16_t)b; - QS_rxPriv_.var.poke.idx = 1U; - } - else { - QS_rxPriv_.var.poke.offs |= (uint16_t)((uint16_t)b << 8U); - QS_RX_TRAN_(WAIT4_POKE_SIZE); - } - break; - } - case (uint8_t)WAIT4_POKE_SIZE: { - if ((b == 1U) || (b == 2U) || (b == 4U)) { - QS_rxPriv_.var.poke.size = b; - QS_RX_TRAN_(WAIT4_POKE_NUM); - } - else { - QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_POKE_NUM: { - if (b > 0U) { - QS_rxPriv_.var.poke.num = b; - QS_rxPriv_.var.poke.data = 0U; - QS_rxPriv_.var.poke.idx = 0U; - QS_RX_TRAN_((QS_rxPriv_.var.poke.fill != 0U) - ? WAIT4_FILL_DATA - : WAIT4_POKE_DATA); - } - else { - QS_rxReportError_((QS_rxPriv_.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_FILL_DATA: { - QS_rxPriv_.var.poke.data |= ((uint32_t)b << QS_rxPriv_.var.poke.idx); - QS_rxPriv_.var.poke.idx += 8U; - if ((uint8_t)(QS_rxPriv_.var.poke.idx >> 3U) == QS_rxPriv_.var.poke.size) { - QS_RX_TRAN_(WAIT4_FILL_FRAME); - } - break; - } - case (uint8_t)WAIT4_POKE_DATA: { - QS_rxPriv_.var.poke.data |= ((uint32_t)b << QS_rxPriv_.var.poke.idx); - QS_rxPriv_.var.poke.idx += 8U; - if ((uint8_t)(QS_rxPriv_.var.poke.idx >> 3U) == QS_rxPriv_.var.poke.size) { - QS_rxPoke_(); - --QS_rxPriv_.var.poke.num; - if (QS_rxPriv_.var.poke.num == 0U) { - QS_RX_TRAN_(WAIT4_POKE_FRAME); - } - } - break; - } - case (uint8_t)WAIT4_FILL_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case WAIT4_POKE_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_FILTER_LEN: { - if (b == sizeof(QS_rxPriv_.var.flt.data)) { - QS_rxPriv_.var.flt.idx = 0U; - QS_RX_TRAN_(WAIT4_FILTER_DATA); - } - else { - QS_rxReportError_(QS_rxPriv_.var.flt.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_FILTER_DATA: { - QS_rxPriv_.var.flt.data[QS_rxPriv_.var.flt.idx] = b; - ++QS_rxPriv_.var.flt.idx; - if (QS_rxPriv_.var.flt.idx == sizeof(QS_rxPriv_.var.flt.data)) { - QS_RX_TRAN_(WAIT4_FILTER_FRAME); - } - break; - } - case (uint8_t)WAIT4_FILTER_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_OBJ_KIND: { - if (b <= (uint8_t)SM_AO_OBJ) { - QS_rxPriv_.var.obj.kind = b; - QS_rxPriv_.var.obj.addr = 0U; - QS_rxPriv_.var.obj.idx = 0U; - QS_RX_TRAN_(WAIT4_OBJ_ADDR); - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_OBJ_ADDR: { - QS_rxPriv_.var.obj.addr |= ((QSObj)b << QS_rxPriv_.var.obj.idx); - QS_rxPriv_.var.obj.idx += 8U; - if (QS_rxPriv_.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) { - QS_RX_TRAN_(WAIT4_OBJ_FRAME); - } - break; - } - case (uint8_t)WAIT4_OBJ_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_QUERY_KIND: { - if (b < (uint8_t)MAX_OBJ) { - QS_rxPriv_.var.obj.kind = b; - QS_RX_TRAN_(WAIT4_QUERY_FRAME); - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case (uint8_t)WAIT4_QUERY_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_EVT_PRIO: { - QS_rxPriv_.var.evt.prio = b; - QS_rxPriv_.var.evt.sig = 0U; - QS_rxPriv_.var.evt.idx = 0U; - QS_RX_TRAN_(WAIT4_EVT_SIG); - break; - } - case (uint8_t)WAIT4_EVT_SIG: { - QS_rxPriv_.var.evt.sig |= (QSignal)((uint32_t)b << QS_rxPriv_.var.evt.idx); - QS_rxPriv_.var.evt.idx += 8U; - if (QS_rxPriv_.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) { - QS_rxPriv_.var.evt.len = 0U; - QS_rxPriv_.var.evt.idx = 0U; - QS_RX_TRAN_(WAIT4_EVT_LEN); - } - break; - } - case (uint8_t)WAIT4_EVT_LEN: { - QS_rxPriv_.var.evt.len |= (uint16_t)((uint32_t)b << QS_rxPriv_.var.evt.idx); - QS_rxPriv_.var.evt.idx += 8U; - if (QS_rxPriv_.var.evt.idx == (8U * 2U)) { - if ((QS_rxPriv_.var.evt.len + sizeof(QEvt)) - <= QF_poolGetMaxBlockSize()) - { - // report Ack before generating any other QS records - QS_rxReportAck_((int8_t)QS_RX_EVENT); - - QS_rxPriv_.var.evt.e = QF_newX_( - ((uint_fast16_t)QS_rxPriv_.var.evt.len + sizeof(QEvt)), - 0U, // margin - (enum_t)QS_rxPriv_.var.evt.sig); - if (QS_rxPriv_.var.evt.e != (QEvt *)0) { // evt allocated? - QS_rxPriv_.var.evt.p = (uint8_t *)QS_rxPriv_.var.evt.e; - QS_rxPriv_.var.evt.p = &QS_rxPriv_.var.evt.p[sizeof(QEvt)]; - if (QS_rxPriv_.var.evt.len > 0U) { - QS_RX_TRAN_(WAIT4_EVT_PAR); - } - else { - QS_RX_TRAN_(WAIT4_EVT_FRAME); - } - } - else { - QS_rxReportError_((int8_t)QS_RX_EVENT); - QS_RX_TRAN_(ERROR_STATE); - } - } - else { - QS_rxReportError_((int8_t)QS_RX_EVENT); - QS_RX_TRAN_(ERROR_STATE); - } - } - break; - } - case (uint8_t)WAIT4_EVT_PAR: { // event parameters - *QS_rxPriv_.var.evt.p = b; - ++QS_rxPriv_.var.evt.p; - --QS_rxPriv_.var.evt.len; - if (QS_rxPriv_.var.evt.len == 0U) { - QS_RX_TRAN_(WAIT4_EVT_FRAME); - } - break; - } - case (uint8_t)WAIT4_EVT_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - -#ifdef Q_UTEST - case (uint8_t)WAIT4_TEST_SETUP_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TEST_TEARDOWN_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TEST_CONTINUE_FRAME: { - // keep ignoring the data until a frame is collected - break; - } - case (uint8_t)WAIT4_TEST_PROBE_DATA: { - QS_rxPriv_.var.tp.data |= ((uint32_t)b << QS_rxPriv_.var.tp.idx); - QS_rxPriv_.var.tp.idx += 8U; - if (QS_rxPriv_.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) { - QS_rxPriv_.var.tp.addr = 0U; - QS_rxPriv_.var.tp.idx = 0U; - QS_RX_TRAN_(WAIT4_TEST_PROBE_ADDR); - } - break; - } - case (uint8_t)WAIT4_TEST_PROBE_ADDR: { - QS_rxPriv_.var.tp.addr |= ((QSFun)b << QS_rxPriv_.var.tp.idx); - QS_rxPriv_.var.tp.idx += 8U; - if (QS_rxPriv_.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) { - QS_RX_TRAN_(WAIT4_TEST_PROBE_FRAME); - } - break; - } - case (uint8_t)WAIT4_TEST_PROBE_FRAME: { - // keep ignoring the data until a frame is collected - break; - } -#endif // Q_UTEST - - case (uint8_t)ERROR_STATE: { - // keep ignoring the data until a good frame is collected - break; - } - default: { // unexpected or unimplemented state - QS_rxReportError_(0x45); - QS_RX_TRAN_(ERROR_STATE); - break; - } - } -} - -//............................................................................ -static void QS_rxHandleGoodFrame_(uint8_t const state) { - uint8_t i; - uint8_t *ptr; - QS_CRIT_STAT - - switch (state) { - case WAIT4_INFO_FRAME: { - // no need to report Ack or Done - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_target_info_pre_(0U); // send only Target info - QS_MEM_APP(); - QS_CRIT_EXIT(); - break; - } - case WAIT4_RESET_FRAME: { - // no need to report Ack or Done, because Target resets - QS_onReset(); // reset the Target - break; - } - case WAIT4_CMD_PARAM1: // intentionally fall-through - case WAIT4_CMD_PARAM2: // intentionally fall-through - case WAIT4_CMD_PARAM3: // intentionally fall-through - case WAIT4_CMD_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_COMMAND); - QS_onCommand(QS_rxPriv_.var.cmd.cmdId, QS_rxPriv_.var.cmd.param1, - QS_rxPriv_.var.cmd.param2, QS_rxPriv_.var.cmd.param3); -#ifdef Q_UTEST - #if Q_UTEST != 0 - QS_processTestEvts_(); // process all events produced - #endif // Q_UTEST != 0 -#endif // Q_UTEST - QS_rxReportDone_((int8_t)QS_RX_COMMAND); - break; - } - case WAIT4_TICK_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TICK); -#ifdef Q_UTEST - QTimeEvt_tick1_((uint_fast8_t)QS_rxPriv_.var.tick.rate, &QS_rxPriv_); - #if Q_UTEST != 0 - QS_processTestEvts_(); // process all events produced - #endif // Q_UTEST != 0 -#else - QTimeEvt_tick_((uint_fast8_t)QS_rxPriv_.var.tick.rate, &QS_rxPriv_); -#endif // Q_UTEST - QS_rxReportDone_((int8_t)QS_RX_TICK); - break; - } - case WAIT4_PEEK_FRAME: { - // no need to report Ack or Done - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_PEEK_DATA); - ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[QS_rxPriv_.var.peek.offs]; - QS_TIME_PRE_(); // timestamp - QS_U16_PRE_(QS_rxPriv_.var.peek.offs); // data offset - QS_U8_PRE_(QS_rxPriv_.var.peek.size); // data size - QS_U8_PRE_(QS_rxPriv_.var.peek.num); // # data items - for (i = 0U; i < QS_rxPriv_.var.peek.num; ++i) { - switch (QS_rxPriv_.var.peek.size) { - case 1: - QS_U8_PRE_(ptr[i]); - break; - case 2: - QS_U16_PRE_(((uint16_t *)ptr)[i]); - break; - case 4: - QS_U32_PRE_(((uint32_t *)ptr)[i]); - break; - default: - // intentionally empty - break; - } - } - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - - QS_REC_DONE(); // user callback (if defined) - break; - } - case WAIT4_POKE_DATA: { - // received less than expected poke data items - QS_rxReportError_((int8_t)QS_RX_POKE); - break; - } - case WAIT4_POKE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_POKE); - // no need to report done - break; - } - case WAIT4_FILL_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_FILL); - ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[QS_rxPriv_.var.poke.offs]; - for (i = 0U; i < QS_rxPriv_.var.poke.num; ++i) { - switch (QS_rxPriv_.var.poke.size) { - case 1: - ptr[i] = (uint8_t)QS_rxPriv_.var.poke.data; - break; - case 2: - ((uint16_t *)ptr)[i] - = (uint16_t)QS_rxPriv_.var.poke.data; - break; - case 4: - ((uint32_t *)ptr)[i] = QS_rxPriv_.var.poke.data; - break; - default: - // intentionally empty - break; - } - } - break; - } - case WAIT4_FILTER_FRAME: { - QS_rxReportAck_(QS_rxPriv_.var.flt.recId); - - // apply the received filters - if (QS_rxPriv_.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) { - for (i = 0U; i < Q_DIM(QS_filt_.glb); ++i) { - QS_filt_.glb[i] = QS_rxPriv_.var.flt.data[i]; - } - // leave the "not maskable" filters enabled, - // see qs.h, Miscellaneous QS records (not maskable) - QS_filt_.glb[0] |= 0x01U; - QS_filt_.glb[7] |= 0xFCU; - QS_filt_.glb[8] |= 0x7FU; - - // never enable the last 3 records (0x7D, 0x7E, 0x7F) - QS_filt_.glb[15] &= 0x1FU; - } - else if (QS_rxPriv_.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) { - for (i = 0U; i < Q_DIM(QS_filt_.loc); ++i) { - QS_filt_.loc[i] = QS_rxPriv_.var.flt.data[i]; - } - // leave QS_ID == 0 always on - QS_filt_.loc[0] |= 0x01U; - } - else { - QS_rxReportError_(QS_rxPriv_.var.flt.recId); - } - // no need to report Done - break; - } - case WAIT4_OBJ_FRAME: { - i = QS_rxPriv_.var.obj.kind; - if (i < (uint8_t)MAX_OBJ) { - if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { - QS_rxPriv_.currObj[i] = (void *)QS_rxPriv_.var.obj.addr; - QS_rxReportAck_((int8_t)QS_RX_CURR_OBJ); - } - else if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_AO_FILTER) { - if (QS_rxPriv_.var.obj.addr != 0U) { - int_fast16_t const filter = - (int_fast16_t)((QActive *)QS_rxPriv_.var.obj.addr)->prio; - QS_locFilter_((i == 0U) ? filter :-filter); - QS_rxReportAck_((int8_t)QS_RX_AO_FILTER); - } - else { - QS_rxReportError_((int8_t)QS_RX_AO_FILTER); - } - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - } - } - // both SM and AO - else if (i == (uint8_t)SM_AO_OBJ) { - if (QS_rxPriv_.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { - QS_rxPriv_.currObj[SM_OBJ] = (void *)QS_rxPriv_.var.obj.addr; - QS_rxPriv_.currObj[AO_OBJ] = (void *)QS_rxPriv_.var.obj.addr; - } - QS_rxReportAck_(QS_rxPriv_.var.obj.recId); - } - else { - QS_rxReportError_(QS_rxPriv_.var.obj.recId); - } - break; - } - case WAIT4_QUERY_FRAME: { - QS_queryCurrObj(QS_rxPriv_.var.obj.kind); - break; - } - case WAIT4_EVT_FRAME: { - // NOTE: Ack was already reported in the WAIT4_EVT_LEN state -#ifdef Q_UTEST - QS_onTestEvt(QS_rxPriv_.var.evt.e); // adjust the event, if needed -#endif // Q_UTEST - i = 0U; // use 'i' as status, 0 == success,no-recycle - - if (QS_rxPriv_.var.evt.prio == 0U) { // publish - QActive_publish_(QS_rxPriv_.var.evt.e, &QS_rxPriv_, 0U); - } - else if (QS_rxPriv_.var.evt.prio < QF_MAX_ACTIVE) { - if (!QACTIVE_POST_X(QActive_registry_[QS_rxPriv_.var.evt.prio], - QS_rxPriv_.var.evt.e, - 0U, // margin - &QS_rxPriv_)) - { - // failed QACTIVE_POST() recycles the event - i = 0x80U; // failure status, no recycle - } - } - else if (QS_rxPriv_.var.evt.prio == 255U) { // special prio - // dispatch to the current SM object - if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - // increment the ref-ctr to simulate the situation - // when the event is just retrieved from a queue. - // This is expected for the following QF_gc() call. - ++QS_rxPriv_.var.evt.e->refCtr_; - - QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; - (*sm->vptr->dispatch)(sm, QS_rxPriv_.var.evt.e, 0U); - i = 0x01U; // success status, recycle needed - } - else { - i = 0x81U; // failure status, recycle needed - } - } - else if (QS_rxPriv_.var.evt.prio == 254U) { // special prio - // init the current SM object" - if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - // increment the ref-ctr to simulate the situation - // when the event is just retrieved from a queue. - // This is expected for the following QF_gc() call. - ++QS_rxPriv_.var.evt.e->refCtr_; - - QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; - (*sm->vptr->init)(sm, QS_rxPriv_.var.evt.e, 0U); - i = 0x01U; // success status, recycle needed - } - else { - i = 0x81U; // failure status, recycle needed - } - } - else if (QS_rxPriv_.var.evt.prio == 253U) { // special prio - // post to the current AO - if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) { - if (!QACTIVE_POST_X( - (QActive *)QS_rxPriv_.currObj[AO_OBJ], - QS_rxPriv_.var.evt.e, - 0U, // margin - &QS_rxPriv_)) - { - // failed QACTIVE_POST() recycles the event - i = 0x80U; // failure status, no recycle - } - } - else { - i = 0x81U; // failure status, recycle needed - } - } - else { - i = 0x81U; // failure status, recycle needed - } - -#if (QF_MAX_EPOOL > 0U) - if ((i & 0x01U) != 0U) { // recycle needed? - QF_gc(QS_rxPriv_.var.evt.e); - } -#endif - if ((i & 0x80U) != 0U) { // failure? - QS_rxReportError_((int8_t)QS_RX_EVENT); - } - else { -#ifdef Q_UTEST - #if Q_UTEST != 0 - QS_processTestEvts_(); // process all events produced - #endif // Q_UTEST != 0 -#endif // Q_UTEST - QS_rxReportDone_((int8_t)QS_RX_EVENT); - } - break; - } - -#ifdef Q_UTEST - case WAIT4_TEST_SETUP_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_SETUP); - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_tstPriv_.tpNum = 0U; // clear the Test-Probes - QS_tstPriv_.testTime = 0U; // clear the time tick - QS_MEM_APP(); - QS_CRIT_EXIT(); - // don't clear current objects - QS_onTestSetup(); // application-specific test setup - // no need to report Done - break; - } - case WAIT4_TEST_TEARDOWN_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_TEARDOWN); - QS_onTestTeardown(); // application-specific test teardown - // no need to report Done - break; - } - case WAIT4_TEST_CONTINUE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_CONTINUE); - QS_rxPriv_.inTestLoop = false; // exit the QUTest loop - // no need to report Done - break; - } - case WAIT4_TEST_PROBE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_PROBE); - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - Q_ASSERT_INCRIT(815, QS_tstPriv_.tpNum - < (sizeof(QS_tstPriv_.tpBuf) / sizeof(QS_tstPriv_.tpBuf[0]))); - QS_tstPriv_.tpBuf[QS_tstPriv_.tpNum] = QS_rxPriv_.var.tp; - ++QS_tstPriv_.tpNum; - QS_MEM_APP(); - QS_CRIT_EXIT(); - // no need to report Done - break; - } -#endif // Q_UTEST - - case ERROR_STATE: { - // keep ignoring all bytes until new frame - break; - } - default: { - QS_rxReportError_(0x47); - break; - } - } -} - -//............................................................................ -static void QS_rxHandleBadFrame_(uint8_t const state) { - QS_rxReportError_(0x50); // report error for all bad frames - - switch (state) { - case WAIT4_EVT_FRAME: { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - Q_ASSERT_INCRIT(910, QS_rxPriv_.var.evt.e != (QEvt *)0); - QS_CRIT_EXIT(); -#if (QF_MAX_EPOOL > 0U) - QF_gc(QS_rxPriv_.var.evt.e); // don't leak allocated evt -#endif - break; - } - default: { - // intentionally empty - break; - } - } -} - -//............................................................................ -static void QS_rxReportAck_(int8_t const recId) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(recId); // record ID - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) -} - -//............................................................................ -static void QS_rxReportError_(int8_t const code) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(0x80U | (uint8_t)code); // error code - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) -} - -//............................................................................ -static void QS_rxReportDone_(int8_t const recId) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_TARGET_DONE); - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(recId); // record ID - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) -} - -//............................................................................ -static void QS_queryCurrObj(uint8_t const obj_kind) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(800, obj_kind < Q_DIM(QS_rxPriv_.currObj)); - QS_CRIT_EXIT(); - - if (QS_rxPriv_.currObj[obj_kind] != (void *)0) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_QUERY_DATA); - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(obj_kind); // object kind - QS_OBJ_PRE_(QS_rxPriv_.currObj[obj_kind]); - switch (obj_kind) { - case (uint8_t)SM_OBJ: // intentionally fall through - case (uint8_t)AO_OBJ: - QS_FUN_PRE_((*((QAsm *)QS_rxPriv_.currObj[obj_kind])->vptr - ->getStateHandler)( - ((QAsm *)QS_rxPriv_.currObj[obj_kind]))); - break; - case (uint8_t)MP_OBJ: - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case (uint8_t)EQ_OBJ: - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case (uint8_t)TE_OBJ: - QS_OBJ_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->act); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->ctr); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->interval); - QS_SIG_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.sig); - QS_U8_PRE_ (((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.refCtr_); - break; - default: - // intentionally empty - break; - } - QS_endRec_(); - QS_MEM_APP(); - QS_CRIT_EXIT(); - QS_REC_DONE(); // user callback (if defined) - } - else { - QS_rxReportError_((int8_t)QS_RX_QUERY_CURR); - } -} - -//............................................................................ -static void QS_rxPoke_(void) { - uint8_t *ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[QS_rxPriv_.var.poke.offs]; - switch (QS_rxPriv_.var.poke.size) { - case 1: - *ptr = (uint8_t)QS_rxPriv_.var.poke.data; - break; - case 2: - *(uint16_t *)ptr = (uint16_t)QS_rxPriv_.var.poke.data; - break; - case 4: - *(uint32_t *)ptr = QS_rxPriv_.var.poke.data; - break; - default: { - Q_ERROR_INCRIT(900); - break; - } - } - - QS_rxPriv_.var.poke.data = 0U; - QS_rxPriv_.var.poke.idx = 0U; - QS_rxPriv_.var.poke.offs += (uint16_t)QS_rxPriv_.var.poke.size; -} - -//! @endcond diff --git a/src/qs/qstamp.c b/src/qs/qstamp.c index 5b81b726..1137aa80 100644 --- a/src/qs/qstamp.c +++ b/src/qs/qstamp.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qs::qstamp.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,29 +14,25 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // //$endhead${src::qs::qstamp.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qstamp.h" -//! the calendar date of the last translation of the form: "Mmm dd yyyy" char const Q_BUILD_DATE[12] = __DATE__; - -//! the time of the last translation of the form: "hh:mm:ss" char const Q_BUILD_TIME[9] = __TIME__; diff --git a/src/qs/qutest.c b/src/qs/qutest.c deleted file mode 100644 index f88a7600..00000000 --- a/src/qs/qutest.c +++ /dev/null @@ -1,570 +0,0 @@ -//$file${src::qs::qutest.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qs::qutest.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qs::qutest.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// only build when Q_UTEST is defined -#ifdef Q_UTEST - -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#include "qs_port.h" // include QS port -#include "qs_pkg.h" // QS facilities for pre-defined trace records - -//============================================================================ -// QUTest unit testing harness -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QS::QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//$enddef${QS::QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//============================================================================ -//! @cond INTERNAL - -QSTestAttr QS_tstPriv_; - -//............................................................................ -void QS_test_pause_(void) { - QS_beginRec_((uint_fast8_t)QS_TEST_PAUSED); - QS_endRec_(); - QS_onTestLoop(); -} - -//............................................................................ -uint32_t QS_getTestProbe_(QSpyFunPtr const api) { - uint32_t data = 0U; - for (uint_fast8_t i = 0U; i < QS_tstPriv_.tpNum; ++i) { - if (QS_tstPriv_.tpBuf[i].addr == (QSFun)api) { - data = QS_tstPriv_.tpBuf[i].data; - - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_TEST_PROBE_GET); - QS_TIME_PRE_(); // timestamp - QS_FUN_PRE_(api); // the calling API - QS_U32_PRE_(data); // the Test-Probe data - QS_endRec_(); - - QS_REC_DONE(); // user callback (if defined) - - --QS_tstPriv_.tpNum; // one less Test-Probe - // move all remaining entries in the buffer up by one - for (uint_fast8_t j = i; j < QS_tstPriv_.tpNum; ++j) { - QS_tstPriv_.tpBuf[j] = QS_tstPriv_.tpBuf[j + 1U]; - } - QS_MEM_APP(); - QS_CRIT_EXIT(); - break; // we are done (Test-Probe retrieved) - } - } - return data; -} - -//............................................................................ -QSTimeCtr QS_onGetTime(void) { - return (++QS_tstPriv_.testTime); -} - -//............................................................................ -Q_NORETURN Q_onError( - char const * const module, - int_t const id) -{ - // NOTE: called in a critical section - - QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); - QS_TIME_PRE_(); - QS_U16_PRE_(id); - QS_STR_PRE_((module != (char *)0) ? module : "?"); - QS_endRec_(); - QS_onFlush(); // flush the assertion record to the host - - QS_onCleanup(); // cleanup before resetting - QS_onReset(); // reset the target to prevent the code from continuing - for (;;) { // QS_onReset() should not return, but to ensure no-return - } -} - -//! @endcond -//============================================================================ - -// QP-stub for QUTest -// NOTE: The QP-stub is needed for unit testing QP applications, but might -// NOT be needed for testing QP itself. In that case, the build process -// can define Q_UTEST=0 to exclude the QP-stub from the build. -#if (Q_UTEST != 0) - -Q_DEFINE_THIS_MODULE("qutest") - -//............................................................................ -void QS_processTestEvts_(void) { - QS_TEST_PROBE_DEF(&QS_processTestEvts_) - - // return immediately (do nothing) for Test Probe != 0 - QS_TEST_PROBE(return;) - - while (QPSet_notEmpty(&QS_tstPriv_.readySet)) { - uint_fast8_t const p = QPSet_findMax(&QS_tstPriv_.readySet); - QActive * const a = QActive_registry_[p]; - - QEvt const * const e = QActive_get_(a); - QASM_DISPATCH(a, e, a->prio); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? - QPSet_remove(&QS_tstPriv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); -#endif - } - } -} - -//$define${QS::QUTest-stub} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QS::QUTest-stub::QF::init} ............................................... -void QF_init(void) { - // Clear the internal QF variables, so that the framework can start - // correctly even if the startup code fails to clear the uninitialized - // data (as is required by the C Standard). - QF_bzero_(&QF_priv_, sizeof(QF_priv_)); - QF_bzero_(&QS_tstPriv_, sizeof(QS_tstPriv_)); - QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - - #ifndef Q_UNSAFE - QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); - #endif -} - -//${QS::QUTest-stub::QF::stop} ............................................... -void QF_stop(void) { - QS_onReset(); -} - -//${QS::QUTest-stub::QF::run} ................................................ -int_t QF_run(void) { - // function dictionaries for the standard API - QS_FUN_DICTIONARY(&QActive_post_); - QS_FUN_DICTIONARY(&QActive_postLIFO_); - QS_FUN_DICTIONARY(&QS_processTestEvts_); - - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - // produce the QS_QF_RUN trace record - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() - - QS_MEM_APP(); - QS_CRIT_EXIT(); - - QS_processTestEvts_(); // process all events posted so far - QS_onTestLoop(); // run the test loop - QS_onCleanup(); // application cleanup - return 0; // return no error -} - -//${QS::QUTest-stub::QActive} ................................................ - -//${QS::QUTest-stub::QActive::start} ......................................... -//! @private @memberof QActive -void QActive_start(QActive * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par) -{ - Q_UNUSED_PAR(stkSto); - Q_UNUSED_PAR(stkSize); - - me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO - me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold - QActive_register_(me); // make QF aware of this active object - - QEQueue_init(&me->eQueue, qSto, qLen); - - // top-most initial tran. (virtual call) - (*me->super.vptr->init)(&me->super, par, me->prio); -} - -//${QS::QUTest-stub::QActive::stop} .......................................... -#ifdef QACTIVE_CAN_STOP -//! @protected @memberof QActive -void QActive_stop(QActive * const me) { - QActive_unsubscribeAll(me); // unsubscribe from all events - QActive_unregister_(me); // un-register this active object -} -#endif // def QACTIVE_CAN_STOP - -//${QS::QUTest-stub::QTimeEvt} ............................................... - -//${QS::QUTest-stub::QTimeEvt::tick1_} ....................................... -//! @private @memberof QTimeEvt -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - - QS_BEGIN_PRE_(QS_QF_TICK, 0U) - ++prev->ctr; - QS_TEC_PRE_(prev->ctr); // tick ctr - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - - // is current Time Event object provided? - QTimeEvt *t = (QTimeEvt *)QS_rxPriv_.currObj[TE_OBJ]; - if (t != (QTimeEvt *)0) { - - // the time event must be armed - Q_ASSERT_INCRIT(810, t->ctr != 0U); - - QActive * const act = (QActive *)(t->act); - - // the recipient AO must be provided - Q_ASSERT_INCRIT(820, act != (QActive *)0); - - // periodic time evt? - if (t->interval != 0U) { - t->ctr = t->interval; // rearm the time event - } - else { // one-shot time event: automatically disarm - t->ctr = 0U; // auto-disarm - // mark time event 't' as NOT linked - t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); // this time event object - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - } - - QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(t); // the time event object - QS_SIG_PRE_(t->super.sig); // signal of this time event - QS_OBJ_PRE_(act); // the target AO - QS_U8_PRE_(tickRate); // tick rate - QS_END_PRE_() - QS_MEM_APP(); - QS_CRIT_EXIT(); // exit critical section before posting - - QACTIVE_POST(act, &t->super, sender); // asserts if queue overflows - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - } - - // update the linked list of time events - for (;;) { - t = prev->next; // advance down the time evt. list - - // end of the list? - if (t == (QTimeEvt *)0) { - - // any new time events armed since the last QTimeEvt_tick_()? - if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - - // sanity check - Q_ASSERT_INCRIT(830, prev != (QTimeEvt *)0); - prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; // switch to the new list - } - else { - break; // all currently armed time evts. processed - } - } - - // time event scheduled for removal? - if (t->ctr == 0U) { - prev->next = t->next; - // mark time event 't' as NOT linked - t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - // do NOT advance the prev pointer - QS_MEM_APP(); - QS_CRIT_EXIT(); // exit crit. section to reduce latency - } - else { - prev = t; // advance to this time event - QS_MEM_APP(); - QS_CRIT_EXIT(); // exit crit. section to reduce latency - } - QS_CRIT_ENTRY(); // re-enter crit. section to continue - QS_MEM_SYS(); - } - - QS_MEM_APP(); - QS_CRIT_EXIT(); -} - -//${QS::QUTest-stub::QHsmDummy} .............................................. - -//${QS::QUTest-stub::QHsmDummy::ctor} ........................................ -//! @public @memberof QHsmDummy -void QHsmDummy_ctor(QHsmDummy * const me) { - static struct QAsmVtable const vtable = { - &QHsmDummy_init_, - &QHsmDummy_dispatch_, - &QHsm_isIn_ - #ifdef Q_SPY - ,&QHsm_getStateHandler_ - #endif - }; - me->super.vptr = &vtable; // hook the vptr -} - -//${QS::QUTest-stub::QHsmDummy::init_} ....................................... -//! @private @memberof QHsmDummy -void QHsmDummy_init_( - QAsm * const me, - void const * const par, - uint_fast8_t const qsId) -{ - Q_UNUSED_PAR(par); - - #ifdef Q_SPY - if ((QS_priv_.flags & 0x01U) == 0U) { - QS_priv_.flags |= 0x01U; - QS_FUN_DICTIONARY(&QHsm_top); - } - #endif - - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.fun); // the source state - QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. - QS_END_PRE_() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} - -//${QS::QUTest-stub::QHsmDummy::dispatch_} ................................... -//! @private @memberof QHsmDummy -void QHsmDummy_dispatch_( - QAsm * const me, - QEvt const * const e, - uint_fast8_t const qsId) -{ - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE_(); // time stamp - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this state machine object - QS_FUN_PRE_(me->state.fun); // the current state - QS_END_PRE_() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} - -//${QS::QUTest-stub::QActiveDummy} ........................................... - -//${QS::QUTest-stub::QActiveDummy::ctor} ..................................... -//! @public @memberof QActiveDummy -void QActiveDummy_ctor(QActiveDummy * const me) { - // superclass' ctor - QActive_ctor(&me->super, Q_STATE_CAST(0)); - - static struct QAsmVtable const vtable = { - &QActiveDummy_init_, - &QActiveDummy_dispatch_, - &QHsm_isIn_ - #ifdef Q_SPY - ,&QHsm_getStateHandler_ - #endif - }; - me->super.super.vptr = &vtable; // hook the vptr -} - -//${QS::QUTest-stub::QActiveDummy::init_} .................................... -//! @private @memberof QActiveDummy -void QActiveDummy_init_( - QAsm * const me, - void const * const par, - uint_fast8_t const qsId) -{ - Q_UNUSED_PAR(qsId); - - QHsmDummy_init_(me, par, ((QActive const *)me)->prio); -} - -//${QS::QUTest-stub::QActiveDummy::dispatch_} ................................ -//! @private @memberof QActiveDummy -void QActiveDummy_dispatch_( - QAsm * const me, - QEvt const * const e, - uint_fast8_t const qsId) -{ - Q_UNUSED_PAR(qsId); - - QHsmDummy_dispatch_(me, e, ((QActive const *)me)->prio); -} - -//${QS::QUTest-stub::QActiveDummy::fakePost_} ................................ -//! @private @memberof QActiveDummy -bool QActiveDummy_fakePost_( - QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, - void const * const sender) -{ - QS_TEST_PROBE_DEF(&QActive_post_) - - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // test-probe#1 for faking queue overflow - bool status = true; - QS_TEST_PROBE_ID(1, - status = false; - if (margin == QF_NO_MARGIN) { - // fake assertion Mod=qf_actq,Loc=110 - Q_onError("qf_actq", 110); - } - ) - - // is it a mutable event? - if (QEvt_getPoolNum_(e) != 0U) { - QEvt_refCtr_inc_(e); - } - - uint_fast8_t const rec = (status ? (uint_fast8_t)QS_QF_ACTIVE_POST - : (uint_fast8_t)QS_QF_ACTIVE_POST_ATTEMPT); - QS_BEGIN_PRE_(rec, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(0U); // # free entries - QS_EQC_PRE_(margin); // margin requested - QS_END_PRE_() - - QF_MEM_APP(); - QF_CRIT_EXIT(); - - // callback to examine the posted event under the same conditions - // as producing the #QS_QF_ACTIVE_POST trace record, which are: - // the local filter for this AO ('me->prio') is set - if (QS_LOC_CHECK_(me->prio)) { - QS_onTestPost(sender, me, e, status); - } - - // recycle the event immediately, because it was not really posted - #if (QF_MAX_EPOOL > 0U) - QF_gc(e); - #endif - - return status; // the event is "posted" correctly -} - -//${QS::QUTest-stub::QActiveDummy::fakePostLIFO_} ............................ -//! @private @memberof QActiveDummy -void QActiveDummy_fakePostLIFO_( - QActive * const me, - QEvt const * const e) -{ - QS_TEST_PROBE_DEF(&QActive_postLIFO_) - - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // test-probe#1 for faking queue overflow - QS_TEST_PROBE_ID(1, - // fake assertion Mod=qf_actq,Loc=210 - Q_onError("qf_actq", 210); - ) - - // is it a mutable event? - if (QEvt_getPoolNum_(e) != 0U) { - QEvt_refCtr_inc_(e); - } - - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(0U); // # free entries - QS_EQC_PRE_(0U); // min # free entries - QS_END_PRE_() - - QF_MEM_APP(); - QF_CRIT_EXIT(); - - // callback to examine the posted event under the same conditions - // as producing the #QS_QF_ACTIVE_POST trace record, which are: - // the local filter for this AO ('me->prio') is set - if (QS_LOC_CHECK_(me->prio)) { - QS_onTestPost((QActive *)0, me, e, true); - } - // recycle the event immediately, because it was not really posted - #if (QF_MAX_EPOOL > 0U) - QF_gc(e); - #endif -} -//$enddef${QS::QUTest-stub} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -#endif // Q_UTEST != 0 - -#endif // Q_UTEST diff --git a/src/qv/qv.c b/src/qv/qv.c index 7a31e1d0..710a0043 100644 --- a/src/qv/qv.c +++ b/src/qv/qv.c @@ -3,17 +3,10 @@ // Model: qpc.qm // File: ${src::qv::qv.c} // -// This code has been generated by QM 6.2.0 . +// This code has been generated by QM 7.0.0 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s // ------------------------ @@ -21,21 +14,20 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // // @@ -81,12 +73,12 @@ void QV_schedDisable(uint_fast8_t const ceiling) { if (ceiling > QV_priv_.schedCeil) { // raising the scheduler ceiling? - QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_LOCK, 0U) + QS_TIME_PRE(); // timestamp // the previous sched ceiling & new sched ceiling - QS_2U8_PRE_((uint8_t)QV_priv_.schedCeil, + QS_2U8_PRE((uint8_t)QV_priv_.schedCeil, (uint8_t)ceiling); - QS_END_PRE_() + QS_END_PRE() QV_priv_.schedCeil = ceiling; #ifndef Q_UNSAFE @@ -109,11 +101,11 @@ void QV_schedEnable(void) { if (QV_priv_.schedCeil != 0U) { // actually enabling the scheduler? - QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); // timestamp + QS_BEGIN_PRE(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE(); // timestamp // current sched ceiling (old), previous sched ceiling (new) - QS_2U8_PRE_((uint8_t)QV_priv_.schedCeil, 0U); - QS_END_PRE_() + QS_2U8_PRE((uint8_t)QV_priv_.schedCeil, 0U); + QS_END_PRE() QV_priv_.schedCeil = 0U; #ifndef Q_UNSAFE @@ -139,13 +131,7 @@ void QF_init(void) { QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U); #endif - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) - { - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, (enum_t)Q_USER_SIG, tickRate); - } + QTimeEvt_init(); // initialize QTimeEvts #ifdef QV_INIT QV_INIT(); // port-specific initialization of the QV kernel @@ -183,7 +169,13 @@ int_t QF_run(void) { #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) uint_fast8_t pprev = 0U; // previously used prio. - #endif + + #ifdef QF_ON_CONTEXT_SW + // officially switch to the idle cotext + QF_onContextSw((QActive *)0, (QActive *)0); + #endif // def QF_ON_CONTEXT_SW + + #endif // def (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) for (;;) { // QV event loop... @@ -203,11 +195,11 @@ int_t QF_run(void) { QActive * const a = QActive_registry_[p]; #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QS_BEGIN_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_((uint8_t)p, + QS_BEGIN_PRE(QS_SCHED_NEXT, p) + QS_TIME_PRE(); // timestamp + QS_2U8_PRE((uint8_t)p, (uint8_t)pprev); - QS_END_PRE_() + QS_END_PRE() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(((pprev != 0U) @@ -242,10 +234,10 @@ int_t QF_run(void) { else { // no AO ready to run --> idle #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (pprev != 0U) { - QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_((uint8_t)pprev); // previous prio - QS_END_PRE_() + QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) + QS_TIME_PRE(); // timestamp + QS_U8_PRE((uint8_t)pprev); // previous prio + QS_END_PRE() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(QActive_registry_[pprev], (QActive *)0); @@ -283,7 +275,7 @@ int_t QF_run(void) { //! @public @memberof QActive void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, diff --git a/src/qxk/CMakeLists.txt b/src/qxk/CMakeLists.txt deleted file mode 100644 index cd022edd..00000000 --- a/src/qxk/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# ./src/qf -target_sources(qpc PRIVATE - qxk_mutex.c - qxk_sema.c - qxk_xthr.c - qxk.c -) diff --git a/src/qxk/qxk.c b/src/qxk/qxk.c deleted file mode 100644 index 30ba8b4a..00000000 --- a/src/qxk/qxk.c +++ /dev/null @@ -1,546 +0,0 @@ -//$file${src::qxk::qxk.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qxk::qxk.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qxk::qxk.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk") - -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXK-base::priv_} .................................................... -QXK_Attr QXK_priv_; - -//${QXK::QXK-base::schedLock} ................................................ -//! @static @public @memberof QXK -QSchedStatus QXK_schedLock(uint_fast8_t const ceiling) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_REQUIRE_INCRIT(100, !QXK_ISR_CONTEXT_()); - - QSchedStatus stat; // saved lock status to be returned - - // is the lock ceiling being raised? - if (ceiling > QXK_priv_.lockCeil) { - QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); // timestamp - // the previous lock ceiling & new lock ceiling - QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)ceiling); - QS_END_PRE_() - - // previous status of the lock - stat = (QSchedStatus)QXK_priv_.lockHolder; - stat |= (QSchedStatus)QXK_priv_.lockCeil << 8U; - - // new status of the lock - QXK_priv_.lockHolder = (QXK_priv_.curr != (QActive *)0) - ? (uint_fast8_t)QXK_priv_.curr->prio - : 0U; - QXK_priv_.lockCeil = ceiling; - } - else { - stat = 0xFFU; // scheduler not locked - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return stat; // return the status to be saved in a stack variable -} - -//${QXK::QXK-base::schedUnlock} .............................................. -//! @static @public @memberof QXK -void QXK_schedUnlock(QSchedStatus const stat) { - // has the scheduler been actually locked by the last QXK_schedLock()? - if (stat != 0xFFU) { - uint8_t const prevCeil = (uint8_t)(stat >> 8U); - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_REQUIRE_INCRIT(200, !QXK_ISR_CONTEXT_()); - Q_REQUIRE_INCRIT(201, QXK_priv_.lockCeil > prevCeil); - - QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); // timestamp - // ceiling before unlocking & prio after unlocking - QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)prevCeil); - QS_END_PRE_() - - // restore the previous lock ceiling and lock holder - QXK_priv_.lockCeil = prevCeil; - QXK_priv_.lockHolder = (stat & 0xFFU); - - // find if any threads should be run after unlocking the scheduler - if (QXK_sched_() != 0U) { // activation needed? - QXK_activate_(); // synchronously activate basic-thread(s) - } - - QF_MEM_APP(); - QF_CRIT_EXIT(); - } -} - -//${QXK::QXK-base::current} .................................................. -//! @static @public @memberof QXK -QActive * QXK_current(void) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_REQUIRE_INCRIT(600, QXK_priv_.lockCeil <= QF_MAX_ACTIVE); - - struct QActive *curr = QXK_priv_.curr; - if (curr == (QActive *)0) { // basic thread? - curr = QActive_registry_[QXK_priv_.actPrio]; - } - - Q_ASSERT_INCRIT(690, curr != (QActive *)0); - - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return curr; -} - -//${QXK::QXK-base::sched_} ................................................... -//! @static @private @memberof QXK -uint_fast8_t QXK_sched_(void) { - Q_INVARIANT_INCRIT(402, QPSet_verify_(&QXK_priv_.readySet, - &QXK_priv_.readySet_dis)); - - QActive const * const curr = QXK_priv_.curr; - uint_fast8_t p; - if (QPSet_isEmpty(&QXK_priv_.readySet)) { - p = 0U; // no activation needed - } - else { - // find the highest-prio thread ready to run - p = QPSet_findMax(&QXK_priv_.readySet); - if (p <= QXK_priv_.lockCeil) { - p = (uint_fast8_t)QActive_registry_[QXK_priv_.lockHolder]->prio; - if (p != 0U) { - Q_ASSERT_INCRIT(410, - QPSet_hasElement(&QXK_priv_.readySet, p)); - } - } - } - QActive * const next = QActive_registry_[p]; - - // is the current thread a basic-thread? - if (curr == (QActive *)0) { - - // is the next prio. above the active prio.? - if (p > QXK_priv_.actPrio) { - QXK_priv_.next = next; // set the next AO to activate - - if (next->osObject != (void *)0) { // is next extended? - QXK_CONTEXT_SWITCH_(); - p = 0U; // no activation needed - } - } - else { // below the active prio. - QXK_priv_.next = (QActive *)0; - p = 0U; // no activation needed - } - } - else { // currently executing an extended-thread - // is the current thread different from the next? - if (curr != next) { - QXK_priv_.next = next; - QXK_CONTEXT_SWITCH_(); - } - else { // current is the same as next - QXK_priv_.next = (QActive *)0; // no need to context-switch - } - p = 0U; // no activation needed - } - return p; -} - -//${QXK::QXK-base::activate_} ................................................ -//! @static @private @memberof QXK -void QXK_activate_(void) { - uint_fast8_t const prio_in = QXK_priv_.actPrio; - QActive *next = QXK_priv_.next; // the next AO (basic-thread) to run - - Q_REQUIRE_INCRIT(500, (next != (QActive *)0) - && (prio_in <= QF_MAX_ACTIVE)); - - // QXK Context switch callback defined or QS tracing enabled? - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QXK_contextSw_(next); - #endif // QF_ON_CONTEXT_SW || Q_SPY - - QXK_priv_.next = (QActive *)0; // clear the next AO - QXK_priv_.curr = (QActive *)0; // current is basic-thread - - // prio. of the next thread - uint_fast8_t p = (uint_fast8_t)next->prio; - - // loop until no more ready-to-run AOs of higher prio than the initial - do { - QXK_priv_.actPrio = p; // next active prio - - QF_MEM_APP(); - QF_INT_ENABLE(); // unconditionally enable interrupts - - QEvt const * const e = QActive_get_(next); - // NOTE QActive_get_() performs QS_MEM_APP() before return - - // dispatch event (virtual call) - (*next->super.vptr->dispatch)(&next->super, e, p); - #if (QF_MAX_EPOOL > 0U) - QF_gc(e); - #endif - - QF_INT_DISABLE(); // unconditionally disable interrupts - QF_MEM_SYS(); - - // check internal integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(502, QPSet_verify_(&QXK_priv_.readySet, - &QXK_priv_.readySet_dis)); - - if (next->eQueue.frontEvt == (QEvt *)0) { // empty queue? - QPSet_remove(&QXK_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - } - - if (QPSet_isEmpty(&QXK_priv_.readySet)) { - QXK_priv_.next = (QActive *)0; - next = QActive_registry_[0]; - p = 0U; // no activation needed - } - else { - // find next highest-prio below the lock ceiling - p = (uint8_t)QPSet_findMax(&QXK_priv_.readySet); - if (p <= QXK_priv_.lockCeil) { - p = QXK_priv_.lockHolder; // thread holding lock - if (p != 0U) { - Q_ASSERT_INCRIT(510, - QPSet_hasElement(&QXK_priv_.readySet, p)); - } - } - - // set the next thread and ensure that it is registered - next = QActive_registry_[p]; - Q_ASSERT_INCRIT(520, next != (QActive *)0); - - // is next a basic thread? - if (next->osObject == (void *)0) { - // is the next prio. above the initial prio.? - if (p > QActive_registry_[prio_in]->prio) { - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (p != QXK_priv_.actPrio) { // changing threads? - QXK_contextSw_(next); - } - #endif // QF_ON_CONTEXT_SW || Q_SPY - QXK_priv_.next = next; - } - else { - QXK_priv_.next = (QActive *)0; - p = 0U; // no activation needed - } - } - else { // next is the extended-thread - QXK_priv_.next = next; - QXK_CONTEXT_SWITCH_(); - p = 0U; // no activation needed - } - } - } while (p != 0U); // while activation needed - - // restore the active prio. - QXK_priv_.actPrio = prio_in; - - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (next->osObject == (void *)0) { - QXK_contextSw_((prio_in == 0U) - ? (QActive *)0 - : QActive_registry_[prio_in]); - } - #endif // QF_ON_CONTEXT_SW || Q_SPY -} - -//${QXK::QXK-base::contextSw_} ............................................... -//! @static @public @memberof QXK -void QXK_contextSw_(QActive * const next) { - #ifdef Q_SPY - uint8_t const prev_prio = (QXK_priv_.prev != (QActive *)0) - ? QXK_priv_.prev->prio - : 0U; - if (next != (QActive *)0) { // next is NOT idle? - QS_BEGIN_PRE_(QS_SCHED_NEXT, next->prio) - QS_TIME_PRE_(); // timestamp - QS_2U8_PRE_(next->prio, prev_prio); - QS_END_PRE_() - } - else { // going to idle - QS_BEGIN_PRE_(QS_SCHED_IDLE, prev_prio) - QS_TIME_PRE_(); // timestamp - QS_U8_PRE_(prev_prio); - QS_END_PRE_() - } - #endif // Q_SPY - - #ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QXK_priv_.prev, next); - #endif // QF_ON_CONTEXT_SW - - QXK_priv_.prev = next; // update the previous thread -} - -//${QXK::QXK-base::threadExit_} .............................................. -//! @static @private @memberof QXK -void QXK_threadExit_(void) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - - QXThread const * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - - Q_REQUIRE_INCRIT(900, (!QXK_ISR_CONTEXT_()) - && (thr != (QXThread *)0)); // current thread must be extended - Q_REQUIRE_INCRIT(901, - QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - - uint_fast8_t const p = (uint_fast8_t)thr->super.prio; - - QF_MEM_SYS(); - QActive_registry_[p] = (QActive *)0; - QPSet_remove(&QXK_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - (void)QXK_sched_(); // schedule other threads - - QF_MEM_APP(); - QF_CRIT_EXIT(); -} -//$enddef${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QXK::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QF-cust::init} ...................................................... -//! @static @public @memberof QF -void QF_init(void) { - QF_bzero_(&QF_priv_, sizeof(QF_priv_)); - QF_bzero_(&QXK_priv_, sizeof(QXK_priv_)); - QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - - // setup the QXK scheduler as initially locked and not running - QXK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked - - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) - { - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, (enum_t)Q_USER_SIG, tickRate); - } - - // QXK idle AO object (const in ROM) - static QActive const idle_ao = { (struct QAsmVtable const *)0 }; - - // register the idle AO object (cast 'const' away) - QActive_registry_[0] = QACTIVE_CAST_(&idle_ao); - QXK_priv_.prev = QActive_registry_[0]; - - #ifdef QXK_INIT - QXK_INIT(); // port-specific initialization of the QXK kernel - #endif -} - -//${QXK::QF-cust::stop} ...................................................... -//! @static @public @memberof QF -void QF_stop(void) { - QF_onCleanup(); // application-specific cleanup callback - // nothing else to do for the dual-mode QXK kernel -} - -//${QXK::QF-cust::run} ....................................................... -//! @static @public @memberof QF -int_t QF_run(void) { - #ifdef Q_SPY - QS_SIG_DICTIONARY(QXK_DELAY_SIG, (void *)0); - QS_SIG_DICTIONARY(QXK_TIMEOUT_SIG, (void *)0); - - // produce the QS_QF_RUN trace record - QF_INT_DISABLE(); - QF_MEM_SYS(); - QS_beginRec_((uint_fast8_t)QS_QF_RUN); - QS_endRec_(); - QF_MEM_APP(); - QF_INT_ENABLE(); - #endif // Q_SPY - - QF_onStartup(); // application-specific startup callback - - QF_INT_DISABLE(); - QF_MEM_SYS(); - - #ifdef QXK_START - QXK_START(); // port-specific startup of the QXK kernel - #endif - - QXK_priv_.lockCeil = 0U; // unlock the QXK scheduler - - // activate AOs to process events posted so far - if (QXK_sched_() != 0U) { - QXK_activate_(); - } - - QF_MEM_APP(); - QF_INT_ENABLE(); - - for (;;) { // QXK idle loop... - QXK_onIdle(); // application-specific QXK idle callback - } - - #ifdef __GNUC__ // GNU compiler? - return 0; - #endif -} -//$enddef${QXK::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QXK::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QActive} ............................................................ - -//${QXK::QActive::start} ..................................................... -//! @public @memberof QActive -void QActive_start(QActive * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par) -{ - QF_CRIT_STAT - QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) - && ((prioSpec & 0xFF00U) == 0U)); - QF_CRIT_EXIT(); - - me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO - me->pthre = 0U; // not used - QActive_register_(me); // make QF aware of this active object - - if (stkSto == (void *)0) { // starting basic thread (AO)? - - QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue - me->osObject = (void *)0; // no private stack for AO - - // top-most initial tran. (virtual call) - (*me->super.vptr->init)(&me->super, par, me->prio); - QS_FLUSH(); // flush the trace buffer to the host - - // see if this AO needs to be scheduled if QXK is already running - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { // scheduler running? - if (QXK_sched_() != 0U) { // activation needed? - QXK_activate_(); // synchronously activate basic-thread(s) - } - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - } - else { // starting QXThread - - // is storage for the queue buffer provided? - if (qSto != (QEvt const **)0) { - QEQueue_init(&me->eQueue, qSto, qLen); - } - - // extended thread constructor puts the thread handler in place of - // the top-most initial tran. 'me->super.temp.act' - QXThread_stackInit_(me, me->super.temp.thr, stkSto, stkSize); - - // the new thread is not blocked on any object - me->super.temp.obj = (QMState *)0; - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // extended-thread becomes ready immediately - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - // see if this thread needs to be scheduled in case QXK is running - if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { - (void)QXK_sched_(); // schedule other threads - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - } -} -//$enddef${QXK::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qxk/qxk_mutex.c b/src/qxk/qxk_mutex.c deleted file mode 100644 index 32519475..00000000 --- a/src/qxk/qxk_mutex.c +++ /dev/null @@ -1,481 +0,0 @@ -//$file${src::qxk::qxk_mutex.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qxk::qxk_mutex.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qxk::qxk_mutex.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk_mutex") - -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXMutex} ............................................................ - -//${QXK::QXMutex::init} ...................................................... -//! @public @memberof QXMutex -void QXMutex_init(QXMutex * const me, - QPrioSpec const prioSpec) -{ - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_REQUIRE_INCRIT(100, (prioSpec & 0xFF00U) == 0U); - - me->ao.prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. - me->ao.pthre = 0U; // preemption-threshold (not used) - QActive * const ao = &me->ao; - - QF_MEM_APP(); - QF_CRIT_EXIT(); - - QActive_register_(ao); // register this mutex as AO -} - -//${QXK::QXMutex::lock} ...................................................... -//! @public @memberof QXMutex -bool QXMutex_lock(QXMutex * const me, - QTimeEvtCtr const nTicks) -{ - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); - - // precondition, this mutex operation must: - // - NOT be called from an ISR; - // - be called from an eXtended thread; - // - the mutex-prio. must be in range; - // - the thread must NOT be already blocked on any object. - Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) - && (curr != (QXThread *)0) - && (me->ao.prio <= QF_MAX_ACTIVE) - && (curr->super.super.temp.obj == (QMState *)0)); - // also: the thread must NOT be holding a scheduler lock. - Q_REQUIRE_INCRIT(201, - QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); - - // is the mutex available? - bool locked = true; // assume that the mutex will be locked - if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; // mutex lock nesting - - // also: the newly locked mutex must have no holder yet - Q_REQUIRE_INCRIT(203, me->ao.osObject == (void *)0); - - // set the new mutex holder to the curr thread and - // save the thread's prio in the mutex - // NOTE: reuse the otherwise unused eQueue data member. - me->ao.osObject = curr; - me->ao.eQueue.head = (QEQueueCtr)curr->super.prio; - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the holder prio. must be lower than that of the mutex - // and the prio. slot must be occupied by this mutex - Q_ASSERT_INCRIT(210, (curr->super.prio < me->ao.prio) - && (QActive_registry_[me->ao.prio] == &me->ao)); - - // remove the thread's original prio from the ready set - // and insert the mutex's prio into the ready set - QPSet_remove(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.prio); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - // put the thread into the AO registry in place of the mutex - QActive_registry_[me->ao.prio] = &curr->super; - - // set thread's prio to that of the mutex - curr->super.prio = me->ao.prio; - #ifndef Q_UNSAFE - curr->super.prio_dis = (uint8_t)(~curr->super.prio); - #endif - } - } - // is the mutex locked by this thread already (nested locking)? - else if (me->ao.osObject == &curr->super) { - - // the nesting level beyond the arbitrary but high bound - // most likely means cyclic or recursive locking of a mutex. - Q_ASSERT_INCRIT(220, me->ao.eQueue.nFree < 0xFFU); - - ++me->ao.eQueue.nFree; // lock one more level - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - } - else { // the mutex is already locked by a different thread - // the mutex holder must be valid - Q_ASSERT_INCRIT(230, me->ao.osObject != (void *)0); - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the prio slot must be occupied by the thr. holding the mutex - Q_ASSERT_INCRIT(240, QActive_registry_[me->ao.prio] - == QACTIVE_CAST_(me->ao.osObject)); - } - - // remove the curr thread's prio from the ready set (will block) - // and insert it to the waiting set on this mutex - uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - QPSet_remove(&QXK_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - QPSet_insert(&me->waitSet, p); - - // set the blocking object (this mutex) - curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); - QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - - QS_BEGIN_PRE_(QS_MTX_BLOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio - curr->super.prio); // blocked thread prio - QS_END_PRE_() - - // schedule the next thread if multitasking started - (void)QXK_sched_(); // schedule other threads - - QF_MEM_APP(); - QF_CRIT_EXIT(); - QF_CRIT_EXIT_NOP(); // BLOCK here !!! - - // AFTER unblocking... - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - // the blocking object must be this mutex - Q_ASSERT_INCRIT(250, curr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me)); - - // did the blocking time-out? (signal of zero means that it did) - if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? - QPSet_remove(&me->waitSet, p); // remove unblocked thread - locked = false; // the mutex was NOT locked - } - } - else { // blocking did NOT time out - // the thread must NOT be waiting on this mutex - Q_ASSERT_INCRIT(260, !QPSet_hasElement(&me->waitSet, p)); - } - curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return locked; -} - -//${QXK::QXMutex::tryLock} ................................................... -//! @public @memberof QXMutex -bool QXMutex_tryLock(QXMutex * const me) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - QActive *curr = QXK_priv_.curr; - if (curr == (QActive *)0) { // called from a basic thread? - curr = QActive_registry_[QXK_priv_.actPrio]; - } - - // precondition, this mutex must: - // - NOT be called from an ISR; - // - the calling thread must be valid; - // - the mutex-prio. must be in range - Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) - && (curr != (QActive *)0) - && (me->ao.prio <= QF_MAX_ACTIVE)); - // also: the thread must NOT be holding a scheduler lock. - Q_REQUIRE_INCRIT(301, - QXK_priv_.lockHolder != (uint_fast8_t)curr->prio); - - // is the mutex available? - if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; // mutex lock nesting - - // also the newly locked mutex must have no holder yet - Q_REQUIRE_INCRIT(303, me->ao.osObject == (void *)0); - - // set the new mutex holder to the curr thread and - // save the thread's prio in the mutex - // NOTE: reuse the otherwise unused eQueue data member. - me->ao.osObject = curr; - me->ao.eQueue.head = (QEQueueCtr)curr->prio; - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the holder prio. must be lower than that of the mutex - // and the prio. slot must be occupied by this mutex - Q_ASSERT_INCRIT(310, (curr->prio < me->ao.prio) - && (QActive_registry_[me->ao.prio] == &me->ao)); - - // remove the thread's original prio from the ready set - // and insert the mutex's prio into the ready set - QPSet_remove(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.prio); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - // put the thread into the AO registry in place of the mutex - QActive_registry_[me->ao.prio] = curr; - - // set thread's prio to that of the mutex - curr->prio = me->ao.prio; - #ifndef Q_UNSAFE - curr->prio_dis = (uint8_t)(~curr->prio); - #endif - } - } - // is the mutex locked by this thread already (nested locking)? - else if (me->ao.osObject == curr) { - // the nesting level must not exceed the specified bound - Q_ASSERT_INCRIT(320, me->ao.eQueue.nFree < 0xFFU); - - ++me->ao.eQueue.nFree; // lock one more level - - QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - } - else { // the mutex is already locked by a different thread - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the prio slot must be occupied by the thr. holding the mutex - Q_ASSERT_INCRIT(330, QActive_registry_[me->ao.prio] - == QACTIVE_CAST_(me->ao.osObject)); - } - - QS_BEGIN_PRE_(QS_MTX_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio - curr->prio); // trying thread prio - QS_END_PRE_() - - curr = (QActive *)0; // means that mutex is NOT available - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return curr != (QActive *)0; -} - -//${QXK::QXMutex::unlock} .................................................... -//! @public @memberof QXMutex -void QXMutex_unlock(QXMutex * const me) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - QActive *curr = QXK_priv_.curr; - if (curr == (QActive *)0) { // called from a basic thread? - curr = QActive_registry_[QXK_priv_.actPrio]; - } - - Q_REQUIRE_INCRIT(400, (!QXK_ISR_CONTEXT_()) - && (curr != (QActive *)0)); - Q_REQUIRE_INCRIT(401, me->ao.eQueue.nFree > 0U); - Q_REQUIRE_INCRIT(403, me->ao.osObject == curr); - - // is this the last nesting level? - if (me->ao.eQueue.nFree == 1U) { - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // prio. must be in range - Q_ASSERT_INCRIT(410, me->ao.prio < QF_MAX_ACTIVE); - - // restore the holding thread's prio from the mutex - curr->prio = (uint8_t)me->ao.eQueue.head; - #ifndef Q_UNSAFE - curr->prio_dis = (uint8_t)(~curr->prio); - #endif - - // put the mutex back into the AO registry - QActive_registry_[me->ao.prio] = &me->ao; - - // remove the mutex' prio from the ready set - // and insert the original thread's prio. - QPSet_remove(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.prio); - QPSet_insert(&QXK_priv_.readySet, - (uint_fast8_t)me->ao.eQueue.head); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - } - - QS_BEGIN_PRE_(QS_MTX_UNLOCK, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio - 0U); // nesting - QS_END_PRE_() - - // are any other threads waiting on this mutex? - if (QPSet_notEmpty(&me->waitSet)) { - // find the highest-prio. thread waiting on this mutex - uint_fast8_t const p = QPSet_findMax(&me->waitSet); - - // remove this thread from waiting on the mutex - // and insert it into the ready set. - QPSet_remove(&me->waitSet, p); - QPSet_insert(&QXK_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - QXThread * const thr = - QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - - // the waiting thread must: - // - be registered in QF - // - have the prio. corresponding to the registration - // - be an extended thread - // - be blocked on this mutex - Q_ASSERT_INCRIT(420, (thr != (QXThread *)0) - && (thr->super.prio == (uint8_t)p) - && (thr->super.super.state.act == Q_ACTION_CAST(0)) - && (thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me))); - - // disarm the internal time event - (void)QXThread_teDisarm_(thr); - - // set the new mutex holder to the curr thread and - // save the thread's prio in the mutex - // NOTE: reuse the otherwise unused eQueue data member. - me->ao.osObject = thr; - me->ao.eQueue.head = (QEQueueCtr)thr->super.prio; - - QS_BEGIN_PRE_(QS_MTX_LOCK, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // the holder prio. must be lower than that of the mutex - Q_ASSERT_INCRIT(430, (me->ao.prio < QF_MAX_ACTIVE) - && (thr->super.prio < me->ao.prio)); - - // put the thread into AO registry in place of the mutex - QActive_registry_[me->ao.prio] = &thr->super; - } - } - else { // no threads are waiting for this mutex - me->ao.eQueue.nFree = 0U; // free up the nesting count - - // the mutex no longer held by any thread - me->ao.osObject = (void *)0; - me->ao.eQueue.head = 0U; - me->ao.eQueue.tail = 0U; - - if (me->ao.prio != 0U) { // prio.-ceiling protocol used? - // put the mutex back at the original mutex slot - QActive_registry_[me->ao.prio] = - QXK_PTR_CAST_(QActive*, me); - } - } - - // schedule the next thread if multitasking started - if (QXK_sched_() != 0U) { // activation needed? - QXK_activate_(); // synchronously activate basic-thread(s) - } - } - else { // releasing one level of nested mutex lock - --me->ao.eQueue.nFree; // unlock one level - - QS_BEGIN_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this mutex - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting - QS_END_PRE_() - } - QF_MEM_APP(); - QF_CRIT_EXIT(); -} -//$enddef${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qxk/qxk_sema.c b/src/qxk/qxk_sema.c deleted file mode 100644 index 320afbb0..00000000 --- a/src/qxk/qxk_sema.c +++ /dev/null @@ -1,287 +0,0 @@ -//$file${src::qxk::qxk_sema.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qxk::qxk_sema.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qxk::qxk_sema.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk_sema") - -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXSemaphore} ........................................................ - -//${QXK::QXSemaphore::init} .................................................. -//! @public @memberof QXSemaphore -void QXSemaphore_init(QXSemaphore * const me, - uint_fast8_t const count, - uint_fast8_t const max_count) -{ - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_REQUIRE_INCRIT(100, (count <= max_count) - && (0U < max_count) && (max_count <= 0xFFU)); - - me->count = (uint8_t)count; - me->max_count = (uint8_t)max_count; - QPSet_setEmpty(&me->waitSet); - - QF_MEM_APP(); - QF_CRIT_EXIT(); -} - -//${QXK::QXSemaphore::wait} .................................................. -//! @public @memberof QXSemaphore -bool QXSemaphore_wait(QXSemaphore * const me, - QTimeEvtCtr const nTicks) -{ - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); - - // precondition, this function: - // - must NOT be called from an ISR; - // - the semaphore must be initialized - // - be called from an extended thread; - // - the thread must NOT be already blocked on any object. - Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) - && (me->max_count > 0U) - && (curr != (QXThread *)0) - && (curr->super.super.temp.obj == (QMState *)0)); - // - the thread must NOT be holding a scheduler lock. - Q_REQUIRE_INCRIT(201, - QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); - - bool taken = true; // assume that the semaphore will be signaled - if (me->count > 0U) { - --me->count; // semaphore taken: decrement the count - - QS_BEGIN_PRE_(QS_SEM_TAKE, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->super.prio, me->count); - QS_END_PRE_() - } - else { // semaphore not available -- BLOCK the thread - uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - // remove the curr prio from the ready set (will block) - // and insert to the waiting set on this semaphore - QPSet_remove(&QXK_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - QPSet_insert(&me->waitSet, p); - - // remember the blocking object (this semaphore) - curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); - QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - - QS_BEGIN_PRE_(QS_SEM_BLOCK, curr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->super.prio, me->count); - QS_END_PRE_() - - // schedule the next thread if multitasking started - (void)QXK_sched_(); // schedule other threads - - QF_MEM_APP(); - QF_CRIT_EXIT(); - QF_CRIT_EXIT_NOP(); // BLOCK here !!! - - QF_CRIT_ENTRY(); // AFTER unblocking... - QF_MEM_SYS(); - - // the blocking object must be this semaphore - Q_ASSERT_INCRIT(240, curr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me)); - - // did the blocking time-out? (signal of zero means that it did) - if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? - QPSet_remove(&me->waitSet, p); // remove unblocked thread - taken = false; // the semaphore was NOT taken - } - } - else { // blocking did NOT time out - // the thread must NOT be waiting on this semaphore - Q_ASSERT_INCRIT(250, !QPSet_hasElement(&me->waitSet, p)); - } - curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return taken; -} - -//${QXK::QXSemaphore::tryWait} ............................................... -//! @public @memberof QXSemaphore -bool QXSemaphore_tryWait(QXSemaphore * const me) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // precondition: - // - the semaphore must be initialized - Q_REQUIRE_INCRIT(300, me->max_count > 0U); - - #ifdef Q_SPY - QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_priv_.curr); - #endif // Q_SPY - - bool taken; - // is the semaphore available? - if (me->count > 0U) { - --me->count; - taken = true; - - QS_BEGIN_PRE_(QS_SEM_TAKE, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->prio, me->count); - QS_END_PRE_() - } - else { // the semaphore is NOT available (would block) - taken = false; - - QS_BEGIN_PRE_(QS_SEM_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(curr->prio, me->count); - QS_END_PRE_() - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return taken; -} - -//${QXK::QXSemaphore::signal} ................................................ -//! @public @memberof QXSemaphore -bool QXSemaphore_signal(QXSemaphore * const me) { - bool signaled = true; // assume that the semaphore will be signaled - - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // precondition: - // - the semaphore must be initialized - Q_REQUIRE_INCRIT(400, me->max_count > 0U); - - // any threads blocked on this semaphore? - if (QPSet_notEmpty(&me->waitSet)) { - // find the highest-prio. thread waiting on this semaphore - uint_fast8_t const p = QPSet_findMax(&me->waitSet); - QXThread * const thr = - QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - - // assert that the thread: - // - must be registered in QF; - // - must be extended; and - // - must be blocked on this semaphore; - Q_ASSERT_INCRIT(410, (thr != (QXThread *)0) - && (thr->super.osObject != (void *)0) - && (thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me))); - - // disarm the internal time event - (void)QXThread_teDisarm_(thr); - - // make the thread ready to run and remove from the wait-list - QPSet_insert(&QXK_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - QPSet_remove(&me->waitSet, p); - - QS_BEGIN_PRE_(QS_SEM_TAKE, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(thr->super.prio, me->count); - QS_END_PRE_() - - if (!QXK_ISR_CONTEXT_()) { // not inside ISR? - (void)QXK_sched_(); // schedule other threads - } - } - else if (me->count < me->max_count) { - ++me->count; // increment the semaphore count - - QS_BEGIN_PRE_(QS_SEM_SIGNAL, 0U) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(me); // this semaphore - QS_2U8_PRE_(0U, me->count); - QS_END_PRE_() - } - else { - signaled = false; // semaphore NOT signaled - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return signaled; -} -//$enddef${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qxk/qxk_xthr.c b/src/qxk/qxk_xthr.c deleted file mode 100644 index 070b87a0..00000000 --- a/src/qxk/qxk_xthr.c +++ /dev/null @@ -1,363 +0,0 @@ -//$file${src::qxk::qxk_xthr.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qxk::qxk_xthr.c} -// -// This code has been generated by QM 6.2.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -// -// This code is covered by the following QP license: -// License # : LicenseRef-QL-dual -// Issued to : Any user of the QP/C real-time embedded framework -// Framework(s) : qpc -// Support ends : 2025-12-31 -// License scope: -// -// Copyright (C) 2005 Quantum Leaps, LLC . -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -// -//$endhead${src::qxk::qxk_xthr.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif // QXK_H_ - -Q_DEFINE_THIS_MODULE("qxk_xthr") - -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QXK::QXThread} ........................................................... -QXThread const * QXThread_dummy; - -//${QXK::QXThread::ctor} ..................................................... -//! @public @memberof QXThread -void QXThread_ctor(QXThread * const me, - QXThreadHandler const handler, - uint_fast8_t const tickRate) -{ - union QAsmAttr tmp; - tmp.thr = handler; - QActive_ctor(&me->super, tmp.fun); // superclass' ctor - - me->super.super.state.act = Q_ACTION_CAST(0); // mark as extended thread - - // instantiate the time-event member in the QXThread class - QTimeEvt_ctorX(&me->timeEvt, &me->super, - (enum_t)QXK_DELAY_SIG, tickRate); -} - -//${QXK::QXThread::delay} .................................................... -//! @public @memberof QXThread -bool QXThread_delay(QTimeEvtCtr const nTicks) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - - // precondition, this function: - // - must NOT be called from an ISR; - // - number of ticks cannot be zero - // - be called from an extended thread; - // - the thread must NOT be already blocked on any object. - Q_REQUIRE_INCRIT(800, (!QXK_ISR_CONTEXT_()) - && (nTicks != 0U) - && (thr != (QXThread *)0) - && (thr->super.super.temp.obj == (QMState *)0)); - // - the thread must NOT be holding a scheduler lock. - Q_REQUIRE_INCRIT(801, - QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - - // remember the blocking object - thr->super.super.temp.obj = QXK_PTR_CAST_(QMState const*, &thr->timeEvt); - QXThread_teArm_(thr, (enum_t)QXK_DELAY_SIG, nTicks); - QXThread_block_(thr); - - QF_MEM_APP(); - QF_CRIT_EXIT(); - QF_CRIT_EXIT_NOP(); // BLOCK here - - // after unblocking... - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // the blocking object must be the time event - Q_ASSERT_INCRIT(890, thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState const*, &thr->timeEvt)); - thr->super.super.temp.obj = (QMState *)0; // clear - - QF_MEM_APP(); - QF_CRIT_EXIT(); - - // signal of zero means that the time event was posted without - // being canceled. - return thr->timeEvt.super.sig == 0U; -} - -//${QXK::QXThread::delayCancel} .............................................. -//! @public @memberof QXThread -bool QXThread_delayCancel(QXThread * const me) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - bool wasArmed; - if (me->super.super.temp.obj == QXK_PTR_CAST_(QMState*, &me->timeEvt)) { - wasArmed = QXThread_teDisarm_(me); - QXThread_unblock_(me); - } - else { - wasArmed = false; - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return wasArmed; -} - -//${QXK::QXThread::queueGet} ................................................. -//! @static @public @memberof QXThread -QEvt const * QXThread_queueGet(QTimeEvtCtr const nTicks) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - - // precondition, this function: - // - must NOT be called from an ISR; - // - be called from an extended thread; - // - the thread must NOT be already blocked on any object. - Q_REQUIRE_INCRIT(500, (!QXK_ISR_CONTEXT_()) - && (thr != (QXThread *)0) - && (thr->super.super.temp.obj == (QMState *)0)); - // - the thread must NOT be holding a scheduler lock. - Q_REQUIRE_INCRIT(501, - QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - - // is the queue empty? - if (thr->super.eQueue.frontEvt == (QEvt *)0) { - - // remember the blocking object (the thread's queue) - thr->super.super.temp.obj - = QXK_PTR_CAST_(QMState const*, &thr->super.eQueue); - - QXThread_teArm_(thr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)thr->super.prio); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - (void)QXK_sched_(); // schedule other threads - - QF_MEM_APP(); - QF_CRIT_EXIT(); - QF_CRIT_EXIT_NOP(); // BLOCK here - - // after unblocking... - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - // the blocking object must be this queue - Q_ASSERT_INCRIT(510, thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState const*, &thr->super.eQueue)); - thr->super.super.temp.obj = (QMState *)0; // clear - } - - // is the queue not empty? - QEvt const *e; - if (thr->super.eQueue.frontEvt != (QEvt *)0) { - e = thr->super.eQueue.frontEvt; // remove from the front - QEQueueCtr const nFree= thr->super.eQueue.nFree + 1U; - thr->super.eQueue.nFree = nFree; // update the # free - - // any events in the ring buffer? - if (nFree <= thr->super.eQueue.end) { - - // remove event from the tail - thr->super.eQueue.frontEvt = - thr->super.eQueue.ring[thr->super.eQueue.tail]; - if (thr->super.eQueue.tail == 0U) { // need to wrap? - thr->super.eQueue.tail = thr->super.eQueue.end; // wrap - } - --thr->super.eQueue.tail; - - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(&thr->super); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE_(nFree); // # free entries - QS_END_PRE_() - } - else { - thr->super.eQueue.frontEvt = (QEvt *)0; // empty queue - - // all entries in the queue must be free (+1 for fronEvt) - Q_ASSERT_INCRIT(520, nFree == (thr->super.eQueue.end + 1U)); - - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, thr->super.prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(&thr->super); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_END_PRE_() - } - } - else { // the queue is still empty -- the timeout must have fired - e = (QEvt *)0; - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - return e; -} - -//${QXK::QXThread::block_} ................................................... -//! @private @memberof QXThread -void QXThread_block_(QXThread const * const me) { - // NOTE: must be called IN a critical section - - Q_REQUIRE_INCRIT(600, - QXK_priv_.lockHolder != (uint_fast8_t)me->super.prio); - - QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - (void)QXK_sched_(); // schedule other threads -} - -//${QXK::QXThread::unblock_} ................................................. -//! @private @memberof QXThread -void QXThread_unblock_(QXThread const * const me) { - // NOTE: must be called IN a critical section - - QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); - #ifndef Q_UNSAFE - QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); - #endif - - if ((!QXK_ISR_CONTEXT_()) // not inside ISR? - && (QActive_registry_[0] != (QActive *)0)) // kernel started? - { - (void)QXK_sched_(); // schedule other threads - } -} - -//${QXK::QXThread::timeout_} ................................................. -//! @private @memberof QXThread -void QXThread_timeout_(QActive * const act) { - // NOTE: must be called IN a critical section - - // the private time event is now disarmed and not in any queue, - // so it is safe to change its signal. The signal of 0 means - // that the time event has expired. - QXTHREAD_CAST_(act)->timeEvt.super.sig = 0U; - - QXThread_unblock_(QXTHREAD_CAST_(act)); -} - -//${QXK::QXThread::teArm_} ................................................... -//! @private @memberof QXThread -void QXThread_teArm_(QXThread * const me, - enum_t const sig, - QTimeEvtCtr const nTicks) -{ - // NOTE: must be called IN a critical section - - // precondition: - // - the time event must be unused - Q_REQUIRE_INCRIT(700, me->timeEvt.ctr == 0U); - - me->timeEvt.super.sig = (QSignal)sig; - - if (nTicks != QXTHREAD_NO_TIMEOUT) { - me->timeEvt.ctr = (QTimeEvtCtr)nTicks; - me->timeEvt.interval = 0U; - - // is the time event unlinked? - // NOTE: For the duration of a single clock tick of the specified tick - // rate a time event can be disarmed and yet still linked in the list, - // because un-linking is performed exclusively in QTimeEvt_tick_(). - if ((me->timeEvt.super.refCtr_ & QTE_IS_LINKED) == 0U) { - uint_fast8_t const tickRate - = ((uint_fast8_t)me->timeEvt.super.refCtr_ & QTE_TICK_RATE); - Q_ASSERT_INCRIT(710, tickRate < QF_MAX_TICK_RATE); - - // mark as linked - me->timeEvt.super.refCtr_ |= QTE_IS_LINKED; - - // The time event is initially inserted into the separate - // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly - // armed" list is appended to the main list of armed time events - // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside - // QTimeEvt_tick_(). - me->timeEvt.next - = QXK_PTR_CAST_(QTimeEvt*, QTimeEvt_timeEvtHead_[tickRate].act); - QTimeEvt_timeEvtHead_[tickRate].act = &me->timeEvt; - } - } -} - -//${QXK::QXThread::teDisarm_} ................................................ -//! @private @memberof QXThread -bool QXThread_teDisarm_(QXThread * const me) { - // NOTE: must be called IN a critical section - - bool wasArmed; - // is the time evt running? - if (me->timeEvt.ctr != 0U) { - wasArmed = true; - me->timeEvt.ctr = 0U; // schedule removal from list - } - // the time event was already automatically disarmed - else { - wasArmed = false; - } - return wasArmed; -} -//$enddef${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/README.txt b/test/README.txt deleted file mode 100644 index 52b3ad4f..00000000 --- a/test/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -The `qpc/test/` directory is planned to contain a growing number of system-level tests, which are based on QUTest, but *without* the QP-stub. The tests take advantage of the new QUTest configuration, where the QP-stub is NOT included (because the actual QP framework is linked). This configuration is activated by defining macro `Q_UTEST=0`. - -@attention -Many tests provided in the `qpc/test/` directory run only on embedded targets and cannot run on the host machine. diff --git a/test/et/et.c b/test/et/et.c deleted file mode 100644 index 6732b745..00000000 --- a/test/et/et.c +++ /dev/null @@ -1,174 +0,0 @@ -//============================================================================ -// ET: embedded test (super-simple embedded testing framework) -// GitHub: https://github.com/QuantumLeaps/Embedded-Test -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, . -// -// SPDX-License-Identifier: MIT -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -//============================================================================ -#include "et.h" // ET: embedded test - -//.......................................................................... -static void print_str(char const *str); -static void print_dec(unsigned const num); -static void print_summary(unsigned ok); -static void test_end(void); -static int str_cmp(char const *str1, char const *str2); - -static unsigned l_test_count; -static unsigned l_skip_count; -static unsigned l_skip_last; - -static char const *l_expect_assert_module; -static int l_expect_assert_label; - -//.......................................................................... -int main(int argc, char *argv[]) { - ET_onInit(argc, argv); - - print_str("\nET embedded test " ET_VERSION - ", https://github.com/QuantumLeaps/ET\n"); - print_str("---------------- group: "); - print_str(ET_group_); - print_str(" -----------------\n"); - - ET_run_(); - - test_end(); - print_summary(1U); - - ET_onExit(0); // success -} - -//.......................................................................... -int ET_test_(char const *title, int skip) { - test_end(); - ++l_test_count; - ET_onPrintChar('['); - print_dec(l_test_count); - print_str("] \""); - print_str(title); - print_str("\" "); - if (skip) { - ++l_skip_count; - } - else { - setup(); - ET_onPrintChar('.'); - } - l_skip_last = skip; - return skip == 0; -} -//.......................................................................... -static void test_end(void) { - if (l_expect_assert_module != (char const *)0) { - ET_fail("Expected Assertion didn't fire", - l_expect_assert_module, l_expect_assert_label); - } - else if (l_test_count > 0) { - if (l_skip_last) { - print_str(" SKIPPED\n"); - l_skip_last = 0; - } - else { - teardown(); - print_str(". PASSED\n"); - } - } -} -//.......................................................................... -void ET_fail(char const *cond, char const *group, int line) { - print_str(" FAILED\n--> "); - print_str(group); - ET_onPrintChar(':'); - print_dec(line); - ET_onPrintChar(' '); - print_str(cond); - ET_onPrintChar('\n'); - print_summary(0U); - - ET_onExit(-1); // failure -} -//.......................................................................... -void ET_expect_assert(char const *module, int label) { - l_expect_assert_module = module; - l_expect_assert_label = label; -} -//.......................................................................... -void ET_verify_assert_(char const *module, int label) { - if ((l_expect_assert_label == label) - && (str_cmp(module, l_expect_assert_module) == 0)) - { - l_expect_assert_module = (char const *)0; - test_end(); - print_str("Assertion (expected) --> Exiting\n"); - print_summary(1U); - - ET_onExit(0); // success - } - else { - ET_fail("Unexpected assertion", module, label); - } -} - -//.......................................................................... -static void print_summary(unsigned ok) { - print_str("------------ "); - print_dec(l_test_count); - print_str(" test(s), "); - print_dec(l_skip_count); - print_str(" skipped -------------\n"); - print_str(ok ? "OK\n" : "FAILED\n"); -} -//.......................................................................... -static void print_str(char const *str) { - for (; *str != '\0'; ++str) { - ET_onPrintChar(*str); - } -} - -//.......................................................................... -static void print_dec(unsigned const num) { - // find power of 10 of the first decimal digit of the number - unsigned pwr10 = 1U; - for (; num > (pwr10 * 9U); pwr10 *= 10U) { - } - // print the decimal digits of the number... - do { - ET_onPrintChar((char)('0' + ((num / pwr10) % 10U))); - pwr10 /= 10U; - } while (pwr10 != 0U); -} - -//.......................................................................... -static int str_cmp(char const *str1, char const *str2) { - while (*str1 == *str2++) { - if (*str1++ == '\0') { - return 0; - } - } - --str2; - return *(unsigned char *)str1 - *(unsigned char *)str2; -} diff --git a/test/et/et.h b/test/et/et.h deleted file mode 100644 index bed2eeed..00000000 --- a/test/et/et.h +++ /dev/null @@ -1,92 +0,0 @@ -//============================================================================ -// ET: embedded test (super-simple embedded testing framework) -// GitHub: https://github.com/QuantumLeaps/Embedded-Test -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, . -// -// SPDX-License-Identifier: MIT -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -//============================================================================ -#ifndef ET_H_ -#define ET_H_ - -// Embedded Test (ET) version -#define ET_VERSION "2.0.0" - -//! macro to define a test group -#define TEST_GROUP(name_) \ - char const ET_group_[] = name_; \ - void ET_run_(void) - -// macro to start a new test -#define TEST(title_) \ - if (ET_test_(title_, 0)) - -// macro to skip a test -#define SKIP_TEST(title_) \ - if (ET_test_(title_, 1)) - -//! macro to verify a test expectation -#define VERIFY(cond_) \ - ((cond_) ? (void)0 : ET_fail(#cond_, &ET_group_[0], __LINE__)) - -#define VERIFY_ASSERT(module_, label_) \ - ET_verify_assert_((module_), (label_)) - -//! macro to force a failure of a test -#define FAIL(note_) \ - (ET_fail(note_, &ET_group_[0], __LINE__)) - -#ifndef ARRAY_NELEM -//! convenience macro to provide the number of elements in the array a_ -#define ARRAY_NELEM(a_) (sizeof(a_) / sizeof((a_)[0])) -#endif // ARRAY_NELEM - -#ifdef __cplusplus -extern "C" { -#endif - -void setup(void); //!< called right before each test -void teardown(void); //!< called right after each test - -// callback functions to be implemented in the ET board support packages -void ET_onInit(int argc, char *argv[]); -void ET_onPrintChar(char const ch); -void ET_onExit(int err); - -// public helpers -void ET_fail(char const *cond, char const *group, int line); -void ET_expect_assert(char const *module, int label); -void ET_verify_assert_(char const *module, int label); - -// private helpers -void ET_run_(void); -int ET_test_(char const *title, int skip); -extern char const ET_group_[]; - -#ifdef __cplusplus -} -#endif - -#endif // ET_H_ diff --git a/test/et/et_host.c b/test/et/et_host.c deleted file mode 100644 index 5b6af46f..00000000 --- a/test/et/et_host.c +++ /dev/null @@ -1,48 +0,0 @@ -//============================================================================ -// Embedded Test (ET) implementation for host computers (Windows, Linux, macOS) -// GitHub: https://github.com/QuantumLeaps/Embedded-Test -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, . -// -// SPDX-License-Identifier: MIT -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -//============================================================================ -#include "et.h" // ET: embedded test - -#include // for fputc() and stdout -#include // for exit() - -//.......................................................................... -void ET_onInit(int argc, char *argv[]) { - (void)argc; - (void)argv; -} -//.......................................................................... -void ET_onPrintChar(char const ch) { - fputc(ch, stdout); -} -//.......................................................................... -void ET_onExit(int err) { - exit(err); -} diff --git a/test/qf/qequeue/Makefile b/test/qf/qequeue/Makefile deleted file mode 100644 index 96c9fa9f..00000000 --- a/test/qf/qequeue/Makefile +++ /dev/null @@ -1,222 +0,0 @@ -############################################################################## -# Product: Makefile for Embedded Test (ET) for Windows *HOST* -# Last Updated for Version: 7.3.0 -# Date of the Last Update: 2023-06-30 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make # make and run the Python tests in the current directory -# make TESTS=test*.py # make and run the selected tests in the curr. dir. -# make HOST=localhost:7705 # connect to host:port -# make norun # only make but not run the tests -# make clean # cleanup the build -# make debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -#----------------------------------------------------------------------------- -# project name: -PROJECT := test - -#----------------------------------------------------------------------------- -# project directories: -# -QPC := ../../.. -ET := ../../et - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(ET) - -# list of all include directories needed by this project -INCLUDES := -I. \ - -I$(QPC)/include \ - -I$(ET) - -#----------------------------------------------------------------------------- -# project files: -# - -# C source files... -C_SRCS := \ - qep_hsm.c \ - qf_act.c \ - qf_actq.c \ - qf_qact.c \ - qf_qeq.c \ - qs.c \ - qs_rx.c \ - test.c \ - et.c \ - et_host.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -DEFINES := -DQ_SPY - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# GNU toolset: -# -# NOTE: -# GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -#----------------------------------------------------------------------------- -# basic utilities (depends on the OS this Makefile runs on): -# -ifeq ($(OS),Windows_NT) - MKDIR := mkdir - RM := rm - TARGET_EXT := .exe -else ifeq ($(OSTYPE),cygwin) - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := .exe -else - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := -endif - -#----------------------------------------------------------------------------- -# build options... - -BIN_DIR := build - -CFLAGS := -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DQ_HOST - -CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DQ_HOST - -ifndef GCC_OLD - LINKFLAGS := -no-pie -endif - -ifdef GCOV - CFLAGS += -fprofile-arcs -ftest-coverage - CPPFLAGS += -fprofile-arcs -ftest-coverage - LINKFLAGS += -lgcov --coverage -endif - -#----------------------------------------------------------------------------- -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : norun clean show - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -run : $(TARGET_EXE) - $(TARGET_EXE) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.* - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - diff --git a/test/qf/qequeue/qp_port.h b/test/qf/qequeue/qp_port.h deleted file mode 100644 index 55aa2afb..00000000 --- a/test/qf/qequeue/qp_port.h +++ /dev/null @@ -1,130 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! -//! @date Last updated on: 2023-08-19 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QP/C "port" for Embedded Test, Win32 with GNU or VisualC++ -//! -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -//! no-return function specifier -#ifdef __GNUC__ - - //! no-return function specifier (GCC-ARM compiler) - #define Q_NORETURN __attribute__ ((noreturn)) void - -#elif (defined _MSC_VER) - #ifdef __cplusplus - // no-return function specifier (Microsoft Visual Studio C++ compiler) - #define Q_NORETURN [[ noreturn ]] void - #else - // no-return function specifier C11 - #define Q_NORETURN _Noreturn void - #endif - - // This is the case where QP/C is compiled by the Microsoft Visual C++ - // compiler in the C++ mode, which can happen when qep_port.h is included - // in a C++ module, or the compilation is forced to C++ by the option /TP. - // - // The following pragma suppresses the level-4 C++ warnings C4510, C4512, - // and C4610, which warn that default constructors and assignment operators - // could not be generated for structures QMState and QMTranActTable. - // - // The QP/C source code cannot be changed to avoid these C++ warnings - // because the structures QMState and QMTranActTable must remain PODs - // (Plain Old Datatypes) to be initializable statically with constant - // initializers. - // - #pragma warning (disable: 4510 4512 4610) - -#endif - -// event queue and thread types -#define QACTIVE_EQUEUE_TYPE QEQueue -// QACTIVE_OS_OBJ_TYPE not used in this port -// QACTIVE_THREAD_TYPE not used in this port - -// The maximum number of active objects in the application -#define QF_MAX_ACTIVE 64U - -// The number of system clock tick rates -#define QF_MAX_TICK_RATE 2U - -// Activate the QF QActive_stop() API -#define QACTIVE_CAN_STOP 1 - -// QF interrupt disable/enable -#define QF_INT_DISABLE() ((void)0) -#define QF_INT_ENABLE() ((void)0) - -// QUIT critical section -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() QF_INT_DISABLE() -#define QF_CRIT_EXIT() QF_INT_ENABLE() - -// QF_LOG2 not defined -- use the internal LOG2() implementation - -// include files ------------------------------------------------------------- -#include "qequeue.h" // Win32-QV needs the native event-queue -#include "qmpool.h" // Win32-QV needs the native memory-pool -#include "qp.h" // QP platform-independent public interface - -//========================================================================== -// interface used only inside QP implementation, but not in applications -#ifdef QP_IMPL - - // ET scheduler locking (not used) - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - // native event queue operations - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) ((void)0) - - // native QF event pool operations - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - #define QF_EPOOL_PUT_(p_, e_, qsId_) \ - (QMPool_put(&(p_), (e_), (qsId_))) - -#endif // QP_IMPL - -#ifdef _MSC_VER - #pragma warning (default: 4510 4512 4610) -#endif - -#endif // QP_PORT_H_ diff --git a/test/qf/qequeue/qs_port.h b/test/qf/qequeue/qs_port.h deleted file mode 100644 index d0460af6..00000000 --- a/test/qf/qequeue/qs_port.h +++ /dev/null @@ -1,61 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-08-16 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QS/C port to Win32 with GNU or Visual C++ compilers -//! -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -#define QS_CTR_SIZE 4U -#define QS_TIME_SIZE 4U - -#ifdef _WIN64 // 64-bit architecture? - #define QS_OBJ_PTR_SIZE 8U - #define QS_FUN_PTR_SIZE 8U -#else // 32-bit architecture - #define QS_OBJ_PTR_SIZE 4U - #define QS_FUN_PTR_SIZE 4U -#endif - -void QS_output(void); // handle the QS output -void QS_rx_input(void); // handle the QS-RX input - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -//*before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QF -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ - diff --git a/test/qf/qequeue/test.c b/test/qf/qequeue/test.c deleted file mode 100644 index e0604954..00000000 --- a/test/qf/qequeue/test.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "et.h" // Embedded Test (ET) - -// includes for the CUT... -#include "qp_port.h" // QP port -#include "qsafe.h" // QP Functional Safety (FuSa) System -#ifdef Q_SPY // software tracing enabled? -#include "qs_port.h" // QS/C port from the port directory -#else -#include "qs_dummy.h" // QS/C dummy (inactive) interface -#endif - -enum { QUEUE_SIZE = 10 }; - - -void setup(void) { -} - -void teardown(void) { -} - -//static QEvt const *queBuf[QUEUE_SIZE]; -static QEQueue queue; - -static QEvt const evt1 = QEVT_INITIALIZER(1); -static QEvt const evt2 = QEVT_INITIALIZER(2); - -// test group -------------------------------------------------------------- -TEST_GROUP("QEQueue") { - -TEST("new no-buffer queue has 1 free") { - QEQueue_init(&queue, (QEvt const **)0, 0U); - VERIFY(1U == QEQueue_getNFree(&queue)); -} - -TEST("no-buffer queue can hold at least 1") { - QEQueue_post(&queue, &evt1, QF_NO_MARGIN, 0U); - VERIFY(0U == QEQueue_getNFree(&queue)); - QEvt const *e = QEQueue_get(&queue, 0U); - VERIFY(&evt1 == e); - VERIFY(1U == QEQueue_getNFree(&queue)); -} - -TEST("no-buffer queue can hold only 1 (expected assertion)") { - QEQueue_post(&queue, &evt1, QF_NO_MARGIN, 0U); - ET_expect_assert("qf_qeq", 210); - VERIFY(false == QEQueue_post(&queue, &evt2, QF_NO_MARGIN, 0U)); - VERIFY(0U == QEQueue_getNFree(&queue)); -} - -} // TEST_GROUP() - -// ========================================================================= -// dependencies for the CUT ... - -//.......................................................................... -void QF_poolInit(void * const poolSto, uint_fast32_t const poolSize, - uint_fast16_t const evtSize) -{ - (void)poolSto; - (void)poolSize; - (void)evtSize; -} -//.......................................................................... -uint_fast16_t QF_poolGetMaxBlockSize(void) { - return 0U; -} -//.......................................................................... -void QActive_publish_(QEvt const * const e, - void const * const sender, uint_fast8_t const qsId) -{ - (void)e; - (void)sender; - (void)qsId; -} -//.......................................................................... -void QTimeEvt_tick_(uint_fast8_t const tickRate, void const * const sender) { - (void)tickRate; - (void)sender; -} -//.......................................................................... -QEvt *QF_newX_(uint_fast16_t const evtSize, - uint_fast16_t const margin, enum_t const sig) -{ - (void)evtSize; - (void)margin; - (void)sig; - - return (QEvt *)0; -} -//.......................................................................... -//! @static @public @memberof QF -void QF_gc(QEvt const * const e) { - (void)e; -} -//.......................................................................... -//! @static @private @memberof QF -QActive *QActive_registry_[QF_MAX_ACTIVE + 1U]; - -//.......................................................................... -Q_NORETURN Q_onError(char const * const module, int_t const location) { - VERIFY_ASSERT(module, location); - for (;;) { // explicitly make it "noreturn" - } -} - -//-------------------------------------------------------------------------- -#ifdef Q_SPY - -void QS_onCleanup(void) { -} -//.......................................................................... -void QS_onReset(void) { -} -//.......................................................................... -void QS_onFlush(void) { -} -//.......................................................................... -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)0U; -} -//.......................................................................... -void QS_onCommand(uint8_t cmdId, uint32_t param1, - uint32_t param2, uint32_t param3) -{ - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; -} - -#endif // Q_SPY diff --git a/test/qk/README.txt b/test/qk/README.txt deleted file mode 100644 index 2476f064..00000000 --- a/test/qk/README.txt +++ /dev/null @@ -1,13 +0,0 @@ -This directory contains tests of the QK kernel. -These are SYSTEM tests, where QP is not stubbed-out, but -rather the actual QP code is used instead. - -NOTE: -The tests run only on embedded targets and do NOT -run on the host computer. - -NOTE: -To avoid stubbing-out the QP framework, the tests -define Q_UTEST=0 - - diff --git a/test/qk/test_sched/bsp.h b/test/qk/test_sched/bsp.h deleted file mode 100644 index cc41b3d0..00000000 --- a/test/qk/test_sched/bsp.h +++ /dev/null @@ -1,61 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing -// Last updated for version 7.2.0 -// Last updated on 2022-12-13 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -#ifndef BSP_H_ -#define BSP_H_ - -void BSP_init(void); -void BSP_terminate(int16_t result); - -// for testing... -void BSP_trace(QActive const *thr, char const *msg); -void BSP_wait4PB1(void); -void BSP_ledOn(void); -void BSP_ledOff(void); -void BSP_trigISR(void); - -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd); -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value); - -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd); -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value); - -enum TestSignals { - TEST0_SIG = Q_USER_SIG, - TEST1_SIG, - TEST2_SIG, - TEST3_SIG, - MAX_PUB_SIG, // the last published signal - - MAX_SIG // the last signal -}; - -#endif // BSP_H_ diff --git a/test/qk/test_sched/bsp_efm32pg1b.c b/test/qk/test_sched/bsp_efm32pg1b.c deleted file mode 100644 index ec8eb486..00000000 --- a/test/qk/test_sched/bsp_efm32pg1b.c +++ /dev/null @@ -1,373 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QK kernel, EFM32-SLSTK3401A board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "em_device.h" // the device specific header (SiLabs) -#include "em_cmu.h" // Clock Management Unit (SiLabs) -#include "em_gpio.h" // GPIO (SiLabs) -#include "em_usart.h" // USART (SiLabs) -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE; - -// ISRs defined in this BSP ------------------------------------------------ -void SysTick_Handler(void); -void GPIO_EVEN_IRQHandler(void); - -// Local-scope objects ----------------------------------------------------- -#define LED_PORT gpioPortF -#define LED0_PIN 4 -#define LED1_PIN 5 - -#define PB_PORT gpioPortF -#define PB0_PIN 6 -#define PB1_PIN 7 - -#ifdef Q_SPY - - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -//.......................................................................... -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QK_ISR_ENTRY(); // inform QK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - //QTICKER_TRIG(the_Ticker0, &l_SysTick_Handler); /* trigger ticker AO */ - - - QK_ISR_EXIT(); // inform QK kernel about exiting an ISR -} -//.......................................................................... -void GPIO_EVEN_IRQHandler(void); // prototype -void GPIO_EVEN_IRQHandler(void) { // for testing, NOTE03 - QK_ISR_ENTRY(); // inform QK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); // inform QK kernel about exiting an ISR -} - -//.......................................................................... -// MPU setup for EFM32PG1B200F256GM48 MCU -static void EFM32PG182_MPU_setup(void) { - // The following MPU configuration contains the general EFM32PG1 memory - // map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map - // - // Please note that the actual STM32 MCUs provide much less Flash and SRAM - // than the maximums configured here. This means that actual MCUs have - // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - // access these regions causes the HardFault exception, which is the - // desired behavior. - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) - 0x20000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 1U), // region #1 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - // region #3: (not configured) - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) - 0x40000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 3U), // region #3 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) - 0xE0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 4U), // region #4 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) - 0x60000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 5U), // region #5 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) - 0xA0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 6U), // region #6 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (7U << MPU_RASR_SIZE_Pos) // 2^(7+1)=256B region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - }; - - // enable the MemManage_Handler for MPU exception - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU - __ISB(); - __DSB(); -} - -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - EFM32PG182_MPU_setup(); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - // - SystemCoreClockUpdate(); - - // NOTE: The VFP (hardware Floating Point) unit is configured by QK - - // enable clock for to the peripherals used by this application... - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - - // configure the LEDs - GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); - GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); - GPIO_PinOutClear(LED_PORT, LED0_PIN); - GPIO_PinOutClear(LED_PORT, LED1_PIN); - - // configure the Buttons - GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); - GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - - // initialize the QS software tracing... - if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//.......................................................................... -void BSP_ledOn(void) { - GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); -} -//.......................................................................... -void BSP_ledOff(void) { - GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(GPIO_EVEN_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 // don't include the NULL-ptr region - : 0x40000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 // don't include the NULL-ptr region - : 0x40000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//.......................................................................... -void QF_onStartup(void) { - // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(GPIO_EVEN_IRQn); -} -//.......................................................................... -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW -//.......................................................................... -void QK_onIdle(void) { - - GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); - -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -// QS callbacks ============================================================ -#ifdef Q_SPY - -//.......................................................................... -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). This works even though the -// Vector Table also resides at address 0x0. However, the *size* of the -// no-access region should not exceed the size of the Vector Table. In this -// case, the size is set to 2**(7+1)==256 bytes, which does not contain any -// data that the CPU would legitimately read with the LDR instruction. -// diff --git a/test/qk/test_sched/bsp_nucleo-c031c6.c b/test/qk/test_sched/bsp_nucleo-c031c6.c deleted file mode 100644 index ddcf94b8..00000000 --- a/test/qk/test_sched/bsp_nucleo-c031c6.c +++ /dev/null @@ -1,345 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QK kernel, NUCLEO-C031C6 board -// Last updated for version 7.4.0 -// Last updated on 2024-06-24 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE - -// Local-scope objects ----------------------------------------------------- -// LED pins available on the board (just one user LED LD4--Green on PA.5) -#define LD4_PIN 5U - -// Button pins available on the board (just one user Button B1 on PC.13) -#define B1_PIN 13U - -#ifdef Q_SPY - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -// ISRs used in this project =============================================== -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QK_ISR_ENTRY(); // inform QK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_1_IRQHandler(void); // prototype -void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 - QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); // inform QK kernel about exiting an ISR -} - -// BSP functions =========================================================== -static void STM32C031C6_MPU_setup(void) { - // The following MPU configuration contains the general STM32 memory model - // as described in the ST AppNote AN4838 "Managing memory protection unit - // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - // - // Please note that the actual STM32 MCUs provide much less Flash and SRAM - // than the maximums configured here. This means that actual MCUs have - // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - // access these regions causes the HardFault exception, which is the - // desired behavior. - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) - 0x20000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 1U), // region #1 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - // region #3: (not configured) - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) - 0x40000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 3U), // region #3 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) - 0xE0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 4U), // region #4 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) - 0x60000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 5U), // region #5 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) - 0xA0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 6U), // region #6 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) - // NOTE: this region extends to 0x080'0000, which is where - // the ROM is re-mapped by STM32 - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - }; - - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region - | MPU_CTRL_ENABLE_Msk; // enable the MPU - __ISB(); - __DSB(); -} -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32C031C6_MPU_setup(); - - // initialize the QS software tracing... - if (QS_INIT((void *)0) == 0U) { - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//............................................................................ -void BSP_ledOn(void) { - GPIOA->BSRR = (1U << LD4_PIN); // turn LD4 on -} -//............................................................................ -void BSP_ledOff(void) { - GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LD4 off -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_1_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08008000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08008000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20003000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20003000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//============================================================================ -// QF callbacks... -void QF_onStartup(void) { - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - SystemCoreClockUpdate(); - - // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - // NOTE: this might have been changed by STM32Cube. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_1_IRQn); -} -//............................................................................ -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//............................................................................ -void QK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -//============================================================================ -// QS callbacks... -#ifdef Q_SPY - -//............................................................................ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY -//---------------------------------------------------------------------------- - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qk/test_sched/bsp_nucleo-h743zi.c b/test/qk/test_sched/bsp_nucleo-h743zi.c deleted file mode 100644 index c229b0d1..00000000 --- a/test/qk/test_sched/bsp_nucleo-h743zi.c +++ /dev/null @@ -1,300 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QK kernel, NUCLEO-H743ZI board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -// STM32CubeH7 include files -#include "stm32h7xx_hal.h" -#include "stm32h7xx_nucleo_144.h" -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -// ISRs used in this project =============================================== -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_IRQHandler(void); // prototype -void EXTI0_IRQHandler(void) { // for testing, NOTE03 - QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} - -// BSP functions =========================================================== -//.......................................................................... -// MPU setup for STM32H743ZI MCU -static void STM32H743ZI_MPU_setup(void) { - // The following MPU configuration contains just a generic ROM - // region (with read-only access) and NULL-pointer protection region. - // Otherwise, the MPU will fall back on the background region (PRIVDEFENA). - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) - // NOTE: this region extends to 0x080'0000, which is where - // the ROM is re-mapped by STM32 - // - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - }; - - // enable the MemManage_Handler for MPU exception - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU - | MPU_CTRL_PRIVDEFENA_Msk; // enable background region - __ISB(); - __DSB(); -} - -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32H743ZI_MPU_setup(); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - // - SystemCoreClockUpdate(); - - SCB_EnableICache(); // Enable I-Cache - SCB_EnableDCache(); // Enable D-Cache - - // Configure Flash prefetch and Instr. cache through ART accelerator -#if (ART_ACCLERATOR_ENABLE != 0) - __HAL_FLASH_ART_ENABLE(); -#endif // ART_ACCLERATOR_ENABLE - - // Configure the LEDs - BSP_LED_Init(LED1); - BSP_LED_Init(LED2); - BSP_LED_Init(LED3); - - // Configure the User Button in GPIO Mode - BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); - - if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//.......................................................................... -void BSP_ledOn(void) { - BSP_LED_On(LED1); -} -//.......................................................................... -void BSP_ledOff(void) { - BSP_LED_Off(LED1); -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//.......................................................................... -void QF_onStartup(void) { - // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - //NOTE: don't start ticking for these tests - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - // NOTE: this might have been changed by STM32Cube. - // - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system, see NOTE1 - // - // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - // - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_IRQn); -} -//.......................................................................... -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//.......................................................................... -void QK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -// QS callbacks ============================================================ -#ifdef Q_SPY - -//.......................................................................... -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qk/test_sched/bsp_nucleo-l053r8.c b/test/qk/test_sched/bsp_nucleo-l053r8.c deleted file mode 100644 index ac2e868b..00000000 --- a/test/qk/test_sched/bsp_nucleo-l053r8.c +++ /dev/null @@ -1,365 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QK kernel, NUCLEO-L053R8 board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE - -// Local-scope objects ----------------------------------------------------- -// LED pins available on the board (just one user LED LD2--Green on PA.5) -#define LED_LD2 (1U << 5) - -// Button pins available on the board (just one user Button B1 on PC.13) -#define BTN_B1 (1U << 13) - -#ifdef Q_SPY - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -// ISRs used in this project =============================================== -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QK_ISR_ENTRY(); // inform QK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QK_ISR_EXIT(); // inform QK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_1_IRQHandler(void); // prototype -void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 - QK_ISR_ENTRY(); // inform QK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); // inform QK kernel about exiting an ISR -} - -// BSP functions =========================================================== -static void STM32L053R8_MPU_setup(void) { - // The following MPU configuration contains the general STM32 memory model - // as described in the ST AppNote AN4838 "Managing memory protection unit - // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - // - // Please note that the actual STM32 MCUs provide much less Flash and SRAM - // than the maximums configured here. This means that actual MCUs have - // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - // access these regions causes the HardFault exception, which is the - // desired behavior. - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) - 0x20000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 1U), // region #1 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - // region #3: (not configured) - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) - 0x40000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 3U), // region #3 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) - 0xE0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 4U), // region #4 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) - 0x60000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 5U), // region #5 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) - 0xA0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 6U), // region #6 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) - // NOTE: this region extends to 0x080'0000, which is where - // the ROM is re-mapped by STM32 - // - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - }; - - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region - | MPU_CTRL_ENABLE_Msk; // enable the MPU - __ISB(); - __DSB(); -} -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32L053R8_MPU_setup(); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - // - SystemCoreClockUpdate(); - - // enable GPIOA clock port for the LED LD2 - RCC->IOPENR |= (1U << 0); - - // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - // enable GPIOC clock port for the Button B1 - RCC->IOPENR |= (1U << 2); - - // configure Button (PC.13) pins as input, no pull-up, pull-down - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - // initialize the QS software tracing... - if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//.......................................................................... -void BSP_ledOn(void) { - GPIOA->BSRR = (LED_LD2); // turn LED2 on -} -//.......................................................................... -void BSP_ledOff(void) { - GPIOA->BSRR = (LED_LD2 << 16); // turn LED2 off -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_1_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//.......................................................................... -void QF_onStartup(void) { - // DON'T set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_1_IRQn); -} -//.......................................................................... -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//.......................................................................... -void QK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -// QS callbacks ============================================================ -#ifdef Q_SPY - -//.......................................................................... -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qk/test_sched/bsp_nucleo-u545re.c b/test/qk/test_sched/bsp_nucleo-u545re.c deleted file mode 100644 index 64e22485..00000000 --- a/test/qk/test_sched/bsp_nucleo-u545re.c +++ /dev/null @@ -1,313 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QK kernel, NUCLEO-U545RE-Q board -// Last updated for version 7.4.0 -// Last updated on 2024-06-24 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "stm32u545xx.h" // CMSIS-compliant header file for the MCU used -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE // define the name of this file for assertions - -// Local-scope defines ----------------------------------------------------- -// LED pins available on the board (just one user LED LD2--Green on PA.5) -#define LD2_PIN 5U - -// Button pins available on the board (just one user Button B1 on PC.13) -#define B1_PIN 13U - -// macros from STM32Cube LL: -#define SET_BIT(REG, BIT) ((REG) |= (BIT)) -#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) -#define READ_BIT(REG, BIT) ((REG) & (BIT)) -#define CLEAR_REG(REG) ((REG) = (0x0)) -#define WRITE_REG(REG, VAL) ((REG) = (VAL)) -#define READ_REG(REG) ((REG)) -#define MODIFY_REG(REG, CLEARMASK, SETMASK) \ - WRITE_REG((REG), ((READ_REG(REG) & (~(CLEARMASK))) | (SETMASK))) - -#ifdef Q_SPY -// QSpy source IDs -static QSpyId const l_SysTick_Handler = { 100U }; -static QSpyId const l_test_ISR = { 101U }; - -enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG -}; - -#endif - -// ISRs used in this project ================================================= -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QK_ISR_ENTRY(); // inform QK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QK_ISR_EXIT(); // inform QK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_IRQHandler(void); // prototype -void EXTI0_IRQHandler(void) { // for testing, NOTE03 - QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); // inform QK kernel about exiting an ISR -} - -// BSP functions =========================================================== -static void STM32U545RE_MPU_setup(void) { - MPU->CTRL = 0U; // disable the MPU - - MPU->RNR = 0U; // region 0 (for ROM: read-only, can-execute) - MPU->RBAR = (0x08000000U & MPU_RBAR_BASE_Msk) | (0x3U << MPU_RBAR_AP_Pos); - MPU->RLAR = (0x08080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - - MPU->RNR = 1U; // region 1 (for RAM1: read-write, execute-never) - MPU->RBAR = (0x20000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) - | MPU_RBAR_XN_Msk; - MPU->RLAR = (0x20040000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - - MPU->RNR = 2U; // region 2 (for RAM2: read-write, execute-never) - MPU->RBAR = (0x28000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) - | MPU_RBAR_XN_Msk; - MPU->RLAR = (0x28004000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - - MPU->RNR = 7U; // region 7 (no access: for NULL pointer protection) - MPU->RBAR = (0x00000000U & MPU_RBAR_BASE_Msk) | MPU_RBAR_XN_Msk; - MPU->RLAR = (0x00080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - __DMB(); - - MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk; - - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - __ISB(); -} -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32U545RE_MPU_setup(); - - // initialize I-CACHE - MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, 0U); // 1-way - SET_BIT(ICACHE->CR, ICACHE_CR_EN); // enable - - // flash prefetch buffer enable - SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN); - - // enable PWR clock interface - SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_PWREN); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - SystemCoreClockUpdate(); - - // enable GPIOA clock port for the LED LD4 - RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOAEN; - - // set all used GPIOA pins as push-pull output, no pull-up, pull-down - MODIFY_REG(GPIOA->OSPEEDR, - GPIO_OSPEEDR_OSPEED0 << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos), - 1U << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos)); // speed==1 - MODIFY_REG(GPIOA->OTYPER, - 1U << LD2_PIN, - 0U << LD2_PIN); // output - MODIFY_REG(GPIOA->PUPDR, - GPIO_PUPDR_PUPD0 << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos), - 0U << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos)); // PUSHPULL - MODIFY_REG(GPIOA->MODER, - GPIO_MODER_MODE0 << (LD2_PIN * GPIO_MODER_MODE1_Pos), - 1U << (LD2_PIN * GPIO_MODER_MODE1_Pos)); // MODE_1 - - // enable GPIOC clock port for the Button B1 - RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOCEN; - - // configure Button B1 pin on GPIOC as input, no pull-up, pull-down - MODIFY_REG(GPIOC->PUPDR, - GPIO_PUPDR_PUPD0 << (B1_PIN * GPIO_PUPDR_PUPD1_Pos), - 0U << (B1_PIN * GPIO_PUPDR_PUPD1_Pos)); // NO PULL - MODIFY_REG(GPIOC->MODER, - GPIO_MODER_MODE0 << (B1_PIN * GPIO_MODER_MODE1_Pos), - 0U << (B1_PIN * GPIO_MODER_MODE1_Pos)); // MODE_0 - - // initialize the QS software tracing... - if (!QS_INIT((void *)0)) { - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//............................................................................ -void BSP_ledOn(void) { - GPIOA->BSRR = (1U << LD2_PIN); // turn LED on -} -//............................................................................ -void BSP_ledOff(void) { - GPIOA->BRR = (1U << LD2_PIN); // turn LED off -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08080000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08080000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20040000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20040000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//============================================================================ -// QF callbacks... -void QF_onStartup(void) { - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - SystemCoreClockUpdate(); - - //NOTE: don't start ticking for these tests - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - // NOTE: this might have been changed by STM32Cube. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_IRQn); -} -//............................................................................ -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//............................................................................ -void QK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -//============================================================================ -// QS callbacks... -#ifdef Q_SPY - -//............................................................................ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY -//---------------------------------------------------------------------------- - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2^(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qk/test_sched/efm32pg1b.mak b/test/qk/test_sched/efm32pg1b.mak deleted file mode 100644 index 2995aace..00000000 --- a/test/qk/test_sched/efm32pg1b.mak +++ /dev/null @@ -1,333 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on EMF32, GNU-ARM -# Last Updated for Version: 7.3.0 -# Date of the Last Update: 2023-09-06 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f efm32pg1b.mak # make and run the tests in the current directory -# make -f efm32pg1b.mak TESTS=thr*.py # make and run the selected tests -# make -f efm32pg1b.mak HOST=localhost:7705 # connect to host:port -# make -f efm32pg1b.mak norun # only make but not run the tests -# make -f efm32pg1b.mak clean # cleanup the build -# make -f efm32pg1b.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := efm32 -TARGET_DIR := $(QPC)/3rd_party/efm32pg1b/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/efm32pg1b \ - $(QPC)/3rd_party/efm32pg1b/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/efm32pg1b - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_efm32pg1b.c \ - startup_efm32pg1b.c \ - system_efm32pg1b.c \ - em_cmu.c \ - em_emu.c \ - em_gpio.c \ - em_usart.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qk.c \ - qk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DEFM32PG1B200F256GM48=1 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# FLASH tool (NOTE: Requires the JLINK utility) -# NOTE: substitution of '/' to '\' is necessary to run the batch file - -FLASH := $(subst /,\,$(TARGET_DIR)/flash.bat) - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(FLASH) $@ - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(FLASH) $(TARGET_BIN) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo FLASH = $(FLASH) - @echo TESTS = $(TESTS) - diff --git a/test/qk/test_sched/efm32pg1b.uvoptx b/test/qk/test_sched/efm32pg1b.uvoptx deleted file mode 100644 index 4172d8f8..00000000 --- a/test/qk/test_sched/efm32pg1b.uvoptx +++ /dev/null @@ -1,730 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc; *.md - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - qutest - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 1 - 0 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\uvision_emf32\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 3 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 4 - - - - - - - - - - - Segger\JL2CM3.dll - - - - 0 - DLGUARM - - - - 0 - JL2CM3 - -U440060969 -O206 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - UL2CM3 - UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - lmidk-agdi - -U0E2006F4 -O4622 -S4 -FO61 - - - - - 0 - 0 - 112 - 1 -
25212
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\src\qs\qutest.c - - \\test\../../../src/qs/qutest.c\112 -
- - 1 - 0 - 142 - 1 -
136
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\src\qs\qs.c - - \\test\../../../src/qs/qs.c\142 -
- - 2 - 0 - 180 - 1 -
27402
- 0 - 0 - 0 - 0 - 0 - 1 - C:\qp-dev\qpc\test\qk\test_sched\test_pts.c - - \\test\test_pts.c\180 -
-
- - - 0 - 1 - QF_readySet_ - - - 1 - 1 - QK_attr_ - - - 2 - 1 - QActive_registry_ - - - 3 - 1 - QS_rxPriv_ - - - 4 - 1 - pspec - - - - - 1 - 2 - 0x20000200 - 0 - - - - - 2 - 0 - 0x400 - 0 - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - -
-
- - - Applicatioin - 1 - 0 - 0 - 0 - - 1 - 1 - 5 - 0 - 0 - 0 - .\bsp.h - bsp.h - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - .\test_sched.c - test_sched.c - 0 - 0 - - - 1 - 3 - 1 - 0 - 0 - 0 - .\bsp_efm32pg1b.c - bsp_efm32pg1b.c - 0 - 0 - - - - - efm32pg1b - 1 - 0 - 0 - 0 - - 2 - 4 - 2 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - startup_efm32pg1b.s - 0 - 0 - - - 2 - 5 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\em_cmu.c - em_cmu.c - 0 - 0 - - - 2 - 6 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\em_emu.c - em_emu.c - 0 - 0 - - - 2 - 7 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\em_gpio.c - em_gpio.c - 0 - 0 - - - 2 - 8 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - system_efm32pg1b.c - 0 - 0 - - - 2 - 9 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\em_system.c - em_system.c - 0 - 0 - - - 2 - 10 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\em_usart.c - em_usart.c - 0 - 0 - - - - - QP - 1 - 0 - 0 - 0 - - 3 - 11 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_hsm.c - qep_hsm.c - 0 - 0 - - - 3 - 12 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_msm.c - qep_msm.c - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qf\qf_act.c - qf_act.c - 0 - 0 - - - 3 - 14 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_actq.c - qf_actq.c - 0 - 0 - - - 3 - 15 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_defer.c - qf_defer.c - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_dyn.c - qf_dyn.c - 0 - 0 - - - 3 - 17 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_mem.c - qf_mem.c - 0 - 0 - - - 3 - 18 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_ps.c - qf_ps.c - 0 - 0 - - - 3 - 19 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qact.c - qf_qact.c - 0 - 0 - - - 3 - 20 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qeq.c - qf_qeq.c - 0 - 0 - - - 3 - 21 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qmact.c - qf_qmact.c - 0 - 0 - - - 3 - 22 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_time.c - qf_time.c - 0 - 0 - - - 3 - 23 - 1 - 0 - 0 - 0 - ..\..\..\src\qk\qk.c - qk.c - 0 - 0 - - - - - QP_port - 1 - 0 - 0 - 0 - - 4 - 25 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qxk\armclang\qp_port.h - qp_port.h - 0 - 0 - - - 4 - 27 - 1 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qk\armclang\qk_port.c - qk_port.c - 0 - 0 - - - 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qs_port.h - 0 - 0 - - - 4 - 29 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\qutest\qutest_port.c - qutest_port.c - 0 - 0 - - - - - QS - 1 - 0 - 0 - 0 - - 5 - 30 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs.c - qs.c - 0 - 0 - - - 5 - 31 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - - - 5 - 32 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 5 - 33 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_rx.c - qs_rx.c - 0 - 0 - - - 5 - 34 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qutest.c - qutest.c - 0 - 0 - - - 5 - 35 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qstamp.c - qstamp.c - 0 - 0 - - - -
diff --git a/test/qk/test_sched/efm32pg1b.uvprojx b/test/qk/test_sched/efm32pg1b.uvprojx deleted file mode 100644 index 7cb07d4c..00000000 --- a/test/qk/test_sched/efm32pg1b.uvprojx +++ /dev/null @@ -1,592 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - qutest - 0x4 - ARM-ADS - 6160000::V6.16::ARMCLANG - 1 - - - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) - 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h - - - - - - - - - - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\uvision_emf32\ - test_fixture - 1 - 0 - 0 - 1 - 1 - .\uvision_emf32\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 1 - 0 - cmd /c "del .\uvision_emf32\qstamp.o" - - 0 - 0 - 0 - 0 - - - 1 - 0 - fromelf --bin --output .\uvision_emf32\test_fixture.bin .\uvision_emf32\test_fixture.axf - - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 - SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4096 - - 1 - BIN\UL2CM3.DLL - "" () - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M4" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 8 - 0 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x8000 - - - 1 - 0x0 - 0x20000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x20000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x8000 - - - 0 - 0x0 - 0x0 - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 1 - 1 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - - - Q_SPY,Q_UTEST=0,QF_ON_CONTEXT_SW - - .;..\..\..\include;..\..\..\ports\arm-cm\qk\armclang;..\..\..\3rd_party\CMSIS\Include;..\..\..\3rd_party\efm32pg1b - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 4 - - - Stack_Size=2048 Heap_Size=16 - - - - - - 1 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - - - - --entry Reset_Handler - - - - - - - - Applicatioin - - - bsp.h - 5 - .\bsp.h - - - test_sched.c - 1 - .\test_sched.c - - - bsp_efm32pg1b.c - 1 - .\bsp_efm32pg1b.c - - - - - efm32pg1b - - - startup_efm32pg1b.s - 2 - ..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - - em_cmu.c - 1 - ..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - em_emu.c - 1 - ..\..\..\3rd_party\efm32pg1b\em_emu.c - - - em_gpio.c - 1 - ..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - system_efm32pg1b.c - 1 - ..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - - - em_system.c - 1 - ..\..\..\3rd_party\efm32pg1b\em_system.c - - - em_usart.c - 1 - ..\..\..\3rd_party\efm32pg1b\em_usart.c - - - - - QP - - - qep_hsm.c - 1 - ..\..\..\src\qf\qep_hsm.c - - - qep_msm.c - 1 - ..\..\..\src\qf\qep_msm.c - - - qf_act.c - 1 - ..\..\..\..\..\src\qf\qf_act.c - - - qf_actq.c - 1 - ..\..\..\src\qf\qf_actq.c - - - qf_defer.c - 1 - ..\..\..\src\qf\qf_defer.c - - - qf_dyn.c - 1 - ..\..\..\src\qf\qf_dyn.c - - - qf_mem.c - 1 - ..\..\..\src\qf\qf_mem.c - - - qf_ps.c - 1 - ..\..\..\src\qf\qf_ps.c - - - qf_qact.c - 1 - ..\..\..\src\qf\qf_qact.c - - - qf_qeq.c - 1 - ..\..\..\src\qf\qf_qeq.c - - - qf_qmact.c - 1 - ..\..\..\src\qf\qf_qmact.c - - - qf_time.c - 1 - ..\..\..\src\qf\qf_time.c - - - qk.c - 1 - ..\..\..\src\qk\qk.c - - - - - QP_port - - - qp_port.h - 5 - ..\..\..\ports\arm-cm\qxk\armclang\qp_port.h - - - qk_port.c - 1 - ..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - - qs_port.h - 5 - ..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - - - qutest_port.c - 1 - ..\..\..\3rd_party\efm32pg1b\qutest\qutest_port.c - - - - - QS - - - qs.c - 1 - ..\..\..\src\qs\qs.c - - - qs_64bit.c - 1 - ..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\src\qs\qs_fp.c - - - qs_rx.c - 1 - ..\..\..\src\qs\qs_rx.c - - - qutest.c - 1 - ..\..\..\src\qs\qutest.c - - - qstamp.c - 1 - ..\..\..\src\qs\qstamp.c - - - - - - - - - - - - - - - - - test - 1 - - - - -
diff --git a/test/qk/test_sched/nucleo-c031c6.mak b/test/qk/test_sched/nucleo-c031c6.mak deleted file mode 100644 index 12948699..00000000 --- a/test/qk/test_sched/nucleo-c031c6.mak +++ /dev/null @@ -1,336 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-c031c6, GNU-ARM -# Last Updated for Version: 7.2.2 -# Date of the Last Update: 2023-02-02 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-c031c6.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-c031c6.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-c031c6.mak HOST=localhost:7705 # connect to host:port -# make -f nucleo-c031c6.mak norun # only make but not run the tests -# make -f nucleo-c031c6.mak clean # cleanup the build -# make -f nucleo-c031c6.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-c031c6 -TARGET_DIR := $(QPC)/3rd_party/nucleo-c031c6/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/nucleo-c031c6 \ - $(QPC)/3rd_party/nucleo-c031c6/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/nucleo-c031c6 - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-c031c6.c \ - system_stm32c0xx.c \ - startup_stm32c031xx.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qk.c \ - qk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DSTM32C031xx \ - -DQP_API_VERSION=9999 \ - -DQK_USE_IRQ_HANDLER=Reserved1_IRQHandler \ - -DQK_USE_IRQ_NUM=1 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m0plus -ARM_FPU := -FLOAT_ABI := - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qk/test_sched/nucleo-c031c6.uvoptx b/test/qk/test_sched/nucleo-c031c6.uvoptx deleted file mode 100644 index 1bcdf271..00000000 --- a/test/qk/test_sched/nucleo-c031c6.uvoptx +++ /dev/null @@ -1,644 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc; *.md - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - qutest - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 1 - 0 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\uvision_nucleo-c031c6\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 18 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 6 - - - - - - - - - - - STLink\ST-LINKIII-KEIL_SWO.dll - - - - 0 - ST-LINKIII-KEIL_SWO - -U066BFF505153848667095842 -O207 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) - - - 0 - UL2CM3 - -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0) - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=1173,620,1584,1122,1)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - - - 0 - 0 - 316 - 1 -
134218224
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - - \\test\../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\316 -
-
- - - 0 - 1 - QS_rxPriv_ - - - - - 1 - 2 - 0x20000200 - 0 - - - - - 2 - 0 - 0x400 - 0 - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - 1 - 0 - 0 - 2 - 10000000 - -
-
- - - test - 1 - 0 - 0 - 0 - - 1 - 1 - 5 - 0 - 0 - 0 - .\bsp.h - bsp.h - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - .\test_sched.c - test_sched.c - 0 - 0 - - - 1 - 3 - 1 - 0 - 0 - 0 - .\bsp_nucleo-c031c6.c - bsp_nucleo-c031c6.c - 0 - 0 - - - - - nucleo-c031c6 - 1 - 0 - 0 - 0 - - 2 - 4 - 2 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - startup_stm32c031xx.s - 0 - 0 - - - 2 - 5 - 5 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h - stm32c031xx.h - 0 - 0 - - - 2 - 6 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c - system_stm32c0xx.c - 0 - 0 - - - 2 - 7 - 5 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h - system_stm32c0xx.h - 0 - 0 - - - 2 - 8 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c - qutest_port.c - 0 - 0 - - - - - QP - 1 - 0 - 0 - 0 - - 3 - 9 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_hsm.c - qep_hsm.c - 0 - 0 - - - 3 - 10 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_msm.c - qep_msm.c - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qf\qf_act.c - qf_act.c - 0 - 0 - - - 3 - 12 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_actq.c - qf_actq.c - 0 - 0 - - - 3 - 13 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_defer.c - qf_defer.c - 0 - 0 - - - 3 - 14 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_dyn.c - qf_dyn.c - 0 - 0 - - - 3 - 15 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_mem.c - qf_mem.c - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_ps.c - qf_ps.c - 0 - 0 - - - 3 - 17 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qact.c - qf_qact.c - 0 - 0 - - - 3 - 18 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qeq.c - qf_qeq.c - 0 - 0 - - - 3 - 19 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qmact.c - qf_qmact.c - 0 - 0 - - - 3 - 20 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_time.c - qf_time.c - 0 - 0 - - - 3 - 21 - 1 - 0 - 0 - 0 - ..\..\..\src\qk\qk.c - qk.c - 0 - 0 - - - - - QP_port - 1 - 0 - 0 - 0 - - 4 - 23 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qk\armclang\qp_port.h - qp_port.h - 0 - 0 - - - 4 - 24 - 1 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qk\armclang\qk_port.c - qk_port.c - 0 - 0 - - - 4 - 26 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qk\armclang\qs_port.h - qs_port.h - 0 - 0 - - - - - QS - 1 - 0 - 0 - 0 - - 5 - 27 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs.c - qs.c - 0 - 0 - - - 5 - 28 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - - - 5 - 29 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 5 - 30 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_rx.c - qs_rx.c - 0 - 0 - - - 5 - 31 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qstamp.c - qstamp.c - 0 - 0 - - - 5 - 32 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qutest.c - qutest.c - 0 - 0 - - - -
diff --git a/test/qk/test_sched/nucleo-c031c6.uvprojx b/test/qk/test_sched/nucleo-c031c6.uvprojx deleted file mode 100644 index 72475c86..00000000 --- a/test/qk/test_sched/nucleo-c031c6.uvprojx +++ /dev/null @@ -1,578 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - qutest - 0x4 - ARM-ADS - 6160000::V6.16::ARMCLANG - 1 - - - STM32C031C6Tx - STMicroelectronics - Keil.STM32C0xx_DFP.1.0.0 - https://www.keil.com/pack/ - IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) - 0 - $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h - - - - - - - - - - $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\uvision_nucleo-c031c6\ - test - 1 - 0 - 0 - 1 - 1 - .\uvision_nucleo-c031c6\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 1 - 0 - cmd /c "del .\uvision_nucleo-c031c6\qstamp.o" - - 0 - 0 - 0 - 0 - - - 1 - 0 - fromelf --bin --output .\uvision_nucleo-c031c6\test.bin .\uvision_nucleo-c031c6\test.axf - - 0 - 0 - 0 - 0 - - 0 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - SARMCM3.DLL - -REMAP-MPU - DARMCM1.DLL - -pCM0+ - SARMCM3.DLL - -MPU - TARMCM1.DLL - -pCM0+ - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4096 - - 1 - BIN\UL2CM3.DLL - "" () - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M0+" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 0 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x3000 - - - 1 - 0x8000000 - 0x8000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x8000000 - 0x8000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x3000 - - - 0 - 0x0 - 0x0 - - - - - - 0 - 1 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 1 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - - - Q_SPY, Q_UTEST=0,QK_USE_IRQ_HANDLER=Reserved1_IRQHandler,QK_USE_IRQ_NUM=1,QF_ON_CONTEXT_SW - - .;..\..\..\include;..\..\..\ports\arm-cm\qk\armclang;..\..\..\3rd_party\CMSIS\Include,..\..\..\3rd_party\nucleo-c031c6 - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 4 - - - Stack_Size=2048 Heap_Size=16 - - - - - - 1 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - dpp-qk.sct - - - --entry Reset_Handler - - - - - - - - test - - - bsp.h - 5 - .\bsp.h - - - test_sched.c - 1 - .\test_sched.c - - - bsp_nucleo-c031c6.c - 1 - .\bsp_nucleo-c031c6.c - - - - - nucleo-c031c6 - - - startup_stm32c031xx.s - 2 - ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - - - stm32c031xx.h - 5 - ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h - - - system_stm32c0xx.c - 1 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c - - - system_stm32c0xx.h - 5 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h - - - qutest_port.c - 1 - ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c - - - - - QP - - - qep_hsm.c - 1 - ..\..\..\src\qf\qep_hsm.c - - - qep_msm.c - 1 - ..\..\..\src\qf\qep_msm.c - - - qf_act.c - 1 - ..\..\..\..\..\src\qf\qf_act.c - - - qf_actq.c - 1 - ..\..\..\src\qf\qf_actq.c - - - qf_defer.c - 1 - ..\..\..\src\qf\qf_defer.c - - - qf_dyn.c - 1 - ..\..\..\src\qf\qf_dyn.c - - - qf_mem.c - 1 - ..\..\..\src\qf\qf_mem.c - - - qf_ps.c - 1 - ..\..\..\src\qf\qf_ps.c - - - qf_qact.c - 1 - ..\..\..\src\qf\qf_qact.c - - - qf_qeq.c - 1 - ..\..\..\src\qf\qf_qeq.c - - - qf_qmact.c - 1 - ..\..\..\src\qf\qf_qmact.c - - - qf_time.c - 1 - ..\..\..\src\qf\qf_time.c - - - qk.c - 1 - ..\..\..\src\qk\qk.c - - - - - QP_port - - - qp_port.h - 5 - ..\..\..\ports\arm-cm\qk\armclang\qp_port.h - - - qk_port.c - 1 - ..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - - qs_port.h - 5 - ..\..\..\ports\arm-cm\qk\armclang\qs_port.h - - - - - QS - - - qs.c - 1 - ..\..\..\src\qs\qs.c - - - qs_64bit.c - 1 - ..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\src\qs\qs_fp.c - - - qs_rx.c - 1 - ..\..\..\src\qs\qs_rx.c - - - qstamp.c - 1 - ..\..\..\src\qs\qstamp.c - - - qutest.c - 1 - ..\..\..\src\qs\qutest.c - - - - - - - - - - - - - - - - - uvision_c031c6 - 1 - nucleo-c031c6 - - - - -
diff --git a/test/qk/test_sched/nucleo-h743zi.mak b/test/qk/test_sched/nucleo-h743zi.mak deleted file mode 100644 index 08d6c4d7..00000000 --- a/test/qk/test_sched/nucleo-h743zi.mak +++ /dev/null @@ -1,347 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C on NUCLEO-H743ZI board, QUTEST, GNU-ARM -# Last Updated for Version: 7.3.0 -# Date of the Last Update: 2023-09-06 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-h743zi.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-h743zi.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-h743zi.mak USB=g: HOST=localhost:7705 # connect to host:port -# make -f nucleo-h743zi.mak USB=g: norun # only make but not run the tests -# make -f nucleo-h743zi.mak USB=g: clean # cleanup the build -# make -f nucleo-h743zi.mak USB=g: debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-h743zi -TARGET_DIR := $(QPC)/3rd_party/STM32CubeH7/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/STM32CubeH7/nucleo-h743zi/gnu \ - $(QPC)/3rd_party/STM32CubeH7/Drivers/BSP\STM32H7xx_Nucleo_144 \ - $(QPC)/3rd_party/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Src \ - $(QPC)/3rd_party/STM32CubeH7/Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/STM32CubeH7/Drivers/CMSIS/Device/ST/STM32H7xx/Include \ - -I$(QPC)/3rd_party/STM32CubeH7/Drivers/BSP/STM32H7xx_Nucleo_144 \ - -I$(QPC)/3rd_party/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-h743zi.c \ - startup_stm32h743xx.c \ - system_stm32h7xx.c \ - stm32h7xx_nucleo_144.c \ - stm32h7xx_hal.c \ - stm32h7xx_hal_cortex.c \ - stm32h7xx_hal_gpio.c \ - stm32h7xx_hal_pwr_ex.c \ - stm32h7xx_hal_rcc.c \ - stm32h7xx_hal_rcc_ex.c \ - stm32h7xx_hal_msp.c \ - stm32h7xx_hal_uart.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qk.c \ - qk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DQP_API_VERSION=9999 \ - -DSTM32H743xx -DUSE_HAL_DRIVER -DUSE_STM32H7XX_NUCLEO_144 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m7 -ARM_FPU := -mfpu=fpv5-d16 -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qk/test_sched/nucleo-l053r8.mak b/test/qk/test_sched/nucleo-l053r8.mak deleted file mode 100644 index bcd9c1cb..00000000 --- a/test/qk/test_sched/nucleo-l053r8.mak +++ /dev/null @@ -1,333 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-L053R8, GNU-ARM -# Last Updated for Version: 7.3.1 -# Date of the Last Update: 2023-11-13 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-l053r8.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-l053r8.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-l053r8.mak HOST=localhost:7705 # connect to host:port -# make -f nucleo-l053r8.mak norun # only make but not run the tests -# make -f nucleo-l053r8.mak clean # cleanup the build -# make -f nucleo-l053r8.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-l053r8 -TARGET_DIR := $(QPC)/3rd_party/nucleo-l053r8/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/nucleo-l053r8 \ - $(QPC)/3rd_party/nucleo-l053r8/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/nucleo-l053r8 - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-l053r8.c \ - system_stm32l0xx.c \ - startup_stm32l053xx.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qk.c \ - qk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DSTM32L053xx \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m0plus -ARM_FPU := -FLOAT_ABI := - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qk/test_sched/nucleo-l053r8.uvoptx b/test/qk/test_sched/nucleo-l053r8.uvoptx deleted file mode 100644 index 47d524ff..00000000 --- a/test/qk/test_sched/nucleo-l053r8.uvoptx +++ /dev/null @@ -1,632 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc; *.md - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - qutest - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 1 - 0 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\uvision_nucleo-l053r8\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 18 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 6 - - - - - - - - - - - STLink\ST-LINKIII-KEIL_SWO.dll - - - - 0 - UL2CM3 - -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32L0xx_64 -FL010000 -FS08000000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) - - - 0 - ST-LINKIII-KEIL_SWO - -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0) - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - - - - 1 - 2 - 0x20000200 - 0 - - - - - 2 - 0 - 0x400 - 0 - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - 1 - 0 - 0 - 2 - 10000000 - - - - - - test - 1 - 0 - 0 - 0 - - 1 - 1 - 5 - 0 - 0 - 0 - .\bsp.h - bsp.h - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - .\test_sched.c - test_sched.c - 0 - 0 - - - 1 - 3 - 1 - 0 - 0 - 0 - .\bsp_nucleo-l053r8.c - bsp_nucleo-l053r8.c - 0 - 0 - - - - - nucleo-l053r8 - 0 - 0 - 0 - 0 - - 2 - 4 - 5 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h - stm32l0xx.h - 0 - 0 - - - 2 - 5 - 5 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h - stm32l053xx.h - 0 - 0 - - - 2 - 6 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c - system_stm32l0xx.c - 0 - 0 - - - 2 - 7 - 5 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.h - system_stm32l0xx.h - 0 - 0 - - - 2 - 8 - 2 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s - startup_stm32l053xx.s - 0 - 0 - - - 2 - 9 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\qutest\qutest_port.c - qutest_port.c - 0 - 0 - - - - - QP - 1 - 0 - 0 - 0 - - 3 - 10 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_hsm.c - qep_hsm.c - 0 - 0 - - - 3 - 11 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_msm.c - qep_msm.c - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qf\qf_act.c - qf_act.c - 0 - 0 - - - 3 - 13 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_actq.c - qf_actq.c - 0 - 0 - - - 3 - 14 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_defer.c - qf_defer.c - 0 - 0 - - - 3 - 15 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_dyn.c - qf_dyn.c - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_mem.c - qf_mem.c - 0 - 0 - - - 3 - 17 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_ps.c - qf_ps.c - 0 - 0 - - - 3 - 18 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qact.c - qf_qact.c - 0 - 0 - - - 3 - 19 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qeq.c - qf_qeq.c - 0 - 0 - - - 3 - 20 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qmact.c - qf_qmact.c - 0 - 0 - - - 3 - 21 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_time.c - qf_time.c - 0 - 0 - - - 3 - 22 - 1 - 0 - 0 - 0 - ..\..\..\src\qk\qk.c - qk.c - 0 - 0 - - - - - QP_port - 1 - 0 - 0 - 0 - - 4 - 24 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qk\armclang\qp_port.h - qp_port.h - 0 - 0 - - - 4 - 25 - 1 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qk\armclang\qk_port.c - qk_port.c - 0 - 0 - - - 4 - 27 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qk\armclang\qs_port.h - qs_port.h - 0 - 0 - - - - - QS - 1 - 0 - 0 - 0 - - 5 - 28 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs.c - qs.c - 0 - 0 - - - 5 - 29 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - - - 5 - 30 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 5 - 31 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_rx.c - qs_rx.c - 0 - 0 - - - 5 - 32 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qstamp.c - qstamp.c - 0 - 0 - - - 5 - 33 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qutest.c - qutest.c - 0 - 0 - - - -
diff --git a/test/qk/test_sched/nucleo-l053r8.uvprojx b/test/qk/test_sched/nucleo-l053r8.uvprojx deleted file mode 100644 index e6d58c6e..00000000 --- a/test/qk/test_sched/nucleo-l053r8.uvprojx +++ /dev/null @@ -1,583 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - qutest - 0x4 - ARM-ADS - 6160000::V6.16::ARMCLANG - 1 - - - STM32L053R8Tx - STMicroelectronics - Keil.STM32L0xx_DFP.2.2.0 - http://www.keil.com/pack/ - IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) - 0 - $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h - - - - - - - - - - $$Device:STM32L053R8Tx$SVD\STM32L053x.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\uvision_nucleo-l053r8\ - test - 1 - 0 - 0 - 1 - 1 - .\uvision_nucleo-l053r8\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 1 - 0 - cmd /c "del .\uvision_nucleo-l053r8\qstamp.o" - - 0 - 0 - 0 - 0 - - - 1 - 0 - fromelf --bin --output .\uvision_nucleo-l053r8\test.bin .\uvision_nucleo-l053r8\test.axf - - 0 - 0 - 0 - 0 - - 0 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - SARMCM3.DLL - -REMAP - DARMCM1.DLL - -pCM0+ - SARMCM3.DLL - - TARMCM1.DLL - -pCM0+ - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4096 - - 1 - BIN\UL2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M0+" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 0 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x2000 - - - 1 - 0x8000000 - 0x10000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x8000000 - 0x10000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x2000 - - - 0 - 0x0 - 0x0 - - - - - - 0 - 1 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 1 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - - - Q_SPY, Q_UTEST=0,QK_USE_IRQ_HANDLER=LCD_IRQHandler,QK_USE_IRQ_NUM=30,QF_ON_CONTEXT_SW - - .;..\..\..\include;..\..\..\ports\arm-cm\qk\armclang;..\..\..\3rd_party\CMSIS\Include,..\..\..\3rd_party\nucleo-l053r8 - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 4 - - - Stack_Size=2048 Heap_Size=16 - - - - - - 1 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - dpp-qk.sct - - - --entry Reset_Handler - - - - - - - - test - - - bsp.h - 5 - .\bsp.h - - - test_sched.c - 1 - .\test_sched.c - - - bsp_nucleo-l053r8.c - 1 - .\bsp_nucleo-l053r8.c - - - - - nucleo-l053r8 - - - stm32l0xx.h - 5 - ..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h - - - stm32l053xx.h - 5 - ..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h - - - system_stm32l0xx.c - 1 - ..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c - - - system_stm32l0xx.h - 5 - ..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.h - - - startup_stm32l053xx.s - 2 - ..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s - - - qutest_port.c - 1 - ..\..\..\3rd_party\nucleo-l053r8\qutest\qutest_port.c - - - - - QP - - - qep_hsm.c - 1 - ..\..\..\src\qf\qep_hsm.c - - - qep_msm.c - 1 - ..\..\..\src\qf\qep_msm.c - - - qf_act.c - 1 - ..\..\..\..\..\src\qf\qf_act.c - - - qf_actq.c - 1 - ..\..\..\src\qf\qf_actq.c - - - qf_defer.c - 1 - ..\..\..\src\qf\qf_defer.c - - - qf_dyn.c - 1 - ..\..\..\src\qf\qf_dyn.c - - - qf_mem.c - 1 - ..\..\..\src\qf\qf_mem.c - - - qf_ps.c - 1 - ..\..\..\src\qf\qf_ps.c - - - qf_qact.c - 1 - ..\..\..\src\qf\qf_qact.c - - - qf_qeq.c - 1 - ..\..\..\src\qf\qf_qeq.c - - - qf_qmact.c - 1 - ..\..\..\src\qf\qf_qmact.c - - - qf_time.c - 1 - ..\..\..\src\qf\qf_time.c - - - qk.c - 1 - ..\..\..\src\qk\qk.c - - - - - QP_port - - - qp_port.h - 5 - ..\..\..\ports\arm-cm\qk\armclang\qp_port.h - - - qk_port.c - 1 - ..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - - qs_port.h - 5 - ..\..\..\ports\arm-cm\qk\armclang\qs_port.h - - - - - QS - - - qs.c - 1 - ..\..\..\src\qs\qs.c - - - qs_64bit.c - 1 - ..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\src\qs\qs_fp.c - - - qs_rx.c - 1 - ..\..\..\src\qs\qs_rx.c - - - qstamp.c - 1 - ..\..\..\src\qs\qstamp.c - - - qutest.c - 1 - ..\..\..\src\qs\qutest.c - - - - - - - - - - - - - - - - - uvision_l053r8 - 1 - nucleo-l053r8 - - - - -
diff --git a/test/qk/test_sched/nucleo-u545re.mak b/test/qk/test_sched/nucleo-u545re.mak deleted file mode 100644 index fb8d523a..00000000 --- a/test/qk/test_sched/nucleo-u545re.mak +++ /dev/null @@ -1,333 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-U545RE-Q, GNU-ARM -# Last Updated for Version: 7.4.0 -# Date of the Last Update: 2024-06-23 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-u545re.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-u545re.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-u545re.mak HOST=localhost:7705 # connect to host:port -# make -f nucleo-u545re.mak norun # only make but not run the tests -# make -f nucleo-u545re.mak clean # cleanup the build -# make -f nucleo-u545re.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-u545re -TARGET_DIR := $(QPC)/3rd_party/nucleo-u545re/qutest - -#----------------------------------------------------------------------------- -# project directories -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/nucleo-u545re \ - $(QPC)/3rd_party/nucleo-u545re/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/nucleo-u545re - -#----------------------------------------------------------------------------- -# project files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-u545re.c \ - system_stm32u5xx.c \ - startup_stm32u545retxq.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qk.c \ - qk_port.c \ - qs.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DSTM32U545xx \ - -DQP_API_VERSION=9999 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m33 -ARM_FPU := -mfpu=fpv5-sp-d16 -FLOAT_ABI := -mfloat-abi=hard -mthumb - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qk/test_sched/qutest230202_192030.txt b/test/qk/test_sched/qutest230202_192030.txt deleted file mode 100644 index a6809a23..00000000 --- a/test/qk/test_sched/qutest230202_192030.txt +++ /dev/null @@ -1,89 +0,0 @@ -Run ID : 230202_192030 -Target : remote - -==================================[Group 1]================================== -test_mpu.py - -@uid{TQP701} -This test group verifies the memory access protection, -specifically the protection of various memory regions. -All tests run during the QS_TEST_PAUSE() in -the test_sched.c fixture. - -[ 1]-------------------------------------------------------------------------- - -NULL-read -> ASSERT - - [ PASS ( 0.2s) ] -[ 2]-------------------------------------------------------------------------- -NULL-write -> ASSERT - [ PASS ( 0.1s) ] -[ 3]-------------------------------------------------------------------------- -Below-Start Flash-read -> ASSERT - [ PASS ( 0.1s) ] -[ 4]-------------------------------------------------------------------------- -Start-of Flash-read - [ PASS ( 0.1s) ] -[ 5]^------------------------------------------------------------------------- -Middle-of Flash-read - [ PASS ( 0.0s) ] -[ 6]^------------------------------------------------------------------------- -End-of Flash-read - [ PASS ( 0.0s) ] -[ 7]^ - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - -After-End Flash-read-> ASSERT - [ SKIPPED ] -[ 8]-------------------------------------------------------------------------- -Middle-of Flash-write -> ASSERT - [ PASS ( 0.1s) ] -[ 9]-------------------------------------------------------------------------- -Below-Start SRAM-read -> ASSERT - [ PASS ( 0.1s) ] -[10]-------------------------------------------------------------------------- -Start-of SRAM-read - [ PASS ( 0.1s) ] -[11]^------------------------------------------------------------------------- -Middle-of SRAM-read - [ PASS ( 0.0s) ] -[12]^------------------------------------------------------------------------- -End-of SRAM-read - [ PASS ( 0.0s) ] -[13]^------------------------------------------------------------------------- -Below-Start SRAM-write -> ASSERT - [ PASS ( 0.0s) ] -[14]- - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - -Middle-of SRAM-write - [ SKIPPED ] -[15]-------------------------------------------------------------------------- -After-End SRAM-write -> ASSERT - [ PASS ( 0.1s) ] - -==================================[Group 2]================================== -test_sched.py -@uid{TQP603} -This test group verifies the preemption scenarios -in the QK preemptive kernel - -[16]-------------------------------------------------------------------------- -Scenario: ao->ao->ao (NO PTS) - @test_sched.py:43 -exp: "0000000013 TRACE_MSG aoB[1] TEST0 2of2" -got: "0000000013 =ASSERT= Mod=Undefined,Loc=1" -! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ![ FAIL ( 0.2s) ] -[17]-------------------------------------------------------------------------- -ao->ao->ao (PTS1) - [ PASS ( 0.2s) ] -[18]-------------------------------------------------------------------------- -ao->ao->ao (PTS2) - [ PASS ( 0.2s) ] - -==================================[ SUMMARY ]================================= - -Target ID : 230202_190526 (QP-Ver=721) -Log file : ./qutest230202_192030.txt -Groups : 2 -Tests : 18 -Skipped : 2 [ 7 14 ] -FAILED : 1 [ 16 ] - -==============================[ FAIL ( 2.8s) ]=============================== diff --git a/test/qk/test_sched/test_mpu.py b/test/qk/test_sched/test_mpu.py deleted file mode 100644 index c1b8908d..00000000 --- a/test/qk/test_sched/test_mpu.py +++ /dev/null @@ -1,99 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html/qutest.html - -note(''' -@uid{TQP701} -This test group verifies the memory access protection, -specifically the protection of various memory regions. -All tests run during the QS_TEST_PAUSE() in -the test_sched.c fixture. -''') - -# preamble -def on_reset(): - expect_pause() - # don't call continue_test() - -def on_setup(): - glb_filter(GRP_SC, GRP_UA) - -MEM_START = 0 -MEM_END = 1 - -# NULL-pointer dereferencing... -test(''' -NULL-read -> ASSERT -''') -command("MEM_READ", 0x0, 0x80) # value = *(uint32_t volatile *)(param1 + param2); -expect("@timestamp =ASSERT= Mod=*") - -test("NULL-write -> ASSERT") -command("MEM_WRITE", 0x0, 0xA0, 123) # *(uint32_t volatile *)(param1 + param2) = param3; -expect("@timestamp =ASSERT= Mod=*") - -# ROM_READ... -test("Below-Start Flash-read -> ASSERT") -command("ROM_READ", (-4 & 0xFFFFFFFF), MEM_START) # value = BSP_romRead(param1, param2); -expect("@timestamp =ASSERT= Mod=*") - -test("Start-of Flash-read") -command("ROM_READ", 0x0, MEM_START) # value = BSP_romRead(param1, param2); -expect("@timestamp USER+000 ROM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("Middle-of Flash-read", NORESET) -command("ROM_READ", 0x400, MEM_START) # value = BSP_romRead(param1, param2); -expect("@timestamp USER+000 ROM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("End-of Flash-read", NORESET) -command("ROM_READ", 0x0, MEM_END) # value = BSP_romRead(param1, param2); -expect("@timestamp USER+000 ROM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -skip(1) -test("After-End Flash-read-> ASSERT", NORESET) -command("ROM_READ", 0x4, MEM_END) # value = BSP_romRead(param1, param2); -expect("@timestamp =ASSERT= Mod=*") - -# ROM_WRITE... -test("Middle-of Flash-write -> ASSERT") -command("ROM_WRITE", 0x400, MEM_START, 123) # BSP_romWrite(param1, param2, param3); -expect("@timestamp =ASSERT= Mod=*") - -# RAM_READ... -test("Below-Start SRAM-read -> ASSERT") -command("RAM_READ", (-0x4 & 0xFFFFFFFF), MEM_START) # value = BSP_ramRead(param1, param2); -expect("@timestamp =ASSERT= Mod=*") - -test("Start-of SRAM-read") -command("RAM_READ", 0x0, MEM_START) # value = BSP_ramRead(param1, param2); -expect("@timestamp USER+000 RAM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("Middle-of SRAM-read", NORESET) -command("RAM_READ", 0x300, MEM_START) # value = BSP_ramRead(param1, param2); -expect("@timestamp USER+000 RAM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("End-of SRAM-read", NORESET) -command("RAM_READ", 0x0, MEM_END) # value = BSP_ramRead(param1, param2); -expect("@timestamp USER+000 RAM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -# RAM_WRITE... -test("Below-Start SRAM-write -> ASSERT", NORESET) -command("RAM_WRITE", (-0x4 & 0xFFFFFFFF), MEM_START, 123) # BSP_ramWrite(param1, param2, param3); -expect("@timestamp =ASSERT= Mod=*") - -# wrtiting to RAM does not need to be tested because the fact -# that the test fixture runs at all means that RAM works. -skip(1) -test("Middle-of SRAM-write") -command("RAM_WRITE", 0x300, MEM_START, 123) # BSP_ramWrite(param1, param2, param3); -expect("@timestamp USER+000 RAM_WRITE *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("After-End SRAM-write -> ASSERT") -command("RAM_WRITE", 0x4, MEM_END, 123) # BSP_ramWrite(param1, param2, param3); -expect("@timestamp =ASSERT= Mod=*") diff --git a/test/qk/test_sched/test_sched.c b/test/qk/test_sched/test_sched.c deleted file mode 100644 index 9e71d64a..00000000 --- a/test/qk/test_sched/test_sched.c +++ /dev/null @@ -1,247 +0,0 @@ -//============================================================================ -// Product: System test fixture for QK kernel -// Last Updated for Version: 7.3.0 -// Date of the Last Update: 2023-06-30 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -//Q_DEFINE_THIS_FILE - -//========================================================================== -// AO ObjB -enum { NUM_B = 3 }; - -typedef struct { - QActive super; -} ObjB; - -QState ObjB_initial(ObjB * const me, void const * const par); -QState ObjB_active(ObjB * const me, QEvt const * const e); - -void ObjB_ctor(ObjB * const me) { - QActive_ctor(&me->super, Q_STATE_CAST(&ObjB_initial)); -} - -//.......................................................................... -QState ObjB_initial(ObjB * const me, void const * const par) { - Q_UNUSED_PAR(par); - QActive_subscribe(&me->super, TEST1_SIG); - QActive_subscribe(&me->super, TEST2_SIG); - QS_FUN_DICTIONARY(&ObjB_active); - return Q_TRAN(&ObjB_active); -} -//.......................................................................... -QState ObjB_active(ObjB * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - case TEST0_SIG: { - BSP_trace(&me->super, "TEST0 1of2"); - BSP_trigISR(); - BSP_trace(&me->super, "TEST0 2of2"); - status_ = Q_HANDLED(); - break; - } - case TEST1_SIG: { - static QEvt const t2 = QEVT_INITIALIZER(TEST2_SIG); - BSP_trace(&me->super, "TEST1 1of2"); - QACTIVE_PUBLISH(&t2, &me->super); - BSP_trace(&me->super, "TEST1 2of2"); - status_ = Q_HANDLED(); - break; - } - case TEST2_SIG: { - BSP_trace(&me->super, "TEST2 1of1"); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -//.......................................................................... -ObjB aoB[NUM_B]; - -//========================================================================== -enum UserCommands { - MEM_READ, MEM_WRITE, - ROM_READ, ROM_WRITE, - RAM_READ, RAM_WRITE, -}; - -int main() { - QF_init(); // initialize the framework and the underlying QXK kernel - BSP_init(); // initialize the Board Support Package - - // initialize publish-subscribe... - static QSubscrList subscrSto[MAX_PUB_SIG]; - QActive_psInit(subscrSto, Q_DIM(subscrSto)); - - // initialize event pools... - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // small pool - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - // dictionaries - QS_SIG_DICTIONARY(TEST0_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST1_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST2_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST3_SIG, (void *)0); - - QS_ENUM_DICTIONARY(MEM_READ, QS_CMD); - QS_ENUM_DICTIONARY(MEM_WRITE, QS_CMD); - QS_ENUM_DICTIONARY(ROM_READ, QS_CMD); - QS_ENUM_DICTIONARY(ROM_WRITE, QS_CMD); - QS_ENUM_DICTIONARY(RAM_READ, QS_CMD); - QS_ENUM_DICTIONARY(RAM_WRITE, QS_CMD); - - for (uint8_t n = 0U; n < NUM_B; ++n) { - QS_OBJ_ARR_DICTIONARY(&aoB[n], n); - } - - // priority specifications for ObjBs... - static QPrioSpec pspecB[NUM_B + 1]; - QS_OBJ_DICTIONARY(pspecB); - - // pause execution of the test and wait for the test script to continue - // NOTE: - // this pause gives the test-script a chance to poke pspecB and pspecX - // variables to start the threads with the desired prio-specifications. - // - QS_TEST_PAUSE(); - - static QEvt const *aoB_queueSto[NUM_B][10]; - for (uint8_t n = 0U; n < NUM_B; ++n) { - if (pspecB[n] != 0U) { - ObjB_ctor(&aoB[n]); // instantiate the AO - QActive_start(&aoB[n].super, // AO to start - pspecB[n], // QF-prio/p-thre. - aoB_queueSto[n], // event queue storage - Q_DIM(aoB_queueSto[n]), // event length [events] - (void *)0, // no stack storage - 0U, // zero stack size [bytes] - (void *)0); // initialization param - } - } - - return QF_run(); // run the QF application -} - -//========================================================================== -void QS_onTestSetup(void) { -} -//.......................................................................... -void QS_onTestTeardown(void) { -} -//.......................................................................... -//! callback function to execute user commands -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - uint32_t volatile value; - - switch (cmdId) { - case MEM_READ: { // read MEM (can trip the MPU) - value = *(uint32_t volatile *)(param1 + param2); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(0, value); - QS_END() - break; - } - case MEM_WRITE: { // write MEM (can trip the MPU) - *(uint32_t volatile *)(param1 + param2) = param3; - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(QS_HEX_FMT , param1); - QS_U32(QS_HEX_FMT , param2); - QS_U32(0 , param3); - QS_END() - break; - } - case ROM_READ: { // read ROM (can trip the MPU) - value = BSP_romRead((int32_t)param1, param2); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(0, value); - QS_END() - break; - } - case ROM_WRITE: { // write ROM (can trip the MPU) - BSP_romWrite(param1, param2, param3); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(QS_HEX_FMT , param1); - QS_U32(QS_HEX_FMT , param2); - QS_U32(0 , param3); - QS_END() - break; - } - case RAM_READ: { // read RAM (can trip the MPU) - value = BSP_ramRead(param1, param2); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(0, value); - QS_END() - break; - } - case RAM_WRITE: { // write RAM (can trip the MPU) - BSP_ramWrite(param1, param2, param3); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(QS_HEX_FMT , param1); - QS_U32(QS_HEX_FMT , param2); - QS_U32(0, param3); - QS_END() - break; - } - default: { - break; - } - } -} - -//**************************************************************************** -//! Host callback function to "massage" the event, if necessary -void QS_onTestEvt(QEvt *e) { - Q_UNUSED_PAR(e); -} -//.......................................................................... -//! callback function to output the posted QP events (not used here) -void QS_onTestPost(void const *sender, QActive *recipient, - QEvt const *e, bool status) -{ - Q_UNUSED_PAR(sender); - Q_UNUSED_PAR(status); -} - diff --git a/test/qk/test_sched/test_sched.py b/test/qk/test_sched/test_sched.py deleted file mode 100644 index 6d7e1263..00000000 --- a/test/qk/test_sched/test_sched.py +++ /dev/null @@ -1,223 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html/qutest.html - -required(VERSION >= 740, "QUTest VERSION >= 740 required") - -note('''@uid{TST-QP-QK_02} -This test group verifies the preemption scenarios -in the QK preemptive kernel -''') - -# preamble -def on_reset(): - expect_pause() - # don't call continue_test() yet - # this will be done by the individual tests - # after they poke the priorities of threads - -# helper function to repliacte the Q_PRIO() macro -def Q_PRIO(prio, pthre): - return prio | (pthre << 8) - -#------------------------------------------------------------------------------- -@scenario("Scenario: ao->ao->ao (NO PTS)") -def do(context): - context.prio = [Q_PRIO(1,0), Q_PRIO(2,0), Q_PRIO(3,0)] - return context - -@given("priorities: (1,0), (2,0), (3,0)") -def do(context): - current_obj(OBJ_AP, "pspecB") - poke(0, 2, pack("2") - expect("@timestamp CONTEXT_SW NULL aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") - expect("@timestamp Sch-Next Pri=2->3") - expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") - expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp Sch-Next Pri=2->3") - expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp Sch-Next Pri=2->1") - expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") - expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp Sch-Next Pri=1->3") - expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp Sch-Next Pri=2->1") - expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") - expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp Sch-Idle Pri=1->0") - expect("@timestamp CONTEXT_SW aoB[0] NULL") - expect("@timestamp Trg-Done QS_RX_EVENT") - - -#------------------------------------------------------------------------------- -@scenario("ao->ao->ao (PTS1)") -def do(context): - context.prio = [Q_PRIO(1,3), Q_PRIO(2,3), Q_PRIO(3,0)] - return context - -@given("priorities: (1,3), (2,3), (3,0)") -def do(context): - current_obj(OBJ_AP, "pspecB") - poke(0, 2, pack("2") - expect("@timestamp CONTEXT_SW NULL aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") - expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") - expect("@timestamp Sch-Next Pri=2->3") - expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") - expect("@timestamp Sch-Next Pri=2->3") - expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp Sch-Next Pri=2->1") - expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") - expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") - expect("@timestamp Sch-Next Pri=1->3") - expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp Sch-Next Pri=2->1") - expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp Sch-Idle Pri=1->0") - expect("@timestamp CONTEXT_SW aoB[0] NULL") - expect("@timestamp Trg-Done QS_RX_EVENT") - - -#------------------------------------------------------------------------------- -@scenario("ao->ao->ao (PTS2)") -def do(context): - context.prio = [Q_PRIO(1,0), Q_PRIO(2,3), Q_PRIO(3,0)] - return context - -@given("priorities: (1,0), (2,3), (3,0)") -def do(context): - current_obj(OBJ_AP, "pspecB") - poke(0, 2, pack("2") - expect("@timestamp CONTEXT_SW NULL aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") - expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") - expect("@timestamp Sch-Next Pri=2->3") - expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") - expect("@timestamp Sch-Next Pri=2->3") - expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp Sch-Next Pri=2->1") - expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") - expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") - expect("@timestamp Sch-Lock Ceil=0->3") - expect("@timestamp Sch-Unlk Ceil=3->0") - expect("@timestamp Sch-Next Pri=1->3") - expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") - expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") - expect("@timestamp Sch-Next Pri=3->2") - expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") - expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") - expect("@timestamp Sch-Next Pri=2->1") - expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") - expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") - expect("@timestamp Sch-Idle Pri=1->0") - expect("@timestamp CONTEXT_SW aoB[0] NULL") - expect("@timestamp Trg-Done QS_RX_EVENT") diff --git a/test/qs/qs_rx/Makefile b/test/qs/qs_rx/Makefile deleted file mode 100644 index b16c5d1b..00000000 --- a/test/qs/qs_rx/Makefile +++ /dev/null @@ -1,221 +0,0 @@ -############################################################################## -# Product: Makefile for Embedded Test (ET) for Windows *HOST* -# Last Updated for Version: 7.3.0 -# Date of the Last Update: 2023-06-30 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make # make and run the Python tests in the current directory -# make TESTS=test*.py # make and run the selected tests in the curr. dir. -# make HOST=localhost:7705 # connect to host:port -# make norun # only make but not run the tests -# make clean # cleanup the build -# make debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -#----------------------------------------------------------------------------- -# project name: -PROJECT := test - -#----------------------------------------------------------------------------- -# project directories: -# -QPC := ../../.. -ET := ../../et - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(ET) - -# list of all include directories needed by this project -INCLUDES := -I. \ - -I$(QPC)/include \ - -I$(ET) - -#----------------------------------------------------------------------------- -# project files: -# - -# C source files... -C_SRCS := \ - qep_hsm.c \ - qf_act.c \ - qf_actq.c \ - qf_qact.c \ - qs.c \ - qs_rx.c \ - test.c \ - et.c \ - et_host.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -DEFINES := -DQ_SPY - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# GNU toolset: -# -# NOTE: -# GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -#----------------------------------------------------------------------------- -# basic utilities (depends on the OS this Makefile runs on): -# -ifeq ($(OS),Windows_NT) - MKDIR := mkdir - RM := rm - TARGET_EXT := .exe -else ifeq ($(OSTYPE),cygwin) - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := .exe -else - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := -endif - -#----------------------------------------------------------------------------- -# build options... - -BIN_DIR := build - -CFLAGS := -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DQ_HOST - -CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DQ_HOST - -ifndef GCC_OLD - LINKFLAGS := -no-pie -endif - -ifdef GCOV - CFLAGS += -fprofile-arcs -ftest-coverage - CPPFLAGS += -fprofile-arcs -ftest-coverage - LINKFLAGS += -lgcov --coverage -endif - -#----------------------------------------------------------------------------- -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : norun clean show - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -run : $(TARGET_EXE) - $(TARGET_EXE) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.* - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - diff --git a/test/qs/qs_rx/qp_port.h b/test/qs/qs_rx/qp_port.h deleted file mode 100644 index 55aa2afb..00000000 --- a/test/qs/qs_rx/qp_port.h +++ /dev/null @@ -1,130 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! -//! @date Last updated on: 2023-08-19 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QP/C "port" for Embedded Test, Win32 with GNU or VisualC++ -//! -#ifndef QP_PORT_H_ -#define QP_PORT_H_ - -#include // Exact-width types. WG14/N843 C99 Standard -#include // Boolean type. WG14/N843 C99 Standard - -//! no-return function specifier -#ifdef __GNUC__ - - //! no-return function specifier (GCC-ARM compiler) - #define Q_NORETURN __attribute__ ((noreturn)) void - -#elif (defined _MSC_VER) - #ifdef __cplusplus - // no-return function specifier (Microsoft Visual Studio C++ compiler) - #define Q_NORETURN [[ noreturn ]] void - #else - // no-return function specifier C11 - #define Q_NORETURN _Noreturn void - #endif - - // This is the case where QP/C is compiled by the Microsoft Visual C++ - // compiler in the C++ mode, which can happen when qep_port.h is included - // in a C++ module, or the compilation is forced to C++ by the option /TP. - // - // The following pragma suppresses the level-4 C++ warnings C4510, C4512, - // and C4610, which warn that default constructors and assignment operators - // could not be generated for structures QMState and QMTranActTable. - // - // The QP/C source code cannot be changed to avoid these C++ warnings - // because the structures QMState and QMTranActTable must remain PODs - // (Plain Old Datatypes) to be initializable statically with constant - // initializers. - // - #pragma warning (disable: 4510 4512 4610) - -#endif - -// event queue and thread types -#define QACTIVE_EQUEUE_TYPE QEQueue -// QACTIVE_OS_OBJ_TYPE not used in this port -// QACTIVE_THREAD_TYPE not used in this port - -// The maximum number of active objects in the application -#define QF_MAX_ACTIVE 64U - -// The number of system clock tick rates -#define QF_MAX_TICK_RATE 2U - -// Activate the QF QActive_stop() API -#define QACTIVE_CAN_STOP 1 - -// QF interrupt disable/enable -#define QF_INT_DISABLE() ((void)0) -#define QF_INT_ENABLE() ((void)0) - -// QUIT critical section -#define QF_CRIT_STAT -#define QF_CRIT_ENTRY() QF_INT_DISABLE() -#define QF_CRIT_EXIT() QF_INT_ENABLE() - -// QF_LOG2 not defined -- use the internal LOG2() implementation - -// include files ------------------------------------------------------------- -#include "qequeue.h" // Win32-QV needs the native event-queue -#include "qmpool.h" // Win32-QV needs the native memory-pool -#include "qp.h" // QP platform-independent public interface - -//========================================================================== -// interface used only inside QP implementation, but not in applications -#ifdef QP_IMPL - - // ET scheduler locking (not used) - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - // native event queue operations - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) ((void)0) - - // native QF event pool operations - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - #define QF_EPOOL_PUT_(p_, e_, qsId_) \ - (QMPool_put(&(p_), (e_), (qsId_))) - -#endif // QP_IMPL - -#ifdef _MSC_VER - #pragma warning (default: 4510 4512 4610) -#endif - -#endif // QP_PORT_H_ diff --git a/test/qs/qs_rx/qs_port.h b/test/qs/qs_rx/qs_port.h deleted file mode 100644 index d0460af6..00000000 --- a/test/qs/qs_rx/qs_port.h +++ /dev/null @@ -1,61 +0,0 @@ -//============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -//! @date Last updated on: 2023-08-16 -//! @version Last updated for: @ref qpc_7_3_0 -//! -//! @file -//! @brief QS/C port to Win32 with GNU or Visual C++ compilers -//! -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -#define QS_CTR_SIZE 4U -#define QS_TIME_SIZE 4U - -#ifdef _WIN64 // 64-bit architecture? - #define QS_OBJ_PTR_SIZE 8U - #define QS_FUN_PTR_SIZE 8U -#else // 32-bit architecture - #define QS_OBJ_PTR_SIZE 4U - #define QS_FUN_PTR_SIZE 4U -#endif - -void QS_output(void); // handle the QS output -void QS_rx_input(void); // handle the QS-RX input - -//============================================================================ -// NOTE: QS might be used with or without other QP components, in which -// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), -// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used -// with the other QP component, by simply including "qp_port.h" -//*before* "qs.h". -#ifndef QP_PORT_H_ -#include "qp_port.h" // use QS with QF -#endif - -#include "qs.h" // QS platform-independent public interface - -#endif // QS_PORT_H_ - diff --git a/test/qs/qs_rx/test.c b/test/qs/qs_rx/test.c deleted file mode 100644 index c3458116..00000000 --- a/test/qs/qs_rx/test.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "et.h" // ET: embedded test - -// includes for the CUT... -#include "qp_port.h" // QP port -#include "qsafe.h" // QP Functional Safety (FuSa) System -#ifdef Q_SPY // software tracing enabled? -#include "qs_port.h" // QS/C port from the port directory -#else -#include "qs_dummy.h" // QS/C dummy (inactive) interface -#endif - -enum { RX_SIZE = 8 }; - -static uint8_t qsBuf[100]; // buffer for QS-TX channel -static uint8_t qsRxBuf[RX_SIZE]; // buffer for QS-RX channel - -void setup(void) { -} - -void teardown(void) { -} - -// test group -------------------------------------------------------------- -TEST_GROUP("QS/RX") { - -QS_initBuf(qsBuf, sizeof(qsBuf)); - -TEST("QS-RX initialization") { - QS_rxInitBuf(qsRxBuf, RX_SIZE); - VERIFY(RX_SIZE - 1 == QS_rxGetNfree()); -} - -TEST("QS-RX putting 3") { - for (uint8_t n = 0U; n < 3U; ++n) { - VERIFY(QS_RX_PUT(n + 1U)); - } - VERIFY(RX_SIZE - 1 - 3 == QS_rxGetNfree()); -} - -TEST("QS-RX QS_rxParse") { - QS_rxParse(); - VERIFY(RX_SIZE - 1 == QS_rxGetNfree()); -} - -TEST("QS-RX putting 6") { - for (uint8_t n = 0U; n < 6U; ++n) { - VERIFY(QS_RX_PUT(n + 1U)); - } - VERIFY(RX_SIZE - 1 - 6 == QS_rxGetNfree()); -} - -TEST("QS-RX putting 3 more") { - VERIFY(QS_RX_PUT(0x7U)); - VERIFY(false == QS_RX_PUT(0x8U)); - VERIFY(false == QS_RX_PUT(0x9U)); - VERIFY(0 == QS_rxGetNfree()); -} - -} // TEST_GROUP() - -// ========================================================================= -// dependencies for the CUT ... - -//.......................................................................... -void QF_poolInit(void * const poolSto, uint_fast32_t const poolSize, - uint_fast16_t const evtSize) -{ - (void)poolSto; - (void)poolSize; - (void)evtSize; -} -//.......................................................................... -uint_fast16_t QF_poolGetMaxBlockSize(void) { - return 0U; -} -//.......................................................................... -void QActive_publish_(QEvt const * const e, - void const * const sender, uint_fast8_t const qsId) -{ - (void)e; - (void)sender; - (void)qsId; -} -//.......................................................................... -void QTimeEvt_tick_(uint_fast8_t const tickRate, void const * const sender) { - (void)tickRate; - (void)sender; -} -//.......................................................................... -QEvt *QF_newX_(uint_fast16_t const evtSize, - uint_fast16_t const margin, enum_t const sig) -{ - (void)evtSize; - (void)margin; - (void)sig; - - return (QEvt *)0; -} -//.......................................................................... -//! @static @public @memberof QF -void QF_gc(QEvt const * const e) { - (void)e; -} -//.......................................................................... -//! @static @private @memberof QF -QActive *QActive_registry_[QF_MAX_ACTIVE + 1U]; - -//.......................................................................... -Q_NORETURN Q_onError(char const * const module, int_t const location) { - ET_fail("Q_onError", module, location); - for (;;) {} // explicitly no-return -} - -//-------------------------------------------------------------------------- -#ifdef Q_SPY - -void QS_onCleanup(void) { -} -//.......................................................................... -void QS_onReset(void) { -} -//.......................................................................... -void QS_onFlush(void) { -} -//.......................................................................... -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)0U; -} -//.......................................................................... -void QS_onCommand(uint8_t cmdId, uint32_t param1, - uint32_t param2, uint32_t param3) -{ - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; -} - -#endif // Q_SPY diff --git a/test/qs/qs_rx/test.sln b/test/qs/qs_rx/test.sln deleted file mode 100644 index b0e72653..00000000 --- a/test/qs/qs_rx/test.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30804.86 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.ActiveCfg = Debug|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.Build.0 = Debug|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5927F686-5967-4B02-A7EA-25F81A1236DB} - EndGlobalSection -EndGlobal diff --git a/test/qs/qs_rx/test.vcxproj b/test/qs/qs_rx/test.vcxproj deleted file mode 100644 index 3ad94465..00000000 --- a/test/qs/qs_rx/test.vcxproj +++ /dev/null @@ -1,75 +0,0 @@ - - - - - Debug - Win32 - - - - - - - - - - - - - - - {8CC465F7-872E-4D03-B93C-1B64858B4E11} - test - Win32Proj - 10.0 - - - - Application - NotSet - v142 - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - - - - Disabled - .;../../../include;../../et;%(AdditionalIncludeDirectories) - Q_SPY;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - NotUsing - Level4 - ProgramDatabase - 4127 - Default - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - - \ No newline at end of file diff --git a/test/qs/qs_rx/test.vcxproj.filters b/test/qs/qs_rx/test.vcxproj.filters deleted file mode 100644 index ade04a60..00000000 --- a/test/qs/qs_rx/test.vcxproj.filters +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - src - - - src - - - et - - - et - - - src - - - - - {ca98b393-b6d6-4f0f-8d96-ee6821a59d87} - - - {e6ea87c4-df60-4f15-a5dc-c180c1cd2bac} - - - - - et - - - diff --git a/test/qxk/README.txt b/test/qxk/README.txt deleted file mode 100644 index 4b3125c3..00000000 --- a/test/qxk/README.txt +++ /dev/null @@ -1,13 +0,0 @@ -This directory contains tests of the QXK kernel. -These are SYSTEM tests, where QP is not stubbed-out, but -rather the actual QP code is used instead. - -NOTE: -The tests run only on embedded targets and do NOT -run on the host computer. - -NOTE: -To avoid stubbing-out the QP framework, the tests -define Q_UTEST=0 - - diff --git a/test/qxk/test_sched/bsp.h b/test/qxk/test_sched/bsp.h deleted file mode 100644 index ed5c7477..00000000 --- a/test/qxk/test_sched/bsp.h +++ /dev/null @@ -1,62 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing -// Last updated for version 7.3.0 -// Last updated on 2023-09-06 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -#ifndef BSP_H_ -#define BSP_H_ - -void BSP_init(void); -void BSP_terminate(int16_t result); - -// for testing... -void BSP_trace(QActive const *thr, char const *msg); -void BSP_wait4PB1(void); -void BSP_ledOn(void); -void BSP_ledOff(void); -void BSP_trigISR(void); - -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd); -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value); - -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd); -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value); - -enum TestSignals { - TEST0_SIG = Q_USER_SIG, - TEST1_SIG, - TEST2_SIG, - TEST3_SIG, - MAX_PUB_SIG, // the last published signal - - MAX_SIG // the last signal -}; - -#endif // BSP_H_ - diff --git a/test/qxk/test_sched/bsp_efm32pg1b.c b/test/qxk/test_sched/bsp_efm32pg1b.c deleted file mode 100644 index 53e015fe..00000000 --- a/test/qxk/test_sched/bsp_efm32pg1b.c +++ /dev/null @@ -1,372 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QXK kernel, EFM32-SLSTK3401A board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "em_device.h" // the device specific header (SiLabs) -#include "em_cmu.h" // Clock Management Unit (SiLabs) -#include "em_gpio.h" // GPIO (SiLabs) -#include "em_usart.h" // USART (SiLabs) -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE - -// ISRs defined in this BSP ------------------------------------------------ -void SysTick_Handler(void); -void GPIO_EVEN_IRQHandler(void); - -// Local-scope objects ----------------------------------------------------- -#define LED_PORT gpioPortF -#define LED0_PIN 4 -#define LED1_PIN 5 - -#define PB_PORT gpioPortF -#define PB0_PIN 6 -#define PB1_PIN 7 - -#ifdef Q_SPY - - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -//.......................................................................... -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - //QTICKER_TRIG(the_Ticker0, &l_SysTick_Handler); /* trigger ticker AO */ - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} -//.......................................................................... -void GPIO_EVEN_IRQHandler(void); // prototype -void GPIO_EVEN_IRQHandler(void) { // for testing, NOTE03 - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} - -//.......................................................................... -// MPU setup for EFM32PG1B200F256GM48 MCU -static void EFM32PG182_MPU_setup(void) { - // The following MPU configuration contains the general EFM32PG1 memory - // map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map - // - // Please note that the actual STM32 MCUs provide much less Flash and SRAM - // than the maximums configured here. This means that actual MCUs have - // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - // access these regions causes the HardFault exception, which is the - // desired behavior. - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) - 0x20000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 1U), // region #1 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - // region #3: (not configured) - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) - 0x40000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 3U), // region #3 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) - 0xE0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 4U), // region #4 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) - 0x60000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 5U), // region #5 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) - 0xA0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 6U), // region #6 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (7U << MPU_RASR_SIZE_Pos) // 2^(7+1)=256B region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - }; - - // enable the MemManage_Handler for MPU exception - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU - __ISB(); - __DSB(); -} - -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - EFM32PG182_MPU_setup(); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - // - SystemCoreClockUpdate(); - - // NOTE: The VFP (hardware Floating Point) unit is configured by QK - - // enable clock for to the peripherals used by this application... - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - - // configure the LEDs - GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); - GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); - GPIO_PinOutClear(LED_PORT, LED0_PIN); - GPIO_PinOutClear(LED_PORT, LED1_PIN); - - // configure the Buttons - GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); - GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - - // initialize the QS software tracing... - if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//.......................................................................... -void BSP_ledOn(void) { - GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); -} -//.......................................................................... -void BSP_ledOff(void) { - GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(GPIO_EVEN_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 // don't include the NULL-ptr region - : 0x40000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 // don't include the NULL-ptr region - : 0x40000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//.......................................................................... -void QF_onStartup(void) { - // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(GPIO_EVEN_IRQn); -} -//.......................................................................... -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW -//.......................................................................... -void QXK_onIdle(void) { - - GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); - -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -// QS callbacks ============================================================ -#ifdef Q_SPY - -//.......................................................................... -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). This works even though the -// Vector Table also resides at address 0x0. However, the *size* of the -// no-access region should not exceed the size of the Vector Table. In this -// case, the size is set to 2**(7+1)==256 bytes, which does not contain any -// data that the CPU would legitimately read with the LDR instruction. -// diff --git a/test/qxk/test_sched/bsp_nucleo-c031c6.c b/test/qxk/test_sched/bsp_nucleo-c031c6.c deleted file mode 100644 index 9d7db3bb..00000000 --- a/test/qxk/test_sched/bsp_nucleo-c031c6.c +++ /dev/null @@ -1,347 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QXK kernel, NUCLEO-C031C6 board -// Last updated for version 7.4.0 -// Last updated on 2024-06-24 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE - -// Local-scope objects ----------------------------------------------------- -// LED pins available on the board (just one user LED LD4--Green on PA.5) -#define LD4_PIN 5U - -// Button pins available on the board (just one user Button B1 on PC.13) -#define B1_PIN 13U - -#ifdef Q_SPY - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -// ISRs used in this project =============================================== -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_1_IRQHandler(void); // prototype -void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} - -// BSP functions =========================================================== - -static void STM32C031C6_MPU_setup(void) { - // The following MPU configuration contains the general STM32 memory model - // as described in the ST AppNote AN4838 "Managing memory protection unit - // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - // - // Please note that the actual STM32 MCUs provide much less Flash and SRAM - // than the maximums configured here. This means that actual MCUs have - // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - // access these regions causes the HardFault exception, which is the - // desired behavior. - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) - 0x20000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 1U), // region #1 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - // region #3: (not configured) - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) - 0x40000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 3U), // region #3 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) - 0xE0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 4U), // region #4 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) - 0x60000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 5U), // region #5 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) - 0xA0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 6U), // region #6 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) - // NOTE: this region extends to 0x080'0000, which is where - // the ROM is re-mapped by STM32 - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - }; - - __DSB(); - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region - | MPU_CTRL_ENABLE_Msk; // enable the MPU - __ISB(); - __DSB(); -} -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32C031C6_MPU_setup(); - - // initialize the QS software tracing... - if (QS_INIT((void *)0) == 0U) { - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//.......................................................................... -void BSP_ledOn(void) { - GPIOA->BSRR = (1U << LD4_PIN); // turn LD4 on -} -//.......................................................................... -void BSP_ledOff(void) { - GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LD4 off -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_1_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08008000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08008000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20003000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20003000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//============================================================================ -// QF callbacks... -void QF_onStartup(void) { - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - SystemCoreClockUpdate(); - - //NOTE: don't start ticking for these tests - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - // NOTE: this might have been changed by STM32Cube. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_1_IRQn); -} -//.......................................................................... -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//.......................................................................... -void QXK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -//============================================================================ -// QS callbacks... -#ifdef Q_SPY - -//.......................................................................... -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY -//---------------------------------------------------------------------------- - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2^(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qxk/test_sched/bsp_nucleo-h743zi.c b/test/qxk/test_sched/bsp_nucleo-h743zi.c deleted file mode 100644 index c354d956..00000000 --- a/test/qxk/test_sched/bsp_nucleo-h743zi.c +++ /dev/null @@ -1,300 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QXK kernel, NUCLEO-H743ZI board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -// STM32CubeH7 include files -#include "stm32h7xx_hal.h" -#include "stm32h7xx_nucleo_144.h" -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -// ISRs used in this project =============================================== -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_IRQHandler(void); // prototype -void EXTI0_IRQHandler(void) { // for testing, NOTE03 - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} - -// BSP functions =========================================================== -//.......................................................................... -// MPU setup for STM32H743ZI MCU -static void STM32H743ZI_MPU_setup(void) { - // The following MPU configuration contains just a generic ROM - // region (with read-only access) and NULL-pointer protection region. - // Otherwise, the MPU will fall back on the background region (PRIVDEFENA). - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) - // NOTE: this region extends to 0x080'0000, which is where - // the ROM is re-mapped by STM32 - // - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - }; - - // enable the MemManage_Handler for MPU exception - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU - | MPU_CTRL_PRIVDEFENA_Msk; // enable background region - __ISB(); - __DSB(); -} - -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32H743ZI_MPU_setup(); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - // - SystemCoreClockUpdate(); - - SCB_EnableICache(); // Enable I-Cache - SCB_EnableDCache(); // Enable D-Cache - - // Configure Flash prefetch and Instr. cache through ART accelerator -#if (ART_ACCLERATOR_ENABLE != 0) - __HAL_FLASH_ART_ENABLE(); -#endif // ART_ACCLERATOR_ENABLE - - // Configure the LEDs - BSP_LED_Init(LED1); - BSP_LED_Init(LED2); - BSP_LED_Init(LED3); - - // Configure the User Button in GPIO Mode - BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); - - if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//.......................................................................... -void BSP_ledOn(void) { - BSP_LED_On(LED1); -} -//.......................................................................... -void BSP_ledOff(void) { - BSP_LED_Off(LED1); -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//.......................................................................... -void QF_onStartup(void) { - // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - //NOTE: don't start ticking for these tests - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - // NOTE: this might have been changed by STM32Cube. - // - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system, see NOTE1 - // - // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - // - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_IRQn); -} -//.......................................................................... -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//.......................................................................... -void QXK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -// QS callbacks ============================================================ -#ifdef Q_SPY - -//.......................................................................... -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qxk/test_sched/bsp_nucleo-l053r8.c b/test/qxk/test_sched/bsp_nucleo-l053r8.c deleted file mode 100644 index 58b9e18e..00000000 --- a/test/qxk/test_sched/bsp_nucleo-l053r8.c +++ /dev/null @@ -1,365 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing QXK kernel, NUCLEO-L053R8 board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE - -// Local-scope objects ----------------------------------------------------- -// LED pins available on the board (just one user LED LD2--Green on PA.5) -#define LED_LD2 (1U << 5) - -// Button pins available on the board (just one user Button B1 on PC.13) -#define BTN_B1 (1U << 13) - -#ifdef Q_SPY - // QSpy source IDs - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -// ISRs used in this project =============================================== -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_1_IRQHandler(void); // prototype -void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} - -// BSP functions =========================================================== -static void STM32L053R8_MPU_setup(void) { - // The following MPU configuration contains the general STM32 memory model - // as described in the ST AppNote AN4838 "Managing memory protection unit - // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - // - // Please note that the actual STM32 MCUs provide much less Flash and SRAM - // than the maximums configured here. This means that actual MCUs have - // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - // access these regions causes the HardFault exception, which is the - // desired behavior. - // - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 0U), // region #0 - (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region - | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) - 0x20000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 1U), // region #1 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_C_Pos) // C=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - // region #3: (not configured) - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) - 0x40000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 3U), // region #3 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) - 0xE0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 4U), // region #4 - (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) - 0x60000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 5U), // region #5 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) - 0xA0000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 6U), // region #6 - (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region - | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw - | (1U << MPU_RASR_XN_Pos) // XN=1 - | (1U << MPU_RASR_S_Pos) // S=1 - | (1U << MPU_RASR_B_Pos) // B=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) - // NOTE: this region extends to 0x080'0000, which is where - // the ROM is re-mapped by STM32 - // - 0x00000000U // base address - | MPU_RBAR_VALID_Msk // valid region - | (MPU_RBAR_REGION_Msk & 7U), // region #7 - (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region - | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na - | (1U << MPU_RASR_XN_Pos) // XN=1 - | MPU_RASR_ENABLE_Msk // region enable - }, - - }; - - MPU->CTRL = 0U; // disable the MPU - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region - | MPU_CTRL_ENABLE_Msk; // enable the MPU - __ISB(); - __DSB(); -} -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32L053R8_MPU_setup(); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - // - SystemCoreClockUpdate(); - - // enable GPIOA clock port for the LED LD2 - RCC->IOPENR |= (1U << 0); - - // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - // enable GPIOC clock port for the Button B1 - RCC->IOPENR |= (1U << 2); - - // configure Button (PC.13) pins as input, no pull-up, pull-down - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - // initialize the QS software tracing... - if (QS_INIT((void *)0) == 0U) { - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//.......................................................................... -void BSP_ledOn(void) { - GPIOA->BSRR = (LED_LD2); // turn LED2 on -} -//.......................................................................... -void BSP_ledOff(void) { - GPIOA->BSRR = (LED_LD2 << 16); // turn LED2 off -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_1_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//.......................................................................... -void QF_onStartup(void) { - // DON'T set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_1_IRQn); -} -//.......................................................................... -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//.......................................................................... -void QXK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -// QS callbacks ============================================================ -#ifdef Q_SPY - -//.......................................................................... -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qxk/test_sched/bsp_nucleo-u545re.c b/test/qxk/test_sched/bsp_nucleo-u545re.c deleted file mode 100644 index 9ca2278c..00000000 --- a/test/qxk/test_sched/bsp_nucleo-u545re.c +++ /dev/null @@ -1,313 +0,0 @@ -//============================================================================ -// Product: BSP for system-testing of QXK kernel, NUCLEO-U545RE-Q board -// Last updated for version 7.4.0 -// Last updated on 2024-06-24 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -// -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: -// -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -#include "stm32u545xx.h" // CMSIS-compliant header file for the MCU used -// add other drivers if necessary... - -Q_DEFINE_THIS_FILE // define the name of this file for assertions - -// Local-scope defines ----------------------------------------------------- -// LED pins available on the board (just one user LED LD2--Green on PA.5) -#define LD2_PIN 5U - -// Button pins available on the board (just one user Button B1 on PC.13) -#define B1_PIN 13U - -// macros from STM32Cube LL: -#define SET_BIT(REG, BIT) ((REG) |= (BIT)) -#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) -#define READ_BIT(REG, BIT) ((REG) & (BIT)) -#define CLEAR_REG(REG) ((REG) = (0x0)) -#define WRITE_REG(REG, VAL) ((REG) = (VAL)) -#define READ_REG(REG) ((REG)) -#define MODIFY_REG(REG, CLEARMASK, SETMASK) \ - WRITE_REG((REG), ((READ_REG(REG) & (~(CLEARMASK))) | (SETMASK))) - -#ifdef Q_SPY -// QSpy source IDs -static QSpyId const l_SysTick_Handler = { 100U }; -static QSpyId const l_test_ISR = { 101U }; - -enum AppRecords { // application-specific trace records - CONTEXT_SW = QS_USER1, - TRACE_MSG -}; - -#endif - -// ISRs used in this project =============================================== -void SysTick_Handler(void); // prototype -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // process time events for rate 0 - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} -//.......................................................................... -void EXTI0_IRQHandler(void); // prototype -void EXTI0_IRQHandler(void) { // for testing, NOTE03 - QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR - - // for testing... - static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR -} - -// BSP functions =========================================================== -static void STM32U545RE_MPU_setup(void) { - MPU->CTRL = 0U; // disable the MPU - - MPU->RNR = 0U; // region 0 (for ROM: read-only, can-execute) - MPU->RBAR = (0x08000000U & MPU_RBAR_BASE_Msk) | (0x3U << MPU_RBAR_AP_Pos); - MPU->RLAR = (0x08080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - - MPU->RNR = 1U; // region 1 (for RAM1: read-write, execute-never) - MPU->RBAR = (0x20000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) - | MPU_RBAR_XN_Msk; - MPU->RLAR = (0x20040000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - - MPU->RNR = 2U; // region 2 (for RAM2: read-write, execute-never) - MPU->RBAR = (0x28000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) - | MPU_RBAR_XN_Msk; - MPU->RLAR = (0x28004000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - - MPU->RNR = 7U; // region 7 (no access: for NULL pointer protection) - MPU->RBAR = (0x00000000U & MPU_RBAR_BASE_Msk) | MPU_RBAR_XN_Msk; - MPU->RLAR = (0x00080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; - __DMB(); - - MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk; - - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - __ISB(); -} -//.......................................................................... -void BSP_init(void) { - // setup the MPU... - STM32U545RE_MPU_setup(); - - // initialize I-CACHE - MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, 0U); // 1-way - SET_BIT(ICACHE->CR, ICACHE_CR_EN); // enable - - // flash prefetch buffer enable - SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN); - - // enable PWR clock interface - SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_PWREN); - - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - SystemCoreClockUpdate(); - - // enable GPIOA clock port for the LED LD4 - RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOAEN; - - // set all used GPIOA pins as push-pull output, no pull-up, pull-down - MODIFY_REG(GPIOA->OSPEEDR, - GPIO_OSPEEDR_OSPEED0 << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos), - 1U << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos)); // speed==1 - MODIFY_REG(GPIOA->OTYPER, - 1U << LD2_PIN, - 0U << LD2_PIN); // output - MODIFY_REG(GPIOA->PUPDR, - GPIO_PUPDR_PUPD0 << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos), - 0U << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos)); // PUSHPULL - MODIFY_REG(GPIOA->MODER, - GPIO_MODER_MODE0 << (LD2_PIN * GPIO_MODER_MODE1_Pos), - 1U << (LD2_PIN * GPIO_MODER_MODE1_Pos)); // MODE_1 - - // enable GPIOC clock port for the Button B1 - RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOCEN; - - // configure Button B1 pin on GPIOC as input, no pull-up, pull-down - MODIFY_REG(GPIOC->PUPDR, - GPIO_PUPDR_PUPD0 << (B1_PIN * GPIO_PUPDR_PUPD1_Pos), - 0U << (B1_PIN * GPIO_PUPDR_PUPD1_Pos)); // NO PULL - MODIFY_REG(GPIOC->MODER, - GPIO_MODER_MODE0 << (B1_PIN * GPIO_MODER_MODE1_Pos), - 0U << (B1_PIN * GPIO_MODER_MODE1_Pos)); // MODE_0 - - // initialize the QS software tracing... - if (!QS_INIT((void *)0)) { - Q_ERROR(); - } - - // dictionaries... - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -//.......................................................................... -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -//............................................................................ -void BSP_ledOn(void) { - GPIOA->BSRR = (1U << LD2_PIN); // turn LED on -} -//............................................................................ -void BSP_ledOff(void) { - GPIOA->BRR = (1U << LD2_PIN); // turn LED off -} -//.......................................................................... -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_IRQn); -} -//.......................................................................... -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -//.......................................................................... -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08080000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -//.......................................................................... -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08080000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -//.......................................................................... -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20040000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -//.......................................................................... -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20040000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -//============================================================================ -// QF callbacks... -void QF_onStartup(void) { - // NOTE: SystemInit() has been already called from the startup code - // but SystemCoreClock needs to be updated - SystemCoreClockUpdate(); - - //NOTE: don't start ticking for these tests - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - // assign all priority bits for preemption-prio. and none to sub-prio. - // NOTE: this might have been changed by STM32Cube. - NVIC_SetPriorityGrouping(0U); - - // set priorities of ALL ISRs used in the system - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c - // ... - - // enable IRQs... - NVIC_EnableIRQ(EXTI0_IRQn); -} -//............................................................................ -void QF_onCleanup(void) { -} -//.......................................................................... -#ifdef QF_ON_CONTEXT_SW -// NOTE: the context-switch callback is called with interrupts DISABLED -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! - QS_OBJ(prev); - QS_OBJ(next); - QS_END_INCRIT() -} -#endif // QF_ON_CONTEXT_SW - -//............................................................................ -void QXK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); // parse all the received bytes - QS_doOutput(); -#elif defined NDEBUG - // Put the CPU and peripherals to the low-power mode. - // you might need to customize the clock management for your application, - // see the datasheet for your particular Cortex-M3 MCU. - // - __WFI(); // Wait-For-Interrupt -#endif -} - -//============================================================================ -// QS callbacks... -#ifdef Q_SPY - -//............................................................................ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - // TODO pend the SysTick - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif // Q_SPY -//---------------------------------------------------------------------------- - -//============================================================================ -// NOTE0: -// The MPU protection against NULL-pointer dereferencing sets up a no-access -// MPU region #7 around the NULL address (0x0). The size of this region is set -// to 2^(26+1)==0x0800'0000, because that is the address of Flash in STM32. -// -// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -// Table in it to address 0x0800'0000 at startup. However, even though the -// region 0..0x0800'0000 is un-mapped after the relocation, the read access -// is still allowed and causes no CPU exception. Therefore setting up the MPU -// to protect that region is necessary. -// diff --git a/test/qxk/test_sched/efm32pg1b.mak b/test/qxk/test_sched/efm32pg1b.mak deleted file mode 100644 index 566916c2..00000000 --- a/test/qxk/test_sched/efm32pg1b.mak +++ /dev/null @@ -1,336 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on EMF32, GNU-ARM -# Last Updated for Version: 7.3.0 -# Date of the Last Update: 2023-09-06 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f efm32pg1b.mak # make and run the tests in the current directory -# make -f efm32pg1b.mak TESTS=thr*.py # make and run the selected tests -# make -f efm32pg1b.mak HOST=localhost:7705 # connect to host:port -# make -f efm32pg1b.mak norun # only make but not run the tests -# make -f efm32pg1b.mak clean # cleanup the build -# make -f efm32pg1b.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := efm32 -TARGET_DIR := $(QPC)/3rd_party/efm32pg1b/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qxk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/efm32pg1b \ - $(QPC)/3rd_party/efm32pg1b/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/efm32pg1b - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_efm32pg1b.c \ - startup_efm32pg1b.c \ - system_efm32pg1b.c \ - em_cmu.c \ - em_emu.c \ - em_gpio.c \ - em_usart.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qxk.c \ - qxk_xthr.c \ - qxk_sema.c \ - qxk_mutex.c \ - qxk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DEFM32PG1B200F256GM48=1 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# FLASH tool (NOTE: Requires the JLINK utility) -# NOTE: substitution of '/' to '\' is necessary to run the batch file - -FLASH := $(subst /,\,$(TARGET_DIR)/flash.bat) - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(FLASH) $@ - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(FLASH) $(TARGET_BIN) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo FLASH = $(FLASH) - @echo TESTS = $(TESTS) - diff --git a/test/qxk/test_sched/nucleo-c031c6.mak b/test/qxk/test_sched/nucleo-c031c6.mak deleted file mode 100644 index c432df06..00000000 --- a/test/qxk/test_sched/nucleo-c031c6.mak +++ /dev/null @@ -1,339 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-C031c6, GNU-ARM -# Last Updated for Version: 7.2.2 -# Date of the Last Update: 2023-02-02 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-c031c6.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-c031c6.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-c031c6.mak HOST=localhost:7705 # connect to host:port -# make -f nucleo-c031c6.mak norun # only make but not run the tests -# make -f nucleo-c031c6.mak clean # cleanup the build -# make -f nucleo-c031c6.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-c031c6 -TARGET_DIR := $(QPC)/3rd_party/nucleo-c031c6/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qxk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/nucleo-c031c6 \ - $(QPC)/3rd_party/nucleo-c031c6/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/nucleo-c031c6 - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-c031c6.c \ - system_stm32c0xx.c \ - startup_stm32c031xx.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qxk.c \ - qxk_xthr.c \ - qxk_sema.c \ - qxk_mutex.c \ - qxk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DSTM32C031xx \ - -DQP_API_VERSION=9999 \ - -DQXK_USE_IRQ_HANDLER=Reserved1_IRQHandler \ - -DQXK_USE_IRQ_NUM=1 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m0plus -ARM_FPU := -FLOAT_ABI := - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qxk/test_sched/nucleo-c031c6.uvoptx b/test/qxk/test_sched/nucleo-c031c6.uvoptx deleted file mode 100644 index d83d823b..00000000 --- a/test/qxk/test_sched/nucleo-c031c6.uvoptx +++ /dev/null @@ -1,738 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc; *.md - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - qutest - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 1 - 0 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\uvision_nucleo-c031c6\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 18 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 6 - - - - - - - - - - - STLink\ST-LINKIII-KEIL_SWO.dll - - - - 0 - ST-LINKIII-KEIL_SWO - -U066BFF505153848667095842 -O207 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2 - - - 0 - UL2CM3 - -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0) - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=1173,620,1584,1122,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - - - 0 - 0 - 0 - 1 -
134223226
- 0 - 0 - 0 - 0 - 0 - 1 - - - -
- - 1 - 0 - 316 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - - -
- - 2 - 0 - 78 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - .\bsp_nucleo-c031c6.c - - -
- - 3 - 0 - 118 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - .\test_sched.c - - -
-
- - - 0 - 1 - QF_readySet_ - - - 1 - 1 - QXK_attr_ - - - 2 - 1 - thrX[0] - - - - - 1 - 2 - 0x20000200 - 0 - - - - - 2 - 0 - 0x400 - 0 - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - 1 - 0 - 0 - 2 - 10000000 - -
-
- - - test - 1 - 0 - 0 - 0 - - 1 - 1 - 5 - 0 - 0 - 0 - .\bsp.h - bsp.h - 0 - 0 - - - 1 - 2 - 1 - 0 - 0 - 0 - .\test_sched.c - test_sched.c - 0 - 0 - - - 1 - 3 - 1 - 0 - 0 - 0 - .\bsp_nucleo-c031c6.c - bsp_nucleo-c031c6.c - 0 - 0 - - - - - nucleo-c031c6 - 1 - 0 - 0 - 0 - - 2 - 4 - 2 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - startup_stm32c031xx.s - 0 - 0 - - - 2 - 5 - 5 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h - stm32c031xx.h - 0 - 0 - - - 2 - 6 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c - system_stm32c0xx.c - 0 - 0 - - - 2 - 7 - 5 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h - system_stm32c0xx.h - 0 - 0 - - - 2 - 8 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c - qutest_port.c - 0 - 0 - - - - - QP - 1 - 0 - 0 - 0 - - 3 - 9 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_hsm.c - qep_hsm.c - 0 - 0 - - - 3 - 10 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qep_msm.c - qep_msm.c - 0 - 0 - - - 3 - 11 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_act.c - qf_act.c - 0 - 0 - - - 3 - 12 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_actq.c - qf_actq.c - 0 - 0 - - - 3 - 13 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_defer.c - qf_defer.c - 0 - 0 - - - 3 - 14 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_dyn.c - qf_dyn.c - 0 - 0 - - - 3 - 15 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_mem.c - qf_mem.c - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_ps.c - qf_ps.c - 0 - 0 - - - 3 - 17 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qact.c - qf_qact.c - 0 - 0 - - - 3 - 18 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qeq.c - qf_qeq.c - 0 - 0 - - - 3 - 19 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_qmact.c - qf_qmact.c - 0 - 0 - - - 3 - 20 - 1 - 0 - 0 - 0 - ..\..\..\src\qf\qf_time.c - qf_time.c - 0 - 0 - - - 3 - 21 - 1 - 0 - 0 - 0 - ..\..\..\src\qxk\qxk.c - qxk.c - 0 - 0 - - - 3 - 22 - 1 - 0 - 0 - 0 - ..\..\..\src\qxk\qxk_mutex.c - qxk_mutex.c - 0 - 0 - - - 3 - 23 - 1 - 0 - 0 - 0 - ..\..\..\src\qxk\qxk_sema.c - qxk_sema.c - 0 - 0 - - - 3 - 24 - 1 - 0 - 0 - 0 - ..\..\..\src\qxk\qxk_xthr.c - qxk_xthr.c - 0 - 0 - - - - - QP_port - 1 - 0 - 0 - 0 - - 4 - 25 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qxk\armclang\qp_port.h - qp_port.h - 0 - 0 - - - 4 - 26 - 5 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qs_port.h - 0 - 0 - - - 4 - 27 - 1 - 0 - 0 - 0 - ..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - qxk_port.c - 0 - 0 - - - - - QS - 1 - 0 - 0 - 0 - - 5 - 28 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs.c - qs.c - 0 - 0 - - - 5 - 29 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - - - 5 - 30 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 5 - 31 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qs_rx.c - qs_rx.c - 0 - 0 - - - 5 - 32 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qstamp.c - qstamp.c - 0 - 0 - - - 5 - 33 - 1 - 0 - 0 - 0 - ..\..\..\src\qs\qutest.c - qutest.c - 0 - 0 - - - -
diff --git a/test/qxk/test_sched/nucleo-c031c6.uvprojx b/test/qxk/test_sched/nucleo-c031c6.uvprojx deleted file mode 100644 index 284d215f..00000000 --- a/test/qxk/test_sched/nucleo-c031c6.uvprojx +++ /dev/null @@ -1,594 +0,0 @@ - - - - 2.1 - -
### uVision Project, (C) Keil Software
- - - - qutest - 0x4 - ARM-ADS - 6190000::V6.19::ARMCLANG - 1 - - - STM32C031C6Tx - STMicroelectronics - Keil.STM32C0xx_DFP.1.0.0 - https://www.keil.com/pack/ - IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) - 0 - $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h - - - - - - - - - - $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\uvision_nucleo-c031c6\ - test - 1 - 0 - 0 - 1 - 1 - .\uvision_nucleo-c031c6\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 1 - 0 - cmd /c "del .\uvision_nucleo-c031c6\qstamp.o" - - 0 - 0 - 0 - 0 - - - 1 - 0 - fromelf --bin --output .\uvision_nucleo-c031c6\test.bin .\uvision_nucleo-c031c6\test.axf - - 0 - 0 - 0 - 0 - - 0 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 1 - - - SARMCM3.DLL - -REMAP-MPU - DARMCM1.DLL - -pCM0+ - SARMCM3.DLL - -MPU - TARMCM1.DLL - -pCM0+ - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4096 - - 1 - BIN\UL2CM3.DLL - "" () - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M0+" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 0 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x3000 - - - 1 - 0x8000000 - 0x8000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x8000000 - 0x8000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x3000 - - - 0 - 0x0 - 0x0 - - - - - - 0 - 1 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 1 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - - - Q_SPY, Q_UTEST=0,QXK_USE_IRQ_HANDLER=Reserved1_IRQHandler,QXK_USE_IRQ_NUM=1,QF_ON_CONTEXT_SW - - .;..\..\..\include;..\..\..\ports\arm-cm\qxk\armclang;..\..\..\3rd_party\CMSIS\Include,..\..\..\3rd_party\nucleo-c031c6 - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 4 - - - Stack_Size=2048 Heap_Size=16 - - - - - - 1 - 0 - 0 - 0 - 1 - 0 - 0x00000000 - 0x20000000 - - dpp-qk.sct - - - --entry Reset_Handler - - - - - - - - test - - - bsp.h - 5 - .\bsp.h - - - test_sched.c - 1 - .\test_sched.c - - - bsp_nucleo-c031c6.c - 1 - .\bsp_nucleo-c031c6.c - - - - - nucleo-c031c6 - - - startup_stm32c031xx.s - 2 - ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - - - stm32c031xx.h - 5 - ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h - - - system_stm32c0xx.c - 1 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c - - - system_stm32c0xx.h - 5 - ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h - - - qutest_port.c - 1 - ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c - - - - - QP - - - qep_hsm.c - 1 - ..\..\..\src\qf\qep_hsm.c - - - qep_msm.c - 1 - ..\..\..\src\qf\qep_msm.c - - - qf_act.c - 1 - ..\..\..\src\qf\qf_act.c - - - qf_actq.c - 1 - ..\..\..\src\qf\qf_actq.c - - - qf_defer.c - 1 - ..\..\..\src\qf\qf_defer.c - - - qf_dyn.c - 1 - ..\..\..\src\qf\qf_dyn.c - - - qf_mem.c - 1 - ..\..\..\src\qf\qf_mem.c - - - qf_ps.c - 1 - ..\..\..\src\qf\qf_ps.c - - - qf_qact.c - 1 - ..\..\..\src\qf\qf_qact.c - - - qf_qeq.c - 1 - ..\..\..\src\qf\qf_qeq.c - - - qf_qmact.c - 1 - ..\..\..\src\qf\qf_qmact.c - - - qf_time.c - 1 - ..\..\..\src\qf\qf_time.c - - - qxk.c - 1 - ..\..\..\src\qxk\qxk.c - - - qxk_mutex.c - 1 - ..\..\..\src\qxk\qxk_mutex.c - - - qxk_sema.c - 1 - ..\..\..\src\qxk\qxk_sema.c - - - qxk_xthr.c - 1 - ..\..\..\src\qxk\qxk_xthr.c - - - - - QP_port - - - qp_port.h - 5 - ..\..\..\ports\arm-cm\qxk\armclang\qp_port.h - - - qs_port.h - 5 - ..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - - - qxk_port.c - 1 - ..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - - - - - QS - - - qs.c - 1 - ..\..\..\src\qs\qs.c - - - qs_64bit.c - 1 - ..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\src\qs\qs_fp.c - - - qs_rx.c - 1 - ..\..\..\src\qs\qs_rx.c - - - qstamp.c - 1 - ..\..\..\src\qs\qstamp.c - - - qutest.c - 1 - ..\..\..\src\qs\qutest.c - - - - - - - - - - - - - - - - - uvision_c031c6 - 1 - nucleo-c031c6 - - - - -
diff --git a/test/qxk/test_sched/nucleo-h743zi.mak b/test/qxk/test_sched/nucleo-h743zi.mak deleted file mode 100644 index b6e48501..00000000 --- a/test/qxk/test_sched/nucleo-h743zi.mak +++ /dev/null @@ -1,350 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C on NUCLEO-H743ZI board, QUTEST, GNU-ARM -# Last Updated for Version: 7.3.0 -# Date of the Last Update: 2023-09-06 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-h743zi.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-h743zi.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-h743zi.mak USB=g: HOST=localhost:7705 # connect to host:port -# make -f nucleo-h743zi.mak USB=g: norun # only make but not run the tests -# make -f nucleo-h743zi.mak USB=g: clean # cleanup the build -# make -f nucleo-h743zi.mak USB=g: debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-h743zi -TARGET_DIR := $(QPC)/3rd_party/STM32CubeH7/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qxk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/STM32CubeH7/nucleo-h743zi/gnu \ - $(QPC)/3rd_party/STM32CubeH7/Drivers/BSP\STM32H7xx_Nucleo_144 \ - $(QPC)/3rd_party/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Src \ - $(QPC)/3rd_party/STM32CubeH7/Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/STM32CubeH7/Drivers/CMSIS/Device/ST/STM32H7xx/Include \ - -I$(QPC)/3rd_party/STM32CubeH7/Drivers/BSP/STM32H7xx_Nucleo_144 \ - -I$(QPC)/3rd_party/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-h743zi.c \ - startup_stm32h743xx.c \ - system_stm32h7xx.c \ - stm32h7xx_nucleo_144.c \ - stm32h7xx_hal.c \ - stm32h7xx_hal_cortex.c \ - stm32h7xx_hal_gpio.c \ - stm32h7xx_hal_pwr_ex.c \ - stm32h7xx_hal_rcc.c \ - stm32h7xx_hal_rcc_ex.c \ - stm32h7xx_hal_msp.c \ - stm32h7xx_hal_uart.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qxk.c \ - qxk_xthr.c \ - qxk_sema.c \ - qxk_mutex.c \ - qxk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DQP_API_VERSION=9999 \ - -DSTM32H743xx -DUSE_HAL_DRIVER -DUSE_STM32H7XX_NUCLEO_144 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m7 -ARM_FPU := -mfpu=fpv5-d16 -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qxk/test_sched/nucleo-l053r8.mak b/test/qxk/test_sched/nucleo-l053r8.mak deleted file mode 100644 index 6bf8aa9e..00000000 --- a/test/qxk/test_sched/nucleo-l053r8.mak +++ /dev/null @@ -1,336 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-L053R8, GNU-ARM -# Last Updated for Version: 7.3.1 -# Date of the Last Update: 2023-11-13 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-l053r8.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-l053r8.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-l053r8.mak HOST=localhost:7705 # connect to host:port -# make -f nucleo-l053r8.mak norun # only make but not run the tests -# make -f nucleo-l053r8.mak clean # cleanup the build -# make -f nucleo-l053r8.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-l053r8 -TARGET_DIR := $(QPC)/3rd_party/nucleo-l053r8/qutest - -#----------------------------------------------------------------------------- -# project directories: -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qxk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/nucleo-l053r8 \ - $(QPC)/3rd_party/nucleo-l053r8/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/nucleo-l053r8 - -#----------------------------------------------------------------------------- -# project files: -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-l053r8.c \ - system_stm32l0xx.c \ - startup_stm32l053xx.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qxk.c \ - qxk_xthr.c \ - qxk_sema.c \ - qxk_mutex.c \ - qxk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DSTM32L053xx \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m0plus -ARM_FPU := -FLOAT_ABI := - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qxk/test_sched/nucleo-u545re.mak b/test/qxk/test_sched/nucleo-u545re.mak deleted file mode 100644 index 5d336fdd..00000000 --- a/test/qxk/test_sched/nucleo-u545re.mak +++ /dev/null @@ -1,337 +0,0 @@ -############################################################################## -# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-U545RE-Q, GNU-ARM -# Last Updated for Version: 7.4.0 -# Date of the Last Update: 2024-06-23 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# make -f nucleo-u545re.mak USB=g: # make, upload to USB drive, run the tests -# make -f nucleo-u545re.mak USB=g: TESTS=philo*.py # make and run the selected tests -# make -f nucleo-u545re.mak HOST=localhost:7705 # connect to host:port -# make -f nucleo-u545re.mak norun # only make but not run the tests -# make -f nucleo-u545re.mak clean # cleanup the build -# make -f nucleo-u545re.mak debug # only run tests in DEBUG mode -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# https://github.com/QuantumLeaps/qtools -# - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project name, target name, target directory: -# -PROJECT := test_sched -TARGET := nucleo-u545re -TARGET_DIR := $(QPC)/3rd_party/nucleo-u545re/qutest - -#----------------------------------------------------------------------------- -# project directories -# - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# list of all source directories used by this project -VPATH := . \ - $(QPC)/src/qf \ - $(QPC)/src/qxk \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(TARGET_DIR) \ - $(QPC)/3rd_party/nucleo-u545re \ - $(QPC)/3rd_party/nucleo-u545re/gnu - -# list of all include directories needed by this project -INCLUDES = -I. \ - -I$(QPC)/include \ - -I$(QP_PORT_DIR) \ - -I$(TARGET_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/nucleo-u545re - -#----------------------------------------------------------------------------- -# project files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_sched.c \ - bsp_nucleo-u545re.c \ - system_stm32u5xx.c \ - startup_stm32u545retxq.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := $(TARGET_DIR)/qutest.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qxk.c \ - qxk_xthr.c \ - qxk_sema.c \ - qxk_mutex.c \ - qxk_port.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DSTM32U545xx \ - -DQP_API_VERSION=9999 \ - -DQF_ON_CONTEXT_SW - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m33 -ARM_FPU := -mfpu=fpv5-sp-d16 -FLOAT_ABI := -mfloat-abi=hard -mthumb - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-none-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ -AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The symbol USB must be provided for the NUCLEO board -# has enumerated as USB drive f: -# -ifeq ($(USB),) -$(error USB drive not provided for the NUCLEO board.) -endif - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in QTools for Windows), see: -# https://www.state-machine.com/qtools - -MKDIR := mkdir -RM := rm -CP := cp -SLEEP := sleep - -#----------------------------------------------------------------------------- -# QUTest test script utilities (requires QTOOLS): -# -ifeq ("$(wildcard $(QUTEST))","") -QUTEST := python3 $(QTOOLS)/qutest/qutest.py -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the sources... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := build_$(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - - -# NOTE: -# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT -# the QP-stub for testing QP itself -# -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - -CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -specs=nosys.specs -specs=nano.specs \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun debug flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(CP) $@ $(USB) - $(SLEEP) 2 - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(CP) $(TARGET_BIN) $(USB) - -run : $(TARGET_BIN) - $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -debug : - $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) - -.PHONY : clean show - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo MAKECMDGOALS = $(MAKECMDGOALS) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo HOST = $(HOST) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - diff --git a/test/qxk/test_sched/test_mpu.py b/test/qxk/test_sched/test_mpu.py deleted file mode 100644 index c1b8908d..00000000 --- a/test/qxk/test_sched/test_mpu.py +++ /dev/null @@ -1,99 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html/qutest.html - -note(''' -@uid{TQP701} -This test group verifies the memory access protection, -specifically the protection of various memory regions. -All tests run during the QS_TEST_PAUSE() in -the test_sched.c fixture. -''') - -# preamble -def on_reset(): - expect_pause() - # don't call continue_test() - -def on_setup(): - glb_filter(GRP_SC, GRP_UA) - -MEM_START = 0 -MEM_END = 1 - -# NULL-pointer dereferencing... -test(''' -NULL-read -> ASSERT -''') -command("MEM_READ", 0x0, 0x80) # value = *(uint32_t volatile *)(param1 + param2); -expect("@timestamp =ASSERT= Mod=*") - -test("NULL-write -> ASSERT") -command("MEM_WRITE", 0x0, 0xA0, 123) # *(uint32_t volatile *)(param1 + param2) = param3; -expect("@timestamp =ASSERT= Mod=*") - -# ROM_READ... -test("Below-Start Flash-read -> ASSERT") -command("ROM_READ", (-4 & 0xFFFFFFFF), MEM_START) # value = BSP_romRead(param1, param2); -expect("@timestamp =ASSERT= Mod=*") - -test("Start-of Flash-read") -command("ROM_READ", 0x0, MEM_START) # value = BSP_romRead(param1, param2); -expect("@timestamp USER+000 ROM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("Middle-of Flash-read", NORESET) -command("ROM_READ", 0x400, MEM_START) # value = BSP_romRead(param1, param2); -expect("@timestamp USER+000 ROM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("End-of Flash-read", NORESET) -command("ROM_READ", 0x0, MEM_END) # value = BSP_romRead(param1, param2); -expect("@timestamp USER+000 ROM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -skip(1) -test("After-End Flash-read-> ASSERT", NORESET) -command("ROM_READ", 0x4, MEM_END) # value = BSP_romRead(param1, param2); -expect("@timestamp =ASSERT= Mod=*") - -# ROM_WRITE... -test("Middle-of Flash-write -> ASSERT") -command("ROM_WRITE", 0x400, MEM_START, 123) # BSP_romWrite(param1, param2, param3); -expect("@timestamp =ASSERT= Mod=*") - -# RAM_READ... -test("Below-Start SRAM-read -> ASSERT") -command("RAM_READ", (-0x4 & 0xFFFFFFFF), MEM_START) # value = BSP_ramRead(param1, param2); -expect("@timestamp =ASSERT= Mod=*") - -test("Start-of SRAM-read") -command("RAM_READ", 0x0, MEM_START) # value = BSP_ramRead(param1, param2); -expect("@timestamp USER+000 RAM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("Middle-of SRAM-read", NORESET) -command("RAM_READ", 0x300, MEM_START) # value = BSP_ramRead(param1, param2); -expect("@timestamp USER+000 RAM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("End-of SRAM-read", NORESET) -command("RAM_READ", 0x0, MEM_END) # value = BSP_ramRead(param1, param2); -expect("@timestamp USER+000 RAM_READ *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -# RAM_WRITE... -test("Below-Start SRAM-write -> ASSERT", NORESET) -command("RAM_WRITE", (-0x4 & 0xFFFFFFFF), MEM_START, 123) # BSP_ramWrite(param1, param2, param3); -expect("@timestamp =ASSERT= Mod=*") - -# wrtiting to RAM does not need to be tested because the fact -# that the test fixture runs at all means that RAM works. -skip(1) -test("Middle-of SRAM-write") -command("RAM_WRITE", 0x300, MEM_START, 123) # BSP_ramWrite(param1, param2, param3); -expect("@timestamp USER+000 RAM_WRITE *") -expect("@timestamp Trg-Done QS_RX_COMMAND") - -test("After-End SRAM-write -> ASSERT") -command("RAM_WRITE", 0x4, MEM_END, 123) # BSP_ramWrite(param1, param2, param3); -expect("@timestamp =ASSERT= Mod=*") diff --git a/test/qxk/test_sched/test_sched.c b/test/qxk/test_sched/test_sched.c deleted file mode 100644 index 06d2ae71..00000000 --- a/test/qxk/test_sched/test_sched.c +++ /dev/null @@ -1,305 +0,0 @@ -//============================================================================ -// Product: System test fixture for QXK kernel -// Last Updated for Version: 7.3.0 -// Date of the Last Update: 2023-06-30 -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software -// -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -// -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Contact information: -// -// -//============================================================================ -#include "qpc.h" -#include "bsp.h" - -//Q_DEFINE_THIS_FILE - -//========================================================================== -// AO ObjB -enum { NUM_B = 3 }; - -typedef struct { - QActive super; -} ObjB; - -QState ObjB_initial(ObjB * const me, void const * const par); -QState ObjB_active(ObjB * const me, QEvt const * const e); - -void ObjB_ctor(ObjB * const me) { - QActive_ctor(&me->super, Q_STATE_CAST(&ObjB_initial)); -} - -//.......................................................................... -QState ObjB_initial(ObjB * const me, void const * const par) { - Q_UNUSED_PAR(par); - QActive_subscribe(&me->super, TEST1_SIG); - QActive_subscribe(&me->super, TEST2_SIG); - QS_FUN_DICTIONARY(&ObjB_active); - return Q_TRAN(&ObjB_active); -} -//.......................................................................... -QState ObjB_active(ObjB * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - case TEST0_SIG: { - BSP_trace(&me->super, "TEST0 1of2"); - BSP_trigISR(); - BSP_trace(&me->super, "TEST0 2of2"); - status_ = Q_HANDLED(); - break; - } - case TEST1_SIG: { - BSP_trace(&me->super, "TEST1 1of1"); - status_ = Q_HANDLED(); - break; - } - case TEST2_SIG: { - BSP_trace(&me->super, "TEST2 1of1"); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -//.......................................................................... -ObjB aoB[NUM_B]; - -//========================================================================== -enum { NUM_X = 3 }; - -enum UserCommands { - MEM_READ, MEM_WRITE, - ROM_READ, ROM_WRITE, - RAM_READ, RAM_WRITE, -}; - -//.......................................................................... -void ThrX_run(QXThread * const me) { - QActive_subscribe(&me->super, TEST1_SIG); - QActive_subscribe(&me->super, TEST2_SIG); - - for (;;) { - QEvt const *e = QXThread_queueGet(QXTHREAD_NO_TIMEOUT); - switch (e->sig) { - case TEST0_SIG: { - BSP_trace(&me->super, "TEST0 1of2"); - BSP_trigISR(); - BSP_trace(&me->super, "TEST0 2of2"); - break; - } - case TEST1_SIG: { - static QEvt const t2 = QEVT_INITIALIZER(TEST2_SIG); - BSP_trace(&me->super, "TEST1 1of2"); - QACTIVE_PUBLISH(&t2, &me->super); - BSP_trace(&me->super, "TEST1 2of2"); - break; - } - case TEST2_SIG: { - BSP_trace(&me->super, "TEST2 1of1"); - break; - } - default: { - break; - } - } - } -} - -//.......................................................................... -QXThread thrX[NUM_X]; - -//========================================================================== -int main() { - QF_init(); // initialize the framework and the underlying QXK kernel - BSP_init(); // initialize the Board Support Package - - // initialize publish-subscribe... - static QSubscrList subscrSto[MAX_PUB_SIG]; - QActive_psInit(subscrSto, Q_DIM(subscrSto)); - - // initialize event pools... - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // small pool - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - // dictionaries - QS_SIG_DICTIONARY(TEST0_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST1_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST2_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST3_SIG, (void *)0); - - QS_ENUM_DICTIONARY(MEM_READ, QS_CMD); - QS_ENUM_DICTIONARY(MEM_WRITE, QS_CMD); - QS_ENUM_DICTIONARY(ROM_READ, QS_CMD); - QS_ENUM_DICTIONARY(ROM_WRITE, QS_CMD); - QS_ENUM_DICTIONARY(RAM_READ, QS_CMD); - QS_ENUM_DICTIONARY(RAM_WRITE, QS_CMD); - - // priority specifications for ObjBs... - static QPrioSpec pspecB[NUM_B]; - QS_OBJ_DICTIONARY(pspecB); - - // priority specifications for ThrXs... - static QPrioSpec pspecX[NUM_X]; - QS_OBJ_DICTIONARY(pspecX); - - uint8_t n; - for (n = 0U; n < NUM_B; ++n) { - QS_OBJ_ARR_DICTIONARY(&aoB[n], n); - pspecB[n] = n + 1U; - } - for (n = 0U; n < NUM_X; ++n) { - QS_OBJ_ARR_DICTIONARY(&thrX[n], n); - pspecX[n] = NUM_B + 1U + n; - } - - // pause execution of the test and wait for the test script to continue - // NOTE: - // this pause gives the test-script a chance to poke pspecB and pspecX - // variables to start the threads with the desired prio-specifications. - QS_TEST_PAUSE(); - - static QEvt const *aoB_queueSto[NUM_B][5]; - for (n = 0U; n < NUM_B; ++n) { - if (pspecB[n] != 0U) { - ObjB_ctor(&aoB[n]); // instantiate the AO - QActive_start(&aoB[n].super, // AO to start - pspecB[n], // QF-prio/p-thre. - aoB_queueSto[n], // event queue storage - Q_DIM(aoB_queueSto[n]), // event length [events] - (void *)0, // no stack storage - 0U, // zero stack size [bytes] - (void *)0); // initialization param - } - } - - static QEvt const *thrX_queueSto[NUM_X][5]; - static uint64_t thrXStackSto[NUM_X][32]; - for (n = 0U; n < NUM_X; ++n) { - QXThread_ctor(&thrX[n], &ThrX_run, 0U); // instantiate the thread - if (pspecX[n] != 0U) { - QXThread_start(&thrX[n], // thread to start - pspecX[n], // QF-prio/p-thre. - thrX_queueSto[n], // event queue storage - Q_DIM(thrX_queueSto[n]), // event length [events] - thrXStackSto[n], // stack storage - sizeof(thrXStackSto[n]), // stack size [bytes] - (void *)0); // initialization param - } - } - return QF_run(); // run the QF application -} - -//========================================================================== -void QS_onTestSetup(void) { -} -//.......................................................................... -void QS_onTestTeardown(void) { -} -//.......................................................................... -//! callback function to execute user commands -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - uint32_t volatile value; - - switch (cmdId) { - case MEM_READ: { // read MEM (can trip the MPU) - value = *(uint32_t volatile *)(param1 + param2); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(0, value); - QS_END() - break; - } - case MEM_WRITE: { // write MEM (can trip the MPU) - *(uint32_t volatile *)(param1 + param2) = param3; - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(QS_HEX_FMT , param1); - QS_U32(QS_HEX_FMT , param2); - QS_U32(0 , param3); - QS_END() - break; - } - case ROM_READ: { // read ROM (can trip the MPU) - value = BSP_romRead((int32_t)param1, param2); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(0, value); - QS_END() - break; - } - case ROM_WRITE: { // write ROM (can trip the MPU) - BSP_romWrite(param1, param2, param3); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(QS_HEX_FMT , param1); - QS_U32(QS_HEX_FMT , param2); - QS_U32(0 , param3); - QS_END() - break; - } - case RAM_READ: { // read RAM (can trip the MPU) - value = BSP_ramRead(param1, param2); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(0, value); - QS_END() - break; - } - case RAM_WRITE: { // write RAM (can trip the MPU) - BSP_ramWrite(param1, param2, param3); - QS_BEGIN_ID(QS_USER, 0U) - QS_ENUM(QS_CMD, cmdId); - QS_U32(QS_HEX_FMT , param1); - QS_U32(QS_HEX_FMT , param2); - QS_U32(0, param3); - QS_END() - break; - } - default: { - break; - } - } -} - -//**************************************************************************** -//! Host callback function to "massage" the event, if necessary -void QS_onTestEvt(QEvt *e) { - Q_UNUSED_PAR(e); -} -//.......................................................................... -//! callback function to output the posted QP events (not used here) -void QS_onTestPost(void const *sender, QActive *recipient, - QEvt const *e, bool status) -{ - Q_UNUSED_PAR(sender); - Q_UNUSED_PAR(status); -} - diff --git a/test/qxk/test_sched/test_sched.py b/test/qxk/test_sched/test_sched.py deleted file mode 100644 index e0a84e19..00000000 --- a/test/qxk/test_sched/test_sched.py +++ /dev/null @@ -1,156 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html/qutest.html - -note(''' -This test group verifies the preemption tests -in the QXK preemptive kernel -''') - -# preamble -def on_reset(): - expect_pause() - # don't call continue_test() yet - # this will be done by the individual tests - # after they poke the priorities of threads - -test("extened->basic") -# given... -current_obj(OBJ_AP, "pspecB") -poke(0, 2, pack("1") -expect("@timestamp CONTEXT_SW NULL thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST0 1of2") -expect("@timestamp Sch-Next Pri=1->4") -expect("@timestamp CONTEXT_SW thrX[0] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 1of1") -expect("@timestamp Sch-Next Pri=4->1") -expect("@timestamp CONTEXT_SW aoB[0] thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST0 2of2") -expect("@timestamp TRACE_MSG thrX[0] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->4") -expect("@timestamp Sch-Unlk Ceil=4->0") -expect("@timestamp Sch-Next Pri=1->4") -expect("@timestamp CONTEXT_SW thrX[0] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp Sch-Next Pri=4->1") -expect("@timestamp CONTEXT_SW aoB[0] thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST1 2of2") -expect("@timestamp TRACE_MSG thrX[0] TEST2 1of1") -expect("@timestamp Sch-Idle Pri=1->0") -expect("@timestamp CONTEXT_SW thrX[0] NULL") -expect("@timestamp Trg-Done QS_RX_EVENT") - - -test("extended->extened->basic") -# given... -current_obj(OBJ_AP, "pspecB") -poke(0, 2, pack("4") -expect("@timestamp CONTEXT_SW NULL thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST0 1of2") -expect("@timestamp Sch-Next Pri=4->5") -expect("@timestamp CONTEXT_SW thrX[0] thrX[1]") -expect("@timestamp TRACE_MSG thrX[1] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->5") -expect("@timestamp Sch-Unlk Ceil=5->0") -expect("@timestamp TRACE_MSG thrX[1] TEST1 2of2") -expect("@timestamp TRACE_MSG thrX[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=5->4") -expect("@timestamp CONTEXT_SW thrX[1] thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST0 2of2") -expect("@timestamp TRACE_MSG thrX[0] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->5") -expect("@timestamp Sch-Unlk Ceil=5->0") -expect("@timestamp Sch-Next Pri=4->5") -expect("@timestamp CONTEXT_SW thrX[0] thrX[1]") -expect("@timestamp TRACE_MSG thrX[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=5->4") -expect("@timestamp CONTEXT_SW thrX[1] thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST1 2of2") -expect("@timestamp TRACE_MSG thrX[0] TEST2 1of1") -expect("@timestamp TRACE_MSG thrX[0] TEST2 1of1") -expect("@timestamp Sch-Next Pri=4->3") -expect("@timestamp CONTEXT_SW thrX[0] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST1 1of1") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST1 1of1") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=2->1") -expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp Sch-Idle Pri=1->0") -expect("@timestamp CONTEXT_SW aoB[0] NULL") -expect("@timestamp Trg-Done QS_RX_EVENT") - - -test("extened->basic->extended") -# given... -current_obj(OBJ_AP, "pspecB") -poke(0, 2, pack("1") -expect("@timestamp CONTEXT_SW NULL thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST0 1of2") -expect("@timestamp Sch-Next Pri=1->5") -expect("@timestamp CONTEXT_SW thrX[0] thrX[1]") -expect("@timestamp TRACE_MSG thrX[1] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->5") -expect("@timestamp Sch-Unlk Ceil=5->0") -expect("@timestamp TRACE_MSG thrX[1] TEST1 2of2") -expect("@timestamp TRACE_MSG thrX[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=5->4") -expect("@timestamp CONTEXT_SW thrX[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp Sch-Next Pri=4->1") -expect("@timestamp CONTEXT_SW aoB[0] thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST0 2of2") -expect("@timestamp TRACE_MSG thrX[0] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->5") -expect("@timestamp Sch-Unlk Ceil=5->0") -expect("@timestamp Sch-Next Pri=1->5") -expect("@timestamp CONTEXT_SW thrX[0] thrX[1]") -expect("@timestamp TRACE_MSG thrX[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=5->4") -expect("@timestamp CONTEXT_SW thrX[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp Sch-Next Pri=4->1") -expect("@timestamp CONTEXT_SW aoB[0] thrX[0]") -expect("@timestamp TRACE_MSG thrX[0] TEST1 2of2") -expect("@timestamp TRACE_MSG thrX[0] TEST2 1of1") -expect("@timestamp TRACE_MSG thrX[0] TEST2 1of1") -expect("@timestamp Sch-Idle Pri=1->0") -expect("@timestamp CONTEXT_SW thrX[0] NULL") -expect("@timestamp Trg-Done QS_RX_EVENT") diff --git a/zephyr/qf_port.c b/zephyr/qf_port.c index 92075d9d..ec4c24b2 100644 --- a/zephyr/qf_port.c +++ b/zephyr/qf_port.c @@ -1,29 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_7_4_0 +//! @date Last updated on: 2024-09-26 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QF/C port to Zephyr RTOS (v 3.1.99) @@ -47,6 +50,10 @@ struct k_spinlock QF_spinlock; //............................................................................ void QF_init(void) { QF_spinlock = (struct k_spinlock){}; + + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + QTimeEvt_init(); // initialize QTimeEvts } //............................................................................ int_t QF_run(void) { @@ -63,8 +70,8 @@ int_t QF_run(void) { // produce the QS_QF_RUN trace record QS_CRIT_STAT QS_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_RUN, 0U) + QS_END_PRE() QS_CRIT_EXIT(); // perform QS work... @@ -115,16 +122,16 @@ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { //............................................................................ void QActive_start(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, + QEvtPtr * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO me->pthre = 0U; // preemption-threshold (not used for AO registration) - QActive_register_(me); // register this AO + QActive_register_(me); // make QF aware of this active object // initialize the Zephyr message queue - k_msgq_init(&me->eQueue, (char *)qSto, sizeof(QEvt *), (uint32_t)qLen); + k_msgq_init(&me->eQueue, (char *)qSto, sizeof(QEvtPtr), (uint32_t)qLen); // top-most initial tran. (virtual call) (*me->super.vptr->init)(&me->super, par, me->prio); @@ -185,6 +192,12 @@ bool QActive_post_(QActive * const me, QEvt const * const e, { QF_CRIT_STAT QF_CRIT_ENTRY(); + + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + // NOTE: k_msgq_num_free_get() can be safely called from crit-section uint_fast16_t nFree = (uint_fast16_t)k_msgq_num_free_get(&me->eQueue); @@ -195,7 +208,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e, } else { status = false; // cannot post - Q_ERROR_INCRIT(510); // must be able to post the event + Q_ERROR_INCRIT(210); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { @@ -207,38 +220,41 @@ bool QActive_post_(QActive * const me, QEvt const * const e, if (status) { // can post the event? - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count - QS_EQC_PRE_(nFree); // # free entries available - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count + QS_EQC_PRE(nFree); // # free entries available + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter } - QF_CRIT_EXIT(); + QF_CRIT_EXIT(); // exit crit.sect. before calling Zephyr API int err = k_msgq_put(&me->eQueue, (void const *)&e, K_NO_WAIT); + QF_CRIT_ENTRY(); // re-enter crit.sect. after calling Zephyr API // posting to the Zephyr message queue must succeed, see NOTE1 - QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(520, err == 0); + Q_ASSERT_INCRIT(220, err == 0); +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif } else { - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); // timestamp - QS_OBJ_PRE_(sender); // the sender object - QS_SIG_PRE_(e->sig); // the signal of the event - QS_OBJ_PRE_(me); // this active object (recipient) - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count - QS_EQC_PRE_(nFree); // # free entries available - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(nFree); // # free entries available + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() } QF_CRIT_EXIT(); @@ -249,50 +265,60 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id & ref-Count - QS_EQC_PRE_(k_msgq_num_free_get(&me->eQueue)); // # free entries - QS_EQC_PRE_(0U); // min # free entries (unknown) - QS_END_PRE_() + Q_REQUIRE_INCRIT(300, e != (QEvt *)0); +#ifndef Q_UNSAFE + Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); +#endif // ndef Q_UNSAFE + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(k_msgq_num_free_get(&me->eQueue)); // # free entries + QS_EQC_PRE(0U); // min # free entries (unknown) + QS_END_PRE() if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? QEvt_refCtr_inc_(e); // increment the reference counter } - QF_CRIT_EXIT(); // NOTE: Zephyr message queue does not currently support LIFO posting // so normal FIFO posting is used instead. + QF_CRIT_EXIT(); // exit crit.sect. before calling Zephyr API int err = k_msgq_put(&me->eQueue, (void *)&e, K_NO_WAIT); + QF_CRIT_ENTRY(); // re-enter crit.sect. after calling Zephyr API + + Q_ASSERT_INCRIT(310, err == 0); +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif - QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(710, err == 0); QF_CRIT_EXIT(); } //............................................................................ QEvt const *QActive_get_(QActive * const me) { - // wait for an event (forever) - QEvt const *e; + QEvtPtr e; int err = k_msgq_get(&me->eQueue, (void *)&e, K_FOREVER); - // queue-get must succeed QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(810, err == 0); - QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); // timestamp - QS_SIG_PRE_(e->sig); // the signal of this event - QS_OBJ_PRE_(me); // this active object - QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id & ref-Count - QS_EQC_PRE_(k_msgq_num_free_get(&me->eQueue));// # free entries - QS_END_PRE_() + Q_ASSERT_INCRIT(410, err == 0); // queue-get must succeed +#ifdef Q_UNSAFE + Q_UNUSED_PAR(err); +#endif + + QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_EQC_PRE(k_msgq_num_free_get(&me->eQueue));// # free entries + QS_END_PRE() QF_CRIT_EXIT(); return e; } - diff --git a/zephyr/qp_port.h b/zephyr/qp_port.h index 6ba4e628..c6e7e65f 100644 --- a/zephyr/qp_port.h +++ b/zephyr/qp_port.h @@ -1,34 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) // +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC . -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// This software is dual-licensed under the terms of the open source GNU -// General Public License version 3 (or any later version), or alternatively, -// under the terms of one of the closed source Quantum Leaps commercial -// licenses. -// -// The terms of the open source GNU General Public License version 3 -// can be found at: -// -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// The QP/C software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL (see ) does NOT permit the +// incorporation of the QP/C software into proprietary programs. Please +// contact Quantum Leaps for commercial licensing options, which expressly +// supersede the GPL and are designed explicitly for licensees interested +// in using QP/C in closed-source proprietary applications. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-12 -//! @version Last updated for: Zephyr 3.4 and @ref qpc_7_3_0 +//! @date Last updated on: 2023-09-30 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QP/C port to Zephyr RTOS @@ -38,8 +38,8 @@ #include // Exact-width types. WG14/N843 C99 Standard #include // Boolean type. WG14/N843 C99 Standard +#include "qp_config.h" // QP configuration from the application #include // Zephyr kernel API -#include "qp_config.h" // external QP configuration // no-return function specifier (C11 Standard) #define Q_NORETURN _Noreturn void @@ -62,15 +62,16 @@ #endif // include files ------------------------------------------------------------- -#include "qequeue.h" // used for event deferral -#include "qmpool.h" // this QP port uses the native QF memory pool -#include "qp.h" // QP platform-independent public interface +#include "qequeue.h" // used for event deferral +#include "qmpool.h" // this QP port uses the native QF memory pool +#include "qp.h" // QP platform-independent public interface // Zephyr spinlock for QF critical section extern struct k_spinlock QF_spinlock; //============================================================================ // interface used only inside QF implementation, but not in applications + #ifdef QP_IMPL // scheduler locking, see NOTE2 diff --git a/zephyr/qs_port.h b/zephyr/qs_port.h index 7895e109..cdb29f7d 100644 --- a/zephyr/qs_port.h +++ b/zephyr/qs_port.h @@ -28,7 +28,7 @@ // //============================================================================ //! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_7_4_0 +//! @version Last updated for: @ref qpc_8_0_0 //! //! @file //! @brief QS/C port to a 32-bit CPU and a generic C99 compiler.