mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-14 05:42:57 +08:00
8.0.1
changed ports to ARM-CM, BASEPRI critical section updated qp_config.hpp files updated examples fixed arm-cr ports, GNU compiler, ARM mode, QF_INT_ENABLE_ALL() macro
This commit is contained in:
parent
c1a9c485b7
commit
2b1661fdce
@ -76,7 +76,7 @@ This file is situated in the root directory of qpcpp. It performs a pre-initiali
|
||||
+ `arm-cm`, `arm-cr` - Arm CortexM or CortexR micro controllers. Tested with GNU cross compiler environments.
|
||||
+ `freertos`, `esp-idf`, `emb-os`, `threadx`, `uc-os2` - real time OS
|
||||
+ `msp430`, `pic32` - TI MSP430 or PIC32 micro controllers
|
||||
+ `riscv`- Risc V µC
|
||||
+ `riscv`- Risc V micro controllers
|
||||
+ `qep-only`, `qube` - test environments
|
||||
+ `win32`, `posix` - host environments MS Windows, Linux (Posix compatible systems)
|
||||
* `QPCPP-CFG-GUI` - BOOL: set this Boolean variable to ON/TRUE, if GUI support (win32) shall be compiled in. Default: OFF
|
||||
|
2
examples
2
examples
@ -1 +1 @@
|
||||
Subproject commit 4325bfa22d9b9335c3baf4bd7acc95f6c1a8fec7
|
||||
Subproject commit 01aad80e4c6f69089ecf7ddc328cad2870505a6e
|
@ -36,9 +36,9 @@
|
||||
#define QP_HPP_
|
||||
|
||||
//============================================================================
|
||||
#define QP_VERSION_STR "8.0.0"
|
||||
#define QP_VERSION 800U
|
||||
#define QP_RELEASE 0x7055936FU
|
||||
#define QP_VERSION_STR "8.0.1"
|
||||
#define QP_VERSION 801U
|
||||
#define QP_RELEASE 0x703931CEU
|
||||
|
||||
//============================================================================
|
||||
//! @cond INTERNAL
|
||||
|
@ -1,5 +1,5 @@
|
||||
//============================================================================
|
||||
// QP configuration file (QK on ARM Cortex-M)
|
||||
// QP configuration file (QV/QK/QXK on ARM Cortex-M)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
@ -59,19 +59,19 @@
|
||||
// <i> * Hard-limits for all loops
|
||||
// <i> * Memory Isolation by means of Memory Protection Unit (MPU)
|
||||
|
||||
// <c3>Disable QP FuSa in development
|
||||
// <c3>Disable QP FuSa in development (NOT recommended)
|
||||
// <i>Disable assertions and other self monitoring features
|
||||
// <i>in development build configurations (NDEBUG undefined).
|
||||
// <i>VIOLATES functional safety standards. NOT recommended !!!
|
||||
// <i>NOTE: Disabling safety *violates* functional safety standards.
|
||||
//#ifndef NDEBUG
|
||||
//#define Q_UNSAFE
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c3>Disable QP FuSa in production release
|
||||
// <i>Disable assertions and other self monitoring features
|
||||
// <c3>Disable QP FuSa in production release (NOT recommended)
|
||||
// <i>Disable assertions and other safety features
|
||||
// <i>in the release build configurations (NDEBUG defined).
|
||||
// <i>VIOLATES functional safety standards. NOT recommended !!!
|
||||
// <i>NOTE: Disabling safety *violates* functional safety standards.
|
||||
//#ifdef NDEBUG
|
||||
//#define Q_UNSAFE
|
||||
//#endif
|
||||
@ -80,7 +80,7 @@
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QEP Event Processor
|
||||
// <h>QEP Event Processor (Events)
|
||||
// <i>Events and state machines.
|
||||
|
||||
// <o>Event signal size (Q_SIGNAL_SIZE)
|
||||
@ -94,7 +94,7 @@
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QF Framework
|
||||
// <h>QF Framework (Active Objects)
|
||||
// <i>Active Object framework
|
||||
|
||||
// <o>Maximum # Active Objects (QF_MAX_ACTIVE) <1-64>
|
||||
@ -120,21 +120,6 @@
|
||||
// <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>Provide destructors for QP classes
|
||||
// <i>Destructors for classes
|
||||
//#define Q_XTOR
|
||||
// </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)
|
||||
@ -174,15 +159,75 @@
|
||||
// <i>Default: 2 (64K bytes maximum block size)
|
||||
#define QF_MPOOL_SIZ_SIZE 2U
|
||||
|
||||
// <c2>Enable event parameter initialization (QEVT_PAR_INIT)
|
||||
// <i>Initialize parameters of dynamic events at allocation
|
||||
// <i>(Resource Acquisition Is Initialization (RAII) for dynamic events)
|
||||
//#define QEVT_PAR_INIT
|
||||
// </c>
|
||||
|
||||
// <c1>Provide destructors for QP classes
|
||||
// <i>Presence of destructors pulls in the C++ delete() opeator
|
||||
// <i>NOTE: Not recommended
|
||||
//#define Q_XTOR
|
||||
// </c>
|
||||
|
||||
// <c1>Enable active object stop API (QACTIVE_CAN_STOP)
|
||||
// <i>NOTE: Not recommended
|
||||
//#define QACTIVE_CAN_STOP
|
||||
// </c>
|
||||
|
||||
// <c1>Enable context switch callback *without* QS (QF_ON_CONTEXT_SW)
|
||||
// <i>Context switch callback QF_onContextSw() when Q_SPY is undefined.
|
||||
//#ifndef Q_SPY
|
||||
//#define QF_ON_CONTEXT_SW
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c1>Enable context switch callback *with* QS (QF_ON_CONTEXT_SW)
|
||||
// <i>Context switch callback QF_onContextSw() when Q_SPY is defined.
|
||||
//#ifdef Q_SPY
|
||||
//#define QF_ON_CONTEXT_SW
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c2>Enable memory isolation (QF_MEM_ISOLATE)
|
||||
// <i>Memory isolation (requires MPU)
|
||||
// <i>NOTE: implies QF_ON_CONTEXT_SW.
|
||||
//#define QF_MEM_ISOLATE
|
||||
// </c>
|
||||
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QS Software Tracing
|
||||
// <h>QV/QK/QXK built-in kernels (ARM Cortex-M)
|
||||
|
||||
// <c2>Kernel uses critical section based on BASEPRI (QF_USE_BASEPRI)
|
||||
// <i>If not selected, critical section will be based on PRIMASK
|
||||
// <i>NOTE: The BASEPRI threshold can be adjusted in the "Text Editor" mode.
|
||||
//#define QF_USE_BASEPRI 0x3F
|
||||
// </c>
|
||||
|
||||
// <c2>QK Kernel uses IRQ for return-from-preemption
|
||||
// <i>NOTE: Use "editor mode" to edit QK_USE_IRQ_NUM
|
||||
// <i>NOTE: Use "editor mode" to edit QK_USE_IRQ_HANDLER
|
||||
//#define QK_USE_IRQ_NUM NNN
|
||||
//#define QK_USE_IRQ_HANDLER XXX_IRQHandler
|
||||
// </c>
|
||||
|
||||
// <c2>QXK Kernel uses IRQ for return-from-preemption
|
||||
// <i>NOTE: Use "editor mode" to edit QXK_USE_IRQ_NUM
|
||||
// <i>NOTE: Use "editor mode" to edit QXK_USE_IRQ_HANDLER
|
||||
//#define QXK_USE_IRQ_NUM NNN
|
||||
//#define QXK_USE_IRQ_HANDLER XXX_IRQHandler
|
||||
// </c>
|
||||
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QS Software Tracing (Q_SPY)
|
||||
// <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>NOTE: 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.
|
||||
|
||||
@ -204,47 +249,6 @@
|
||||
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QK Preemptive Non-Blocking 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 QK 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 (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 <adjust to your MCU>
|
||||
//#define QK_USE_IRQ_HANDLER <adjust to your MCU>
|
||||
// </c>
|
||||
|
||||
// </h>
|
||||
|
||||
//------------- <<< end of configuration section >>> -----------------------
|
||||
|
||||
#endif // QP_CONFIG_HPP_
|
@ -26,12 +26,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @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
|
||||
|
||||
#define QP_IMPL 1U
|
||||
#include "qp_port.hpp"
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
@ -70,7 +64,6 @@ void NMI_Handler(void);
|
||||
// For best performance, these functions are implemented in assembly,
|
||||
// but they can be implemented in C as well.
|
||||
|
||||
|
||||
//std::int32_t volatile QF_int_lock_nest_; // not used
|
||||
extern char const QF_port_module_[];
|
||||
char const QF_port_module_[] = "qk_port";
|
||||
@ -79,24 +72,23 @@ 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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are disabled with BASEPRI.
|
||||
// Otherwise interrupts are disabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for interrupt disabling?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for disabling interrupts
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for disabling interrupts
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_int_disable_error\n"
|
||||
" BX lr \n"
|
||||
@ -111,28 +103,29 @@ __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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are enabled with BASEPRI.
|
||||
// Otherwise interrupts are enabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
" BX lr \n"
|
||||
"QF_int_enable_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -145,25 +138,23 @@ __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
|
||||
// with the PRIMASK register.
|
||||
// On ARMv7-M and higher, critical section is entered by disabling
|
||||
// interrupts *selectively* with the BASEPRI register.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_crit_entry_error\n"
|
||||
" BX lr \n"
|
||||
@ -179,29 +170,27 @@ __asm volatile (
|
||||
// NOTE: this function must NOT use the stack.
|
||||
//
|
||||
// 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.
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK
|
||||
" BX lr \n"
|
||||
"QF_crit_exit_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -219,7 +208,7 @@ __asm volatile (
|
||||
// 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.
|
||||
// to the safe value QF_USE_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.
|
||||
@ -228,18 +217,18 @@ __asm volatile (
|
||||
// by the application-level code.
|
||||
void QK_init(void) {
|
||||
|
||||
#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher...
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
|
||||
// SCB_SYSPRI[2]: SysTick
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U));
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_USE_BASEPRI << 24U));
|
||||
|
||||
// set all 240 possible IRQ priories to QF_BASEPRI...
|
||||
// set all 240 possible IRQ priories to QF_USE_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;
|
||||
NVIC_IP[n] = (QF_USE_BASEPRI << 24U) | (QF_USE_BASEPRI << 16U)
|
||||
| (QF_USE_BASEPRI << 8U) | QF_USE_BASEPRI;
|
||||
}
|
||||
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#endif //--------- use BASEPRI for critical section
|
||||
|
||||
// SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest)
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U));
|
||||
@ -374,9 +363,12 @@ void QK_thread_ret(void) {
|
||||
#endif //--------- use the NMI
|
||||
|
||||
#else //--------- ARMv7-M and higher...
|
||||
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
" CPSID i \n" // disable interrupts with PRIMASK
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // enable interrupts with BASEPRI
|
||||
#endif //--------- QF_USE_BASEPRI
|
||||
// NOTE: interrupts remain disabled with PRIMASK
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
@ -392,7 +384,12 @@ void QK_thread_ret(void) {
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit
|
||||
" STR r1,[r0] \n" // pend the IRQ
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
" CPSIE i \n" // enable interrupts with PRIMASK
|
||||
#else //--------- interrupt disabling with PRIMASK
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // enable interrupts with BASEPRI
|
||||
#endif //--------- interrupt disabling with PRIMASK
|
||||
// This code stops here and continues in the IRQ handler
|
||||
|
||||
#else //--------- use the NMI (default)
|
||||
@ -442,15 +439,16 @@ 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...
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
// NOTE: QF_int_enable_() already called
|
||||
" CPSIE i \n" // enable interrupts with PRIMASK
|
||||
#else //--------- interrupt disabling with PRIMASK
|
||||
" 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
|
||||
#endif //--------- interrupt disabling with PRIMASK
|
||||
" POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc
|
||||
);
|
||||
// NOTE: this causes exception-return to the preempted *thread* context
|
||||
|
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-M, preemptive QK kernel, ARM-CLANG
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -47,32 +41,9 @@
|
||||
// QK event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
// 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(static_cast<std::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_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
|
||||
#endif
|
||||
|
||||
// interrupt disabling policy, see NOTE2 and NOTE3
|
||||
#define QF_INT_DISABLE() (QF_int_disable_())
|
||||
#define QF_INT_ENABLE() (QF_int_enable_())
|
||||
@ -84,11 +55,28 @@
|
||||
|
||||
#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory")
|
||||
|
||||
// Efficient log2() ----------------------------------------------------------
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
// hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M)
|
||||
#define QF_LOG2(n_) QF_qlog2(static_cast<std::uint32_t>(n_))
|
||||
|
||||
// hand-optimized quick LOG2 in assembly
|
||||
extern "C" std::uint_fast8_t QF_qlog2(std::uint32_t x);
|
||||
#else // ARMv7-M or higher
|
||||
// ARMv7-M or higher provide the CLZ instruction for fast LOG2
|
||||
#define QF_LOG2(n_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
#endif // ARMv7-M or higher
|
||||
|
||||
// Critical section policy ---------------------------------------------------
|
||||
#ifdef QF_USE_BASEPRI
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI (QF_USE_BASEPRI >> (8 - __NVIC_PRIO_BITS))
|
||||
#else
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI 0
|
||||
#endif // QF_USE_BASEPRI
|
||||
|
||||
// Memory isolation ----------------------------------------------------------
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
|
||||
@ -105,7 +93,7 @@
|
||||
extern "C" void QF_onMemSys(void);
|
||||
extern "C" void QF_onMemApp(void);
|
||||
|
||||
#endif // def QF_MEM_ISOLATE
|
||||
#endif // QF_MEM_ISOLATE
|
||||
|
||||
// determination if the code executes in the ISR context
|
||||
#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U)
|
||||
@ -154,7 +142,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()
|
||||
extern "C" void QK_init(void);
|
||||
extern "C" void QK_thread_ret(void);
|
||||
|
||||
@ -189,7 +177,7 @@ extern "C" {
|
||||
// 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.
|
||||
// functions in the qv_port.c module for details.
|
||||
//
|
||||
// NOTE2:
|
||||
// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt
|
||||
@ -198,15 +186,15 @@ extern "C" {
|
||||
// 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.
|
||||
// If macro QF_USE_BASEPRI is defined, the interrupt disable/enable policy
|
||||
// uses BASEPRI register to disable interrupts only with priority lower than
|
||||
// the threshold specified by the QF_USE_BASEPRI macro. The interrupts with
|
||||
// priorities above QF_USE_BASEPRI (i.e., with numerical priority values
|
||||
// lower than QF_USE_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
|
||||
// numerical values of priorities equal to or higher than QF_USE_BASEPRI
|
||||
// ("kernel-aware" interrupts ), can call QF services.
|
||||
//
|
||||
// NOTE4:
|
||||
|
@ -26,12 +26,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @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
|
||||
|
||||
#define QP_IMPL 1U
|
||||
#include "qp_port.hpp"
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
@ -70,7 +64,6 @@ void NMI_Handler(void);
|
||||
// For best performance, these functions are implemented in assembly,
|
||||
// but they can be implemented in C as well.
|
||||
|
||||
|
||||
//std::int32_t volatile QF_int_lock_nest_; // not used
|
||||
extern char const QF_port_module_[];
|
||||
char const QF_port_module_[] = "qk_port";
|
||||
@ -79,24 +72,23 @@ 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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are disabled with BASEPRI.
|
||||
// Otherwise interrupts are disabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for interrupt disabling?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for disabling interrupts
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for disabling interrupts
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_int_disable_error\n"
|
||||
" BX lr \n"
|
||||
@ -111,28 +103,29 @@ __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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are enabled with BASEPRI.
|
||||
// Otherwise interrupts are enabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
" BX lr \n"
|
||||
"QF_int_enable_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -145,25 +138,23 @@ __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
|
||||
// with the PRIMASK register.
|
||||
// On ARMv7-M and higher, critical section is entered by disabling
|
||||
// interrupts *selectively* with the BASEPRI register.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_crit_entry_error\n"
|
||||
" BX lr \n"
|
||||
@ -179,29 +170,27 @@ __asm volatile (
|
||||
// NOTE: this function must NOT use the stack.
|
||||
//
|
||||
// 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.
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK
|
||||
" BX lr \n"
|
||||
"QF_crit_exit_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -219,7 +208,7 @@ __asm volatile (
|
||||
// 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.
|
||||
// to the safe value QF_USE_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.
|
||||
@ -228,18 +217,18 @@ __asm volatile (
|
||||
// by the application-level code.
|
||||
void QK_init(void) {
|
||||
|
||||
#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher...
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
|
||||
// SCB_SYSPRI[2]: SysTick
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U));
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_USE_BASEPRI << 24U));
|
||||
|
||||
// set all 240 possible IRQ priories to QF_BASEPRI...
|
||||
// set all 240 possible IRQ priories to QF_USE_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;
|
||||
NVIC_IP[n] = (QF_USE_BASEPRI << 24U) | (QF_USE_BASEPRI << 16U)
|
||||
| (QF_USE_BASEPRI << 8U) | QF_USE_BASEPRI;
|
||||
}
|
||||
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#endif //--------- use BASEPRI for critical section
|
||||
|
||||
// SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest)
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U));
|
||||
@ -383,9 +372,12 @@ void QK_thread_ret(void) {
|
||||
#endif //--------- use the NMI
|
||||
|
||||
#else //--------- ARMv7-M and higher...
|
||||
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
" CPSID i \n" // disable interrupts with PRIMASK
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // enable interrupts with BASEPRI
|
||||
#endif //--------- QF_USE_BASEPRI
|
||||
// NOTE: interrupts remain disabled with PRIMASK
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
@ -401,7 +393,12 @@ void QK_thread_ret(void) {
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit
|
||||
" STR r1,[r0] \n" // pend the IRQ
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
" CPSIE i \n" // enable interrupts with PRIMASK
|
||||
#else //--------- interrupt disabling with PRIMASK
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // enable interrupts with BASEPRI
|
||||
#endif //--------- interrupt disabling with PRIMASK
|
||||
// This code stops here and continues in the IRQ handler
|
||||
|
||||
#else //--------- use the NMI (default)
|
||||
@ -451,15 +448,16 @@ 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...
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
// NOTE: QF_int_enable_() already called
|
||||
" CPSIE i \n" // enable interrupts with PRIMASK
|
||||
#else //--------- interrupt disabling with PRIMASK
|
||||
" 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
|
||||
#endif //--------- interrupt disabling with PRIMASK
|
||||
" POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc
|
||||
);
|
||||
// NOTE: this causes exception-return to the preempted *thread* context
|
||||
|
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-M, preemptive QK kernel, GNU-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -47,32 +41,9 @@
|
||||
// QK event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
// 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(static_cast<std::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_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
|
||||
#endif
|
||||
|
||||
// interrupt disabling policy, see NOTE2 and NOTE3
|
||||
#define QF_INT_DISABLE() (QF_int_disable_())
|
||||
#define QF_INT_ENABLE() (QF_int_enable_())
|
||||
@ -84,11 +55,28 @@
|
||||
|
||||
#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory")
|
||||
|
||||
// Efficient log2() ----------------------------------------------------------
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
// hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M)
|
||||
#define QF_LOG2(n_) QF_qlog2(static_cast<std::uint32_t>(n_))
|
||||
|
||||
// hand-optimized quick LOG2 in assembly
|
||||
extern "C" std::uint_fast8_t QF_qlog2(std::uint32_t x);
|
||||
#else // ARMv7-M or higher
|
||||
// ARMv7-M or higher provide the CLZ instruction for fast LOG2
|
||||
#define QF_LOG2(n_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
#endif // ARMv7-M or higher
|
||||
|
||||
// Critical section policy ---------------------------------------------------
|
||||
#ifdef QF_USE_BASEPRI
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI (QF_USE_BASEPRI >> (8 - __NVIC_PRIO_BITS))
|
||||
#else
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI 0
|
||||
#endif // QF_USE_BASEPRI
|
||||
|
||||
// Memory isolation ----------------------------------------------------------
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
|
||||
@ -105,7 +93,7 @@
|
||||
extern "C" void QF_onMemSys(void);
|
||||
extern "C" void QF_onMemApp(void);
|
||||
|
||||
#endif // def QF_MEM_ISOLATE
|
||||
#endif // QF_MEM_ISOLATE
|
||||
|
||||
// determination if the code executes in the ISR context
|
||||
#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U)
|
||||
@ -189,7 +177,7 @@ extern "C" {
|
||||
// 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.
|
||||
// functions in the qv_port.c module for details.
|
||||
//
|
||||
// NOTE2:
|
||||
// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt
|
||||
@ -198,15 +186,15 @@ extern "C" {
|
||||
// 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.
|
||||
// If macro QF_USE_BASEPRI is defined, the interrupt disable/enable policy
|
||||
// uses BASEPRI register to disable interrupts only with priority lower than
|
||||
// the threshold specified by the QF_USE_BASEPRI macro. The interrupts with
|
||||
// priorities above QF_USE_BASEPRI (i.e., with numerical priority values
|
||||
// lower than QF_USE_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
|
||||
// numerical values of priorities equal to or higher than QF_USE_BASEPRI
|
||||
// ("kernel-aware" interrupts ), can call QF services.
|
||||
//
|
||||
// NOTE4:
|
||||
@ -221,8 +209,6 @@ extern "C" {
|
||||
// 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_HPP_
|
||||
|
||||
|
@ -26,12 +26,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @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
|
||||
|
||||
#define QP_IMPL 1U
|
||||
#include "qp_port.hpp"
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
@ -83,24 +77,23 @@ 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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are disabled with BASEPRI.
|
||||
// Otherwise interrupts are disabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for interrupt disabling?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for disabling interrupts
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for disabling interrupts
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_int_disable_error\n"
|
||||
" BX lr \n"
|
||||
@ -115,28 +108,29 @@ __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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are enabled with BASEPRI.
|
||||
// Otherwise interrupts are enabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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?
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
" BX lr \n"
|
||||
"QF_int_enable_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -149,25 +143,23 @@ __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
|
||||
// with the PRIMASK register.
|
||||
// On ARMv7-M and higher, critical section is entered by disabling
|
||||
// interrupts *selectively* with the BASEPRI register.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_crit_entry_error\n"
|
||||
" BX lr \n"
|
||||
@ -183,29 +175,27 @@ __asm volatile (
|
||||
// NOTE: this function must NOT use the stack.
|
||||
//
|
||||
// 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.
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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?
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK
|
||||
" BX lr \n"
|
||||
"QF_crit_exit_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -223,7 +213,7 @@ __asm volatile (
|
||||
// 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.
|
||||
// to the safe value QF_USE_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.
|
||||
@ -232,18 +222,18 @@ __asm volatile (
|
||||
// by the application-level code.
|
||||
void QK_init(void) {
|
||||
|
||||
#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher...
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
|
||||
// SCB_SYSPRI[2]: SysTick
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U));
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_USE_BASEPRI << 24U));
|
||||
|
||||
// set all 240 possible IRQ priories to QF_BASEPRI...
|
||||
// set all 240 possible IRQ priories to QF_USE_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;
|
||||
NVIC_IP[n] = (QF_USE_BASEPRI << 24U) | (QF_USE_BASEPRI << 16U)
|
||||
| (QF_USE_BASEPRI << 8U) | QF_USE_BASEPRI;
|
||||
}
|
||||
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#endif //--------- use BASEPRI for critical section
|
||||
|
||||
// SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest)
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U));
|
||||
@ -378,9 +368,12 @@ void QK_thread_ret(void) {
|
||||
#endif //--------- use the NMI
|
||||
|
||||
#else //--------- ARMv7-M and higher...
|
||||
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
" CPSID i \n" // disable interrupts with PRIMASK
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // enable interrupts with BASEPRI
|
||||
#endif //--------- QF_USE_BASEPRI
|
||||
// NOTE: interrupts remain disabled with PRIMASK
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
@ -396,7 +389,12 @@ void QK_thread_ret(void) {
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit
|
||||
" STR r1,[r0] \n" // pend the IRQ
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
" CPSIE i \n" // enable interrupts with PRIMASK
|
||||
#else //--------- interrupt disabling with PRIMASK
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // enable interrupts with BASEPRI
|
||||
#endif //--------- interrupt disabling with PRIMASK
|
||||
// This code stops here and continues in the IRQ handler
|
||||
|
||||
#else //--------- use the NMI (default)
|
||||
@ -446,15 +444,16 @@ 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...
|
||||
#ifdef QF_USE_BASEPRI //--------- QF_USE_BASEPRI
|
||||
// NOTE: QF_int_enable_() already called
|
||||
" CPSIE i \n" // enable interrupts with PRIMASK
|
||||
#else //--------- interrupt disabling with PRIMASK
|
||||
" 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
|
||||
#endif //--------- interrupt disabling with PRIMASK
|
||||
" POP {r0,pc} \n" // pop stack aligner and EXC_RETURN to pc
|
||||
);
|
||||
// NOTE: this causes exception-return to the preempted *thread* context
|
||||
@ -475,7 +474,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"
|
||||
@ -495,7 +494,7 @@ __asm volatile (
|
||||
" ADDS %[n],%[n],#4 \n"
|
||||
" MOVS r0,r2 \n"
|
||||
"QF_qlog2_3:" : [n]"=r"(n)
|
||||
);
|
||||
);
|
||||
return n + log2LUT[x];
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-M, preemptive QK kernel, IAR-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -48,32 +42,9 @@
|
||||
// QK event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
// 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(static_cast<std::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_) \
|
||||
(static_cast<std::uint32_t>(32U - __CLZ((n_))))
|
||||
|
||||
#endif
|
||||
|
||||
// interrupt disabling policy, see NOTE2 and NOTE3
|
||||
#define QF_INT_DISABLE() (QF_int_disable_())
|
||||
#define QF_INT_ENABLE() (QF_int_enable_())
|
||||
@ -85,11 +56,28 @@
|
||||
|
||||
#define QF_CRIT_EXIT_NOP() __ISB()
|
||||
|
||||
// Efficient log2() ----------------------------------------------------------
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
// hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M)
|
||||
#define QF_LOG2(n_) QF_qlog2(static_cast<std::uint32_t>(n_))
|
||||
|
||||
// hand-optimized quick LOG2 in assembly
|
||||
extern "C" std::uint_fast8_t QF_qlog2(std::uint32_t x);
|
||||
#else // ARMv7-M or higher
|
||||
// ARMv7-M or higher provide the CLZ instruction for fast LOG2
|
||||
#define QF_LOG2(n_) \
|
||||
(static_cast<std::uint32_t>(32U - __CLZ((n_))))
|
||||
#endif // ARMv7-M or higher
|
||||
|
||||
// Critical section policy ---------------------------------------------------
|
||||
#ifdef QF_USE_BASEPRI
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI (QF_USE_BASEPRI >> (8 - __NVIC_PRIO_BITS))
|
||||
#else
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI 0
|
||||
#endif // QF_USE_BASEPRI
|
||||
|
||||
// Memory isolation ----------------------------------------------------------
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
|
||||
@ -106,7 +94,7 @@
|
||||
extern "C" void QF_onMemSys(void);
|
||||
extern "C" void QF_onMemApp(void);
|
||||
|
||||
#endif // def QF_MEM_ISOLATE
|
||||
#endif // QF_MEM_ISOLATE
|
||||
|
||||
// determination if the code executes in the ISR context
|
||||
#define QK_ISR_CONTEXT_() (__get_IPSR() != 0U)
|
||||
@ -183,7 +171,7 @@ extern "C" {
|
||||
// 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.
|
||||
// functions in the qv_port.c module for details.
|
||||
//
|
||||
// NOTE2:
|
||||
// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt
|
||||
@ -192,15 +180,15 @@ extern "C" {
|
||||
// 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.
|
||||
// If macro QF_USE_BASEPRI is defined, the interrupt disable/enable policy
|
||||
// uses BASEPRI register to disable interrupts only with priority lower than
|
||||
// the threshold specified by the QF_USE_BASEPRI macro. The interrupts with
|
||||
// priorities above QF_USE_BASEPRI (i.e., with numerical priority values
|
||||
// lower than QF_USE_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
|
||||
// numerical values of priorities equal to or higher than QF_USE_BASEPRI
|
||||
// ("kernel-aware" interrupts ), can call QF services.
|
||||
//
|
||||
// NOTE4:
|
||||
@ -215,8 +203,6 @@ extern "C" {
|
||||
// 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_HPP_
|
||||
|
||||
|
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QF/C++ port to ARM Cortex-M, cooperative QV kernel, ARM-CLANG
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -47,32 +41,9 @@
|
||||
// QV event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
// 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(static_cast<std::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_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
|
||||
#endif
|
||||
|
||||
// interrupt disabling policy, see NOTE2 and NOTE3
|
||||
#define QF_INT_DISABLE() (QF_int_disable_())
|
||||
#define QF_INT_ENABLE() (QF_int_enable_())
|
||||
@ -84,11 +55,28 @@
|
||||
|
||||
#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory")
|
||||
|
||||
// Efficient log2() ----------------------------------------------------------
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
// hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M)
|
||||
#define QF_LOG2(n_) QF_qlog2(static_cast<std::uint32_t>(n_))
|
||||
|
||||
// hand-optimized quick LOG2 in assembly
|
||||
extern "C" std::uint_fast8_t QF_qlog2(std::uint32_t x);
|
||||
#else // ARMv7-M or higher
|
||||
// ARMv7-M or higher provide the CLZ instruction for fast LOG2
|
||||
#define QF_LOG2(n_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
#endif // ARMv7-M or higher
|
||||
|
||||
// Critical section policy ---------------------------------------------------
|
||||
#ifdef QF_USE_BASEPRI
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI (QF_USE_BASEPRI >> (8 - __NVIC_PRIO_BITS))
|
||||
#else
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI 0
|
||||
#endif // QF_USE_BASEPRI
|
||||
|
||||
// Memory isolation ----------------------------------------------------------
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
|
||||
@ -105,20 +93,10 @@
|
||||
extern "C" void QF_onMemSys(void);
|
||||
extern "C" void QF_onMemApp(void);
|
||||
|
||||
#endif // def QF_MEM_ISOLATE
|
||||
#endif // QF_MEM_ISOLATE
|
||||
|
||||
// determination if the code executes in the ISR context
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
__asm volatile ("wfi"::: "memory"); \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
|
||||
#define QV_ARM_ERRATUM_838869() ((void)0)
|
||||
|
||||
#else // ARMv7-M or higher
|
||||
// QV kernel sleep mode transition
|
||||
#ifdef QF_USE_BASEPRI
|
||||
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
@ -128,6 +106,17 @@
|
||||
__asm volatile ("cpsie i" ::: "memory"); \
|
||||
} while (false)
|
||||
|
||||
#else // no BASEPRI (QV uses PRIMASK)
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
__asm volatile ("wfi"::: "memory"); \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
#endif // no BASEPRI (QV uses PRIMASK)
|
||||
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
#define QV_ARM_ERRATUM_838869() (static_cast<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.
|
||||
@ -171,7 +160,7 @@ extern "C" {
|
||||
// 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.
|
||||
// functions in the qv_port.c module for details.
|
||||
//
|
||||
// NOTE2:
|
||||
// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt
|
||||
@ -180,15 +169,15 @@ extern "C" {
|
||||
// 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.
|
||||
// If macro QF_USE_BASEPRI is defined, the interrupt disable/enable policy
|
||||
// uses BASEPRI register to disable interrupts only with priority lower than
|
||||
// the threshold specified by the QF_USE_BASEPRI macro. The interrupts with
|
||||
// priorities above QF_USE_BASEPRI (i.e., with numerical priority values
|
||||
// lower than QF_USE_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
|
||||
// numerical values of priorities equal to or higher than QF_USE_BASEPRI
|
||||
// ("kernel-aware" interrupts ), can call QF services.
|
||||
//
|
||||
// NOTE4:
|
||||
@ -203,8 +192,6 @@ extern "C" {
|
||||
// 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_HPP_
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
// 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
|
||||
@ -26,12 +26,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QV/C++ port to ARM Cortex-M, ARM-CLANG
|
||||
|
||||
#define QP_IMPL 1U
|
||||
#include "qp_port.hpp"
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
@ -67,24 +61,23 @@ 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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are disabled with BASEPRI.
|
||||
// Otherwise interrupts are disabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for interrupt disabling?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for disabling interrupts
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for disabling interrupts
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_int_disable_error\n"
|
||||
" BX lr \n"
|
||||
@ -99,28 +92,29 @@ __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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are enabled with BASEPRI.
|
||||
// Otherwise interrupts are enabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
" BX lr \n"
|
||||
"QF_int_enable_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -133,25 +127,23 @@ __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
|
||||
// with the PRIMASK register.
|
||||
// On ARMv7-M and higher, critical section is entered by disabling
|
||||
// interrupts *selectively* with the BASEPRI register.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_crit_entry_error\n"
|
||||
" BX lr \n"
|
||||
@ -167,29 +159,27 @@ __asm volatile (
|
||||
// NOTE: this function must NOT use the stack.
|
||||
//
|
||||
// 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.
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK
|
||||
" BX lr \n"
|
||||
"QF_crit_exit_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -207,7 +197,7 @@ __asm volatile (
|
||||
// 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.
|
||||
// to the safe value QF_USE_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.
|
||||
@ -216,18 +206,18 @@ __asm volatile (
|
||||
// by the application-level code.
|
||||
void QV_init(void) {
|
||||
|
||||
#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher...
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
|
||||
// SCB_SYSPRI[2]: SysTick
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U));
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_USE_BASEPRI << 24U));
|
||||
|
||||
// set all 240 possible IRQ priories to QF_BASEPRI...
|
||||
// set all 240 possible IRQ priories to QF_USE_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;
|
||||
NVIC_IP[n] = (QF_USE_BASEPRI << 24U) | (QF_USE_BASEPRI << 16U)
|
||||
| (QF_USE_BASEPRI << 8U) | QF_USE_BASEPRI;
|
||||
}
|
||||
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#endif //--------- use BASEPRI for critical section
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
// make sure that the FPU is enabled by setting CP10 & CP11 Full Access
|
||||
|
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief Qp/C++ port to ARM Cortex-M, cooperative QV kernel, GNU-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -47,32 +41,9 @@
|
||||
// QV event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
// 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(static_cast<std::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_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
|
||||
#endif
|
||||
|
||||
// interrupt disabling policy, see NOTE2 and NOTE3
|
||||
#define QF_INT_DISABLE() (QF_int_disable_())
|
||||
#define QF_INT_ENABLE() (QF_int_enable_())
|
||||
@ -84,11 +55,28 @@
|
||||
|
||||
#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory")
|
||||
|
||||
// Efficient log2() ----------------------------------------------------------
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
// hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M)
|
||||
#define QF_LOG2(n_) QF_qlog2(static_cast<std::uint32_t>(n_))
|
||||
|
||||
// hand-optimized quick LOG2 in assembly
|
||||
extern "C" std::uint_fast8_t QF_qlog2(std::uint32_t x);
|
||||
#else // ARMv7-M or higher
|
||||
// ARMv7-M or higher provide the CLZ instruction for fast LOG2
|
||||
#define QF_LOG2(n_) \
|
||||
(static_cast<std::uint32_t>(32 - __builtin_clz((n_))))
|
||||
#endif // ARMv7-M or higher
|
||||
|
||||
// Critical section policy ---------------------------------------------------
|
||||
#ifdef QF_USE_BASEPRI
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI (QF_USE_BASEPRI >> (8 - __NVIC_PRIO_BITS))
|
||||
#else
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI 0
|
||||
#endif // QF_USE_BASEPRI
|
||||
|
||||
// Memory isolation ----------------------------------------------------------
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
|
||||
@ -105,20 +93,10 @@
|
||||
extern "C" void QF_onMemSys(void);
|
||||
extern "C" void QF_onMemApp(void);
|
||||
|
||||
#endif // def QF_MEM_ISOLATE
|
||||
#endif // QF_MEM_ISOLATE
|
||||
|
||||
// determination if the code executes in the ISR context
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
__asm volatile ("wfi"::: "memory"); \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
|
||||
#define QV_ARM_ERRATUM_838869() ((void)0)
|
||||
|
||||
#else // ARMv7-M or higher
|
||||
// QV kernel sleep mode transition
|
||||
#ifdef QF_USE_BASEPRI
|
||||
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
@ -128,6 +106,17 @@
|
||||
__asm volatile ("cpsie i" ::: "memory"); \
|
||||
} while (false)
|
||||
|
||||
#else // no BASEPRI (QV uses PRIMASK)
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
__asm volatile ("wfi"::: "memory"); \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
#endif // no BASEPRI (QV uses PRIMASK)
|
||||
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
#define QV_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.
|
||||
@ -171,7 +160,7 @@ extern "C" {
|
||||
// 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.
|
||||
// functions in the qv_port.c module for details.
|
||||
//
|
||||
// NOTE2:
|
||||
// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt
|
||||
@ -180,15 +169,15 @@ extern "C" {
|
||||
// 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.
|
||||
// If macro QF_USE_BASEPRI is defined, the interrupt disable/enable policy
|
||||
// uses BASEPRI register to disable interrupts only with priority lower than
|
||||
// the threshold specified by the QF_USE_BASEPRI macro. The interrupts with
|
||||
// priorities above QF_USE_BASEPRI (i.e., with numerical priority values
|
||||
// lower than QF_USE_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
|
||||
// numerical values of priorities equal to or higher than QF_USE_BASEPRI
|
||||
// ("kernel-aware" interrupts ), can call QF services.
|
||||
//
|
||||
// NOTE4:
|
||||
@ -203,8 +192,6 @@ extern "C" {
|
||||
// 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_HPP_
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
// 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
|
||||
@ -26,12 +26,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QV/C++ port to ARM Cortex-M, GNU-ARM
|
||||
|
||||
#define QP_IMPL 1U
|
||||
#include "qp_port.hpp"
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
@ -67,24 +61,23 @@ 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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are disabled with BASEPRI.
|
||||
// Otherwise interrupts are disabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for interrupt disabling?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for disabling interrupts
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for disabling interrupts
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_int_disable_error\n"
|
||||
" BX lr \n"
|
||||
@ -99,28 +92,29 @@ __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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are enabled with BASEPRI.
|
||||
// Otherwise interrupts are enabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
" BX lr \n"
|
||||
"QF_int_enable_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -133,25 +127,23 @@ __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
|
||||
// with the PRIMASK register.
|
||||
// On ARMv7-M and higher, critical section is entered by disabling
|
||||
// interrupts *selectively* with the BASEPRI register.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_crit_entry_error\n"
|
||||
" BX lr \n"
|
||||
@ -167,29 +159,27 @@ __asm volatile (
|
||||
// NOTE: this function must NOT use the stack.
|
||||
//
|
||||
// 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.
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK
|
||||
" BX lr \n"
|
||||
"QF_crit_exit_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -207,7 +197,7 @@ __asm volatile (
|
||||
// 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.
|
||||
// to the safe value QF_USE_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.
|
||||
@ -216,18 +206,18 @@ __asm volatile (
|
||||
// by the application-level code.
|
||||
void QV_init(void) {
|
||||
|
||||
#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher...
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
|
||||
// SCB_SYSPRI[2]: SysTick
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U));
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_USE_BASEPRI << 24U));
|
||||
|
||||
// set all 240 possible IRQ priories to QF_BASEPRI...
|
||||
// set all 240 possible IRQ priories to QF_USE_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;
|
||||
NVIC_IP[n] = (QF_USE_BASEPRI << 24U) | (QF_USE_BASEPRI << 16U)
|
||||
| (QF_USE_BASEPRI << 8U) | QF_USE_BASEPRI;
|
||||
}
|
||||
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#endif //--------- use BASEPRI for critical section
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
// make sure that the FPU is enabled by setting CP10 & CP11 Full Access
|
||||
|
@ -1,6 +1,6 @@
|
||||
//============================================================================
|
||||
// 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
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-M, cooperative QV kernel, IAR-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -48,32 +42,9 @@
|
||||
// QV event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
// 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(static_cast<std::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_) \
|
||||
(static_cast<std::uint32_t>(32U - __CLZ((n_))))
|
||||
|
||||
#endif
|
||||
|
||||
// interrupt disabling policy, see NOTE2 and NOTE3
|
||||
#define QF_INT_DISABLE() (QF_int_disable_())
|
||||
#define QF_INT_ENABLE() (QF_int_enable_())
|
||||
@ -83,13 +54,30 @@
|
||||
#define QF_CRIT_ENTRY() (QF_crit_entry_())
|
||||
#define QF_CRIT_EXIT() (QF_crit_exit_())
|
||||
|
||||
#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory")
|
||||
#define QF_CRIT_EXIT_NOP() __ISB()
|
||||
|
||||
// Efficient log2() ----------------------------------------------------------
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
// hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M)
|
||||
#define QF_LOG2(n_) QF_qlog2(static_cast<std::uint32_t>(n_))
|
||||
|
||||
// hand-optimized quick LOG2 in assembly
|
||||
extern "C" std::uint_fast8_t QF_qlog2(std::uint32_t x);
|
||||
#else // ARMv7-M or higher
|
||||
// ARMv7-M or higher provide the CLZ instruction for fast LOG2
|
||||
#define QF_LOG2(n_) \
|
||||
(static_cast<std::uint32_t>(32U - __CLZ((n_))))
|
||||
#endif // ARMv7-M or higher
|
||||
|
||||
// Critical section policy ---------------------------------------------------
|
||||
#ifdef QF_USE_BASEPRI
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI (QF_USE_BASEPRI >> (8 - __NVIC_PRIO_BITS))
|
||||
#else
|
||||
// CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4
|
||||
#define QF_AWARE_ISR_CMSIS_PRI 0
|
||||
#endif // QF_USE_BASEPRI
|
||||
|
||||
// Memory isolation ----------------------------------------------------------
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
|
||||
@ -106,20 +94,10 @@
|
||||
extern "C" void QF_onMemSys(void);
|
||||
extern "C" void QF_onMemApp(void);
|
||||
|
||||
#endif // def QF_MEM_ISOLATE
|
||||
#endif // QF_MEM_ISOLATE
|
||||
|
||||
// determination if the code executes in the ISR context
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
__WFI(); \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
|
||||
#define QV_ARM_ERRATUM_838869() ((void)0)
|
||||
|
||||
#else // ARMv7-M or higher
|
||||
// QV kernel sleep mode transition
|
||||
#ifdef QF_USE_BASEPRI
|
||||
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
@ -129,6 +107,18 @@
|
||||
__enable_interrupt(); \
|
||||
} while (false)
|
||||
|
||||
#else // no BASEPRI (QV uses PRIMASK)
|
||||
// macro to put the CPU to sleep inside QV_onIdle()
|
||||
|
||||
#define QV_CPU_SLEEP() do { \
|
||||
__WFI(); \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
#endif // no BASEPRI (QV uses PRIMASK)
|
||||
|
||||
#if (__ARM_ARCH == 6) // ARMv6-M?
|
||||
#define QV_ARM_ERRATUM_838869() (static_cast<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.
|
||||
@ -172,7 +162,7 @@ extern "C" {
|
||||
// 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.
|
||||
// functions in the qv_port.c module for details.
|
||||
//
|
||||
// NOTE2:
|
||||
// On Cortex-M0/M0+/M1 (architecture ARMv6-M, ARMv6S-M), the interrupt
|
||||
@ -181,15 +171,15 @@ extern "C" {
|
||||
// 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.
|
||||
// If macro QF_USE_BASEPRI is defined, the interrupt disable/enable policy
|
||||
// uses BASEPRI register to disable interrupts only with priority lower than
|
||||
// the threshold specified by the QF_USE_BASEPRI macro. The interrupts with
|
||||
// priorities above QF_USE_BASEPRI (i.e., with numerical priority values
|
||||
// lower than QF_USE_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
|
||||
// numerical values of priorities equal to or higher than QF_USE_BASEPRI
|
||||
// ("kernel-aware" interrupts ), can call QF services.
|
||||
//
|
||||
// NOTE4:
|
||||
@ -204,8 +194,6 @@ extern "C" {
|
||||
// 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_HPP_
|
||||
|
||||
|
@ -26,12 +26,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QV/C++ port to ARM Cortex-M, IAR-ARM toolset
|
||||
|
||||
#define QP_IMPL 1U
|
||||
#include "qp_port.hpp"
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
@ -72,24 +66,23 @@ 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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are disabled with BASEPRI.
|
||||
// Otherwise interrupts are disabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for interrupt disabling?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for disabling interrupts
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for disabling interrupts
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_int_disable_error\n"
|
||||
" BX lr \n"
|
||||
@ -104,28 +97,29 @@ __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.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, interrupts are enabled with BASEPRI.
|
||||
// Otherwise interrupts are enabled with the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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?
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for enabling interrupts?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for enabling interrupts
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK for enabling interrupts
|
||||
" BX lr \n"
|
||||
"QF_int_enable_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -138,25 +132,23 @@ __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
|
||||
// with the PRIMASK register.
|
||||
// On ARMv7-M and higher, critical section is entered by disabling
|
||||
// interrupts *selectively* with the BASEPRI register.
|
||||
// Description:
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts are
|
||||
// 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?
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
" MOVS r1,#" STRINGIFY(QF_USE_BASEPRI) "\n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" CMP r0,#0 \n" // assert(PRIMASK/BASEPRI == 0)
|
||||
" BNE QF_crit_entry_error\n"
|
||||
" BX lr \n"
|
||||
@ -172,29 +164,27 @@ __asm volatile (
|
||||
// NOTE: this function must NOT use the stack.
|
||||
//
|
||||
// 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.
|
||||
// When QF_USE_BASEPRI is defined, critical section uses BASEPRI.
|
||||
// Otherwise, critical section uses the PRIMASK register.
|
||||
// Additionally, the function also asserts that the interrupts ARE
|
||||
// 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?
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#else //--------- ARMv7-M or higher
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MRS r0,BASEPRI \n" // r0 <- previous BASEPRI
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK for critical section
|
||||
" MRS r0,PRIMASK \n" // r0 <- previous PRIMASK
|
||||
#endif //--------- use PRIMASK for critical section
|
||||
" 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
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
" MOVS r1,#0 \n"
|
||||
" MSR BASEPRI,r1 \n" // NOTE: Cortes-M7 erratum 837070 is OK
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#else //--------- use PRIMASK
|
||||
" CPSIE i \n" // clear PRIMASK
|
||||
#endif //--------- use PRIMASK
|
||||
" BX lr \n"
|
||||
"QF_crit_exit_error: \n"
|
||||
" LDR r0,=QF_port_module_ \n"
|
||||
@ -212,7 +202,7 @@ __asm volatile (
|
||||
// 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.
|
||||
// to the safe value QF_USE_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.
|
||||
@ -221,18 +211,18 @@ __asm volatile (
|
||||
// by the application-level code.
|
||||
void QV_init(void) {
|
||||
|
||||
#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher...
|
||||
#ifdef QF_USE_BASEPRI //--------- use BASEPRI for critical section?
|
||||
|
||||
// SCB_SYSPRI[2]: SysTick
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U));
|
||||
SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_USE_BASEPRI << 24U));
|
||||
|
||||
// set all 240 possible IRQ priories to QF_BASEPRI...
|
||||
// set all 240 possible IRQ priories to QF_USE_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;
|
||||
NVIC_IP[n] = (QF_USE_BASEPRI << 24U) | (QF_USE_BASEPRI << 16U)
|
||||
| (QF_USE_BASEPRI << 8U) | QF_USE_BASEPRI;
|
||||
}
|
||||
|
||||
#endif //--------- ARMv7-M or higher
|
||||
#endif //--------- use BASEPRI for critical section
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
// make sure that the FPU is enabled by setting CP10 & CP11 Full Access
|
||||
|
@ -1,5 +1,5 @@
|
||||
//============================================================================
|
||||
// QP configuration file (QV on ARM Cortex-M)
|
||||
// QP configuration file (QV/QK/QXK on ARM Cortex-R)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
@ -59,19 +59,19 @@
|
||||
// <i> * Hard-limits for all loops
|
||||
// <i> * Memory Isolation by means of Memory Protection Unit (MPU)
|
||||
|
||||
// <c3>Disable QP FuSa in development
|
||||
// <c3>Disable QP FuSa in development (NOT recommended)
|
||||
// <i>Disable assertions and other self monitoring features
|
||||
// <i>in development build configurations (NDEBUG undefined).
|
||||
// <i>VIOLATES functional safety standards. NOT recommended !!!
|
||||
// <i>NOTE: Disabling safety *violates* functional safety standards.
|
||||
//#ifndef NDEBUG
|
||||
//#define Q_UNSAFE
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c3>Disable QP FuSa in production release
|
||||
// <i>Disable assertions and other self monitoring features
|
||||
// <c3>Disable QP FuSa in production release (NOT recommended)
|
||||
// <i>Disable assertions and other safety features
|
||||
// <i>in the release build configurations (NDEBUG defined).
|
||||
// <i>VIOLATES functional safety standards. NOT recommended !!!
|
||||
// <i>NOTE: Disabling safety *violates* functional safety standards.
|
||||
//#ifdef NDEBUG
|
||||
//#define Q_UNSAFE
|
||||
//#endif
|
||||
@ -80,7 +80,7 @@
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QEP Event Processor
|
||||
// <h>QEP Event Processor (Events)
|
||||
// <i>Events and state machines.
|
||||
|
||||
// <o>Event signal size (Q_SIGNAL_SIZE)
|
||||
@ -94,7 +94,7 @@
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QF Framework
|
||||
// <h>QF Framework (Active Objects)
|
||||
// <i>Active Object framework
|
||||
|
||||
// <o>Maximum # Active Objects (QF_MAX_ACTIVE) <1-64>
|
||||
@ -120,21 +120,6 @@
|
||||
// <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>Provide destructors for QP classes
|
||||
// <i>Destructors for classes
|
||||
//#define Q_XTOR
|
||||
// </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)
|
||||
@ -174,15 +159,50 @@
|
||||
// <i>Default: 2 (64K bytes maximum block size)
|
||||
#define QF_MPOOL_SIZ_SIZE 2U
|
||||
|
||||
// <c2>Enable event parameter initialization (QEVT_PAR_INIT)
|
||||
// <i>Initialize parameters of dynamic events at allocation
|
||||
// <i>(Resource Acquisition Is Initialization (RAII) for dynamic events)
|
||||
//#define QEVT_PAR_INIT
|
||||
// </c>
|
||||
|
||||
// <c1>Provide destructors for QP classes
|
||||
// <i>Presence of destructors pulls in the C++ delete() opeator
|
||||
// <i>NOTE: Not recommended
|
||||
//#define Q_XTOR
|
||||
// </c>
|
||||
|
||||
// <c1>Enable active object stop API (QACTIVE_CAN_STOP)
|
||||
// <i>NOTE: Not recommended
|
||||
//#define QACTIVE_CAN_STOP
|
||||
// </c>
|
||||
|
||||
// <c1>Enable context switch callback *without* QS (QF_ON_CONTEXT_SW)
|
||||
// <i>Context switch callback QF_onContextSw() when Q_SPY is undefined.
|
||||
//#ifndef Q_SPY
|
||||
//#define QF_ON_CONTEXT_SW
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c1>Enable context switch callback *with* QS (QF_ON_CONTEXT_SW)
|
||||
// <i>Context switch callback QF_onContextSw() when Q_SPY is defined.
|
||||
//#ifdef Q_SPY
|
||||
//#define QF_ON_CONTEXT_SW
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c2>Enable memory isolation (QF_MEM_ISOLATE)
|
||||
// <i>Memory isolation (requires MPU)
|
||||
// <i>NOTE: implies QF_ON_CONTEXT_SW.
|
||||
//#define QF_MEM_ISOLATE
|
||||
// </c>
|
||||
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QS Software Tracing
|
||||
// <h>QS Software Tracing (Q_SPY)
|
||||
// <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>NOTE: 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.
|
||||
|
||||
@ -204,38 +224,6 @@
|
||||
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QV Cooperative Kernel
|
||||
// <i>Cooperative run-to-completion 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>
|
||||
|
||||
// </h>
|
||||
|
||||
//------------- <<< end of configuration section >>> -----------------------
|
||||
|
||||
#endif // QP_CONFIG_HPP_
|
@ -1,235 +0,0 @@
|
||||
//============================================================================
|
||||
// QP configuration file (QK on ARM Cortex-R)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// The QP/C software is dual-licensed under the terms of the open-source GNU
|
||||
// General Public License (GPL) or under the terms of one of the closed-
|
||||
// source Quantum Leaps commercial licenses.
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// NOTE:
|
||||
// The GPL (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_HPP_
|
||||
#define QP_CONFIG_HPP_
|
||||
|
||||
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
|
||||
|
||||
// <o>QP API compatibility version (QP_API_VERSION)
|
||||
// <0=> 0 (Maximum compatibility)
|
||||
// <691=>691 (QP 6.9.1 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
|
||||
// <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>Provide destructors for QP classes
|
||||
// <i>Destructors for classes
|
||||
//#define Q_XTOR
|
||||
// </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
|
||||
// <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>QK Preemptive Non-Blocking Kernel
|
||||
// <i>Preemptive non-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>
|
||||
|
||||
// </h>
|
||||
|
||||
//------------- <<< end of configuration section >>> -----------------------
|
||||
|
||||
#endif // QP_CONFIG_HPP_
|
@ -27,7 +27,7 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @date Last updated on: 2024-11-22
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
@ -61,7 +61,7 @@
|
||||
#define QF_INT_ENABLE() \
|
||||
__asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc")
|
||||
#define QF_INT_ENABLE_ALL() \
|
||||
__asm volatile ("MSR cpsr_c,#(0x1F | 0x80 | 0x40)" ::: "cc")
|
||||
__asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc")
|
||||
#else
|
||||
#error Incorrect CPU mode. Must be either __arm__ or __thumb__.
|
||||
#endif
|
||||
|
@ -1,235 +0,0 @@
|
||||
//============================================================================
|
||||
// QP configuration file (QV on ARM Cortex-R)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// The QP/C software is dual-licensed under the terms of the open-source GNU
|
||||
// General Public License (GPL) or under the terms of one of the closed-
|
||||
// source Quantum Leaps commercial licenses.
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// NOTE:
|
||||
// The GPL (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_HPP_
|
||||
#define QP_CONFIG_HPP_
|
||||
|
||||
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
|
||||
|
||||
// <o>QP API compatibility version (QP_API_VERSION)
|
||||
// <0=> 0 (Maximum compatibility)
|
||||
// <691=>691 (QP 6.9.1 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
|
||||
// <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>Provide destructors for QP classes
|
||||
// <i>Destructors for classes
|
||||
//#define Q_XTOR
|
||||
// </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
|
||||
// <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>QV Cooperative Kernel
|
||||
// <i>Cooperative run-to-completion 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>
|
||||
|
||||
// </h>
|
||||
|
||||
//------------- <<< end of configuration section >>> -----------------------
|
||||
|
||||
#endif // QP_CONFIG_HPP_
|
@ -27,7 +27,7 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @date Last updated on: 2024-11-22
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
@ -61,7 +61,7 @@
|
||||
#define QF_INT_ENABLE() \
|
||||
__asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc")
|
||||
#define QF_INT_ENABLE_ALL() \
|
||||
__asm volatile ("MSR cpsr_c,#(0x1F | 0x80 | 0x40)" ::: "cc")
|
||||
__asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc")
|
||||
#else
|
||||
#error Incorrect CPU mode. Must be either __arm__ or __thumb__.
|
||||
#endif
|
||||
|
@ -59,19 +59,19 @@
|
||||
// <i> * Hard-limits for all loops
|
||||
// <i> * Memory Isolation by means of Memory Protection Unit (MPU)
|
||||
|
||||
// <c3>Disable QP FuSa in development
|
||||
// <c3>Disable QP FuSa in development (NOT recommended)
|
||||
// <i>Disable assertions and other self monitoring features
|
||||
// <i>in development build configurations (NDEBUG undefined).
|
||||
// <i>VIOLATES functional safety standards. NOT recommended !!!
|
||||
// <i>NOTE: Disabling safety *violates* functional safety standards.
|
||||
//#ifndef NDEBUG
|
||||
//#define Q_UNSAFE
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c3>Disable QP FuSa in production release
|
||||
// <i>Disable assertions and other self monitoring features
|
||||
// <c3>Disable QP FuSa in production release (NOT recommended)
|
||||
// <i>Disable assertions and other safety features
|
||||
// <i>in the release build configurations (NDEBUG defined).
|
||||
// <i>VIOLATES functional safety standards. NOT recommended !!!
|
||||
// <i>NOTE: Disabling safety *violates* functional safety standards.
|
||||
//#ifdef NDEBUG
|
||||
//#define Q_UNSAFE
|
||||
//#endif
|
||||
@ -80,7 +80,7 @@
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QEP Event Processor
|
||||
// <h>QEP Event Processor (Events)
|
||||
// <i>Events and state machines.
|
||||
|
||||
// <o>Event signal size (Q_SIGNAL_SIZE)
|
||||
@ -94,7 +94,7 @@
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QF Framework
|
||||
// <h>QF Framework (Active Objects)
|
||||
// <i>Active Object framework
|
||||
|
||||
// <o>Maximum # Active Objects (QF_MAX_ACTIVE) <1-64>
|
||||
@ -120,21 +120,6 @@
|
||||
// <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>Provide destructors for QP classes
|
||||
// <i>Destructors for classes
|
||||
//#define Q_XTOR
|
||||
// </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)
|
||||
@ -174,15 +159,50 @@
|
||||
// <i>Default: 2 (64K bytes maximum block size)
|
||||
#define QF_MPOOL_SIZ_SIZE 2U
|
||||
|
||||
// <c2>Enable event parameter initialization (QEVT_PAR_INIT)
|
||||
// <i>Initialize parameters of dynamic events at allocation
|
||||
// <i>(Resource Acquisition Is Initialization (RAII) for dynamic events)
|
||||
//#define QEVT_PAR_INIT
|
||||
// </c>
|
||||
|
||||
// <c1>Provide destructors for QP classes
|
||||
// <i>Presence of destructors pulls in the C++ delete() opeator
|
||||
// <i>NOTE: Not recommended
|
||||
//#define Q_XTOR
|
||||
// </c>
|
||||
|
||||
// <c1>Enable active object stop API (QACTIVE_CAN_STOP)
|
||||
// <i>NOTE: Not recommended
|
||||
//#define QACTIVE_CAN_STOP
|
||||
// </c>
|
||||
|
||||
// <c1>Enable context switch callback *without* QS (QF_ON_CONTEXT_SW)
|
||||
// <i>Context switch callback QF_onContextSw() when Q_SPY is undefined.
|
||||
//#ifndef Q_SPY
|
||||
//#define QF_ON_CONTEXT_SW
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c1>Enable context switch callback *with* QS (QF_ON_CONTEXT_SW)
|
||||
// <i>Context switch callback QF_onContextSw() when Q_SPY is defined.
|
||||
//#ifdef Q_SPY
|
||||
//#define QF_ON_CONTEXT_SW
|
||||
//#endif
|
||||
// </c>
|
||||
|
||||
// <c2>Enable memory isolation (QF_MEM_ISOLATE)
|
||||
// <i>Memory isolation (requires MPU)
|
||||
// <i>NOTE: implies QF_ON_CONTEXT_SW.
|
||||
//#define QF_MEM_ISOLATE
|
||||
// </c>
|
||||
|
||||
// </h>
|
||||
|
||||
//..........................................................................
|
||||
// <h>QS Software Tracing
|
||||
// <h>QS Software Tracing (Q_SPY)
|
||||
// <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>NOTE: 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.
|
||||
|
||||
|
16
qpcpp.qm
16
qpcpp.qm
@ -3431,12 +3431,12 @@ QF_CRIT_EXIT();</code>
|
||||
<specifiers>noexcept</specifiers>
|
||||
<!--${QF::QTimeEvt::noActive::tickRate}-->
|
||||
<parameter name="tickRate" type="std::uint_fast8_t const"/>
|
||||
<code>QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
<code>// NOTE: this function must be called *inside* critical section
|
||||
Q_REQUIRE_INCRIT(900, tickRate < QF_MAX_TICK_RATE);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
bool inactive;
|
||||
|
||||
QF_MEM_SYS();
|
||||
if (timeEvtHead_[tickRate].m_next != nullptr) {
|
||||
inactive = false;
|
||||
}
|
||||
@ -3446,6 +3446,8 @@ else if (timeEvtHead_[tickRate].m_act != nullptr) {
|
||||
else {
|
||||
inactive = true;
|
||||
}
|
||||
QF_MEM_APP();
|
||||
|
||||
return inactive;</code>
|
||||
</operation>
|
||||
<!--${QF::QTimeEvt::toActive}-->
|
||||
@ -5840,9 +5842,9 @@ QF_onContextSw(QP::QActive::registry_[pprev], a);
|
||||
#define QP_HPP_
|
||||
|
||||
//============================================================================
|
||||
#define QP_VERSION_STR "8.0.0"
|
||||
#define QP_VERSION 800U
|
||||
#define QP_RELEASE 0x7055936FU
|
||||
#define QP_VERSION_STR "8.0.1"
|
||||
#define QP_VERSION 801U
|
||||
#define QP_RELEASE 0x703931CEU
|
||||
|
||||
//============================================================================
|
||||
//! @cond INTERNAL
|
||||
@ -6299,7 +6301,6 @@ using char_t = char;
|
||||
<file name="qep_hsm.cpp">
|
||||
<text>#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
#ifdef Q_SPY // QS software tracing enabled?
|
||||
#include "qs_port.hpp" // QS port
|
||||
@ -6367,7 +6368,6 @@ $define ${QEP::QHsm}</text>
|
||||
<file name="qep_msm.cpp">
|
||||
<text>#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
#ifdef Q_SPY // QS software tracing enabled?
|
||||
#include "qs_port.hpp" // QS port
|
||||
|
@ -1,18 +1,21 @@
|
||||
a37f690d75dac83d45b5da3082d28f188191fd9a *qpcpp.qm
|
||||
bda783a346fb750c7a1fe32dc0a8ca52609cb5f4 *qpcpp.qm
|
||||
46578fc304c597329289978acee1027c8c533335 *include/qequeue.hpp
|
||||
1a8e0b05536b89c1cd3806782ae1a21dd4ceca69 *include/qk.hpp
|
||||
cb1c39aabacb619060924356f7c8e900686538e0 *include/qmpool.hpp
|
||||
e0d974faef6b60cc455e49abb32d43128b8c79cf *include/qp.hpp
|
||||
559a9ca895f97f38c5d3bb0511675f321e041911 *include/qp.hpp
|
||||
bf47a939e525fa575673f89b8106bcee166240a2 *include/qp_pkg.hpp
|
||||
e5b0d14c9e6994b82a5cd9200bde46bd179bfb20 *include/qpcpp.hpp
|
||||
d4f14d2ed18ef725ea17d0a97b78ae22a283c96b *include/qs.hpp
|
||||
88220a7d892fee54053b467b596dc6b536aaf8be *include/qs_dummy.hpp
|
||||
9694f10e44d53563599410d37dd1c5a19cf1788b *include/qs_pkg.hpp
|
||||
49d2620b0afa9e74d73680495c3e8a931e5d8f73 *include/qsafe.h
|
||||
09e9ffe95120ba17a49d7039b5316f2614710dab *include/qstamp.hpp
|
||||
73749ed396bbc0419971769a47069448c8136960 *include/qv.hpp
|
||||
05b617dad20f07f07b64dccf84f9b7cd9b8d2bb7 *include/qxk.hpp
|
||||
0199f3eeb6c02b8cc890ee4c6f6d344569a0858f *include/README.md
|
||||
71899ce74eeb04f333ed00d53f87719f722a39ab *src/qf/CMakeLists.txt
|
||||
81b54ca9a4dff44d24c0f3cd687aaa58afe634ab *src/qf/qep_hsm.cpp
|
||||
13cb63db437dd4f176dd846eda49bda9827ca571 *src/qf/qep_msm.cpp
|
||||
864d627f2600987a2194c57093e1f210e0de2a7a *src/qf/qep_hsm.cpp
|
||||
d3242def2b23df5b9704bb3b0411fd01de6c0a67 *src/qf/qep_msm.cpp
|
||||
62f87a60d04e1c98f40162a166ec14a1f2f1252f *src/qf/qf_act.cpp
|
||||
07671fb85e9b2492b0ea37b853d7e0eea42bf637 *src/qf/qf_actq.cpp
|
||||
ed83f5f8b3533cc97ffc2a85aeeb63f29b4f1dd8 *src/qf/qf_defer.cpp
|
||||
@ -22,41 +25,58 @@ ef51e4840107b0ed6ec97e170ac2689e1b1fdb95 *src/qf/qf_ps.cpp
|
||||
08b490d7505a7ff6fe493058975eb9f0a82daa3d *src/qf/qf_qact.cpp
|
||||
23892cde4fd7226e899026884e07b01e32d0aef4 *src/qf/qf_qeq.cpp
|
||||
5fc4874b74779641454e2d8e7960a5bf3d130115 *src/qf/qf_qmact.cpp
|
||||
7aedf35884943f3add9f39e57e5ea4ad7344d110 *src/qf/qf_time.cpp
|
||||
04dd9fbddc336f096bd214f8e7368d7a6dce43c8 *src/qf/qf_time.cpp
|
||||
7cdab433e81612862fd27f0cf792d38e1197d064 *src/qk/CMakeLists.txt
|
||||
1be4743dc14186779abb96b4bd16ba9a99d3314d *src/qk/qk.cpp
|
||||
eb28260d471fc752ca54b2c1e2d763f28432c2c1 *src/qs/CMakeLists.txt
|
||||
66fd2a553c8ae6709dfe286b6ccce002208251f1 *src/qs/qs.cpp
|
||||
2ca73a0d38dd7b544864d72fd337f29c7dae2a85 *src/qs/qs_64bit.cpp
|
||||
349c18625bd2cceda297e1c98a85a9fa9538cef9 *src/qs/qs_fp.cpp
|
||||
ad4e3a9faacc038cb51a7773ffc42903be947a22 *src/qs/qs_rx.cpp
|
||||
8008d9c24757b2bb02e85123aa89a3a33090921d *src/qs/qstamp.cpp
|
||||
92338453dc612419b0e16e0560e761312d0f3900 *src/qs/qutest.cpp
|
||||
b6d93a16f5b176d3da4888a7efb265730337f46d *src/qv/CMakeLists.txt
|
||||
f530563e062ff7ea84763f6e799bf4ca1cb73054 *src/qv/qv.cpp
|
||||
8456ce45995423dd872685229539618abaa9c580 *ports/arm-cm/qk/armclang/qk_port.cpp
|
||||
94a289a5f900afaeb47b5454824bc4911df8014f *ports/arm-cm/qk/armclang/qp_port.hpp
|
||||
2d0c3d3d93e4d4ac8e2218b9ed68e6269b02419e *src/qxk/qxk.cpp
|
||||
e0e633a980e4c04a85f877e810ce77ad51903e87 *src/qxk/qxk_mutex.cpp
|
||||
8e15812d14f250866dfa8a96fe5b14638ca2c4ae *src/qxk/qxk_sema.cpp
|
||||
58e6a9354a1c7c4d53204b7ad2fad05d6eb3117c *src/qxk/qxk_xthr.cpp
|
||||
81f1a6dbcebd0b5df9e437902ffbe0fecdd03d25 *ports/arm-cm/qk/armclang/qk_port.cpp
|
||||
7119fc94c0b5560ab8e3197a83917667e311e415 *ports/arm-cm/qk/armclang/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qk/armclang/qs_port.hpp
|
||||
fafeded481e004677bfa6eb7cce7e4c4dbd5fd2f *ports/arm-cm/qk/config/qp_config.hpp
|
||||
f94a3fb033b87de04efec19e25c5630b82e9d749 *ports/arm-cm/qk/gnu/qk_port.cpp
|
||||
1c35b7f6a992d0a4755080903d2a2fd5aa06c923 *ports/arm-cm/qk/gnu/qp_port.hpp
|
||||
5f2353117f9940b0ea891d2e0bd486e0d024b67c *ports/arm-cm/qk/gnu/qk_port.cpp
|
||||
7119fc94c0b5560ab8e3197a83917667e311e415 *ports/arm-cm/qk/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qk/gnu/qs_port.hpp
|
||||
f52bee74512d5c2016eaf20996eee10e52a5d71f *ports/arm-cm/qk/iar/qk_port.cpp
|
||||
458994edab3235f9d9a9faf78485ecb4edc3bdd1 *ports/arm-cm/qk/iar/qp_port.hpp
|
||||
2b9c1112e3e5be79ce2b1799adfd5e812467765b *ports/arm-cm/qk/iar/qk_port.cpp
|
||||
f54416674c33ffd19408f02af60f7d69b8613797 *ports/arm-cm/qk/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qk/iar/qs_port.hpp
|
||||
f59663361efec401c02436eabfe6931729d98b1d *ports/arm-cm/qv/armclang/qp_port.hpp
|
||||
9cc71aed12d57408252019035aff449ce028372c *ports/arm-cm/qv/armclang/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qv/armclang/qs_port.hpp
|
||||
c225966c8601a651196e3e30af7d0dce6079d610 *ports/arm-cm/qv/armclang/qv_port.cpp
|
||||
d7f22b95fc3b2228a669c5b9167bc3021156a8c7 *ports/arm-cm/qv/config/qp_config.hpp
|
||||
fffed0cc5c1180df7550f579268ab7c528f3afda *ports/arm-cm/qv/gnu/qp_port.hpp
|
||||
90b14adcd8f8b29de3358073c39bd4161f5ce2eb *ports/arm-cm/qv/armclang/qv_port.cpp
|
||||
bed3687b29555f6fa9c721cf34a098218f64e1ad *ports/arm-cm/qv/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qv/gnu/qs_port.hpp
|
||||
bd87c7c78142119968ae65dda01ba75b3170ca08 *ports/arm-cm/qv/gnu/qv_port.cpp
|
||||
cf46244c7dfb6185f2c01cfdba4d699bf01388e7 *ports/arm-cm/qv/iar/qp_port.hpp
|
||||
b2d5e72b65813bdc37bcab3c8cd9107bda009131 *ports/arm-cm/qv/gnu/qv_port.cpp
|
||||
424864680661227e4ab418b2af905d4bd92767ad *ports/arm-cm/qv/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qv/iar/qs_port.hpp
|
||||
421f4bc740a150dae18672f22633bef822119071 *ports/arm-cm/qv/iar/qv_port.cpp
|
||||
7341172192afc119dc3188b51e64b6cb33dc4f23 *ports/arm-cr/qk/config/qp_config.hpp
|
||||
53378c89dd07cdf1b5fc1428938a2bf33ef9c897 *ports/arm-cr/qk/gnu/qp_port.hpp
|
||||
15fb0660dff33295bad38facfc7aacca928133a3 *ports/arm-cm/qv/iar/qv_port.cpp
|
||||
9e248cb426d8495e5cd677ff79cd3b9ced2a76a5 *ports/arm-cm/qxk/armclang/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qxk/armclang/qs_port.hpp
|
||||
16423aebab91be16d8c2c7b128d8494709a6a746 *ports/arm-cm/qxk/armclang/qxk_port.cpp
|
||||
9ec8ed9717f9130b23252d2c381f779617165932 *ports/arm-cm/qxk/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qxk/gnu/qs_port.hpp
|
||||
75fc7a6c1b0775832f3e0e0e2bbacc19f56ddc94 *ports/arm-cm/qxk/gnu/qxk_port.cpp
|
||||
f40b0ea4761d187ac7d4460a161efb9b4f3e6ef6 *ports/arm-cm/qxk/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qxk/iar/qs_port.hpp
|
||||
44509ff079ba173a28076f3fa1488582a6ef48a1 *ports/arm-cm/qxk/iar/qxk_port.cpp
|
||||
69256fd1a5b81db3e3174cba9196bf9da925e098 *ports/arm-cm/qutest/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qutest/qs_port.hpp
|
||||
1194c26fdfc9665a04cc3d01e6de49afe1698376 *ports/arm-cr/qk/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qk/gnu/qs_port.hpp
|
||||
a8f4351725564e449206909176d09bc58cd6f45d *ports/arm-cr/qk/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qk/iar/qs_port.hpp
|
||||
7203200deaa5dbb4746434d4a3d79a160d4ccf4b *ports/arm-cr/qk/ti/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qk/ti/qs_port.hpp
|
||||
b79ee5fda27709554b5dbdc3162d59787af85ecb *ports/arm-cr/qv/gnu/qp_port.hpp
|
||||
fd3e4b882efb671f2522ae83bfde016ea416d4a7 *ports/arm-cr/qv/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qv/gnu/qs_port.hpp
|
||||
fafbe56ae4266a412cb1b6db6e146fbfe5022b4a *ports/arm-cr/qv/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qv/iar/qs_port.hpp
|
||||
@ -68,7 +88,7 @@ bc080e68d0edfc28da2df882ed3661cf99f2942c *ports/msp430/qk/qp_port.hpp
|
||||
197ec45394793b79a29afe5bb31b6de1ad78ad00 *ports/msp430/qv/qs_port.hpp
|
||||
650f628d87a39c559a87c6f849c58fb9a8e777a7 *ports/msp430/qutest/qp_port.hpp
|
||||
197ec45394793b79a29afe5bb31b6de1ad78ad00 *ports/msp430/qutest/qs_port.hpp
|
||||
59011c6a3cbf07a38f1a74139cef1a82f22cc475 *ports/config/qp_config.hpp
|
||||
8614593b911e6db6f634d972e79093e964756556 *ports/config/qp_config.hpp
|
||||
b6b5d23c618976a6fbed51dc5a13e227928e1d4b *ports/embos/CMakeLists.txt
|
||||
0b5ad806f47800c1481c9af3d88c1bff3cb1d784 *ports/embos/qf_port.cpp
|
||||
5e28aa0e89239f970e4b5e85be4e5c3b6a34dd69 *ports/embos/qp_port.hpp
|
||||
@ -103,6 +123,11 @@ f458af1511007d6ba2a4a0a0e40d74e03719ceb1 *ports/posix-qv/qp_port.hpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/posix-qv/qs_port.hpp
|
||||
e2e295c371bc14f0089a888b07d98c657dea07bf *ports/posix-qv/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix-qv/safe_std.h
|
||||
c9969a454b540a3b1abd3dd5cc46fb211663310e *ports/posix-qutest/CMakeLists.txt
|
||||
edfa2baff22735f98a094e315db11c40ed07e5e8 *ports/posix-qutest/qp_port.hpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/posix-qutest/qs_port.hpp
|
||||
772fdcf6a4ca3e3303016384de92874ec06c11fe *ports/posix-qutest/qutest_port.cpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix-qutest/safe_std.h
|
||||
06b76c6c30ea880876b47ee27115178ff62ea66b *ports/win32/CMakeLists.txt
|
||||
48dfd18fce993f237138d5d99f2fb0e385efbe93 *ports/win32/qf_port.cpp
|
||||
ea88910c991455756433cff5338a62ed3d181bf2 *ports/win32/qp_port.hpp
|
||||
@ -121,6 +146,11 @@ f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/win32-qv/qs_port.hpp
|
||||
ddc62932b46bbc0ad147193d0dd7efa28127c6c4 *ports/win32-qv/qwin_gui.h
|
||||
ddd27415c3d1df6d8c210966e8915c407b15bf58 *ports/win32-qv/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32-qv/safe_std.h
|
||||
3c23c06f425a8d8dbb18d1f191ac6cab483a8e51 *ports/win32-qutest/CMakeLists.txt
|
||||
edfa2baff22735f98a094e315db11c40ed07e5e8 *ports/win32-qutest/qp_port.hpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/win32-qutest/qs_port.hpp
|
||||
5bda26c8c82914e6cc16685e4adc02cbc32c5291 *ports/win32-qutest/qutest_port.cpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32-qutest/safe_std.h
|
||||
76dd9078dc4311d53d3862d44177a8660258da6d *zephyr/CMakeLists.txt
|
||||
36a0252cf0bfd6be0d345c48c00b2300f8917f05 *zephyr/Kconfig
|
||||
2eb2a922e18b4760a68151ebee1b6282d20b4692 *zephyr/module.yml
|
@ -1,18 +1,20 @@
|
||||
@setlocal
|
||||
|
||||
set VERSION=8.0.1
|
||||
|
||||
:: usage
|
||||
@echo Usage: qppcp_sha1 [gen]
|
||||
@echo examples:
|
||||
@echo qppcp_sha1 : check the sha1 sums in the file qpcpp.sha1
|
||||
@echo qpcpp_sha1 gen : generate the sha1 file qpcpp.sha1
|
||||
@echo qppcp_sha1 : check the sha1 sums in the file qpcpp_%VERSION%.sha1
|
||||
@echo qpcpp_sha1 gen : generate the sha1 file qpcpp_%VERSION%.sha1
|
||||
@echo.
|
||||
|
||||
@if NOT "%1"=="gen" (
|
||||
sha1sum --check --warn qpcpp.sha1
|
||||
sha1sum --check --warn qpcpp_%VERSION%.sha1
|
||||
goto end
|
||||
)
|
||||
|
||||
@echo generating qpcpp.sha1...
|
||||
@echo generating qpcpp_%VERSION%.sha1...
|
||||
@sha1sum qpcpp.qm ^
|
||||
include/* ^
|
||||
src/qf/* src/qk/* src/qs/* src/qv/* src/qxk/* ^
|
||||
@ -33,7 +35,7 @@ goto end
|
||||
ports/posix/* ports/posix-qv/* ports/posix-qutest/* ^
|
||||
ports/win32/* ports/win32-qv/* ports/win32-qutest/* ^
|
||||
zephyr/* ^
|
||||
> qpcpp.sha1
|
||||
> qpcpp_%VERSION%.sha1
|
||||
@echo done
|
||||
|
||||
:end
|
||||
|
@ -1,7 +1,7 @@
|
||||
# qpcpp/src
|
||||
add_subdirectory(qf)
|
||||
add_subdirectory(qs)
|
||||
if(${PORT} IN_LIST QPC_BAREMETAL_PORTS)
|
||||
if(${PORT} IN_LIST QPCPP_BAREMETAL_PORTS)
|
||||
message(STATUS "adding subdir '${KERNEL}' for port '${PORT}'")
|
||||
add_subdirectory(${KERNEL})
|
||||
endif()
|
||||
|
@ -34,7 +34,6 @@
|
||||
//$endhead${src::qf::qep_hsm.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
#ifdef Q_SPY // QS software tracing enabled?
|
||||
#include "qs_port.hpp" // QS port
|
||||
|
@ -34,7 +34,6 @@
|
||||
//$endhead${src::qf::qep_msm.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
#ifdef Q_SPY // QS software tracing enabled?
|
||||
#include "qs_port.hpp" // QS port
|
||||
|
@ -519,12 +519,12 @@ void QTimeEvt::tick(
|
||||
|
||||
//${QF::QTimeEvt::noActive} ..................................................
|
||||
bool QTimeEvt::noActive(std::uint_fast8_t const tickRate) noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
// NOTE: this function must be called *inside* critical section
|
||||
Q_REQUIRE_INCRIT(900, tickRate < QF_MAX_TICK_RATE);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
bool inactive;
|
||||
|
||||
QF_MEM_SYS();
|
||||
if (timeEvtHead_[tickRate].m_next != nullptr) {
|
||||
inactive = false;
|
||||
}
|
||||
@ -534,6 +534,8 @@ bool QTimeEvt::noActive(std::uint_fast8_t const tickRate) noexcept {
|
||||
else {
|
||||
inactive = true;
|
||||
}
|
||||
QF_MEM_APP();
|
||||
|
||||
return inactive;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user