mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-28 06:02:56 +08:00
5.9.6-beta
This commit is contained in:
parent
d90418fdb9
commit
f691fd14b9
225
3rd_party/CMSIS/Include/cmsis_ccs.h
vendored
225
3rd_party/CMSIS/Include/cmsis_ccs.h
vendored
@ -1,9 +1,6 @@
|
||||
//*****************************************************************************
|
||||
// Updated by Quantum Leaps for CMIS 5.0.1
|
||||
// 2016-12-12
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (C) 2012 - 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
// Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
@ -40,63 +37,18 @@
|
||||
#ifndef CMSIS_CCS_H_
|
||||
#define CMSIS_CCS_H_
|
||||
|
||||
// Data Synchronization Barrier
|
||||
__attribute__( ( always_inline ) ) static inline void __DSB(void)
|
||||
{
|
||||
__asm(" dsb");
|
||||
}
|
||||
|
||||
// Instruction Synchronization Barrier
|
||||
__attribute__( ( always_inline ) ) static inline void __ISB(void)
|
||||
{
|
||||
__asm(" isb");
|
||||
}
|
||||
|
||||
#if (0)
|
||||
// Get Main Stack Pointer
|
||||
static inline uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
//__asm (" mrs result, msp");
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Set Main Stack Pointer
|
||||
static inline void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
asm(" .global topOfMainStack");
|
||||
__asm (" msr msp, topOfMainStack");
|
||||
}
|
||||
|
||||
|
||||
// Get Priority Mask
|
||||
static inline uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__asm (" mrs result, primask");
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
// Set Priority Mask
|
||||
static inline void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
__asm (" msr primask, priMask");
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
// CMSIS-compatible instruction calls
|
||||
//*****************************************************************************
|
||||
|
||||
//
|
||||
// v5e, v6, Cortex-M3, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics
|
||||
//
|
||||
#define __CLZ _norm
|
||||
#define __SXTB _sxtb
|
||||
#define __SXTH _sxth
|
||||
#define __UXTB _uxtb
|
||||
#define __UXTH _uxth
|
||||
#define __NOP __nop
|
||||
#define __WFI __wfi
|
||||
|
||||
#define __CLZ _norm
|
||||
#define __SXTB _sxtb
|
||||
#define __SXTH _sxth
|
||||
#define __UXTB _uxtb
|
||||
#define __UXTH _uxth
|
||||
// CCS supports intrinsics to take advantage of the shift operand left/right
|
||||
// before saturation extension of SSAT, but CMSIS does not take advantage
|
||||
// of those, so tell the compiler to use a sat & shift left with a shift
|
||||
@ -108,18 +60,67 @@ static inline void __set_PRIMASK(uint32_t priMask)
|
||||
// Only define M4 based intrinsics if we're not using an M4
|
||||
//
|
||||
#if defined (__TI_TMS470_V7M4__)
|
||||
|
||||
//
|
||||
// Add definitions for enable and disable interrupts
|
||||
//
|
||||
#if defined (__TI_COMPILER_VERSION__)
|
||||
|
||||
#if (__TI_COMPILER_VERSION__ >= 5002000)
|
||||
|
||||
#define __enable_irq _enable_IRQ
|
||||
#define __disable_irq _disable_IRQ
|
||||
|
||||
// No Operation
|
||||
#define __NOP __nop
|
||||
// Data Synchronization Barrier
|
||||
#define __DSB _dsb
|
||||
|
||||
#define __ISB _isb
|
||||
|
||||
#elif (__TI_COMPILER_VERSION__ >= 4009000)
|
||||
|
||||
#define __enable_fault_irq _enable_interrupts
|
||||
#define __disable_fault_irq _disable_interrupts
|
||||
|
||||
// No Operation
|
||||
__attribute__( ( always_inline ) ) static inline void __nop(void)
|
||||
{
|
||||
__asm(" nop");
|
||||
}
|
||||
__attribute__( ( always_inline ) ) static inline void __NOP(void)
|
||||
{
|
||||
__asm(" nop");
|
||||
}
|
||||
// Data Synchronization Barrier
|
||||
__attribute__( ( always_inline ) ) static inline void __DSB(void)
|
||||
{
|
||||
__asm(" dsb");
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) static inline void __ISB(void)
|
||||
{
|
||||
__asm(" isb");
|
||||
}
|
||||
|
||||
#endif /*__TI_COMPILER_VERSION__ version*/
|
||||
|
||||
#endif /*__TI_COMPILER_VERSION__*/
|
||||
|
||||
//
|
||||
// V5E, V6, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics
|
||||
//
|
||||
#define __QADD _sadd
|
||||
#define __QDADD _sdadd
|
||||
#define __QDSUB _sdsub
|
||||
#define __SMLABB _smlabb
|
||||
#define __SMLABT _smlabt
|
||||
#define __SMLALBB _smlalbb
|
||||
#define __SMLALBT _smlalbt
|
||||
#define __SMLALTB _smlaltb
|
||||
#define __SMLALTT _smlaltt
|
||||
#define __ROR __ror
|
||||
#define __SXTB16(src) _sxtb16((src),0)
|
||||
#define __QADD _sadd
|
||||
#define __QDADD _sdadd
|
||||
#define __QDSUB _sdsub
|
||||
#define __SMLABB _smlabb
|
||||
#define __SMLABT _smlabt
|
||||
#define __SMLALBB _smlalbb
|
||||
#define __SMLALBT _smlalbt
|
||||
#define __SMLALTB _smlaltb
|
||||
#define __SMLALTT _smlaltt
|
||||
#define __SMLATB _smlatb
|
||||
#define __SMLATT _smlatt
|
||||
#define __SMLAWB _smlawb
|
||||
@ -131,77 +132,77 @@ static inline void __set_PRIMASK(uint32_t priMask)
|
||||
#define __SMULTT _smultt
|
||||
#define __SMULWB _smulwb
|
||||
#define __SMULWT _smulwt
|
||||
#define __QSUB _ssub
|
||||
#define __SUBC _subc
|
||||
#define __QSUB _ssub
|
||||
#define __SUBC _subc
|
||||
|
||||
//
|
||||
// v6, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics
|
||||
//
|
||||
#define __SHASX _shaddsubx
|
||||
#define __SHSAX _shsubaddx
|
||||
#define __PKHBT _pkhbt
|
||||
#define __PKHTB _pkhtb
|
||||
#define __SHASX _shaddsubx
|
||||
#define __SHSAX _shsubaddx
|
||||
#define __PKHBT _pkhbt
|
||||
#define __PKHTB _pkhtb
|
||||
#define __QADD16 _qadd16
|
||||
#define __QADD8 _qadd8
|
||||
#define __QADD8 _qadd8
|
||||
#define __QSUB16 _qsub16
|
||||
#define __QSUB8 _qsub8
|
||||
#define __QASX _saddsubx
|
||||
#define __QSAX _qsubaddx
|
||||
#define __QSUB8 _qsub8
|
||||
#define __QASX _saddsubx
|
||||
#define __QSAX _qsubaddx
|
||||
#define __SADD16 _sadd16
|
||||
#define __SADD8 _sadd8
|
||||
#define __SASX _saddsubx
|
||||
#define __SEL _sel
|
||||
#define __SHADD16 _shadd16
|
||||
#define __SADD8 _sadd8
|
||||
#define __SASX _saddsubx
|
||||
#define __SEL _sel
|
||||
#define __SHADD16 _shadd16
|
||||
#define __SHADD8 _shadd8
|
||||
#define __SHSUB16 _shsub16
|
||||
#define __SHSUB16 _shsub16
|
||||
#define __SHSUB8 _shsub8
|
||||
#define __SMLAD _smlad
|
||||
#define __SMLAD _smlad
|
||||
#define __SMLADX _smladx
|
||||
#define __SMLALD _smlald
|
||||
#define __SMLALDX _smlaldx
|
||||
#define __SMLSD _smlsd
|
||||
#define __SMLALD(src1, src2, accumulator) _smlald(accumulator, src1, src2)
|
||||
#define __SMLALDX _smlaldx
|
||||
#define __SMLSD _smlsd
|
||||
#define __SMLSDX _smlsdx
|
||||
#define __SMLSLD _smlsld
|
||||
#define __SMLSLDX _smlsldx
|
||||
#define __SMMLA _smmla
|
||||
#define __SMLSLDX _smlsldx
|
||||
#define __SMMLA _smmla
|
||||
#define __SMMLAR _smmlar
|
||||
#define __SMMLS _smmls
|
||||
#define __SMMLS _smmls
|
||||
#define __SMMLSR _smmlsr
|
||||
#define __SMMUL _smmul
|
||||
#define __SMMUL _smmul
|
||||
#define __SMMULR _smmulr
|
||||
#define __SMUAD _smuad
|
||||
#define __SMUAD _smuad
|
||||
#define __SMUADX _smuadx
|
||||
#define __SMUSD _smusd
|
||||
#define __SMUSDX _smusd
|
||||
#define __SMUSD _smusd
|
||||
#define __SMUSDX _smusdx
|
||||
#define __SSAT16 _ssat16
|
||||
#define __SSUB16 _ssub16
|
||||
#define __SSUB8 _ssub8
|
||||
#define __SSAX _ssubaddx
|
||||
#define __SXTAB _sxtab
|
||||
#define __SXTAB16 _sxtab16
|
||||
#define __SXTAH _sxtah
|
||||
#define __UMAAL _umaal
|
||||
#define __SSUB8 _ssub8
|
||||
#define __SSAX _ssubaddx
|
||||
#define __SXTAB _sxtab
|
||||
#define __SXTAB16 _sxtab16
|
||||
#define __SXTAH _sxtah
|
||||
#define __UMAAL _umaal
|
||||
#define __UADD16 _uadd16
|
||||
#define __UADD8 _uadd8
|
||||
#define __UHADD16 _uhadd16
|
||||
#define __UADD8 _uadd8
|
||||
#define __UHADD16 _uhadd16
|
||||
#define __UHADD8 _uhadd8
|
||||
#define __UASX _uaddsubx
|
||||
#define __UHSUB16 _uhsub16
|
||||
#define __UASX _uaddsubx
|
||||
#define __UHSUB16 _uhsub16
|
||||
#define __UHSUB8 _uhsub8
|
||||
#define __UQADD16 _uqadd16
|
||||
#define __UQADD16 _uqadd16
|
||||
#define __UQADD8 _uqadd8
|
||||
#define __UQASX _uqaddsubx
|
||||
#define __UQSUB16 _uqsub16
|
||||
#define __UQASX _uqaddsubx
|
||||
#define __UQSUB16 _uqsub16
|
||||
#define __UQSUB8 _uqsub8
|
||||
#define __UQSAX _uqsubaddx
|
||||
#define __USAD8 _usad8
|
||||
#define __UQSAX _uqsubaddx
|
||||
#define __USAD8 _usad8
|
||||
#define __USAT16 _usat16
|
||||
#define __USUB16 _usub16
|
||||
#define __USUB8 _usub8
|
||||
#define __USAX _usubaddx
|
||||
#define __UXTAB _uxtab
|
||||
#define __UXTAB16 _uxtab16
|
||||
#define __UXTAH _uxtah
|
||||
#define __USUB8 _usub8
|
||||
#define __USAX _usubaddx
|
||||
#define __UXTAB _uxtab
|
||||
#define __UXTAB16 _uxtab16
|
||||
#define __UXTAH _uxtah
|
||||
#define __UXTB16 _uxtb16
|
||||
#endif /*__TI_TMS470_V7M4__*/
|
||||
|
||||
|
17
README.md
17
README.md
@ -1,8 +1,9 @@
|
||||
![QP framework](https://state-machine.com/img/qp_banner.jpg)
|
||||
|
||||
> **NOTE:** If your company has a policy forbidding open source in your product, all QP frameworks can be [licensed commercially](https://state-machine.com/licensing), in which case you don't use any open source license and you do not violate your policy.
|
||||
|
||||
# What's New?
|
||||
View QP/C++ Revision History at:
|
||||
https://state-machine.com/qpcpp/history.html
|
||||
View QP/C++ Revision History at: https://state-machine.com/qpcpp/history.html
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
# About QP/C++
|
||||
@ -71,14 +72,20 @@ https://state-machine.com/doc/AN_Getting_Started_with_QPCpp.pdf
|
||||
The guide also contains a tutorial, in which you build a simple "Blinky"
|
||||
application.
|
||||
|
||||
> NOTE: QP/C++ can be unzipped anywhere in your file system, but the
|
||||
> **NOTE:** QP/C++ can be unzipped anywhere in your file system, but the
|
||||
recommended location is `C:\qp\qpcpp` on Windows and `~/qp/qpcpp`
|
||||
on Linux/MacOS.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
# QP/C++ Licensing
|
||||
QP/C++ is licensed under the increasingly popular [dual licensing model](https://state-machine.com/licensing), in which both the open source software distribution mechanism and traditional closed source software distribution models are combined.
|
||||
|
||||
> **NOTE:** If your company has a policy forbidding open source in your product, all QP frameworks can be [licensed commercially](https://state-machine.com/licensing), in which case you don't use any open source license and you do not violate your policy.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
# QP/C++ Documentation
|
||||
The **QP/C++ Manual** is located online at:
|
||||
- https://state-machine.com/qpcpp
|
||||
The **QP/C++ Manual** is located online at: https://state-machine.com/qpcpp
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
# How to get help?
|
||||
|
@ -4,8 +4,8 @@ namespace QP {
|
||||
|
||||
@section qpcpp_5_9_5 Version 5.9.5, 2017-07-20
|
||||
This release fixes the following bugs:
|
||||
- <a href="https://sourceforge.net/p/qpc/bugs/178/" class="extern">bug#178</a> "GNU-ARM compiler reports "Error: unaligned opcodes..." in startup code for QP/C/C++/nano examples". The bug fix entails modifying the startup code for the GNU-ARM compiler in the `3rd_party` directory. Specifically, the proper alignment directives have been added to the inline assembly in the exception handlers.
|
||||
- <a href="https://sourceforge.net/p/qpc/bugs/179/" class="extern">bug#179</a> "Assertion ID 210 fires when signaling on a QXK semaphore"
|
||||
- <a href="https://sourceforge.net/p/qpc/bugs/178/" class="extern">bug#178</a> "GNU-ARM compiler reports "Error: unaligned opcodes..." in startup code for QP/C/C++/nano examples". The bug fix entails modifying the startup code for the GNU-ARM compiler in the `3rd_party` directory. Specifically, the proper alignment directives have been added to the inline assembly in the exception handlers.
|
||||
- <a href="https://sourceforge.net/p/qpc/bugs/179/" class="extern">bug#179</a> "Assertion ID 210 fires when signaling on a QXK semaphore"
|
||||
|
||||
This release fixes the naming problem of the startup code for the
|
||||
STM32F7-Discovery board (in the `3rd_party/stm32f7-discovery/gnu/ and arm/`
|
||||
|
6312
doxygen/metrics.dox
6312
doxygen/metrics.dox
File diff suppressed because it is too large
Load Diff
@ -7,15 +7,15 @@ private:
|
||||
uint8_t m_opKey;
|
||||
|
||||
public:
|
||||
Calc() : QHsm(Q_STATE_CAST(&QCalc::initial)) { // ctor
|
||||
Calc() : QHsm(Q_STATE_CAST(&Calc::initial)) { // ctor
|
||||
}
|
||||
|
||||
protected:
|
||||
static QState initial (Calc * const me, QEvt const *e);
|
||||
static QState on (Calc * const me, QEvt const *e);
|
||||
static QState error (Calc * const me, QEvt const *e);
|
||||
static QState ready (Calc * const me, QEvt const *e);
|
||||
static QState result (Calc * const me, QEvt const *e);
|
||||
static QState begin (Calc * const me, QEvt const *e);
|
||||
static QState initial(Calc * const me, QEvt const *e);
|
||||
static QState on (Calc * const me, QEvt const *e);
|
||||
static QState error (Calc * const me, QEvt const *e);
|
||||
static QState ready (Calc * const me, QEvt const *e);
|
||||
static QState result (Calc * const me, QEvt const *e);
|
||||
static QState begin (Calc * const me, QEvt const *e);
|
||||
. . .
|
||||
};
|
||||
|
@ -13,11 +13,11 @@ protected:
|
||||
// NOTE: QMsm state machine code is not intended for manual
|
||||
// coding but rather needs to be generated automatically by
|
||||
// the QM modeling tool
|
||||
static QState initial (Calc * const me, QEvt const *e);
|
||||
static QState on (Calc * const me, QEvt const *e);
|
||||
static QState error (Calc * const me, QEvt const *e);
|
||||
static QState ready (Calc * const me, QEvt const *e);
|
||||
static QState result (Calc * const me, QEvt const *e);
|
||||
static QState begin (Calc * const me, QEvt const *e);
|
||||
static QState initial(Calc * const me, QEvt const *e);
|
||||
static QState on (Calc * const me, QEvt const *e);
|
||||
static QState error (Calc * const me, QEvt const *e);
|
||||
static QState ready (Calc * const me, QEvt const *e);
|
||||
static QState result (Calc * const me, QEvt const *e);
|
||||
static QState begin (Calc * const me, QEvt const *e);
|
||||
. . .
|
||||
};
|
||||
|
@ -32,11 +32,11 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>Input description</name>
|
||||
<state>No specifier n, no float nor long long, no scan set, no assignment suppressing.</state>
|
||||
<state>No specifier n, no float nor long long, no scan set, no assignment suppressing, without multibyte support.</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>Output description</name>
|
||||
<state>No specifier a, A, no specifier n, no float nor long long, no flags.</state>
|
||||
<state>No specifier a, A, no specifier n, no float nor long long, no flags, without multibyte support.</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>GOutputBinary</name>
|
||||
@ -143,12 +143,12 @@
|
||||
<option>
|
||||
<name>FPU2</name>
|
||||
<version>0</version>
|
||||
<state>4</state>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>NrRegs</name>
|
||||
<version>0</version>
|
||||
<state>1</state>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>NEON</name>
|
||||
@ -339,7 +339,7 @@
|
||||
<state>$PROJ_DIR$\..</state>
|
||||
<state>$PROJ_DIR$\..\..</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\include</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\source</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\src</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
|
||||
@ -1087,7 +1087,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>OGLastSavedByProductVersion</name>
|
||||
<state>7.60.1.11206</state>
|
||||
<state>8.11.1.13270</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>GeneralEnableMisra</name>
|
||||
@ -1361,7 +1361,7 @@
|
||||
<state>$PROJ_DIR$\..</state>
|
||||
<state>$PROJ_DIR$\..\..</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\include</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\source</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\src</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
|
||||
@ -2109,7 +2109,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>OGLastSavedByProductVersion</name>
|
||||
<state>7.60.1.11206</state>
|
||||
<state>8.11.1.13270</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>GeneralEnableMisra</name>
|
||||
@ -2383,7 +2383,7 @@
|
||||
<state>$PROJ_DIR$\..</state>
|
||||
<state>$PROJ_DIR$\..\..</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\include</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\source</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\src</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
|
||||
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
|
||||
@ -3117,58 +3117,52 @@
|
||||
<group>
|
||||
<name>QP</name>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qep_hsm.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qep_msm.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_act.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_actq.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_defer.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_dyn.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_mem.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_pkg.h</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_ps.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qact.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qeq.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qmact.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_time.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_mutex.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_pkg.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_sema.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_xthr.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.cpp</name>
|
||||
</file>
|
||||
</group>
|
||||
<group>
|
||||
@ -3184,16 +3178,19 @@
|
||||
<configuration>Release</configuration>
|
||||
</excluded>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qs.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qs\qs.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qs_fp.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qs\qs_64bit.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qs_pkg.h</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\source\qs_rx.cpp</name>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.cpp</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\..\..\..\src\qs\qutest.cpp</name>
|
||||
</file>
|
||||
</group>
|
||||
</project>
|
||||
|
@ -1,7 +1,7 @@
|
||||
//****************************************************************************
|
||||
// DPP example for QXK
|
||||
// Last updated for version 5.9.4
|
||||
// Last updated on 2017-07-06
|
||||
// Last updated for version 5.9.6
|
||||
// Last updated on 2017-07-27
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ---------------------------
|
||||
@ -41,7 +41,6 @@ namespace DPP {
|
||||
static void Thread1_run(QP::QXThread * const me);
|
||||
static void Thread2_run(QP::QXThread * const me);
|
||||
|
||||
|
||||
static QP::QXThread l_test1(&Thread1_run, 0U);
|
||||
static QP::QXThread l_test2(&Thread2_run, 0U);
|
||||
static QP::QXMutex l_mutex;
|
||||
@ -76,11 +75,11 @@ static void Thread1_run(QP::QXThread * const me) {
|
||||
(void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
|
||||
BSP::ledOn();
|
||||
|
||||
|
||||
l_mutex.lock(); // exercise the mutex
|
||||
// some flating point code to exercise the VFP...
|
||||
float volatile x = 1.4142135F;
|
||||
x = x * 1.4142135F;
|
||||
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
|
||||
l_mutex.unlock();
|
||||
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK
|
||||
@ -105,7 +104,8 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
// NOTE: the semaphore is initialized in the highest-priority thread
|
||||
// that uses it. Alternatively, the semaphore can be initialized
|
||||
// before any thread runs.
|
||||
l_sema.init(0U); // start with zero count
|
||||
l_sema.init(0U, // count==0 (signaling semaphore)
|
||||
1U); // max_count==1 (binary semaphore)
|
||||
|
||||
for (;;) {
|
||||
// some flating point code to exercise the VFP...
|
||||
@ -120,7 +120,7 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
QP::QF::gc(e); // recycle the event manually!
|
||||
}
|
||||
else {
|
||||
me->delay(BSP::TICKS_PER_SEC/2, 0U); // wait some more (BLOCK)
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/2, 0U); // BLOCK
|
||||
l_sema.signal(); // signal Thread1
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//****************************************************************************
|
||||
// DPP example for QXK
|
||||
// Last updated for version 5.7.2
|
||||
// Last updated on 2016-09-28
|
||||
// Last updated for version 5.9.6
|
||||
// Last updated on 2017-07-27
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ---------------------------
|
||||
@ -41,7 +41,6 @@ namespace DPP {
|
||||
static void Thread1_run(QP::QXThread * const me);
|
||||
static void Thread2_run(QP::QXThread * const me);
|
||||
|
||||
|
||||
static QP::QXThread l_test1(&Thread1_run, 0U);
|
||||
static QP::QXThread l_test2(&Thread2_run, 0U);
|
||||
static QP::QXMutex l_mutex;
|
||||
@ -62,11 +61,11 @@ static void Thread1_run(QP::QXThread * const /*me*/) {
|
||||
(void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
|
||||
BSP::ledOn();
|
||||
|
||||
|
||||
l_mutex.lock(); // exercise the mutex
|
||||
// some flating point code to exercise the VFP...
|
||||
float volatile x = 1.4142135F;
|
||||
x = x * 1.4142135F;
|
||||
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
|
||||
l_mutex.unlock();
|
||||
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK
|
||||
@ -86,7 +85,8 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
// NOTE: the semaphore is initialized in the highest-priority thread
|
||||
// that uses it. Alternatively, the semaphore can be initialized
|
||||
// before any thread runs.
|
||||
l_sema.init(0U); // start with zero count
|
||||
l_sema.init(0U, // count==0 (signaling semaphore)
|
||||
1U); // max_count==1 (binary semaphore)
|
||||
|
||||
for (;;) {
|
||||
// some flating point code to exercise the VFP...
|
||||
@ -101,7 +101,7 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
QP::QF::gc(e); // recycle the event manually!
|
||||
}
|
||||
else {
|
||||
me->delay(BSP::TICKS_PER_SEC/2, 0U); // wait some more (BLOCK)
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/2, 0U); // BLOCK
|
||||
l_sema.signal(); // signal Thread1
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//****************************************************************************
|
||||
// DPP example for QXK
|
||||
// Last updated for version 5.7.2
|
||||
// Last updated on 2016-09-28
|
||||
// Last updated for version 5.9.6
|
||||
// Last updated on 2017-07-27
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ---------------------------
|
||||
@ -41,7 +41,6 @@ namespace DPP {
|
||||
static void Thread1_run(QP::QXThread * const me);
|
||||
static void Thread2_run(QP::QXThread * const me);
|
||||
|
||||
|
||||
static QP::QXThread l_test1(&Thread1_run, 0U);
|
||||
static QP::QXThread l_test2(&Thread2_run, 0U);
|
||||
static QP::QXMutex l_mutex;
|
||||
@ -62,11 +61,11 @@ static void Thread1_run(QP::QXThread * const /*me*/) {
|
||||
(void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
|
||||
BSP::ledOn();
|
||||
|
||||
|
||||
l_mutex.lock(); // exercise the mutex
|
||||
// some flating point code to exercise the VFP...
|
||||
float volatile x = 1.4142135F;
|
||||
x = x * 1.4142135F;
|
||||
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
|
||||
l_mutex.unlock();
|
||||
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK
|
||||
@ -86,7 +85,8 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
// NOTE: the semaphore is initialized in the highest-priority thread
|
||||
// that uses it. Alternatively, the semaphore can be initialized
|
||||
// before any thread runs.
|
||||
l_sema.init(0U); // start with zero count
|
||||
l_sema.init(0U, // count==0 (signaling semaphore)
|
||||
1U); // max_count==1 (binary semaphore)
|
||||
|
||||
for (;;) {
|
||||
// some flating point code to exercise the VFP...
|
||||
@ -101,7 +101,7 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
QP::QF::gc(e); // recycle the event manually!
|
||||
}
|
||||
else {
|
||||
me->delay(BSP::TICKS_PER_SEC/2, 0U); // wait some more (BLOCK)
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/2, 0U); // BLOCK
|
||||
l_sema.signal(); // signal Thread1
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//****************************************************************************
|
||||
// DPP example for QXK
|
||||
// Last updated for version 5.7.2
|
||||
// Last updated on 2016-09-28
|
||||
// Last updated for version 5.9.6
|
||||
// Last updated on 2017-07-27
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ---------------------------
|
||||
@ -41,7 +41,6 @@ namespace DPP {
|
||||
static void Thread1_run(QP::QXThread * const me);
|
||||
static void Thread2_run(QP::QXThread * const me);
|
||||
|
||||
|
||||
static QP::QXThread l_test1(&Thread1_run, 0U);
|
||||
static QP::QXThread l_test2(&Thread2_run, 0U);
|
||||
static QP::QXMutex l_mutex;
|
||||
@ -62,11 +61,11 @@ static void Thread1_run(QP::QXThread * const /*me*/) {
|
||||
(void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
|
||||
BSP::ledOn();
|
||||
|
||||
|
||||
l_mutex.lock(); // exercise the mutex
|
||||
// some flating point code to exercise the VFP...
|
||||
float volatile x = 1.4142135F;
|
||||
x = x * 1.4142135F;
|
||||
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
|
||||
l_mutex.unlock();
|
||||
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK
|
||||
@ -86,7 +85,8 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
// NOTE: the semaphore is initialized in the highest-priority thread
|
||||
// that uses it. Alternatively, the semaphore can be initialized
|
||||
// before any thread runs.
|
||||
l_sema.init(0U); // start with zero count
|
||||
l_sema.init(0U, // count==0 (signaling semaphore)
|
||||
1U); // max_count==1 (binary semaphore)
|
||||
|
||||
for (;;) {
|
||||
// some flating point code to exercise the VFP...
|
||||
@ -101,7 +101,7 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
QP::QF::gc(e); // recycle the event manually!
|
||||
}
|
||||
else {
|
||||
me->delay(BSP::TICKS_PER_SEC/2, 0U); // wait some more (BLOCK)
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/2, 0U); // BLOCK
|
||||
l_sema.signal(); // signal Thread1
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//****************************************************************************
|
||||
// DPP example for QXK
|
||||
// Last updated for version 5.8.2
|
||||
// Last updated on 2017-02-03
|
||||
// Last updated for version 5.9.6
|
||||
// Last updated on 2017-07-27
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ---------------------------
|
||||
@ -41,7 +41,6 @@ namespace DPP {
|
||||
static void Thread1_run(QP::QXThread * const me);
|
||||
static void Thread2_run(QP::QXThread * const me);
|
||||
|
||||
|
||||
static QP::QXThread l_test1(&Thread1_run, 0U);
|
||||
static QP::QXThread l_test2(&Thread2_run, 0U);
|
||||
static QP::QXMutex l_mutex;
|
||||
@ -67,6 +66,7 @@ static void Thread1_run(QP::QXThread * const /*me*/) {
|
||||
// some flating point code to exercise the VFP...
|
||||
float volatile x = 1.4142135F;
|
||||
x = x * 1.4142135F;
|
||||
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
|
||||
l_mutex.unlock();
|
||||
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK
|
||||
@ -86,7 +86,8 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
// NOTE: the semaphore is initialized in the highest-priority thread
|
||||
// that uses it. Alternatively, the semaphore can be initialized
|
||||
// before any thread runs.
|
||||
l_sema.init(0U); // start with zero count
|
||||
l_sema.init(0U, // count==0 (signaling semaphore)
|
||||
1U); // max_count==1 (binary semaphore)
|
||||
|
||||
for (;;) {
|
||||
// some flating point code to exercise the VFP...
|
||||
@ -101,7 +102,7 @@ static void Thread2_run(QP::QXThread * const me) {
|
||||
QP::QF::gc(e); // recycle the event manually!
|
||||
}
|
||||
else {
|
||||
me->delay(BSP::TICKS_PER_SEC/2, 0U); // wait some more (BLOCK)
|
||||
QP::QXThread::delay(BSP::TICKS_PER_SEC/2, 0U); // BLOCK
|
||||
l_sema.signal(); // signal Thread1
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//****************************************************************************
|
||||
// DPP example for QXK
|
||||
// Last updated for version 5.8.0
|
||||
// Last updated on 2016-11-30
|
||||
// Last updated for version 5.9.6
|
||||
// Last updated on 2017-07-27
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ---------------------------
|
||||
|
@ -3,8 +3,8 @@
|
||||
/// @ingroup qxk
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.8.0
|
||||
/// Last updated on 2016-11-19
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -69,18 +69,19 @@ class QXThread : public QActive {
|
||||
public:
|
||||
|
||||
//! public constructor
|
||||
QXThread(QXThreadHandler const handler, uint_fast8_t const tickRate);
|
||||
QXThread(QXThreadHandler const handler,
|
||||
uint_fast8_t const tickRate = static_cast<uint_fast8_t>(0));
|
||||
|
||||
//! delay (block) the current extended thread for a specified # ticks
|
||||
static bool delay(uint_fast16_t const nTicks,
|
||||
uint_fast8_t const tickRate);
|
||||
uint_fast8_t const tickRate = static_cast<uint_fast8_t>(0));
|
||||
|
||||
//! cancel the delay
|
||||
bool delayCancel(void);
|
||||
|
||||
//! obtain a message from the private message queue (block if no messages)
|
||||
static QEvt const *queueGet(uint_fast16_t const nTicks,
|
||||
uint_fast8_t const tickRate);
|
||||
uint_fast8_t const tickRate = static_cast<uint_fast8_t>(0));
|
||||
|
||||
// virtual function overrides...
|
||||
//! Executes the top-most initial transition in QP::QMsm.
|
||||
@ -123,7 +124,7 @@ private:
|
||||
void block_(void) const;
|
||||
void unblock_(void) const;
|
||||
void teArm_(enum_t const sig, uint_fast16_t const nTicks,
|
||||
uint_fast8_t const tickRate);
|
||||
uint_fast8_t const tickRate = static_cast<uint_fast8_t>(0));
|
||||
bool teDisarm_(void);
|
||||
|
||||
// attributes...
|
||||
@ -141,18 +142,20 @@ private:
|
||||
class QXSemaphore {
|
||||
public:
|
||||
//! initialize the counting semaphore
|
||||
void init(uint_fast16_t const count);
|
||||
void init(uint_fast16_t const count,
|
||||
uint_fast16_t const max_count = UINT16_MAX);
|
||||
|
||||
//! signal (unblock) the semaphore
|
||||
void signal(void);
|
||||
bool signal(void);
|
||||
|
||||
//! wait (block) on the semaphore
|
||||
bool wait(uint_fast16_t const nTicks,
|
||||
uint_fast8_t const tickRate);
|
||||
uint_fast8_t const tickRate = static_cast<uint_fast8_t>(0));
|
||||
|
||||
private:
|
||||
uint_fast16_t m_count;
|
||||
QPSet m_waitSet; //!< set of extended threads waiting on this semaphore
|
||||
uint_fast16_t m_count;
|
||||
uint_fast16_t m_max_count;
|
||||
};
|
||||
|
||||
} // namespace QP
|
||||
|
86
include/stdint_c.h
Normal file
86
include/stdint_c.h
Normal file
@ -0,0 +1,86 @@
|
||||
/// @file
|
||||
/// @brief Macros for casting strongly-typed integer constants.
|
||||
///
|
||||
/// @description This header file provides the standard C99 and C++11
|
||||
/// macros of the form UINT8_C(), UINT_FAST8_C(), etc. for building
|
||||
/// strongly-typed constants of standard integers from <stdint.h>.
|
||||
///
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.9.5
|
||||
/// Last updated on 2017-07-20
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
/// innovating embedded systems
|
||||
///
|
||||
/// Copyright (C) Quantum Leaps. All rights reserved.
|
||||
///
|
||||
/// This program is open source software: you can redistribute it and/or
|
||||
/// modify it under the terms of the GNU General Public License as published
|
||||
/// by the Free Software Foundation, either version 3 of the License, or
|
||||
/// (at your option) any later version.
|
||||
///
|
||||
/// Alternatively, this program may be distributed and modified under the
|
||||
/// terms of Quantum Leaps commercial licenses, which expressly supersede
|
||||
/// the GNU General Public License and are specifically designed for
|
||||
/// licensees interested in retaining the proprietary status of their code.
|
||||
///
|
||||
/// This program is distributed in the hope that it will be useful,
|
||||
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/// GNU General Public License for more details.
|
||||
///
|
||||
/// You should have received a copy of the GNU General Public License
|
||||
/// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
///
|
||||
/// Contact information:
|
||||
/// https://state-machine.com
|
||||
/// mailto:info@state-machine.com
|
||||
///***************************************************************************
|
||||
/// @endcond
|
||||
|
||||
#ifndef stdint_c_h
|
||||
#define stdint_c_h
|
||||
|
||||
#ifndef UINT8_C
|
||||
#define UINT8_C(x_) (static_cast<std::uint8_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef INT8_C
|
||||
#define INT8_C(x_) (static_cast<std::int8_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef UINT_FAST8_C
|
||||
#define UINT_FAST8_C(x_) (static_cast<std::uint_fast8_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef INT_FAST8_C
|
||||
#define INT_FAST8_C(x_) (static_cast<std::int_fast8_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef UINT16_C
|
||||
#define UINT16_C(x_) (static_cast<std::uint16_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef INT16_C
|
||||
#define INT16_C(x_) (static_cast<std::int16_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef UINT_FAST16_C
|
||||
#define UINT_FAST16_C(x_) (static_cast<std::uint_fast16_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_C
|
||||
#define UINT32_C(x_) (static_cast<std::uint32_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef INT32_C
|
||||
#define INT32_C(x_) (static_cast<std::int32_t>(x_))
|
||||
#endif
|
||||
|
||||
#ifndef UINT_FAST32_C
|
||||
#define UINT_FAST32_C(x_) (static_cast<std::uint_fast32_t>(x_))
|
||||
#endif
|
||||
|
||||
#endif // stdint_c_h
|
@ -1,7 +1,7 @@
|
||||
;*****************************************************************************
|
||||
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), ARM-KEIL assembler
|
||||
; Last Updated for Version: 5.9.0
|
||||
; Date of the Last Update: 2017-03-17
|
||||
; Last Updated for Version: 5.9.6
|
||||
; Date of the Last Update: 2017-07-28
|
||||
;
|
||||
; Q u a n t u m L e a P s
|
||||
; ---------------------------
|
||||
@ -111,16 +111,17 @@ QK_init FUNCTION
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register
|
||||
LDR r3,[r3] ; r3 := INTLINESUM
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
|
||||
LDR r3,[r3]
|
||||
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 ; r3 == number of NVIC_PRIO registers
|
||||
ADDS r3,r3,#8 ; r3 == (# NVIC_PRIO registers)/4
|
||||
|
||||
; loop over all implemented NVIC_PRIO registers for IRQs...
|
||||
QK_init_irq
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
CMP r3,#0
|
||||
BNE QK_init_irq
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
* Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), GNU-ARM assembler
|
||||
* Last Updated for Version: 5.9.3
|
||||
* Date of the Last Update: 2017-06-17
|
||||
* Last Updated for Version: 5.9.6
|
||||
* Date of the Last Update: 2017-07-28
|
||||
*
|
||||
* Q u a n t u m L e a P s
|
||||
* ---------------------------
|
||||
@ -106,16 +106,18 @@ QK_init:
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r3,=0xE000E004 /* Interrupt Controller Type Register */
|
||||
LDR r3,[r3] /* r3 := INTLINESUM */
|
||||
LDR r2,=0xE000E400 /* NVIC_PRI0 register */
|
||||
LDR r3,=0xE000E004 /* Interrupt Controller Type Register (ICTR) */
|
||||
LDR r3,[r3]
|
||||
LDR r3,[r3]
|
||||
ANDS r3,r3,#7 /* r3 := ICTR[0:2] (INTLINESNUM) */
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 /* r3 == number of NVIC_PRIO registers */
|
||||
ADDS r3,r3,#8 /* r3 == (# NVIC_PRIO registers)/4 */
|
||||
|
||||
/* loop over all implemented NVIC_PRIO registers for IRQs... */
|
||||
QK_init_irq:
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,=0xE000E400 /* NVIC_PRI0 register */
|
||||
STR r1,[r2,r3,LSL #2] /* NVIC_PRI0[r3] := r1 */
|
||||
STR r1,[r2,r3,LSL #2] /* NVIC_PRI0[r3] := r1 */
|
||||
CMP r3,#0
|
||||
BNE QK_init_irq
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
;*****************************************************************************
|
||||
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler
|
||||
; Last Updated for Version: 5.9.0
|
||||
; Date of the Last Update: 2017-03-17
|
||||
; Last Updated for Version: 5.9.6
|
||||
; Date of the Last Update: 2017-07-28
|
||||
;
|
||||
; Q u a n t u m L e a P s
|
||||
; ---------------------------
|
||||
@ -110,16 +110,17 @@ QK_init:
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register
|
||||
LDR r3,[r3] ; r3 := INTLINESUM
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
|
||||
LDR r3,[r3]
|
||||
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 ; r3 == number of NVIC_PRIO registers
|
||||
ADDS r3,r3,#8 ; r3 == (# NVIC_PRIO registers)/4
|
||||
|
||||
; loop over all implemented NVIC_PRIO registers for IRQs...
|
||||
QK_init_irq:
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
CMP r3,#0
|
||||
BNE QK_init_irq
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
;*****************************************************************************
|
||||
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
|
||||
; Last Updated for Version: 5.9.0
|
||||
; Date of the Last Update: 2017-03-17
|
||||
; Last Updated for Version: 5.9.6
|
||||
; Date of the Last Update: 2017-07-28
|
||||
;
|
||||
; Q u a n t u m L e a P s
|
||||
; ---------------------------
|
||||
@ -109,16 +109,17 @@ QK_init: .asmfunc
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r3,ICTR_addr ; Interrupt Controller Type Register
|
||||
LDR r3,[r3] ; r3 := INTLINESUM
|
||||
LDR r2,PRI0_addr ; NVIC_PRI0 register
|
||||
LDR r3,ICTR_addr ; Interrupt Controller Type Register (ICTR)
|
||||
LDR r3,[r3] ; r3 := ICTR
|
||||
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 ; r3 == number of NVIC_PRIO registers
|
||||
ADDS r3,r3,#8 ; r3 == (# NVIC_PRIO registers)/4
|
||||
|
||||
; loop over all implemented NVIC_PRIO registers for IRQs...
|
||||
QK_init_irq:
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,PRI0_addr ; NVIC_PRI0 register
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
CMP r3,#0
|
||||
BNE QK_init_irq
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
/// @file
|
||||
/// @brief QP/C++ port to ARM Cortex-M, cooperative QV kernel, IAR-ARM toolset
|
||||
/// @brief QP/C++ port to ARM Cortex-M, cooperative QV kernel, ARM-KEIL toolset
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.8.1
|
||||
/// Last updated on 2016-12-12
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-28
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -30,7 +30,7 @@
|
||||
/// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
///
|
||||
/// Contact information:
|
||||
/// www.state-machine.com
|
||||
/// https://state-machine.com
|
||||
/// mailto:info@state-machine.com
|
||||
///***************************************************************************
|
||||
/// @endcond
|
||||
@ -61,7 +61,6 @@ extern "C" {
|
||||
* The interrupt priorities established in QV_init() can be later
|
||||
* changed by the application-level code.
|
||||
*/
|
||||
|
||||
void QV_init(void) {
|
||||
|
||||
// set exception priorities to QF_BASEPRI...
|
||||
@ -75,7 +74,7 @@ void QV_init(void) {
|
||||
SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI;
|
||||
|
||||
// set all implemented IRQ priories to QF_BASEPRI...
|
||||
uint32_t n = 8 + (*SCnSCB_ICTR << 3); // # interrupt priority registers
|
||||
uint32_t n = 8U + ((*SCnSCB_ICTR & 0x7U) << 3); // (# NVIC_PRIO regs)/4
|
||||
do {
|
||||
--n;
|
||||
NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16)
|
||||
|
@ -1,9 +1,9 @@
|
||||
/// @file
|
||||
/// @brief QP/C++ port to ARM Cortex-M, cooperative QV kernel, IAR-ARM toolset
|
||||
/// @brief QP/C++ port to ARM Cortex-M, cooperative QV kernel, GNU-ARM toolset
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.8.1
|
||||
/// Last updated on 2016-12-12
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-28
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -30,21 +30,21 @@
|
||||
/// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
///
|
||||
/// Contact information:
|
||||
/// www.state-machine.com
|
||||
/// https://state-machine.com
|
||||
/// mailto:info@state-machine.com
|
||||
///***************************************************************************
|
||||
/// @endcond
|
||||
|
||||
#include "qf_port.h"
|
||||
|
||||
#if (__ARM_ARCH != 6) /* NOT Cortex-M0/M0+/M1 ? */
|
||||
#if (__ARM_ARCH != 6) // NOT Cortex-M0/M0+/M1 ?
|
||||
|
||||
extern "C" {
|
||||
|
||||
#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004)
|
||||
#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14)
|
||||
#define NVIC_IP ((uint32_t volatile *)0xE000E400)
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
* Initialize the exception priorities and IRQ priorities to safe values.
|
||||
*
|
||||
@ -74,7 +74,7 @@ void QV_init(void) {
|
||||
SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI;
|
||||
|
||||
// set all implemented IRQ priories to QF_BASEPRI...
|
||||
uint32_t n = 8 + (*SCnSCB_ICTR << 3); // # interrupt priority registers
|
||||
uint32_t n = 8U + ((*SCnSCB_ICTR & 0x7U) << 3); // (# NVIC_PRIO regs)/4
|
||||
do {
|
||||
--n;
|
||||
NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16)
|
||||
|
@ -2,8 +2,8 @@
|
||||
/// @brief QP/C++ port to ARM Cortex-M, cooperative QV kernel, IAR-ARM toolset
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.8.1
|
||||
/// Last updated on 2016-12-12
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-28
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -30,7 +30,7 @@
|
||||
/// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
///
|
||||
/// Contact information:
|
||||
/// www.state-machine.com
|
||||
/// https://state-machine.com
|
||||
/// mailto:info@state-machine.com
|
||||
///***************************************************************************
|
||||
/// @endcond
|
||||
@ -61,7 +61,6 @@ extern "C" {
|
||||
* The interrupt priorities established in QV_init() can be later
|
||||
* changed by the application-level code.
|
||||
*/
|
||||
|
||||
void QV_init(void) {
|
||||
|
||||
// set exception priorities to QF_BASEPRI...
|
||||
@ -75,7 +74,7 @@ void QV_init(void) {
|
||||
SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI;
|
||||
|
||||
// set all implemented IRQ priories to QF_BASEPRI...
|
||||
uint32_t n = 8 + (*SCnSCB_ICTR << 3); // # interrupt priority registers
|
||||
uint32_t n = 8U + ((*SCnSCB_ICTR & 0x7U) << 3); // (# NVIC_PRIO regs)/4
|
||||
do {
|
||||
--n;
|
||||
NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16)
|
||||
@ -86,4 +85,3 @@ void QV_init(void) {
|
||||
} // extern "C"
|
||||
|
||||
#endif // NOT Cortex-M0/M0+/M1 ?
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
;*****************************************************************************
|
||||
; Product: QV port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler
|
||||
; Last Updated for Version: 5.9.0
|
||||
; Date of the Last Update: 2017-03-17
|
||||
; Product: QV port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
|
||||
; Last Updated for Version: 5.9.6
|
||||
; Date of the Last Update: 2017-07-28
|
||||
;
|
||||
; Q u a n t u m L e a P s
|
||||
; ---------------------------
|
||||
@ -139,16 +139,17 @@ QV_init: .asmfunc
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r2,PRI0_addr ; NVIC_PRI0 register
|
||||
LDR r3,ICTR_addr ; Interrupt Controller Type Register
|
||||
LDR r3,[r3] ; r3 := INTLINESUM
|
||||
LDR r3,[r3] ; r3 := ICTR
|
||||
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 ; r3 == number of NVIC_PRIO registers
|
||||
ADDS r3,r3,#8 ; r3 == (# NVIC_PRIO registers)/4
|
||||
|
||||
; loop over all implemented NVIC_PRIO registers for IRQs...
|
||||
QV_init_irq:
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,PRI0_addr ; NVIC_PRI0 register
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
CMP r3,#0
|
||||
BNE QV_init_irq
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
;*****************************************************************************
|
||||
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), ARM-Keil assembler
|
||||
; Last Updated for Version: 5.9.4
|
||||
; Date of the Last Update: 2017-07-06
|
||||
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), ARM-Keil assembler
|
||||
; Last Updated for Version: 5.9.6
|
||||
; Date of the Last Update: 2017-07-28
|
||||
;
|
||||
; Q u a n t u m L e a P s
|
||||
; ---------------------------
|
||||
@ -83,7 +83,7 @@ QXK_init FUNCTION
|
||||
ELSE ; Cortex-M3/M4/..
|
||||
|
||||
; NOTE:
|
||||
; On Cortex-M3/M4/M7.., this QK port disables interrupts by means of
|
||||
; On Cortex-M3/M4/M7.., this QXK port disables interrupts by means of
|
||||
; the BASEPRI register. However, this method cannot disable interrupt
|
||||
; priority zero, which is the default for all interrupts out of reset.
|
||||
; The following code changes the SysTick priority and all IRQ priorities
|
||||
@ -124,16 +124,17 @@ QXK_init FUNCTION
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register
|
||||
LDR r3,[r3] ; r3 := INTLINESUM
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
|
||||
LDR r3,[r3]
|
||||
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 ; r3 == number of NVIC_PRIO registers
|
||||
ADDS r3,r3,#8 ; r3 == (# NVIC_PRIO registers)/4
|
||||
|
||||
; loop over all implemented NVIC_PRIO registers for IRQs...
|
||||
QXK_init_irq
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
CMP r3,#0
|
||||
BNE QXK_init_irq
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
* Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), GNU-ARM assembler
|
||||
* Last Updated for Version: 5.9.4
|
||||
* Date of the Last Update: 2017-07-06
|
||||
* Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), GNU-ARM assembler
|
||||
* Last Updated for Version: 5.9.6
|
||||
* Date of the Last Update: 2017-07-28
|
||||
*
|
||||
* Q u a n t u m L e a P s
|
||||
* ---------------------------
|
||||
@ -114,16 +114,17 @@ QXK_init:
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r3,=0xE000E004 /* Interrupt Controller Type Register */
|
||||
LDR r3,[r3] /* r3 := INTLINESUM */
|
||||
LDR r2,=0xE000E400 /* NVIC_PRI0 register */
|
||||
LDR r3,=0xE000E004 /* Interrupt Controller Type Register (ICTR) */
|
||||
LDR r3,[r3]
|
||||
ANDS r3,r3,#7 /* r3 := ICTR[0:2] (INTLINESNUM) */
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 /* r3 == number of NVIC_PRIO registers */
|
||||
ADDS r3,r3,#8 /* r3 == (# NVIC_PRIO registers)/4 */
|
||||
|
||||
/* loop over all implemented NVIC_PRIO registers for IRQs... */
|
||||
QXK_init_irq:
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,=0xE000E400 /* NVIC_PRI0 register */
|
||||
STR r1,[r2,r3,LSL #2] /* NVIC_PRI0[r3] := r1 */
|
||||
STR r1,[r2,r3,LSL #2] /* NVIC_PRI0[r3] := r1 */
|
||||
CMP r3,#0
|
||||
BNE QXK_init_irq
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
;*****************************************************************************
|
||||
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler
|
||||
; Last Updated for Version: 5.9.4
|
||||
; Date of the Last Update: 2017-07-06
|
||||
; Last Updated for Version: 5.9.6
|
||||
; Date of the Last Update: 2017-07-28
|
||||
;
|
||||
; Q u a n t u m L e a P s
|
||||
; ---------------------------
|
||||
@ -51,7 +51,7 @@ QXK_NEXT EQU 4
|
||||
QXK_TOP_PRIO EQU 8
|
||||
|
||||
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!!
|
||||
QMACTIVE_OSOBJ EQU 40
|
||||
QMACTIVE_OSOBJ EQU 40
|
||||
QMACTIVE_PRIO EQU 48
|
||||
|
||||
|
||||
@ -123,20 +123,21 @@ QXK_init:
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register
|
||||
LDR r3,[r3] ; r3 := INTLINESUM
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
|
||||
LDR r3,[r3]
|
||||
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 ; r3 == number of NVIC_PRIO registers
|
||||
ADDS r3,r3,#8 ; r3 == (# NVIC_PRIO registers)/4
|
||||
|
||||
; loop over all implemented NVIC_PRIO registers for IRQs...
|
||||
QXK_init_irq:
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,=0xE000E400 ; NVIC_PRI0 register
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
CMP r3,#0
|
||||
BNE QXK_init_irq
|
||||
|
||||
#endif ; Cortex-M3/M4/...
|
||||
#endif ; Cortex-M3/M4/M7
|
||||
|
||||
MOV r0,r12 ; r0 := original PRIMASK
|
||||
MSR PRIMASK,r0 ; PRIMASK := r0
|
||||
|
@ -1,7 +1,7 @@
|
||||
;*****************************************************************************
|
||||
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
|
||||
; Last Updated for Version: 5.9.4
|
||||
; Date of the Last Update: 2017-07-06
|
||||
; Last Updated for Version: 5.9.6
|
||||
; Date of the Last Update: 2017-07-28
|
||||
;
|
||||
; Q u a n t u m L e a P s
|
||||
; ---------------------------
|
||||
@ -59,7 +59,7 @@ QXK_NEXT .equ 4
|
||||
QXK_TOP_PRIO .equ 8
|
||||
|
||||
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!!
|
||||
QMACTIVE_OSOBJ .equ 44
|
||||
QMACTIVE_OSOBJ .equ 40
|
||||
QMACTIVE_PRIO .equ 48
|
||||
|
||||
.text
|
||||
@ -77,7 +77,7 @@ QXK_init: .asmfunc
|
||||
|
||||
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__ ; M3/4/7?
|
||||
; NOTE:
|
||||
; On Cortex-M3/M4/M7.., this QK port disables interrupts by means of
|
||||
; On Cortex-M3/M4/M7.., this QXK port disables interrupts by means of
|
||||
; the BASEPRI register. However, this method cannot disable interrupt
|
||||
; priority zero, which is the default for all interrupts out of reset.
|
||||
; The following code changes the SysTick priority and all IRQ priorities
|
||||
@ -118,16 +118,17 @@ QXK_init: .asmfunc
|
||||
LSLS r1,r1,#8
|
||||
ORRS r1,r1,#QF_BASEPRI
|
||||
|
||||
LDR r2,PRI0_addr ; NVIC_PRI0 register
|
||||
LDR r3,ICTR_addr ; Interrupt Controller Type Register
|
||||
LDR r3,[r3] ; r3 := INTLINESUM
|
||||
LDR r3,[r3] ; r3 := INTLINESNUM
|
||||
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
|
||||
LSLS r3,r3,#3
|
||||
ADDS r3,r3,#8 ; r3 == number of NVIC_PRIO registers
|
||||
ADDS r3,r3,#8 ; r3 == (# NVIC_PRIO registers)/4
|
||||
|
||||
; loop over all implemented NVIC_PRIO registers for IRQs...
|
||||
QXK_init_irq:
|
||||
SUBS r3,r3,#1
|
||||
LDR r2,PRI0_addr ; NVIC_PRI0 register
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
STR r1,[r2,r3,LSL #2] ; NVIC_PRI0[r3] := r1
|
||||
CMP r3,#0
|
||||
BNE QXK_init_irq
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
/// @ingroup qxk
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.9.4
|
||||
/// Last updated on 2017-07-06
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -52,6 +52,8 @@
|
||||
#error "Source file included in a project NOT based on the QXK kernel"
|
||||
#endif // qxk_h
|
||||
|
||||
Q_DEFINE_THIS_MODULE("qxk")
|
||||
|
||||
// Public-scope objects ******************************************************
|
||||
extern "C" {
|
||||
QXK_Attr QXK_attr_; // global attributes of the QXK kernel
|
||||
@ -59,8 +61,6 @@ extern "C" {
|
||||
|
||||
namespace QP {
|
||||
|
||||
Q_DEFINE_THIS_MODULE("qxk")
|
||||
|
||||
// Local-scope objects *******************************************************
|
||||
class QXKIdleThread : public QActive {
|
||||
public:
|
||||
@ -441,8 +441,14 @@ QP::QActive *QXK_current(void) {
|
||||
|
||||
QF_CRIT_ENTRY_();
|
||||
curr = QXK_attr_.curr;
|
||||
if (curr == static_cast<QP::QActive *>(0)) { // basic thread?
|
||||
curr = QP::QF::active_[QXK_attr_.actPrio];
|
||||
}
|
||||
QF_CRIT_EXIT_();
|
||||
|
||||
//! @post the current thread must be valid
|
||||
Q_ENSURE_ID(900, curr != static_cast<QP::QActive *>(0));
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Product: QK/C++
|
||||
/// Last updated for version 5.9.4
|
||||
/// Last updated on 2017-07-05
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -105,7 +105,7 @@ void QXMutex::lock(void) {
|
||||
QF_CRIT_STAT_
|
||||
QF_CRIT_ENTRY_();
|
||||
|
||||
/// @pre scheduler cannot be locked from the ISR context
|
||||
/// @pre The mutex cannot be locked from the ISR context
|
||||
/// and the mutex must be unused
|
||||
Q_REQUIRE_ID(700, (!QXK_ISR_CONTEXT_())
|
||||
&& (m_prevPrio == static_cast<uint_fast8_t>(MUTEX_UNUSED)));
|
||||
@ -124,7 +124,7 @@ void QXMutex::lock(void) {
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_LOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
QS_2U8_(static_cast<uint8_t>(m_prevPrio), /* previouis lock prio */
|
||||
QS_2U8_(static_cast<uint8_t>(m_prevPrio), /* previous lock prio */
|
||||
static_cast<uint8_t>(QXK_attr_.lockPrio)); // new lock prio
|
||||
QS_END_NOCRIT_()
|
||||
|
||||
@ -152,7 +152,7 @@ void QXMutex::unlock(void) {
|
||||
QF_CRIT_STAT_
|
||||
QF_CRIT_ENTRY_();
|
||||
|
||||
/// @pre scheduler cannot be unlocked from the ISR context
|
||||
/// @pre The mutex cannot be unlocked from the ISR context
|
||||
/// and the mutex must NOT be unused
|
||||
Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_())
|
||||
&& (m_prevPrio != static_cast<uint_fast8_t>(MUTEX_UNUSED)));
|
||||
@ -164,19 +164,41 @@ void QXMutex::unlock(void) {
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock prio */
|
||||
(QXK_attr_.lockPrio > p) /* the new lock prio */
|
||||
? static_cast<uint8_t>(p)
|
||||
: static_cast<uint8_t>(QXK_attr_.lockPrio));
|
||||
if (QXK_attr_.lockPrio > p) {
|
||||
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
}
|
||||
else {
|
||||
p = QXK_attr_.lockPrio;
|
||||
QS_2U8_(static_cast<uint8_t>(p), /* prev lock prio */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
}
|
||||
QS_END_NOCRIT_()
|
||||
|
||||
if (QXK_attr_.lockPrio > p) {
|
||||
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
QS_END_NOCRIT_()
|
||||
|
||||
QXK_attr_.lockPrio = p; // restore the previous lock prio
|
||||
// find the highest-prio thread ready to run
|
||||
if (QXK_sched_() != static_cast<uint_fast8_t>(0)) { // priority found?
|
||||
QXK_activate_(); // activate any unlocked basic threads
|
||||
}
|
||||
}
|
||||
else {
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
p = QXK_attr_.lockPrio;
|
||||
QS_2U8_(static_cast<uint8_t>(p), /* prev lock */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
QS_END_NOCRIT_()
|
||||
}
|
||||
QF_CRIT_EXIT_();
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
/// @ingroup qxk
|
||||
/// @cond
|
||||
////**************************************************************************
|
||||
/// Last updated for version 5.9.5
|
||||
/// Last updated on 2017-07-20
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -57,21 +57,30 @@ Q_DEFINE_THIS_MODULE("qxk_sema")
|
||||
|
||||
//****************************************************************************
|
||||
/// @description
|
||||
/// Initializes a semaphore with the specified count. If the semaphore is used
|
||||
/// for resource sharing, the initial value of the semaphore count should be
|
||||
/// set to the number of identical resources guarded by the semaphore. If the
|
||||
/// semaphore is used as a signaling mechanism, the initial count should set
|
||||
/// to 0.
|
||||
/// Initializes a semaphore with the specified count and maximum count.
|
||||
/// If the semaphore is used for resource sharing, both the initial count
|
||||
/// and maximum count should be set to the number of identical resources
|
||||
/// guarded by the semaphore. If the semaphore is used as a signaling
|
||||
/// mechanism, the initial count should set to 0 and maximum count to 1
|
||||
/// (binary semaphore).
|
||||
///
|
||||
/// @param[in] count initial value of the semaphore counter
|
||||
///
|
||||
/// @param[in] max_count maximum value of the semaphore counter.
|
||||
/// The purpose of the max_count is to limit the counter
|
||||
/// so that the semaphore cannot unblock more times than
|
||||
/// the maximum.
|
||||
/// @note
|
||||
/// QXSemaphore::init() must be called **before** the semaphore can be used
|
||||
/// (signaled or waited on).
|
||||
///
|
||||
void QXSemaphore::init(uint_fast16_t const count) {
|
||||
m_count = count;
|
||||
void QXSemaphore::init(uint_fast16_t const count,
|
||||
uint_fast16_t const max_count)
|
||||
{
|
||||
Q_REQUIRE_ID(100, max_count > static_cast<uint_fast16_t>(0));
|
||||
|
||||
m_waitSet.setEmpty();
|
||||
m_count = count;
|
||||
m_max_count = max_count;
|
||||
}
|
||||
|
||||
//****************************************************************************
|
||||
@ -105,8 +114,14 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
|
||||
|
||||
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
|
||||
|
||||
Q_REQUIRE_ID(100, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
/// @pre this function must:
|
||||
/// (1) NOT be called from an ISR; (2) be called from an extended thread;
|
||||
/// (3) the thread must NOT be holding a mutex and
|
||||
/// (4) the thread must NOT be already blocked on any object.
|
||||
///
|
||||
Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */
|
||||
&& (QXK_attr_.lockPrio == static_cast<uint_fast8_t>(0)) /* no lock */
|
||||
&& (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
|
||||
|
||||
if (m_count > static_cast<uint_fast16_t>(0)) {
|
||||
@ -125,7 +140,7 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
|
||||
|
||||
QF_CRIT_ENTRY_();
|
||||
// the blocking object must be this semaphore
|
||||
Q_ASSERT_ID(110, thr->m_temp.obj
|
||||
Q_ASSERT_ID(210, thr->m_temp.obj
|
||||
== reinterpret_cast<QMState const *>(this));
|
||||
thr->m_temp.obj = static_cast<QMState const *>(0); // clear
|
||||
}
|
||||
@ -145,11 +160,15 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
|
||||
/// if the awakened thread is now the highest-priority thread that is
|
||||
/// ready-to-run.
|
||||
///
|
||||
/// @returns true when the semaphore gets signaled and false when
|
||||
/// the semaphore count exceeded the maximum.
|
||||
///
|
||||
/// @note
|
||||
/// A semaphore can be signaled from many places, including from ISRs, basic
|
||||
/// threads (AOs), and extended threads.
|
||||
///
|
||||
void QXSemaphore::signal(void) {
|
||||
bool QXSemaphore::signal(void) {
|
||||
bool signaled = true; // assume that the semaphore will be signaled
|
||||
QF_CRIT_STAT_
|
||||
|
||||
QF_CRIT_ENTRY_();
|
||||
@ -161,8 +180,9 @@ void QXSemaphore::signal(void) {
|
||||
QXThread *thr = static_cast<QXThread *>(QF::active_[p]);
|
||||
|
||||
// the thread must be extended and the semaphore count must be zero
|
||||
Q_ASSERT_ID(210, (thr->m_osObject != static_cast<void *>(0))
|
||||
&& (m_count == static_cast<uint_fast16_t>(0)));
|
||||
Q_ASSERT_ID(210, (thr != static_cast<QXThread *>(0)) /* registered */
|
||||
&& (thr->m_osObject != static_cast<void *>(0)) /* extended */
|
||||
&& (m_count == static_cast<uint_fast16_t>(0))); // not signaled
|
||||
|
||||
// disarm the internal time event
|
||||
(void)thr->teDisarm_();
|
||||
@ -172,9 +192,16 @@ void QXSemaphore::signal(void) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
++m_count;
|
||||
if (m_count < m_max_count) {
|
||||
++m_count;
|
||||
}
|
||||
else {
|
||||
signaled = false; // semaphore NOT signaled
|
||||
}
|
||||
}
|
||||
QF_CRIT_EXIT_();
|
||||
|
||||
return signaled;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
|
@ -3,8 +3,8 @@
|
||||
/// @ingroup qxk
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.9.4
|
||||
/// Last updated on 2017-07-05
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -335,8 +335,14 @@ QEvt const *QXThread::queueGet(uint_fast16_t const nTicks,
|
||||
QF_CRIT_ENTRY_();
|
||||
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
|
||||
|
||||
/// @pre this function must:
|
||||
/// (1) NOT be called from an ISR; (2) be called from an extended thread;
|
||||
/// (3) the thread must NOT be holding a mutex and
|
||||
/// (4) the thread must NOT be already blocked on any object.
|
||||
///
|
||||
Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */
|
||||
&& (QXK_attr_.lockPrio == static_cast<uint_fast8_t>(0)) /* !locked */
|
||||
&& (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
|
||||
|
||||
// is the queue empty? -- block and wait for event(s)
|
||||
@ -453,7 +459,7 @@ void QXThread::teArm_(enum_t const sig,
|
||||
uint_fast16_t const nTicks,
|
||||
uint_fast8_t const tickRate)
|
||||
{
|
||||
// the time event must be unused
|
||||
/// @pre the time event must be unused
|
||||
Q_REQUIRE_ID(700, m_timeEvt.m_ctr == static_cast<QTimeEvtCtr>(0));
|
||||
|
||||
m_timeEvt.sig = static_cast<QSignal>(sig);
|
||||
@ -517,8 +523,16 @@ bool QXThread::delay(uint_fast16_t const nTicks,
|
||||
QF_CRIT_ENTRY_();
|
||||
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
|
||||
|
||||
// the delaying thread must not be blocked on any object
|
||||
Q_REQUIRE_ID(900, thr->m_temp.obj == static_cast<QMState const *>(0));
|
||||
/// @pre this function must:
|
||||
/// (1) NOT be called from an ISR; (2) be called from an extended thread;
|
||||
/// (3) the thread must NOT be holding a mutex and
|
||||
/// (4) the thread must NOT be already blocked on any object.
|
||||
///
|
||||
Q_REQUIRE_ID(900, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */
|
||||
&& (QXK_attr_.lockPrio == static_cast<uint_fast8_t>(0)) /* !locked */
|
||||
&& (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
|
||||
|
||||
|
||||
// remember the blocking object
|
||||
thr->m_temp.obj = reinterpret_cast<QMState const *>(&thr->m_timeEvt);
|
||||
|
@ -4,8 +4,8 @@
|
||||
/// @ingroup qxk
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.9.5
|
||||
/// Last updated on 2017-07-19
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -441,6 +441,9 @@ QP::QActive *QXK_current(void) {
|
||||
|
||||
QF_CRIT_ENTRY_();
|
||||
curr = QXK_attr_.curr;
|
||||
if (curr == static_cast<QP::QActive *>(0)) { // basic thread?
|
||||
curr = QP::QF::active_[QXK_attr_.actPrio];
|
||||
}
|
||||
QF_CRIT_EXIT_();
|
||||
|
||||
//! @post the current thread must be valid
|
||||
|
@ -5,8 +5,8 @@
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Product: QK/C++
|
||||
/// Last updated for version 5.9.4
|
||||
/// Last updated on 2017-07-05
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -105,7 +105,7 @@ void QXMutex::lock(void) {
|
||||
QF_CRIT_STAT_
|
||||
QF_CRIT_ENTRY_();
|
||||
|
||||
/// @pre scheduler cannot be locked from the ISR context
|
||||
/// @pre The mutex cannot be locked from the ISR context
|
||||
/// and the mutex must be unused
|
||||
Q_REQUIRE_ID(700, (!QXK_ISR_CONTEXT_())
|
||||
&& (m_prevPrio == static_cast<uint_fast8_t>(MUTEX_UNUSED)));
|
||||
@ -124,7 +124,7 @@ void QXMutex::lock(void) {
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_LOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
QS_2U8_(static_cast<uint8_t>(m_prevPrio), /* previouis lock prio */
|
||||
QS_2U8_(static_cast<uint8_t>(m_prevPrio), /* previous lock prio */
|
||||
static_cast<uint8_t>(QXK_attr_.lockPrio)); // new lock prio
|
||||
QS_END_NOCRIT_()
|
||||
|
||||
@ -152,7 +152,7 @@ void QXMutex::unlock(void) {
|
||||
QF_CRIT_STAT_
|
||||
QF_CRIT_ENTRY_();
|
||||
|
||||
/// @pre scheduler cannot be unlocked from the ISR context
|
||||
/// @pre The mutex cannot be unlocked from the ISR context
|
||||
/// and the mutex must NOT be unused
|
||||
Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_())
|
||||
&& (m_prevPrio != static_cast<uint_fast8_t>(MUTEX_UNUSED)));
|
||||
@ -164,19 +164,41 @@ void QXMutex::unlock(void) {
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock prio */
|
||||
(QXK_attr_.lockPrio > p) /* the new lock prio */
|
||||
? static_cast<uint8_t>(p)
|
||||
: static_cast<uint8_t>(QXK_attr_.lockPrio));
|
||||
if (QXK_attr_.lockPrio > p) {
|
||||
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
}
|
||||
else {
|
||||
p = QXK_attr_.lockPrio;
|
||||
QS_2U8_(static_cast<uint8_t>(p), /* prev lock prio */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
}
|
||||
QS_END_NOCRIT_()
|
||||
|
||||
if (QXK_attr_.lockPrio > p) {
|
||||
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
QS_END_NOCRIT_()
|
||||
|
||||
QXK_attr_.lockPrio = p; // restore the previous lock prio
|
||||
// find the highest-prio thread ready to run
|
||||
if (QXK_sched_() != static_cast<uint_fast8_t>(0)) { // priority found?
|
||||
QXK_activate_(); // activate any unlocked basic threads
|
||||
}
|
||||
}
|
||||
else {
|
||||
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
|
||||
static_cast<void *>(0), static_cast<void *>(0))
|
||||
QS_TIME_(); // timestamp
|
||||
p = QXK_attr_.lockPrio;
|
||||
QS_2U8_(static_cast<uint8_t>(p), /* prev lock */
|
||||
static_cast<uint8_t>(p)); // new lock prio
|
||||
QS_END_NOCRIT_()
|
||||
}
|
||||
QF_CRIT_EXIT_();
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
/// @ingroup qxk
|
||||
/// @cond
|
||||
////**************************************************************************
|
||||
/// Last updated for version 5.9.5
|
||||
/// Last updated on 2017-07-20
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -57,21 +57,30 @@ Q_DEFINE_THIS_MODULE("qxk_sema")
|
||||
|
||||
//****************************************************************************
|
||||
/// @description
|
||||
/// Initializes a semaphore with the specified count. If the semaphore is used
|
||||
/// for resource sharing, the initial value of the semaphore count should be
|
||||
/// set to the number of identical resources guarded by the semaphore. If the
|
||||
/// semaphore is used as a signaling mechanism, the initial count should set
|
||||
/// to 0.
|
||||
/// Initializes a semaphore with the specified count and maximum count.
|
||||
/// If the semaphore is used for resource sharing, both the initial count
|
||||
/// and maximum count should be set to the number of identical resources
|
||||
/// guarded by the semaphore. If the semaphore is used as a signaling
|
||||
/// mechanism, the initial count should set to 0 and maximum count to 1
|
||||
/// (binary semaphore).
|
||||
///
|
||||
/// @param[in] count initial value of the semaphore counter
|
||||
///
|
||||
/// @param[in] max_count maximum value of the semaphore counter.
|
||||
/// The purpose of the max_count is to limit the counter
|
||||
/// so that the semaphore cannot unblock more times than
|
||||
/// the maximum.
|
||||
/// @note
|
||||
/// QXSemaphore::init() must be called **before** the semaphore can be used
|
||||
/// (signaled or waited on).
|
||||
///
|
||||
void QXSemaphore::init(uint_fast16_t const count) {
|
||||
m_count = count;
|
||||
void QXSemaphore::init(uint_fast16_t const count,
|
||||
uint_fast16_t const max_count)
|
||||
{
|
||||
Q_REQUIRE_ID(100, max_count > static_cast<uint_fast16_t>(0));
|
||||
|
||||
m_waitSet.setEmpty();
|
||||
m_count = count;
|
||||
m_max_count = max_count;
|
||||
}
|
||||
|
||||
//****************************************************************************
|
||||
@ -105,8 +114,14 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
|
||||
|
||||
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
|
||||
|
||||
Q_REQUIRE_ID(100, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
/// @pre this function must:
|
||||
/// (1) NOT be called from an ISR; (2) be called from an extended thread;
|
||||
/// (3) the thread must NOT be holding a mutex and
|
||||
/// (4) the thread must NOT be already blocked on any object.
|
||||
///
|
||||
Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */
|
||||
&& (QXK_attr_.lockPrio == static_cast<uint_fast8_t>(0)) /* no lock */
|
||||
&& (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
|
||||
|
||||
if (m_count > static_cast<uint_fast16_t>(0)) {
|
||||
@ -125,7 +140,7 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
|
||||
|
||||
QF_CRIT_ENTRY_();
|
||||
// the blocking object must be this semaphore
|
||||
Q_ASSERT_ID(110, thr->m_temp.obj
|
||||
Q_ASSERT_ID(210, thr->m_temp.obj
|
||||
== reinterpret_cast<QMState const *>(this));
|
||||
thr->m_temp.obj = static_cast<QMState const *>(0); // clear
|
||||
}
|
||||
@ -145,11 +160,15 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
|
||||
/// if the awakened thread is now the highest-priority thread that is
|
||||
/// ready-to-run.
|
||||
///
|
||||
/// @returns true when the semaphore gets signaled and false when
|
||||
/// the semaphore count exceeded the maximum.
|
||||
///
|
||||
/// @note
|
||||
/// A semaphore can be signaled from many places, including from ISRs, basic
|
||||
/// threads (AOs), and extended threads.
|
||||
///
|
||||
void QXSemaphore::signal(void) {
|
||||
bool QXSemaphore::signal(void) {
|
||||
bool signaled = true; // assume that the semaphore will be signaled
|
||||
QF_CRIT_STAT_
|
||||
|
||||
QF_CRIT_ENTRY_();
|
||||
@ -161,8 +180,9 @@ void QXSemaphore::signal(void) {
|
||||
QXThread *thr = static_cast<QXThread *>(QF::active_[p]);
|
||||
|
||||
// the thread must be extended and the semaphore count must be zero
|
||||
Q_ASSERT_ID(210, (thr->m_osObject != static_cast<void *>(0))
|
||||
&& (m_count == static_cast<uint_fast16_t>(0)));
|
||||
Q_ASSERT_ID(210, (thr != static_cast<QXThread *>(0)) /* registered */
|
||||
&& (thr->m_osObject != static_cast<void *>(0)) /* extended */
|
||||
&& (m_count == static_cast<uint_fast16_t>(0))); // not signaled
|
||||
|
||||
// disarm the internal time event
|
||||
(void)thr->teDisarm_();
|
||||
@ -172,9 +192,16 @@ void QXSemaphore::signal(void) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
++m_count;
|
||||
if (m_count < m_max_count) {
|
||||
++m_count;
|
||||
}
|
||||
else {
|
||||
signaled = false; // semaphore NOT signaled
|
||||
}
|
||||
}
|
||||
QF_CRIT_EXIT_();
|
||||
|
||||
return signaled;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
|
@ -3,8 +3,8 @@
|
||||
/// @ingroup qxk
|
||||
/// @cond
|
||||
///***************************************************************************
|
||||
/// Last updated for version 5.9.4
|
||||
/// Last updated on 2017-07-05
|
||||
/// Last updated for version 5.9.6
|
||||
/// Last updated on 2017-07-27
|
||||
///
|
||||
/// Q u a n t u m L e a P s
|
||||
/// ---------------------------
|
||||
@ -335,8 +335,14 @@ QEvt const *QXThread::queueGet(uint_fast16_t const nTicks,
|
||||
QF_CRIT_ENTRY_();
|
||||
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
|
||||
|
||||
/// @pre this function must:
|
||||
/// (1) NOT be called from an ISR; (2) be called from an extended thread;
|
||||
/// (3) the thread must NOT be holding a mutex and
|
||||
/// (4) the thread must NOT be already blocked on any object.
|
||||
///
|
||||
Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */
|
||||
&& (QXK_attr_.lockPrio == static_cast<uint_fast8_t>(0)) /* !locked */
|
||||
&& (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
|
||||
|
||||
// is the queue empty? -- block and wait for event(s)
|
||||
@ -453,7 +459,7 @@ void QXThread::teArm_(enum_t const sig,
|
||||
uint_fast16_t const nTicks,
|
||||
uint_fast8_t const tickRate)
|
||||
{
|
||||
// the time event must be unused
|
||||
/// @pre the time event must be unused
|
||||
Q_REQUIRE_ID(700, m_timeEvt.m_ctr == static_cast<QTimeEvtCtr>(0));
|
||||
|
||||
m_timeEvt.sig = static_cast<QSignal>(sig);
|
||||
@ -517,8 +523,16 @@ bool QXThread::delay(uint_fast16_t const nTicks,
|
||||
QF_CRIT_ENTRY_();
|
||||
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
|
||||
|
||||
// the delaying thread must not be blocked on any object
|
||||
Q_REQUIRE_ID(900, thr->m_temp.obj == static_cast<QMState const *>(0));
|
||||
/// @pre this function must:
|
||||
/// (1) NOT be called from an ISR; (2) be called from an extended thread;
|
||||
/// (3) the thread must NOT be holding a mutex and
|
||||
/// (4) the thread must NOT be already blocked on any object.
|
||||
///
|
||||
Q_REQUIRE_ID(900, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
|
||||
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */
|
||||
&& (QXK_attr_.lockPrio == static_cast<uint_fast8_t>(0)) /* !locked */
|
||||
&& (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
|
||||
|
||||
|
||||
// remember the blocking object
|
||||
thr->m_temp.obj = reinterpret_cast<QMState const *>(&thr->m_timeEvt);
|
||||
|
Loading…
x
Reference in New Issue
Block a user