This commit is contained in:
MMS 2024-10-15 13:15:11 -04:00
parent d3f94c7783
commit efec63749b
244 changed files with 5591 additions and 44698 deletions

24
.gitignore vendored
View File

@ -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/

@ -1 +1 @@
Subproject commit aca09a2e3571adf97e5ce6cb5b1d645ba2418c1d
Subproject commit 43a99789efed81bd200558e742623745822c779a

View File

@ -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.

View File

@ -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 <state-machine.com>.
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 <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 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

View File

@ -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)
<p align="center">
<img src="https://www.state-machine.com/img/github-star.jpg"/><br>
</p>
[RTEF]: <https://www.state-machine.com/rtef>
[QP]: <https://www.state-machine.com/products/qp>
[QP/C]: <https://github.com/QuantumLeaps/qpc>
[QP/C++]: <https://github.com/QuantumLeaps/qpcpp>
[QS/C]: <https://www.state-machine.com/qpc/srs-qp_qs.html>
[QV]: <https://www.state-machine.com/qpc/srs-qp_qv.html>
[QK]: <https://www.state-machine.com/qpc/srs-qp_qk.html>
[QXK]: <https://www.state-machine.com/qpc/srs-qp_qxk.html>
[QM]: <https://github.com/QuantumLeaps/qm>
[QTools]: <https://github.com/QuantumLeaps/qtools>
[QP-Rel]: <https://github.com/QuantumLeaps/qpc/releases>
@ -153,6 +172,7 @@ If you like this project, please give it a star (in the upper-right corner of yo
[HSM]: <https://www.state-machine.com/qpc/srs-qp_sm.html>
[Lic]: <https://www.state-machine.com/licensing>
[Cust]: <https://www.state-machine.com/customers>
[Sup]: <mailto:support@state-machine.com>
[AN]: <https://www.state-machine.com/doc/AN_Getting_Started_with_QP.pdf>
[Tutorial]: <https://www.state-machine.com/qpc/gs_tut.html>
[Video]: <https://youtu.be/O7ER6_VqIH0>

View File

@ -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`.

@ -1 +1 @@
Subproject commit 16ea07cc4dbcbde83431a9962cf4ec157b951dcf
Subproject commit f505eec147a61e8a10f725bf343f914b5cedb57c

45
include/README.md Normal file
View File

@ -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]: <https://www.state-machine.com/licensing>
[Cust]: <https://www.state-machine.com/customers>
[Sup]: <mailto:support@state-machine.com>

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qequeue.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
@ -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

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qk.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
@ -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

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qmpool.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
@ -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:

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qp.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
@ -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,

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qp_pkg.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
@ -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_

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qpc.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
@ -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_

File diff suppressed because it is too large Load Diff

View File

@ -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 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
//$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

View File

@ -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 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
//
// 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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//
//$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_

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qsafe.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qstamp.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//

View File

@ -3,17 +3,10 @@
// Model: qpc.qm
// File: ${include::qv.h}
//
// This code has been generated by QM 6.2.0 <www.state-machine.com/qm>.
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
// 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: <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 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>
//
@ -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

View File

@ -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 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
//
// 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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//
//$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_

View File

@ -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})

63
ports/README.md Normal file
View File

@ -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]: <https://www.state-machine.com/customers>
[sup]: <mailto:support@state-machine.com>

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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...

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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);

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
#ifndef QP_CONFIG_H_
@ -34,17 +32,10 @@
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
// <n>NOTE: Requires command-line macro: QP_CONFIG
// <i>This qp_config.h header file is activated only when the macro
// <i>QP_CONFIG is defined on the command-line to the compiler
// <n>-------------------------------------------
// <o>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)
// <i>QP API backwards compatibility with the QP/C API version.
// <i>Lower QP_API_VERSION values enable backwards compatibility
@ -158,7 +149,6 @@
// <o>Event queue counter size (QF_EQUEUE_CTR_SIZE)
// <1U=>1 (default)
// <2U=>2
// <4U=>4
// <i>Size of event queue counter [bytes]
// <i>Default: 1 (255 events maximum in a queue)
#define QF_EQUEUE_CTR_SIZE 1U
@ -244,8 +234,8 @@
// <i>If enabled, provide the otherwise unused IRQ number (QK_USE_IRQ_NUM)
// <i>and the corresponding IRQ handler name (QK_USE_IRQ_HANDLER)
// <i>in the "Text Editor" mode.
//#define QK_USE_IRQ_NUM 31
//#define QK_USE_IRQ_HANDLER Reserved31_IRQHandler
//#define QK_USE_IRQ_NUM <adjust to your MCU>
//#define QK_USE_IRQ_HANDLER <adjust to your MCU>
// </c>
// </h>

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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...

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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];
}

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <intrinsics.h> // 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_

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -1,100 +0,0 @@
//============================================================================
// QP/C Real-Time Embedded Framework (RTEF)
// 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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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_

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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...

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
#ifndef QP_CONFIG_H_
@ -34,17 +32,10 @@
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
// <n>NOTE: Requires command-line macro: QP_CONFIG
// <i>This qp_config.h header file is activated only when the macro
// <i>QP_CONFIG is defined on the command-line to the compiler
// <n>-------------------------------------------
// <o>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)
// <i>QP API backwards compatibility with the QP/C API version.
// <i>Lower QP_API_VERSION values enable backwards compatibility
@ -158,7 +149,6 @@
// <o>Event queue counter size (QF_EQUEUE_CTR_SIZE)
// <1U=>1 (default)
// <2U=>2
// <4U=>4
// <i>Size of event queue counter [bytes]
// <i>Default: 1 (255 events maximum in a queue)
#define QF_EQUEUE_CTR_SIZE 1U

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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...

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <intrinsics.h> // 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_

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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 <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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];
}

View File

@ -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 <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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_

View File

@ -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 <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stddef.h> // 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

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
#ifndef QP_CONFIG_H_
#define QP_CONFIG_H_
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
// <n>NOTE: Requires command-line macro: QP_CONFIG
// <i>This qp_config.h header file is activated only when the macro
// <i>QP_CONFIG is defined on the command-line to the compiler
// <n>-------------------------------------------
// <o>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)
// <i>QP API backwards compatibility with the QP/C API version.
// <i>Lower QP_API_VERSION values enable backwards compatibility
// <i>with lower (older) QP API versions.
// <i>For example, QP_API_VERSION==691 will enable the compatibility
// <i>layer with QP version 6.9.1 and newer, but not older than 6.9.1.
// <i>QP_API_VERSION==0 enables the maximum currently supported
// <i>backwards compatibility. Conversely, QP_API_VERSION==9999 means
// <i>that no backwards compatibility layer should be enabled.
// <i>Default: 0 (All supported)
#define QP_API_VERSION 0
//..........................................................................
// <h>QP Functional Safety (FuSa) Subsystem (Q_UNSAFE)
// <i>The QP FuSa Subsystem consists of the following facilities:
// <i>- Software assertions as a recommended technique
// <i> (called Failure Assertion Programming (FAP) in IEC 61508)
// <i>- Software Self-Monitoring (SSM), which encompasses such techniques:
// <i> * Duplicate Inverse Storage for critical variables
// <i> * Memory Markers for critical objects (e.g., events)
// <i> * Hard-limits for all loops
// <i> * Memory Isolation by means of Memory Protection Unit (MPU)
// <c3>Disable QP FuSa in development
// <i>Disable assertions and other self monitoring features
// <i>in development build configurations (NDEBUG undefined).
// <i>VIOLATES functional safety standards. NOT recommended !!!
//#ifndef NDEBUG
//#define Q_UNSAFE
//#endif
// </c>
// <c3>Disable QP FuSa in production release
// <i>Disable assertions and other self monitoring features
// <i>in the release build configurations (NDEBUG defined).
// <i>VIOLATES functional safety standards. NOT recommended !!!
//#ifdef NDEBUG
//#define Q_UNSAFE
//#endif
// </c>
// </h>
//..........................................................................
// <h>QEP Event Processor
// <i>Events and state machines.
// <o>Event signal size (Q_SIGNAL_SIZE)
// <1U=>1
// <2U=>2 (default)
// <4U=>4
// <i>Size of the QEvt signal for QEP/QF [bytes]
// <i>Default: 2
#define Q_SIGNAL_SIZE 2U
// </h>
//..........................................................................
// <h>QF Framework
// <i>Active Object framework
// <o>Maximum # Active Objects (QF_MAX_ACTIVE) <1-64>
// <i>Maximum # Active Objects in the system <1..64>
// <i>Default: 32
#define QF_MAX_ACTIVE 32U
// <o>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
// <i>Maximum # Event Pools <1..15>
// <i>Default: 3
#define QF_MAX_EPOOL 3U
// <o>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
// <i>Maximum # clock tick rates for time events <1..15>
// <i>Default: 1
#define QF_MAX_TICK_RATE 1U
// <c1>Event parameter initialization (QEVT_PAR_INIT)
// <i>Resource Acquisition Is Initialization (RAII) for dynamic events
//#define QEVT_PAR_INIT
// </c>
// <c1>Active Object stop API (QACTIVE_CAN_STOP)
// <i>Enable Active Object stop API (Not recommended)
//#define QACTIVE_CAN_STOP
// </c>
// <o>Event size (QF_EVENT_SIZ_SIZE)
// <1U=>1
// <2U=>2 (default)
// <4U=>4
// <i>Size of the dynamic events for QF [bytes]
// <i>Default: 2 (64K bytes maximum event size)
#define QF_EVENT_SIZ_SIZE 2U
// <o>Time event counter size (QF_TIMEEVT_CTR_SIZE)
// <1U=>1
// <2U=>2
// <4U=>4 (default)
// <i>Size of the QTimeEvt counter [bytes]
// <i>Default: 4 (2^32 dynamic range)
#define QF_TIMEEVT_CTR_SIZE 4U
// <o>Event queue counter size (QF_EQUEUE_CTR_SIZE)
// <1U=>1 (default)
// <2U=>2
// <4U=>4
// <i>Size of event queue counter [bytes]
// <i>Default: 1 (255 events maximum in a queue)
#define QF_EQUEUE_CTR_SIZE 1U
// <o>Memory pool counter size (QF_MPOOL_CTR_SIZE)
// <1U=>1
// <2U=>2 (default)
// <4U=>4
// <i>Size of memory pool counter [bytes]
// <i>Default: 2 (64K blocks maximum in a pool)
#define QF_MPOOL_CTR_SIZE 2U
// <o>Memory block size (QF_MPOOL_SIZ_SIZE)
// <1U=>1
// <2U=>2 (default)
// <4U=>4
// <i>Size of memory pool block [bytes]
// <i>Default: 2 (64K bytes maximum block size)
#define QF_MPOOL_SIZ_SIZE 2U
// </h>
//..........................................................................
// <h>QS Software Tracing
// <i>Target-resident component of QP/Spy software tracing system
// <i>(tracing instrumentation and command-input).
// <n>NOTE: Requires command-line macro: Q_SPY
// <i>The QS software tracing instrumentation is activated only when
// <i>the macro Q_SPY is defined on the command-line to the compiler.
// <i>Typically, Q_SPY is defined only in the "spy" build configuration.
// <o>QS timestamp size (QS_TIME_SIZE)
// <1U=>1
// <2U=>2
// <4U=>4 (default)
// <i>Size of the timestamp in QS [bytes]
// <i>Default: 4 (2^32 dynamic range)
#define QS_TIME_SIZE 4U
// <o>QS buffer counter size (QS_CTR_SIZE)
// <1U=>1
// <2U=>2 (default)
// <4U=>4
// <i>Size of the counter in the internal QS buffer [bytes]
// <i>Default: 2 (64K bytes in QS buffer)
#define QS_CTR_SIZE 2U
// </h>
//..........................................................................
// <h>QXK Preemptive Dual-Mode Kernel
// <i>Preemptive non-blocking/blocking RTOS kernel.
// <h>Context switch callback (QF_ON_CONTEXT_SW)
// <c2>Context switch callback WITHOUT QS
// <i>Enable context switch callback QF_onContextSw()
// <i>When Q_SPY is undefined.
//#ifndef Q_SPY
//#define QF_ON_CONTEXT_SW
//#endif
// </c>
// <c2>Context switch callback WITH QS
// <i>Enable context switch callback QF_onContextSw()
// <i>When Q_SPY is defined.
//#ifdef Q_SPY
//#define QF_ON_CONTEXT_SW
//#endif
// </c>
// </h>
// <c2>MPU memory isolation (QF_MEM_ISOLATE)
// <i>Enable memory isolation (requires MPU)
// <i>NOTE: implies QF_ON_CONTEXT_SW.
//#define QF_MEM_ISOLATE
// </c>
// <c4>Use IRQ handler for QXK return-from-preemption
// <i>Enable this option only if the NMI handler is used in the project.
// <i>If enabled, provide the otherwise unused IRQ number (QXK_USE_IRQ_NUM)
// <i>and the corresponding IRQ handler name (QXK_USE_IRQ_HANDLER)
// <i>in the "Text Editor" mode.
//#define QXK_USE_IRQ_NUM 31
//#define QXK_USE_IRQ_HANDLER Reserved31_IRQHandler
// </c>
// </h>
//------------- <<< end of configuration section >>> -----------------------
#endif // QP_CONFIG_H_

View File

@ -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 <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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_

View File

@ -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 <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stddef.h> // 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

View File

@ -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 <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <intrinsics.h> // 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_

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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_

View File

@ -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 <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stddef.h> // 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

View File

@ -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

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
#ifndef QP_CONFIG_H_
@ -34,17 +32,10 @@
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
// <n>NOTE: Requires command-line macro: QP_CONFIG
// <i>This qp_config.h header file is activated only when the macro
// <i>QP_CONFIG is defined on the command-line to the compiler
// <n>-------------------------------------------
// <o>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)
// <i>QP API backwards compatibility with the QP/C API version.
// <i>Lower QP_API_VERSION values enable backwards compatibility
@ -158,7 +149,6 @@
// <o>Event queue counter size (QF_EQUEUE_CTR_SIZE)
// <1U=>1 (default)
// <2U=>2
// <4U=>4
// <i>Size of event queue counter [bytes]
// <i>Default: 1 (255 events maximum in a queue)
#define QF_EQUEUE_CTR_SIZE 1U

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <intrinsics.h> // 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

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
#ifndef QP_CONFIG_H_
@ -34,17 +32,10 @@
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
// <n>NOTE: Requires command-line macro: QP_CONFIG
// <i>This qp_config.h header file is activated only when the macro
// <i>QP_CONFIG is defined on the command-line to the compiler
// <n>-------------------------------------------
// <o>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)
// <i>QP API backwards compatibility with the QP/C API version.
// <i>Lower QP_API_VERSION values enable backwards compatibility
@ -158,7 +149,6 @@
// <o>Event queue counter size (QF_EQUEUE_CTR_SIZE)
// <1U=>1 (default)
// <2U=>2
// <4U=>4
// <i>Size of event queue counter [bytes]
// <i>Default: 1 (255 events maximum in a queue)
#define QF_EQUEUE_CTR_SIZE 1U
@ -233,6 +223,7 @@
// </h>
//------------- <<< end of configuration section >>> -----------------------
#endif // QP_CONFIG_H_

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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...

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#include <intrinsics.h> // 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...

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
#ifndef QP_CONFIG_H_
@ -34,17 +32,10 @@
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
// <n>NOTE: Requires command-line macro: QP_CONFIG
// <i>This qp_config.h header file is activated only when the macro
// <i>QP_CONFIG is defined on the command-line to the compiler
// <n>-------------------------------------------
// <o>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)
// <i>QP API backwards compatibility with the QP/C API version.
// <i>Lower QP_API_VERSION values enable backwards compatibility
@ -158,7 +149,6 @@
// <o>Event queue counter size (QF_EQUEUE_CTR_SIZE)
// <1U=>1 (default)
// <2U=>2
// <4U=>4
// <i>Size of event queue counter [bytes]
// <i>Default: 1 (255 events maximum in a queue)
#define QF_EQUEUE_CTR_SIZE 1U

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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,

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

File diff suppressed because it is too large Load Diff

View File

@ -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: <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:
// <www.state-machine.com>
// 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>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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:

View File

@ -28,7 +28,7 @@
// <info@state-machine.com>
//============================================================================
//! @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.

View File

@ -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

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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_

View File

@ -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_

View File

@ -1,3 +0,0 @@
// Size Options for 32bit CPU (e.g., ARM Cortex-M)
-si4 -sl4 -sll8 -ss2 -sw4 -sp4 -sf4 -sd8 -sld8

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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_

View File

@ -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_

View File

@ -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])

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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]' ~ '^(?P<keyword>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 '%[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]' ~ '^(?P<keyword>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 '%[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])

View File

@ -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: <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 top-level comment block.
:: Plagiarizing this software to sidestep the license obligations is illegal.
::
:: Contact information:
:: <www.state-machine.com>
:: <info@state-machine.com>
:: ===========================================================================
@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

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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<macro>)
-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_)

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -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]' ~ '^(?P<keyword>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 '%[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]' ~ '^(?P<keyword>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 '%[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])

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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)
//! '<symbol>' 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)

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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 <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // 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_

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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<nn> 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

View File

@ -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_

View File

@ -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

View File

@ -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: <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 top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @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_

View File

@ -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_

View File

@ -1,3 +0,0 @@
// Size Options for 32bit CPU (e.g., ARM Cortex-M)
-si4 -sl4 -sll8 -ss2 -sw4 -sp4 -sf4 -sd8 -sld8

Some files were not shown because too many files have changed in this diff Show More