5.9.6-beta

This commit is contained in:
Quantum Leaps 2017-07-28 22:54:35 -04:00
parent d90418fdb9
commit f691fd14b9
35 changed files with 3756 additions and 3519 deletions

View File

@ -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 // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions // modification, are permitted provided that the following conditions
@ -40,63 +37,18 @@
#ifndef CMSIS_CCS_H_ #ifndef CMSIS_CCS_H_
#define CMSIS_CCS_H_ #define CMSIS_CCS_H_
// Data Synchronization Barrier //*****************************************************************************
__attribute__( ( always_inline ) ) static inline void __DSB(void) // CMSIS-compatible instruction calls
{ //*****************************************************************************
__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
// //
// v5e, v6, Cortex-M3, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics // v5e, v6, Cortex-M3, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics
// //
#define __CLZ _norm #define __CLZ _norm
#define __SXTB _sxtb #define __SXTB _sxtb
#define __SXTH _sxth #define __SXTH _sxth
#define __UXTB _uxtb #define __UXTB _uxtb
#define __UXTH _uxth #define __UXTH _uxth
#define __NOP __nop
#define __WFI __wfi
// CCS supports intrinsics to take advantage of the shift operand left/right // CCS supports intrinsics to take advantage of the shift operand left/right
// before saturation extension of SSAT, but CMSIS does not take advantage // 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 // 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 // Only define M4 based intrinsics if we're not using an M4
// //
#if defined (__TI_TMS470_V7M4__) #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 // V5E, V6, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics
// //
#define __QADD _sadd #define __ROR __ror
#define __QDADD _sdadd #define __SXTB16(src) _sxtb16((src),0)
#define __QDSUB _sdsub #define __QADD _sadd
#define __SMLABB _smlabb #define __QDADD _sdadd
#define __SMLABT _smlabt #define __QDSUB _sdsub
#define __SMLALBB _smlalbb #define __SMLABB _smlabb
#define __SMLALBT _smlalbt #define __SMLABT _smlabt
#define __SMLALTB _smlaltb #define __SMLALBB _smlalbb
#define __SMLALTT _smlaltt #define __SMLALBT _smlalbt
#define __SMLALTB _smlaltb
#define __SMLALTT _smlaltt
#define __SMLATB _smlatb #define __SMLATB _smlatb
#define __SMLATT _smlatt #define __SMLATT _smlatt
#define __SMLAWB _smlawb #define __SMLAWB _smlawb
@ -131,77 +132,77 @@ static inline void __set_PRIMASK(uint32_t priMask)
#define __SMULTT _smultt #define __SMULTT _smultt
#define __SMULWB _smulwb #define __SMULWB _smulwb
#define __SMULWT _smulwt #define __SMULWT _smulwt
#define __QSUB _ssub #define __QSUB _ssub
#define __SUBC _subc #define __SUBC _subc
// //
// v6, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics // v6, Cortex-M4, Cortex-R4, and Cortex-A8 compiler intrinsics
// //
#define __SHASX _shaddsubx #define __SHASX _shaddsubx
#define __SHSAX _shsubaddx #define __SHSAX _shsubaddx
#define __PKHBT _pkhbt #define __PKHBT _pkhbt
#define __PKHTB _pkhtb #define __PKHTB _pkhtb
#define __QADD16 _qadd16 #define __QADD16 _qadd16
#define __QADD8 _qadd8 #define __QADD8 _qadd8
#define __QSUB16 _qsub16 #define __QSUB16 _qsub16
#define __QSUB8 _qsub8 #define __QSUB8 _qsub8
#define __QASX _saddsubx #define __QASX _saddsubx
#define __QSAX _qsubaddx #define __QSAX _qsubaddx
#define __SADD16 _sadd16 #define __SADD16 _sadd16
#define __SADD8 _sadd8 #define __SADD8 _sadd8
#define __SASX _saddsubx #define __SASX _saddsubx
#define __SEL _sel #define __SEL _sel
#define __SHADD16 _shadd16 #define __SHADD16 _shadd16
#define __SHADD8 _shadd8 #define __SHADD8 _shadd8
#define __SHSUB16 _shsub16 #define __SHSUB16 _shsub16
#define __SHSUB8 _shsub8 #define __SHSUB8 _shsub8
#define __SMLAD _smlad #define __SMLAD _smlad
#define __SMLADX _smladx #define __SMLADX _smladx
#define __SMLALD _smlald #define __SMLALD(src1, src2, accumulator) _smlald(accumulator, src1, src2)
#define __SMLALDX _smlaldx #define __SMLALDX _smlaldx
#define __SMLSD _smlsd #define __SMLSD _smlsd
#define __SMLSDX _smlsdx #define __SMLSDX _smlsdx
#define __SMLSLD _smlsld #define __SMLSLD _smlsld
#define __SMLSLDX _smlsldx #define __SMLSLDX _smlsldx
#define __SMMLA _smmla #define __SMMLA _smmla
#define __SMMLAR _smmlar #define __SMMLAR _smmlar
#define __SMMLS _smmls #define __SMMLS _smmls
#define __SMMLSR _smmlsr #define __SMMLSR _smmlsr
#define __SMMUL _smmul #define __SMMUL _smmul
#define __SMMULR _smmulr #define __SMMULR _smmulr
#define __SMUAD _smuad #define __SMUAD _smuad
#define __SMUADX _smuadx #define __SMUADX _smuadx
#define __SMUSD _smusd #define __SMUSD _smusd
#define __SMUSDX _smusd #define __SMUSDX _smusdx
#define __SSAT16 _ssat16 #define __SSAT16 _ssat16
#define __SSUB16 _ssub16 #define __SSUB16 _ssub16
#define __SSUB8 _ssub8 #define __SSUB8 _ssub8
#define __SSAX _ssubaddx #define __SSAX _ssubaddx
#define __SXTAB _sxtab #define __SXTAB _sxtab
#define __SXTAB16 _sxtab16 #define __SXTAB16 _sxtab16
#define __SXTAH _sxtah #define __SXTAH _sxtah
#define __UMAAL _umaal #define __UMAAL _umaal
#define __UADD16 _uadd16 #define __UADD16 _uadd16
#define __UADD8 _uadd8 #define __UADD8 _uadd8
#define __UHADD16 _uhadd16 #define __UHADD16 _uhadd16
#define __UHADD8 _uhadd8 #define __UHADD8 _uhadd8
#define __UASX _uaddsubx #define __UASX _uaddsubx
#define __UHSUB16 _uhsub16 #define __UHSUB16 _uhsub16
#define __UHSUB8 _uhsub8 #define __UHSUB8 _uhsub8
#define __UQADD16 _uqadd16 #define __UQADD16 _uqadd16
#define __UQADD8 _uqadd8 #define __UQADD8 _uqadd8
#define __UQASX _uqaddsubx #define __UQASX _uqaddsubx
#define __UQSUB16 _uqsub16 #define __UQSUB16 _uqsub16
#define __UQSUB8 _uqsub8 #define __UQSUB8 _uqsub8
#define __UQSAX _uqsubaddx #define __UQSAX _uqsubaddx
#define __USAD8 _usad8 #define __USAD8 _usad8
#define __USAT16 _usat16 #define __USAT16 _usat16
#define __USUB16 _usub16 #define __USUB16 _usub16
#define __USUB8 _usub8 #define __USUB8 _usub8
#define __USAX _usubaddx #define __USAX _usubaddx
#define __UXTAB _uxtab #define __UXTAB _uxtab
#define __UXTAB16 _uxtab16 #define __UXTAB16 _uxtab16
#define __UXTAH _uxtah #define __UXTAH _uxtah
#define __UXTB16 _uxtb16 #define __UXTB16 _uxtb16
#endif /*__TI_TMS470_V7M4__*/ #endif /*__TI_TMS470_V7M4__*/

View File

@ -1,8 +1,9 @@
![QP framework](https://state-machine.com/img/qp_banner.jpg) ![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? # What's New?
View QP/C++ Revision History at: View QP/C++ Revision History at: https://state-machine.com/qpcpp/history.html
https://state-machine.com/qpcpp/history.html
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
# About QP/C++ # 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" The guide also contains a tutorial, in which you build a simple "Blinky"
application. 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` recommended location is `C:\qp\qpcpp` on Windows and `~/qp/qpcpp`
on Linux/MacOS. 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 # QP/C++ Documentation
The **QP/C++ Manual** is located online at: The **QP/C++ Manual** is located online at: https://state-machine.com/qpcpp
- https://state-machine.com/qpcpp
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
# How to get help? # How to get help?

View File

@ -7,15 +7,15 @@ private:
uint8_t m_opKey; uint8_t m_opKey;
public: public:
Calc() : QHsm(Q_STATE_CAST(&QCalc::initial)) { // ctor Calc() : QHsm(Q_STATE_CAST(&Calc::initial)) { // ctor
} }
protected: protected:
static QState initial (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 on (Calc * const me, QEvt const *e);
static QState error (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 ready (Calc * const me, QEvt const *e);
static QState result (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 begin (Calc * const me, QEvt const *e);
. . . . . .
}; };

View File

@ -13,11 +13,11 @@ protected:
// NOTE: QMsm state machine code is not intended for manual // NOTE: QMsm state machine code is not intended for manual
// coding but rather needs to be generated automatically by // coding but rather needs to be generated automatically by
// the QM modeling tool // the QM modeling tool
static QState initial (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 on (Calc * const me, QEvt const *e);
static QState error (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 ready (Calc * const me, QEvt const *e);
static QState result (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 begin (Calc * const me, QEvt const *e);
. . . . . .
}; };

View File

@ -32,11 +32,11 @@
</option> </option>
<option> <option>
<name>Input description</name> <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>
<option> <option>
<name>Output description</name> <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>
<option> <option>
<name>GOutputBinary</name> <name>GOutputBinary</name>
@ -143,12 +143,12 @@
<option> <option>
<name>FPU2</name> <name>FPU2</name>
<version>0</version> <version>0</version>
<state>4</state> <state>0</state>
</option> </option>
<option> <option>
<name>NrRegs</name> <name>NrRegs</name>
<version>0</version> <version>0</version>
<state>1</state> <state>0</state>
</option> </option>
<option> <option>
<name>NEON</name> <name>NEON</name>
@ -339,7 +339,7 @@
<state>$PROJ_DIR$\..</state> <state>$PROJ_DIR$\..</state>
<state>$PROJ_DIR$\..\..</state> <state>$PROJ_DIR$\..\..</state>
<state>$PROJ_DIR$\..\..\..\..\..\include</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$\..\..\..\..\..\ports\arm-cm\qxk\iar</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state> <state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state> <state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
@ -1087,7 +1087,7 @@
</option> </option>
<option> <option>
<name>OGLastSavedByProductVersion</name> <name>OGLastSavedByProductVersion</name>
<state>7.60.1.11206</state> <state>8.11.1.13270</state>
</option> </option>
<option> <option>
<name>GeneralEnableMisra</name> <name>GeneralEnableMisra</name>
@ -1361,7 +1361,7 @@
<state>$PROJ_DIR$\..</state> <state>$PROJ_DIR$\..</state>
<state>$PROJ_DIR$\..\..</state> <state>$PROJ_DIR$\..\..</state>
<state>$PROJ_DIR$\..\..\..\..\..\include</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$\..\..\..\..\..\ports\arm-cm\qxk\iar</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state> <state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state> <state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
@ -2109,7 +2109,7 @@
</option> </option>
<option> <option>
<name>OGLastSavedByProductVersion</name> <name>OGLastSavedByProductVersion</name>
<state>7.60.1.11206</state> <state>8.11.1.13270</state>
</option> </option>
<option> <option>
<name>GeneralEnableMisra</name> <name>GeneralEnableMisra</name>
@ -2383,7 +2383,7 @@
<state>$PROJ_DIR$\..</state> <state>$PROJ_DIR$\..</state>
<state>$PROJ_DIR$\..\..</state> <state>$PROJ_DIR$\..\..</state>
<state>$PROJ_DIR$\..\..\..\..\..\include</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$\..\..\..\..\..\ports\arm-cm\qxk\iar</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state> <state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state> <state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
@ -3117,58 +3117,52 @@
<group> <group>
<name>QP</name> <name>QP</name>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qep_hsm.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qep_msm.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_act.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_actq.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_defer.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_dyn.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_mem.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_pkg.h</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_ps.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qact.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qeq.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qmact.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_time.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_mutex.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_pkg.h</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.cpp</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_sema.cpp</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_xthr.cpp</name>
</file> </file>
</group> </group>
<group> <group>
@ -3184,16 +3178,19 @@
<configuration>Release</configuration> <configuration>Release</configuration>
</excluded> </excluded>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qs.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qs\qs.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qs_fp.cpp</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qs\qs_64bit.cpp</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qs_pkg.h</name> <name>$PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.cpp</name>
</file> </file>
<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> </file>
</group> </group>
</project> </project>

View File

@ -1,7 +1,7 @@
//**************************************************************************** //****************************************************************************
// DPP example for QXK // DPP example for QXK
// Last updated for version 5.9.4 // Last updated for version 5.9.6
// Last updated on 2017-07-06 // Last updated on 2017-07-27
// //
// Q u a n t u m L e a P s // 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 Thread1_run(QP::QXThread * const me);
static void Thread2_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_test1(&Thread1_run, 0U);
static QP::QXThread l_test2(&Thread2_run, 0U); static QP::QXThread l_test2(&Thread2_run, 0U);
static QP::QXMutex l_mutex; 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); (void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
BSP::ledOn(); BSP::ledOn();
l_mutex.lock(); // exercise the mutex l_mutex.lock(); // exercise the mutex
// some flating point code to exercise the VFP... // some flating point code to exercise the VFP...
float volatile x = 1.4142135F; float volatile x = 1.4142135F;
x = x * 1.4142135F; x = x * 1.4142135F;
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
l_mutex.unlock(); l_mutex.unlock();
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK 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 // NOTE: the semaphore is initialized in the highest-priority thread
// that uses it. Alternatively, the semaphore can be initialized // that uses it. Alternatively, the semaphore can be initialized
// before any thread runs. // 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 (;;) { for (;;) {
// some flating point code to exercise the VFP... // 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! QP::QF::gc(e); // recycle the event manually!
} }
else { 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 l_sema.signal(); // signal Thread1
} }

View File

@ -1,7 +1,7 @@
//**************************************************************************** //****************************************************************************
// DPP example for QXK // DPP example for QXK
// Last updated for version 5.7.2 // Last updated for version 5.9.6
// Last updated on 2016-09-28 // Last updated on 2017-07-27
// //
// Q u a n t u m L e a P s // 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 Thread1_run(QP::QXThread * const me);
static void Thread2_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_test1(&Thread1_run, 0U);
static QP::QXThread l_test2(&Thread2_run, 0U); static QP::QXThread l_test2(&Thread2_run, 0U);
static QP::QXMutex l_mutex; 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); (void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
BSP::ledOn(); BSP::ledOn();
l_mutex.lock(); // exercise the mutex l_mutex.lock(); // exercise the mutex
// some flating point code to exercise the VFP... // some flating point code to exercise the VFP...
float volatile x = 1.4142135F; float volatile x = 1.4142135F;
x = x * 1.4142135F; x = x * 1.4142135F;
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
l_mutex.unlock(); l_mutex.unlock();
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK 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 // NOTE: the semaphore is initialized in the highest-priority thread
// that uses it. Alternatively, the semaphore can be initialized // that uses it. Alternatively, the semaphore can be initialized
// before any thread runs. // 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 (;;) { for (;;) {
// some flating point code to exercise the VFP... // 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! QP::QF::gc(e); // recycle the event manually!
} }
else { 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 l_sema.signal(); // signal Thread1
} }
} }

View File

@ -1,7 +1,7 @@
//**************************************************************************** //****************************************************************************
// DPP example for QXK // DPP example for QXK
// Last updated for version 5.7.2 // Last updated for version 5.9.6
// Last updated on 2016-09-28 // Last updated on 2017-07-27
// //
// Q u a n t u m L e a P s // 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 Thread1_run(QP::QXThread * const me);
static void Thread2_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_test1(&Thread1_run, 0U);
static QP::QXThread l_test2(&Thread2_run, 0U); static QP::QXThread l_test2(&Thread2_run, 0U);
static QP::QXMutex l_mutex; 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); (void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
BSP::ledOn(); BSP::ledOn();
l_mutex.lock(); // exercise the mutex l_mutex.lock(); // exercise the mutex
// some flating point code to exercise the VFP... // some flating point code to exercise the VFP...
float volatile x = 1.4142135F; float volatile x = 1.4142135F;
x = x * 1.4142135F; x = x * 1.4142135F;
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
l_mutex.unlock(); l_mutex.unlock();
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK 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 // NOTE: the semaphore is initialized in the highest-priority thread
// that uses it. Alternatively, the semaphore can be initialized // that uses it. Alternatively, the semaphore can be initialized
// before any thread runs. // 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 (;;) { for (;;) {
// some flating point code to exercise the VFP... // 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! QP::QF::gc(e); // recycle the event manually!
} }
else { 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 l_sema.signal(); // signal Thread1
} }
} }

View File

@ -1,7 +1,7 @@
//**************************************************************************** //****************************************************************************
// DPP example for QXK // DPP example for QXK
// Last updated for version 5.7.2 // Last updated for version 5.9.6
// Last updated on 2016-09-28 // Last updated on 2017-07-27
// //
// Q u a n t u m L e a P s // 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 Thread1_run(QP::QXThread * const me);
static void Thread2_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_test1(&Thread1_run, 0U);
static QP::QXThread l_test2(&Thread2_run, 0U); static QP::QXThread l_test2(&Thread2_run, 0U);
static QP::QXMutex l_mutex; 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); (void)l_sema.wait(BSP::TICKS_PER_SEC, 0U);
BSP::ledOn(); BSP::ledOn();
l_mutex.lock(); // exercise the mutex l_mutex.lock(); // exercise the mutex
// some flating point code to exercise the VFP... // some flating point code to exercise the VFP...
float volatile x = 1.4142135F; float volatile x = 1.4142135F;
x = x * 1.4142135F; x = x * 1.4142135F;
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
l_mutex.unlock(); l_mutex.unlock();
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK 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 // NOTE: the semaphore is initialized in the highest-priority thread
// that uses it. Alternatively, the semaphore can be initialized // that uses it. Alternatively, the semaphore can be initialized
// before any thread runs. // 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 (;;) { for (;;) {
// some flating point code to exercise the VFP... // 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! QP::QF::gc(e); // recycle the event manually!
} }
else { 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 l_sema.signal(); // signal Thread1
} }
} }

View File

@ -1,7 +1,7 @@
//**************************************************************************** //****************************************************************************
// DPP example for QXK // DPP example for QXK
// Last updated for version 5.8.2 // Last updated for version 5.9.6
// Last updated on 2017-02-03 // Last updated on 2017-07-27
// //
// Q u a n t u m L e a P s // 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 Thread1_run(QP::QXThread * const me);
static void Thread2_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_test1(&Thread1_run, 0U);
static QP::QXThread l_test2(&Thread2_run, 0U); static QP::QXThread l_test2(&Thread2_run, 0U);
static QP::QXMutex l_mutex; 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... // some flating point code to exercise the VFP...
float volatile x = 1.4142135F; float volatile x = 1.4142135F;
x = x * 1.4142135F; x = x * 1.4142135F;
//QP::QXThread::delay(1U, 0U); // asserts (blocking while holding a mutex)
l_mutex.unlock(); l_mutex.unlock();
QP::QXThread::delay(BSP::TICKS_PER_SEC/7, 0U); // BLOCK 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 // NOTE: the semaphore is initialized in the highest-priority thread
// that uses it. Alternatively, the semaphore can be initialized // that uses it. Alternatively, the semaphore can be initialized
// before any thread runs. // 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 (;;) { for (;;) {
// some flating point code to exercise the VFP... // 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! QP::QF::gc(e); // recycle the event manually!
} }
else { 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 l_sema.signal(); // signal Thread1
} }
} }

View File

@ -1,7 +1,7 @@
//**************************************************************************** //****************************************************************************
// DPP example for QXK // DPP example for QXK
// Last updated for version 5.8.0 // Last updated for version 5.9.6
// Last updated on 2016-11-30 // Last updated on 2017-07-27
// //
// Q u a n t u m L e a P s // Q u a n t u m L e a P s
// --------------------------- // ---------------------------

View File

@ -3,8 +3,8 @@
/// @ingroup qxk /// @ingroup qxk
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.8.0 /// Last updated for version 5.9.6
/// Last updated on 2016-11-19 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// Q u a n t u m L e a P s
/// --------------------------- /// ---------------------------
@ -69,18 +69,19 @@ class QXThread : public QActive {
public: public:
//! public constructor //! 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 //! delay (block) the current extended thread for a specified # ticks
static bool delay(uint_fast16_t const nTicks, 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 //! cancel the delay
bool delayCancel(void); bool delayCancel(void);
//! obtain a message from the private message queue (block if no messages) //! obtain a message from the private message queue (block if no messages)
static QEvt const *queueGet(uint_fast16_t const nTicks, 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... // virtual function overrides...
//! Executes the top-most initial transition in QP::QMsm. //! Executes the top-most initial transition in QP::QMsm.
@ -123,7 +124,7 @@ private:
void block_(void) const; void block_(void) const;
void unblock_(void) const; void unblock_(void) const;
void teArm_(enum_t const sig, uint_fast16_t const nTicks, 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); bool teDisarm_(void);
// attributes... // attributes...
@ -141,18 +142,20 @@ private:
class QXSemaphore { class QXSemaphore {
public: public:
//! initialize the counting semaphore //! 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 //! signal (unblock) the semaphore
void signal(void); bool signal(void);
//! wait (block) on the semaphore //! wait (block) on the semaphore
bool wait(uint_fast16_t const nTicks, bool wait(uint_fast16_t const nTicks,
uint_fast8_t const tickRate); uint_fast8_t const tickRate = static_cast<uint_fast8_t>(0));
private: private:
uint_fast16_t m_count;
QPSet m_waitSet; //!< set of extended threads waiting on this semaphore QPSet m_waitSet; //!< set of extended threads waiting on this semaphore
uint_fast16_t m_count;
uint_fast16_t m_max_count;
}; };
} // namespace QP } // namespace QP

86
include/stdint_c.h Normal file
View 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

View File

@ -1,7 +1,7 @@
;***************************************************************************** ;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), ARM-KEIL assembler ; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), ARM-KEIL assembler
; Last Updated for Version: 5.9.0 ; Last Updated for Version: 5.9.6
; Date of the Last Update: 2017-03-17 ; Date of the Last Update: 2017-07-28
; ;
; Q u a n t u m L e a P s ; Q u a n t u m L e a P s
; --------------------------- ; ---------------------------
@ -111,16 +111,17 @@ QK_init FUNCTION
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r3,=0xE000E004 ; Interrupt Controller Type Register LDR r2,=0xE000E400 ; NVIC_PRI0 register
LDR r3,[r3] ; r3 := INTLINESUM LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
LDR r3,[r3]
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
LSLS r3,r3,#3 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... ; loop over all implemented NVIC_PRIO registers for IRQs...
QK_init_irq QK_init_irq
SUBS r3,r3,#1 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 CMP r3,#0
BNE QK_init_irq BNE QK_init_irq

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), GNU-ARM assembler * Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), GNU-ARM assembler
* Last Updated for Version: 5.9.3 * Last Updated for Version: 5.9.6
* Date of the Last Update: 2017-06-17 * Date of the Last Update: 2017-07-28
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* --------------------------- * ---------------------------
@ -106,16 +106,18 @@ QK_init:
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r3,=0xE000E004 /* Interrupt Controller Type Register */ LDR r2,=0xE000E400 /* NVIC_PRI0 register */
LDR r3,[r3] /* r3 := INTLINESUM */ 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 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... */ /* loop over all implemented NVIC_PRIO registers for IRQs... */
QK_init_irq: QK_init_irq:
SUBS r3,r3,#1 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 CMP r3,#0
BNE QK_init_irq BNE QK_init_irq

View File

@ -1,7 +1,7 @@
;***************************************************************************** ;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler ; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler
; Last Updated for Version: 5.9.0 ; Last Updated for Version: 5.9.6
; Date of the Last Update: 2017-03-17 ; Date of the Last Update: 2017-07-28
; ;
; Q u a n t u m L e a P s ; Q u a n t u m L e a P s
; --------------------------- ; ---------------------------
@ -110,16 +110,17 @@ QK_init:
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r3,=0xE000E004 ; Interrupt Controller Type Register LDR r2,=0xE000E400 ; NVIC_PRI0 register
LDR r3,[r3] ; r3 := INTLINESUM LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
LDR r3,[r3]
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
LSLS r3,r3,#3 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... ; loop over all implemented NVIC_PRIO registers for IRQs...
QK_init_irq: QK_init_irq:
SUBS r3,r3,#1 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 CMP r3,#0
BNE QK_init_irq BNE QK_init_irq

View File

@ -1,7 +1,7 @@
;***************************************************************************** ;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler ; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
; Last Updated for Version: 5.9.0 ; Last Updated for Version: 5.9.6
; Date of the Last Update: 2017-03-17 ; Date of the Last Update: 2017-07-28
; ;
; Q u a n t u m L e a P s ; Q u a n t u m L e a P s
; --------------------------- ; ---------------------------
@ -109,16 +109,17 @@ QK_init: .asmfunc
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r3,ICTR_addr ; Interrupt Controller Type Register LDR r2,PRI0_addr ; NVIC_PRI0 register
LDR r3,[r3] ; r3 := INTLINESUM 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 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... ; loop over all implemented NVIC_PRIO registers for IRQs...
QK_init_irq: QK_init_irq:
SUBS r3,r3,#1 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 CMP r3,#0
BNE QK_init_irq BNE QK_init_irq

View File

@ -1,9 +1,9 @@
/// @file /// @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 /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.8.1 /// Last updated for version 5.9.6
/// Last updated on 2016-12-12 /// Last updated on 2017-07-28
/// ///
/// Q u a n t u m L e a P s /// 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/>. /// along with this program. If not, see <http://www.gnu.org/licenses/>.
/// ///
/// Contact information: /// Contact information:
/// www.state-machine.com /// https://state-machine.com
/// mailto:info@state-machine.com /// mailto:info@state-machine.com
///*************************************************************************** ///***************************************************************************
/// @endcond /// @endcond
@ -61,7 +61,6 @@ extern "C" {
* The interrupt priorities established in QV_init() can be later * The interrupt priorities established in QV_init() can be later
* changed by the application-level code. * changed by the application-level code.
*/ */
void QV_init(void) { void QV_init(void) {
// set exception priorities to QF_BASEPRI... // 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; SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI;
// set all implemented IRQ priories to 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 { do {
--n; --n;
NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16) NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16)

View File

@ -1,9 +1,9 @@
/// @file /// @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 /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.8.1 /// Last updated for version 5.9.6
/// Last updated on 2016-12-12 /// Last updated on 2017-07-28
/// ///
/// Q u a n t u m L e a P s /// 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/>. /// along with this program. If not, see <http://www.gnu.org/licenses/>.
/// ///
/// Contact information: /// Contact information:
/// www.state-machine.com /// https://state-machine.com
/// mailto:info@state-machine.com /// mailto:info@state-machine.com
///*************************************************************************** ///***************************************************************************
/// @endcond /// @endcond
#include "qf_port.h" #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 SCnSCB_ICTR ((uint32_t volatile *)0xE000E004)
#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14) #define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14)
#define NVIC_IP ((uint32_t volatile *)0xE000E400) #define NVIC_IP ((uint32_t volatile *)0xE000E400)
extern "C" {
/* /*
* Initialize the exception priorities and IRQ priorities to safe values. * 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; SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI;
// set all implemented IRQ priories to 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 { do {
--n; --n;
NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16) NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16)

View File

@ -2,8 +2,8 @@
/// @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, IAR-ARM toolset
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.8.1 /// Last updated for version 5.9.6
/// Last updated on 2016-12-12 /// Last updated on 2017-07-28
/// ///
/// Q u a n t u m L e a P s /// 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/>. /// along with this program. If not, see <http://www.gnu.org/licenses/>.
/// ///
/// Contact information: /// Contact information:
/// www.state-machine.com /// https://state-machine.com
/// mailto:info@state-machine.com /// mailto:info@state-machine.com
///*************************************************************************** ///***************************************************************************
/// @endcond /// @endcond
@ -61,7 +61,6 @@ extern "C" {
* The interrupt priorities established in QV_init() can be later * The interrupt priorities established in QV_init() can be later
* changed by the application-level code. * changed by the application-level code.
*/ */
void QV_init(void) { void QV_init(void) {
// set exception priorities to QF_BASEPRI... // 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; SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI;
// set all implemented IRQ priories to 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 { do {
--n; --n;
NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16) NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16)
@ -86,4 +85,3 @@ void QV_init(void) {
} // extern "C" } // extern "C"
#endif // NOT Cortex-M0/M0+/M1 ? #endif // NOT Cortex-M0/M0+/M1 ?

View File

@ -1,7 +1,7 @@
;***************************************************************************** ;*****************************************************************************
; Product: QV port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler ; Product: QV port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
; Last Updated for Version: 5.9.0 ; Last Updated for Version: 5.9.6
; Date of the Last Update: 2017-03-17 ; Date of the Last Update: 2017-07-28
; ;
; Q u a n t u m L e a P s ; Q u a n t u m L e a P s
; --------------------------- ; ---------------------------
@ -139,16 +139,17 @@ QV_init: .asmfunc
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r2,PRI0_addr ; NVIC_PRI0 register
LDR r3,ICTR_addr ; Interrupt Controller Type 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 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... ; loop over all implemented NVIC_PRIO registers for IRQs...
QV_init_irq: QV_init_irq:
SUBS r3,r3,#1 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 CMP r3,#0
BNE QV_init_irq BNE QV_init_irq

View File

@ -1,7 +1,7 @@
;***************************************************************************** ;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), ARM-Keil assembler ; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), ARM-Keil assembler
; Last Updated for Version: 5.9.4 ; Last Updated for Version: 5.9.6
; Date of the Last Update: 2017-07-06 ; Date of the Last Update: 2017-07-28
; ;
; Q u a n t u m L e a P s ; Q u a n t u m L e a P s
; --------------------------- ; ---------------------------
@ -83,7 +83,7 @@ QXK_init FUNCTION
ELSE ; Cortex-M3/M4/.. ELSE ; Cortex-M3/M4/..
; NOTE: ; 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 ; the BASEPRI register. However, this method cannot disable interrupt
; priority zero, which is the default for all interrupts out of reset. ; priority zero, which is the default for all interrupts out of reset.
; The following code changes the SysTick priority and all IRQ priorities ; The following code changes the SysTick priority and all IRQ priorities
@ -124,16 +124,17 @@ QXK_init FUNCTION
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r3,=0xE000E004 ; Interrupt Controller Type Register LDR r2,=0xE000E400 ; NVIC_PRI0 register
LDR r3,[r3] ; r3 := INTLINESUM LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
LDR r3,[r3]
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
LSLS r3,r3,#3 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... ; loop over all implemented NVIC_PRIO registers for IRQs...
QXK_init_irq QXK_init_irq
SUBS r3,r3,#1 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 CMP r3,#0
BNE QXK_init_irq BNE QXK_init_irq

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), GNU-ARM assembler * Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), GNU-ARM assembler
* Last Updated for Version: 5.9.4 * Last Updated for Version: 5.9.6
* Date of the Last Update: 2017-07-06 * Date of the Last Update: 2017-07-28
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* --------------------------- * ---------------------------
@ -114,16 +114,17 @@ QXK_init:
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r3,=0xE000E004 /* Interrupt Controller Type Register */ LDR r2,=0xE000E400 /* NVIC_PRI0 register */
LDR r3,[r3] /* r3 := INTLINESUM */ LDR r3,=0xE000E004 /* Interrupt Controller Type Register (ICTR) */
LDR r3,[r3]
ANDS r3,r3,#7 /* r3 := ICTR[0:2] (INTLINESNUM) */
LSLS r3,r3,#3 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... */ /* loop over all implemented NVIC_PRIO registers for IRQs... */
QXK_init_irq: QXK_init_irq:
SUBS r3,r3,#1 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 CMP r3,#0
BNE QXK_init_irq BNE QXK_init_irq

View File

@ -1,7 +1,7 @@
;***************************************************************************** ;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler ; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler
; Last Updated for Version: 5.9.4 ; Last Updated for Version: 5.9.6
; Date of the Last Update: 2017-07-06 ; Date of the Last Update: 2017-07-28
; ;
; Q u a n t u m L e a P s ; 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 QXK_TOP_PRIO EQU 8
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!! ; 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 QMACTIVE_PRIO EQU 48
@ -123,20 +123,21 @@ QXK_init:
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r3,=0xE000E004 ; Interrupt Controller Type Register LDR r2,=0xE000E400 ; NVIC_PRI0 register
LDR r3,[r3] ; r3 := INTLINESUM LDR r3,=0xE000E004 ; Interrupt Controller Type Register (ICTR)
LDR r3,[r3]
ANDS r3,r3,#7 ; r3 := ICTR[0:2] (INTLINESNUM)
LSLS r3,r3,#3 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... ; loop over all implemented NVIC_PRIO registers for IRQs...
QXK_init_irq: QXK_init_irq:
SUBS r3,r3,#1 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 CMP r3,#0
BNE QXK_init_irq BNE QXK_init_irq
#endif ; Cortex-M3/M4/... #endif ; Cortex-M3/M4/M7
MOV r0,r12 ; r0 := original PRIMASK MOV r0,r12 ; r0 := original PRIMASK
MSR PRIMASK,r0 ; PRIMASK := r0 MSR PRIMASK,r0 ; PRIMASK := r0

View File

@ -1,7 +1,7 @@
;***************************************************************************** ;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler ; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
; Last Updated for Version: 5.9.4 ; Last Updated for Version: 5.9.6
; Date of the Last Update: 2017-07-06 ; Date of the Last Update: 2017-07-28
; ;
; Q u a n t u m L e a P s ; 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 QXK_TOP_PRIO .equ 8
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!! ; 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 QMACTIVE_PRIO .equ 48
.text .text
@ -77,7 +77,7 @@ QXK_init: .asmfunc
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__ ; M3/4/7? .if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__ ; M3/4/7?
; NOTE: ; 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 ; the BASEPRI register. However, this method cannot disable interrupt
; priority zero, which is the default for all interrupts out of reset. ; priority zero, which is the default for all interrupts out of reset.
; The following code changes the SysTick priority and all IRQ priorities ; The following code changes the SysTick priority and all IRQ priorities
@ -118,16 +118,17 @@ QXK_init: .asmfunc
LSLS r1,r1,#8 LSLS r1,r1,#8
ORRS r1,r1,#QF_BASEPRI ORRS r1,r1,#QF_BASEPRI
LDR r2,PRI0_addr ; NVIC_PRI0 register
LDR r3,ICTR_addr ; Interrupt Controller Type 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 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... ; loop over all implemented NVIC_PRIO registers for IRQs...
QXK_init_irq: QXK_init_irq:
SUBS r3,r3,#1 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 CMP r3,#0
BNE QXK_init_irq BNE QXK_init_irq

View File

@ -4,8 +4,8 @@
/// @ingroup qxk /// @ingroup qxk
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.9.4 /// Last updated for version 5.9.6
/// Last updated on 2017-07-06 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// 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" #error "Source file included in a project NOT based on the QXK kernel"
#endif // qxk_h #endif // qxk_h
Q_DEFINE_THIS_MODULE("qxk")
// Public-scope objects ****************************************************** // Public-scope objects ******************************************************
extern "C" { extern "C" {
QXK_Attr QXK_attr_; // global attributes of the QXK kernel QXK_Attr QXK_attr_; // global attributes of the QXK kernel
@ -59,8 +61,6 @@ extern "C" {
namespace QP { namespace QP {
Q_DEFINE_THIS_MODULE("qxk")
// Local-scope objects ******************************************************* // Local-scope objects *******************************************************
class QXKIdleThread : public QActive { class QXKIdleThread : public QActive {
public: public:
@ -441,8 +441,14 @@ QP::QActive *QXK_current(void) {
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
curr = QXK_attr_.curr; curr = QXK_attr_.curr;
if (curr == static_cast<QP::QActive *>(0)) { // basic thread?
curr = QP::QF::active_[QXK_attr_.actPrio];
}
QF_CRIT_EXIT_(); QF_CRIT_EXIT_();
//! @post the current thread must be valid
Q_ENSURE_ID(900, curr != static_cast<QP::QActive *>(0));
return curr; return curr;
} }

View File

@ -5,8 +5,8 @@
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Product: QK/C++ /// Product: QK/C++
/// Last updated for version 5.9.4 /// Last updated for version 5.9.6
/// Last updated on 2017-07-05 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// 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_STAT_
QF_CRIT_ENTRY_(); 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 /// and the mutex must be unused
Q_REQUIRE_ID(700, (!QXK_ISR_CONTEXT_()) Q_REQUIRE_ID(700, (!QXK_ISR_CONTEXT_())
&& (m_prevPrio == static_cast<uint_fast8_t>(MUTEX_UNUSED))); && (m_prevPrio == static_cast<uint_fast8_t>(MUTEX_UNUSED)));
@ -124,7 +124,7 @@ void QXMutex::lock(void) {
QS_BEGIN_NOCRIT_(QS_SCHED_LOCK, QS_BEGIN_NOCRIT_(QS_SCHED_LOCK,
static_cast<void *>(0), static_cast<void *>(0)) static_cast<void *>(0), static_cast<void *>(0))
QS_TIME_(); // timestamp 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 static_cast<uint8_t>(QXK_attr_.lockPrio)); // new lock prio
QS_END_NOCRIT_() QS_END_NOCRIT_()
@ -152,7 +152,7 @@ void QXMutex::unlock(void) {
QF_CRIT_STAT_ QF_CRIT_STAT_
QF_CRIT_ENTRY_(); 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 /// and the mutex must NOT be unused
Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_()) Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_())
&& (m_prevPrio != static_cast<uint_fast8_t>(MUTEX_UNUSED))); && (m_prevPrio != static_cast<uint_fast8_t>(MUTEX_UNUSED)));
@ -164,19 +164,41 @@ void QXMutex::unlock(void) {
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK, QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
static_cast<void *>(0), static_cast<void *>(0)) static_cast<void *>(0), static_cast<void *>(0))
QS_TIME_(); // timestamp QS_TIME_(); // timestamp
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock prio */ if (QXK_attr_.lockPrio > p) {
(QXK_attr_.lockPrio > p) /* the new lock prio */ QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock */
? static_cast<uint8_t>(p) static_cast<uint8_t>(p)); // new lock prio
: static_cast<uint8_t>(QXK_attr_.lockPrio)); }
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_() QS_END_NOCRIT_()
if (QXK_attr_.lockPrio > p) { 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 QXK_attr_.lockPrio = p; // restore the previous lock prio
// find the highest-prio thread ready to run // find the highest-prio thread ready to run
if (QXK_sched_() != static_cast<uint_fast8_t>(0)) { // priority found? if (QXK_sched_() != static_cast<uint_fast8_t>(0)) { // priority found?
QXK_activate_(); // activate any unlocked basic threads 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_(); QF_CRIT_EXIT_();
} }

View File

@ -3,8 +3,8 @@
/// @ingroup qxk /// @ingroup qxk
/// @cond /// @cond
////************************************************************************** ////**************************************************************************
/// Last updated for version 5.9.5 /// Last updated for version 5.9.6
/// Last updated on 2017-07-20 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// Q u a n t u m L e a P s
/// --------------------------- /// ---------------------------
@ -57,21 +57,30 @@ Q_DEFINE_THIS_MODULE("qxk_sema")
//**************************************************************************** //****************************************************************************
/// @description /// @description
/// Initializes a semaphore with the specified count. If the semaphore is used /// Initializes a semaphore with the specified count and maximum count.
/// for resource sharing, the initial value of the semaphore count should be /// If the semaphore is used for resource sharing, both the initial count
/// set to the number of identical resources guarded by the semaphore. If the /// and maximum count should be set to the number of identical resources
/// semaphore is used as a signaling mechanism, the initial count should set /// guarded by the semaphore. If the semaphore is used as a signaling
/// to 0. /// 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] 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 /// @note
/// QXSemaphore::init() must be called **before** the semaphore can be used /// QXSemaphore::init() must be called **before** the semaphore can be used
/// (signaled or waited on). /// (signaled or waited on).
/// ///
void QXSemaphore::init(uint_fast16_t const count) { void QXSemaphore::init(uint_fast16_t const count,
m_count = count; uint_fast16_t const max_count)
{
Q_REQUIRE_ID(100, max_count > static_cast<uint_fast16_t>(0));
m_waitSet.setEmpty(); 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); 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 */ && (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 && (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
if (m_count > static_cast<uint_fast16_t>(0)) { if (m_count > static_cast<uint_fast16_t>(0)) {
@ -125,7 +140,7 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
// the blocking object must be this semaphore // 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)); == reinterpret_cast<QMState const *>(this));
thr->m_temp.obj = static_cast<QMState const *>(0); // clear 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 /// if the awakened thread is now the highest-priority thread that is
/// ready-to-run. /// ready-to-run.
/// ///
/// @returns true when the semaphore gets signaled and false when
/// the semaphore count exceeded the maximum.
///
/// @note /// @note
/// A semaphore can be signaled from many places, including from ISRs, basic /// A semaphore can be signaled from many places, including from ISRs, basic
/// threads (AOs), and extended threads. /// 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_STAT_
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
@ -161,8 +180,9 @@ void QXSemaphore::signal(void) {
QXThread *thr = static_cast<QXThread *>(QF::active_[p]); QXThread *thr = static_cast<QXThread *>(QF::active_[p]);
// the thread must be extended and the semaphore count must be zero // the thread must be extended and the semaphore count must be zero
Q_ASSERT_ID(210, (thr->m_osObject != static_cast<void *>(0)) Q_ASSERT_ID(210, (thr != static_cast<QXThread *>(0)) /* registered */
&& (m_count == static_cast<uint_fast16_t>(0))); && (thr->m_osObject != static_cast<void *>(0)) /* extended */
&& (m_count == static_cast<uint_fast16_t>(0))); // not signaled
// disarm the internal time event // disarm the internal time event
(void)thr->teDisarm_(); (void)thr->teDisarm_();
@ -172,9 +192,16 @@ void QXSemaphore::signal(void) {
} }
} }
else { else {
++m_count; if (m_count < m_max_count) {
++m_count;
}
else {
signaled = false; // semaphore NOT signaled
}
} }
QF_CRIT_EXIT_(); QF_CRIT_EXIT_();
return signaled;
} }
} // namespace QP } // namespace QP

View File

@ -3,8 +3,8 @@
/// @ingroup qxk /// @ingroup qxk
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.9.4 /// Last updated for version 5.9.6
/// Last updated on 2017-07-05 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// 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_(); QF_CRIT_ENTRY_();
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr); 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 */ Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */ && (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 && (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
// is the queue empty? -- block and wait for event(s) // 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_fast16_t const nTicks,
uint_fast8_t const tickRate) 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)); Q_REQUIRE_ID(700, m_timeEvt.m_ctr == static_cast<QTimeEvtCtr>(0));
m_timeEvt.sig = static_cast<QSignal>(sig); m_timeEvt.sig = static_cast<QSignal>(sig);
@ -517,8 +523,16 @@ bool QXThread::delay(uint_fast16_t const nTicks,
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr); QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
// the delaying thread must not be blocked on any object /// @pre this function must:
Q_REQUIRE_ID(900, thr->m_temp.obj == static_cast<QMState const *>(0)); /// (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 // remember the blocking object
thr->m_temp.obj = reinterpret_cast<QMState const *>(&thr->m_timeEvt); thr->m_temp.obj = reinterpret_cast<QMState const *>(&thr->m_timeEvt);

View File

@ -4,8 +4,8 @@
/// @ingroup qxk /// @ingroup qxk
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.9.5 /// Last updated for version 5.9.6
/// Last updated on 2017-07-19 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// Q u a n t u m L e a P s
/// --------------------------- /// ---------------------------
@ -441,6 +441,9 @@ QP::QActive *QXK_current(void) {
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
curr = QXK_attr_.curr; curr = QXK_attr_.curr;
if (curr == static_cast<QP::QActive *>(0)) { // basic thread?
curr = QP::QF::active_[QXK_attr_.actPrio];
}
QF_CRIT_EXIT_(); QF_CRIT_EXIT_();
//! @post the current thread must be valid //! @post the current thread must be valid

View File

@ -5,8 +5,8 @@
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Product: QK/C++ /// Product: QK/C++
/// Last updated for version 5.9.4 /// Last updated for version 5.9.6
/// Last updated on 2017-07-05 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// 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_STAT_
QF_CRIT_ENTRY_(); 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 /// and the mutex must be unused
Q_REQUIRE_ID(700, (!QXK_ISR_CONTEXT_()) Q_REQUIRE_ID(700, (!QXK_ISR_CONTEXT_())
&& (m_prevPrio == static_cast<uint_fast8_t>(MUTEX_UNUSED))); && (m_prevPrio == static_cast<uint_fast8_t>(MUTEX_UNUSED)));
@ -124,7 +124,7 @@ void QXMutex::lock(void) {
QS_BEGIN_NOCRIT_(QS_SCHED_LOCK, QS_BEGIN_NOCRIT_(QS_SCHED_LOCK,
static_cast<void *>(0), static_cast<void *>(0)) static_cast<void *>(0), static_cast<void *>(0))
QS_TIME_(); // timestamp 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 static_cast<uint8_t>(QXK_attr_.lockPrio)); // new lock prio
QS_END_NOCRIT_() QS_END_NOCRIT_()
@ -152,7 +152,7 @@ void QXMutex::unlock(void) {
QF_CRIT_STAT_ QF_CRIT_STAT_
QF_CRIT_ENTRY_(); 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 /// and the mutex must NOT be unused
Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_()) Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_())
&& (m_prevPrio != static_cast<uint_fast8_t>(MUTEX_UNUSED))); && (m_prevPrio != static_cast<uint_fast8_t>(MUTEX_UNUSED)));
@ -164,19 +164,41 @@ void QXMutex::unlock(void) {
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK, QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK,
static_cast<void *>(0), static_cast<void *>(0)) static_cast<void *>(0), static_cast<void *>(0))
QS_TIME_(); // timestamp QS_TIME_(); // timestamp
QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock prio */ if (QXK_attr_.lockPrio > p) {
(QXK_attr_.lockPrio > p) /* the new lock prio */ QS_2U8_(static_cast<uint8_t>(QXK_attr_.lockPrio), /* prev lock */
? static_cast<uint8_t>(p) static_cast<uint8_t>(p)); // new lock prio
: static_cast<uint8_t>(QXK_attr_.lockPrio)); }
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_() QS_END_NOCRIT_()
if (QXK_attr_.lockPrio > p) { 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 QXK_attr_.lockPrio = p; // restore the previous lock prio
// find the highest-prio thread ready to run // find the highest-prio thread ready to run
if (QXK_sched_() != static_cast<uint_fast8_t>(0)) { // priority found? if (QXK_sched_() != static_cast<uint_fast8_t>(0)) { // priority found?
QXK_activate_(); // activate any unlocked basic threads 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_(); QF_CRIT_EXIT_();
} }

View File

@ -3,8 +3,8 @@
/// @ingroup qxk /// @ingroup qxk
/// @cond /// @cond
////************************************************************************** ////**************************************************************************
/// Last updated for version 5.9.5 /// Last updated for version 5.9.6
/// Last updated on 2017-07-20 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// Q u a n t u m L e a P s
/// --------------------------- /// ---------------------------
@ -57,21 +57,30 @@ Q_DEFINE_THIS_MODULE("qxk_sema")
//**************************************************************************** //****************************************************************************
/// @description /// @description
/// Initializes a semaphore with the specified count. If the semaphore is used /// Initializes a semaphore with the specified count and maximum count.
/// for resource sharing, the initial value of the semaphore count should be /// If the semaphore is used for resource sharing, both the initial count
/// set to the number of identical resources guarded by the semaphore. If the /// and maximum count should be set to the number of identical resources
/// semaphore is used as a signaling mechanism, the initial count should set /// guarded by the semaphore. If the semaphore is used as a signaling
/// to 0. /// 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] 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 /// @note
/// QXSemaphore::init() must be called **before** the semaphore can be used /// QXSemaphore::init() must be called **before** the semaphore can be used
/// (signaled or waited on). /// (signaled or waited on).
/// ///
void QXSemaphore::init(uint_fast16_t const count) { void QXSemaphore::init(uint_fast16_t const count,
m_count = count; uint_fast16_t const max_count)
{
Q_REQUIRE_ID(100, max_count > static_cast<uint_fast16_t>(0));
m_waitSet.setEmpty(); 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); 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 */ && (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 && (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
if (m_count > static_cast<uint_fast16_t>(0)) { if (m_count > static_cast<uint_fast16_t>(0)) {
@ -125,7 +140,7 @@ bool QXSemaphore::wait(uint_fast16_t const nTicks,
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
// the blocking object must be this semaphore // 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)); == reinterpret_cast<QMState const *>(this));
thr->m_temp.obj = static_cast<QMState const *>(0); // clear 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 /// if the awakened thread is now the highest-priority thread that is
/// ready-to-run. /// ready-to-run.
/// ///
/// @returns true when the semaphore gets signaled and false when
/// the semaphore count exceeded the maximum.
///
/// @note /// @note
/// A semaphore can be signaled from many places, including from ISRs, basic /// A semaphore can be signaled from many places, including from ISRs, basic
/// threads (AOs), and extended threads. /// 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_STAT_
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
@ -161,8 +180,9 @@ void QXSemaphore::signal(void) {
QXThread *thr = static_cast<QXThread *>(QF::active_[p]); QXThread *thr = static_cast<QXThread *>(QF::active_[p]);
// the thread must be extended and the semaphore count must be zero // the thread must be extended and the semaphore count must be zero
Q_ASSERT_ID(210, (thr->m_osObject != static_cast<void *>(0)) Q_ASSERT_ID(210, (thr != static_cast<QXThread *>(0)) /* registered */
&& (m_count == static_cast<uint_fast16_t>(0))); && (thr->m_osObject != static_cast<void *>(0)) /* extended */
&& (m_count == static_cast<uint_fast16_t>(0))); // not signaled
// disarm the internal time event // disarm the internal time event
(void)thr->teDisarm_(); (void)thr->teDisarm_();
@ -172,9 +192,16 @@ void QXSemaphore::signal(void) {
} }
} }
else { else {
++m_count; if (m_count < m_max_count) {
++m_count;
}
else {
signaled = false; // semaphore NOT signaled
}
} }
QF_CRIT_EXIT_(); QF_CRIT_EXIT_();
return signaled;
} }
} // namespace QP } // namespace QP

View File

@ -3,8 +3,8 @@
/// @ingroup qxk /// @ingroup qxk
/// @cond /// @cond
///*************************************************************************** ///***************************************************************************
/// Last updated for version 5.9.4 /// Last updated for version 5.9.6
/// Last updated on 2017-07-05 /// Last updated on 2017-07-27
/// ///
/// Q u a n t u m L e a P s /// 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_(); QF_CRIT_ENTRY_();
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr); 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 */ Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
&& (thr != static_cast<QXThread *>(0)) /* current must be extended */ && (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 && (thr->m_temp.obj == static_cast<QMState const *>(0))); // !blocked
// is the queue empty? -- block and wait for event(s) // 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_fast16_t const nTicks,
uint_fast8_t const tickRate) 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)); Q_REQUIRE_ID(700, m_timeEvt.m_ctr == static_cast<QTimeEvtCtr>(0));
m_timeEvt.sig = static_cast<QSignal>(sig); m_timeEvt.sig = static_cast<QSignal>(sig);
@ -517,8 +523,16 @@ bool QXThread::delay(uint_fast16_t const nTicks,
QF_CRIT_ENTRY_(); QF_CRIT_ENTRY_();
QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr); QXThread *thr = static_cast<QXThread *>(QXK_attr_.curr);
// the delaying thread must not be blocked on any object /// @pre this function must:
Q_REQUIRE_ID(900, thr->m_temp.obj == static_cast<QMState const *>(0)); /// (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 // remember the blocking object
thr->m_temp.obj = reinterpret_cast<QMState const *>(&thr->m_timeEvt); thr->m_temp.obj = reinterpret_cast<QMState const *>(&thr->m_timeEvt);