This commit is contained in:
Quantum Leaps 2017-07-06 13:30:17 -04:00
parent 37ffba0781
commit fb5a6033c1
48 changed files with 2111 additions and 390 deletions

View File

@ -42,6 +42,11 @@ mailto:info@state-machine.com
#######################################################################
##################### QP/C Revision History ###########################
QP/C Version 5.9.4 (07-Jul-2017)
--------------------------------
This release adds Thread-Local Storage (TLS) feature for the dual-mode
QXK kernel (https://state-machine.com/qpc/group__qxk.html#qxk_tls).
QP/C Version 5.9.3 (19-Jun-2017)
--------------------------------
This release implements the feature request #126 "Allow non-asserting
@ -96,11 +101,11 @@ qpc\
+-source\ - exitsting source directory with "flat" structure
| (for backwards-compatibility)
+-src\ - new source directory grouped by functionality
+-qf\ - core framework (QEP + QF)
+-qk\ - QK kernel
+-qv\ - QV kernel (only one file qv.c)
+-qxk\ - QXK kernel
+-qs\ - QS software tracing
+-qf\ - core framework (QEP + QF)
+-qk\ - QK kernel
+-qv\ - QV kernel (only one file qv.c)
+-qxk\ - QXK kernel
+-qs\ - QS software tracing
+-qf_pkg.h
+-qs_pkg.h
+-qxk_pkg.h

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C"
PROJECT_NUMBER = "5.9.3"
PROJECT_NUMBER = "5.9.4"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =
@ -121,6 +121,7 @@ INPUT = \
exa_mware.dox \
ports.dox \
ports_native.dox \
ports_arm-cm.dox \
ports_rtos.dox \
ports_os.dox \
history.dox \
@ -129,10 +130,7 @@ INPUT = \
modules.dox \
../include \
../src \
../ports/lint \
../ports/lint/qk \
../ports/lint/qv \
../ports/lint/qxk
../ports/lint
INPUT_ENCODING = UTF-8
FILE_PATTERNS = \

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C"
PROJECT_NUMBER = "5.9.3"
PROJECT_NUMBER = "5.9.4"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =
@ -121,6 +121,7 @@ INPUT = \
exa_mware.dox \
ports.dox \
ports_native.dox \
ports_arm-cm.dox \
ports_rtos.dox \
ports_os.dox \
history.dox \
@ -129,10 +130,7 @@ INPUT = \
modules.dox \
../include \
../src \
../ports/lint \
../ports/lint/qk \
../ports/lint/qv \
../ports/lint/qxk
../ports/lint
INPUT_ENCODING = UTF-8
FILE_PATTERNS = \

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C"
PROJECT_NUMBER = "5.9.3"
PROJECT_NUMBER = "5.9.4"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =
@ -125,6 +125,7 @@ INPUT = \
exa_mware.dox \
ports.dox \
ports_native.dox \
ports_arm-cm.dox \
ports_rtos.dox \
ports_os.dox \
history.dox \
@ -133,10 +134,7 @@ INPUT = \
modules.dox \
../include \
../src \
../ports/lint \
../ports/lint/qk \
../ports/lint/qv \
../ports/lint/qxk
../ports/lint
INPUT_ENCODING = UTF-8
FILE_PATTERNS = \

View File

@ -1,15 +1,21 @@
/**
@page history Revision History
@section qpc_5_9_4 Version 5.9.4, 2017-07-07
This release adds Thread-Local Storage (TLS) feature for the dual-mode
QXK kernel (see @ref qxk_tls).
-----------------------------------------------------------------------------
@section qpc_5_9_3 Version 5.9.3, 2017-06-19
This release implements the feature request
<a href="https://sourceforge.net/p/qpc/feature-requests/126/" target="_blank" class="extern">#126</a> "Allow non-asserting
event allocation for zero-margin allocations". Specifically, calling
Q_NEW_X() or QACTIVE_POST_X() with the margin argument of zero will no
longer assert if the allocation/posting fails.
This release implements the feature request
<a href="https://sourceforge.net/p/qpc/feature-requests/126/" target="_blank" class="extern">#126</a> "Allow non-asserting
event allocation for zero-margin allocations". Specifically, calling
Q_NEW_X() or QACTIVE_POST_X() with the margin argument of zero will no
longer assert if the allocation/posting fails.
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
@section qpc_5_9_2 Version 5.9.2, 2017-06-05
This release adapts the Makefiles for GNU-ARM to the new location of the
GNU-ARM toolset, which is now included in the QTools Collection (v 5.9.1)

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
doxygen/images/qk_synch.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,8 +1,8 @@
@echo off
:: ==========================================================================
:: Product: QP/C script for generating Doxygen documentation
:: Last Updated for Version: 5.9.3
:: Date of the Last Update: 2017-06-17
:: Last Updated for Version: 5.9.4
:: Date of the Last Update: 2017-07-05
::
:: Q u a n t u m L e a P s
:: ---------------------------
@ -38,7 +38,7 @@ echo usage:
echo make
echo make -CHM
set VERSION=5.9.3
set VERSION=5.9.7
:: Generate Resource Standard Metrics for QP/C ...............................
set DOXHOME="C:\tools\doxygen\bin"

View File

@ -1,7 +1,7 @@
/** @page metrics Code Metrics
@code
Standard Code Metrics for QP/C 5.9.3
Standard Code Metrics for QP/C 5.9.7
Resource Standard Metrics (TM) for C, C++, C# and Java
Version 7.75 - mSquaredTechnologies.com
@ -9,7 +9,7 @@
License Type: Windows Single User License
Licensed To : Quantum Leaps, LLC
License No. : WS2975 License Date: Dec 15, 2013
Build Date : Sep 2 2009 Run Date: Jun 19, 2017
Build Date : Sep 2 2009 Run Date: Jul 06, 2017
(C)1996-2009 M Squared Technologies LLC
________________________________________________________________________
@ -51,7 +51,7 @@
~~ Total File Summary ~~
LOC 191 eLOC 191 lLOC 75 Comment 530 Lines 826
LOC 191 eLOC 191 lLOC 75 Comment 530 Lines 825
________________________________________________________________________
End of File: ..\include\qf.h
@ -178,7 +178,7 @@
~~ Total File Summary ~~
LOC 67 eLOC 67 lLOC 26 Comment 112 Lines 186
LOC 71 eLOC 71 lLOC 28 Comment 122 Lines 204
________________________________________________________________________
End of File: ..\include\qxk.h
@ -1730,7 +1730,7 @@
LOC 32 eLOC 28 lLOC 17 Comment 18 Lines 42
Function: Q_onAssert
Parameters: (char const * const module, int_t loc)
Parameters: (char_t const * const module, int_t location)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 5 eLOC 4 lLOC 3 Comment 4 Lines 5
@ -1894,31 +1894,36 @@
Complexity Param 0 Return 1 Cyclo Vg 8 Total 9
LOC 75 eLOC 65 lLOC 36 Comment 54 Lines 104
Function: QXK_current
Parameters: (void)
Complexity Param 0 Return 1 Cyclo Vg 1 Total 2
LOC 8 eLOC 7 lLOC 5 Comment 1 Lines 10
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 212 eLOC 181 lLOC 99 Comment 236 Lines 428
LOC 220 eLOC 188 lLOC 104 Comment 237 Lines 441
------------------------------------------------------------------------
~~ File Functional Summary ~~
File Function Count....: 8
Total Function LOC.....: 192 Total Function Pts LOC : 1.7
Total Function eLOC....: 161 Total Function Pts eLOC: 1.4
Total Function lLOC....: 96 Total Function Pts lLOC: 0.8
Total Function Params .: 8 Total Function Return .: 8
Total Cyclo Complexity : 28 Total Function Complex.: 44
File Function Count....: 9
Total Function LOC.....: 200 Total Function Pts LOC : 1.7
Total Function eLOC....: 168 Total Function Pts eLOC: 1.5
Total Function lLOC....: 101 Total Function Pts lLOC: 0.8
Total Function Params .: 8 Total Function Return .: 9
Total Cyclo Complexity : 29 Total Function Complex.: 46
------ ----- ----- ------ ------ -----
Max Function LOC ......: 75 Average Function LOC ..: 24.00
Max Function eLOC .....: 65 Average Function eLOC .: 20.13
Max Function lLOC .....: 36 Average Function lLOC .: 12.00
Max Function LOC ......: 75 Average Function LOC ..: 22.22
Max Function eLOC .....: 65 Average Function eLOC .: 18.67
Max Function lLOC .....: 36 Average Function lLOC .: 11.22
------ ----- ----- ------ ------ -----
Max Function Parameters: 7 Avg Function Parameters: 1.00
Max Function Parameters: 7 Avg Function Parameters: 0.89
Max Function Returns ..: 1 Avg Function Returns ..: 1.00
Max Interface Complex. : 8 Avg Interface Complex. : 2.00
Max Cyclomatic Complex.: 8 Avg Cyclomatic Complex.: 3.50
Max Total Complexity ..: 14 Avg Total Complexity ..: 5.50
Max Interface Complex. : 8 Avg Interface Complex. : 1.89
Max Cyclomatic Complex.: 8 Avg Cyclomatic Complex.: 3.22
Max Total Complexity ..: 14 Avg Total Complexity ..: 5.11
________________________________________________________________________
End of File: ..\source\qxk.c
@ -1945,31 +1950,30 @@
Parameters: (QXMutex * const me)
Cyclomatic Complexity Vg Detail
Function Base : 1
Conditional if / else if: 2
Inlined if-else ( ? : ) : 1
Conditional if / else if: 3
Logical and ( && ) : 1
Complexity Param 1 Return 1 Cyclo Vg 5 Total 7
LOC 24 eLOC 21 lLOC 11 Comment 37 Lines 32
LOC 29 eLOC 24 lLOC 13 Comment 39 Lines 37
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 65 eLOC 58 lLOC 23 Comment 139 Lines 197
LOC 70 eLOC 61 lLOC 25 Comment 141 Lines 202
------------------------------------------------------------------------
~~ File Functional Summary ~~
File Function Count....: 3
Total Function LOC.....: 49 Total Function Pts LOC : 0.5
Total Function eLOC....: 43 Total Function Pts eLOC: 0.5
Total Function lLOC....: 22 Total Function Pts lLOC: 0.2
Total Function LOC.....: 54 Total Function Pts LOC : 0.5
Total Function eLOC....: 46 Total Function Pts eLOC: 0.5
Total Function lLOC....: 24 Total Function Pts lLOC: 0.2
Total Function Params .: 4 Total Function Return .: 3
Total Cyclo Complexity : 10 Total Function Complex.: 17
------ ----- ----- ------ ------ -----
Max Function LOC ......: 24 Average Function LOC ..: 16.33
Max Function eLOC .....: 21 Average Function eLOC .: 14.33
Max Function lLOC .....: 11 Average Function lLOC .: 7.33
Max Function LOC ......: 29 Average Function LOC ..: 18.00
Max Function eLOC .....: 24 Average Function eLOC .: 15.33
Max Function lLOC .....: 13 Average Function lLOC .: 8.00
------ ----- ----- ------ ------ -----
Max Function Parameters: 2 Avg Function Parameters: 1.33
Max Function Returns ..: 1 Avg Function Returns ..: 1.00
@ -2175,9 +2179,9 @@
~~ Total Project Summary ~~
LOC 6163 eLOC 5463 lLOC 2728 Comment 7693 Lines 13906
LOC 6180 eLOC 5477 lLOC 2737 Comment 7706 Lines 13941
Average per File, metric/41 files
LOC 150 eLOC 133 lLOC 66 Comment 187 Lines 339
LOC 150 eLOC 133 lLOC 66 Comment 187 Lines 340
------------------------------------------------------------------------
@ -2807,7 +2811,7 @@
LOC 32 eLOC 28 lLOC 17 Comment 18 Lines 42
Function: Q_onAssert
Parameters: (char const * const module, int_t loc)
Parameters: (char_t const * const module, int_t location)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 5 eLOC 4 lLOC 3 Comment 4 Lines 5
@ -2880,6 +2884,11 @@
Complexity Param 0 Return 1 Cyclo Vg 8 Total 9
LOC 75 eLOC 65 lLOC 36 Comment 54 Lines 104
Function: QXK_current
Parameters: (void)
Complexity Param 0 Return 1 Cyclo Vg 1 Total 2
LOC 8 eLOC 7 lLOC 5 Comment 1 Lines 10
Function: QXMutex_init
Parameters: (QXMutex * const me, uint_fast8_t prio)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
@ -2893,7 +2902,7 @@
Function: QXMutex_unlock
Parameters: (QXMutex * const me)
Complexity Param 1 Return 1 Cyclo Vg 5 Total 7
LOC 24 eLOC 21 lLOC 11 Comment 37 Lines 32
LOC 29 eLOC 24 lLOC 13 Comment 39 Lines 37
Function: QXSemaphore_init
Parameters: (QXSemaphore * const me, uint_fast16_t count)
@ -2987,26 +2996,26 @@
LOC 10 eLOC 9 lLOC 7 Comment 12 Lines 12
Total: Functions
LOC 4067 eLOC 3392 lLOC 2211 InCmp 416 CycloCmp 653
Function Points FP(LOC) 31.6 FP(eLOC) 26.4 FP(lLOC) 17.2
LOC 4080 eLOC 3402 lLOC 2218 InCmp 417 CycloCmp 654
Function Points FP(LOC) 31.7 FP(eLOC) 26.4 FP(lLOC) 17.2
------------------------------------------------------------------------
~~ Project Functional Analysis ~~
Total Functions .......: 155 Total Physical Lines ..: 5230
Total LOC .............: 4067 Total Function Pts LOC : 31.6
Total eLOC ............: 3392 Total Function Pts eLOC: 26.4
Total lLOC.............: 2211 Total Function Pts lLOC: 17.2
Total Cyclomatic Comp. : 653 Total Interface Comp. .: 416
Total Parameters ......: 261 Total Return Points ...: 155
Total Comment Lines ...: 3327 Total Blank Lines .....: 635
Total Functions .......: 156 Total Physical Lines ..: 5245
Total LOC .............: 4080 Total Function Pts LOC : 31.7
Total eLOC ............: 3402 Total Function Pts eLOC: 26.4
Total lLOC.............: 2218 Total Function Pts lLOC: 17.2
Total Cyclomatic Comp. : 654 Total Interface Comp. .: 417
Total Parameters ......: 261 Total Return Points ...: 156
Total Comment Lines ...: 3330 Total Blank Lines .....: 637
------ ----- ----- ------ ------ -----
Avg Physical Lines ....: 33.74
Avg LOC ...............: 26.24 Avg eLOC ..............: 21.88
Avg lLOC ..............: 14.26 Avg Cyclomatic Comp. ..: 4.21
Avg Interface Comp. ...: 2.68 Avg Parameters ........: 1.68
Avg Return Points .....: 1.00 Avg Comment Lines .....: 21.46
Avg Physical Lines ....: 33.62
Avg LOC ...............: 26.15 Avg eLOC ..............: 21.81
Avg lLOC ..............: 14.22 Avg Cyclomatic Comp. ..: 4.19
Avg Interface Comp. ...: 2.67 Avg Parameters ........: 1.67
Avg Return Points .....: 1.00 Avg Comment Lines .....: 21.35
------ ----- ----- ------ ------ -----
Max LOC ...............: 412
Max eLOC ..............: 324 Max lLOC ..............: 200

View File

@ -6,7 +6,7 @@ Hierarchical Event Processor
QEP is a universal, UML-compliant event processor that enables developers to code UML state machines in highly readable ANSI-C, in which every state machine element is mapped to code precisely, unambiguously, and exactly once (traceability). QEP fully supports hierarchical state nesting, which is the fundamental mechanism for reusing behavior across many states instead of repeating the same actions and transitions over and over again.
*/
/*###########################################################################*/
/*##########################################################################*/
/*! @defgroup qf QF
@brief
@ -15,16 +15,16 @@ Active Object (Actor) Framework
QF is a portable, event-driven, real-time framework for execution of active objects (concurrent state machines) specifically designed for real-time embedded (RTE) systems.
*/
/*###########################################################################*/
/*##########################################################################*/
/*! @defgroup qs QS
@brief
Software Tracing Instrumentation
QS is software tracing system that enables developers to monitor live event-driven QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing.
QS is software tracing system that enables developers to monitor live QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. Please see <a href="https://state-machine.com/qtools/qs.html"><b>QS Manual</b></a> inside the <a href="https://state-machine.com/qtools" target="_blank" class="extern">QTools collection</a> for more information.
*/
/*###########################################################################*/
/*##########################################################################*/
/*! @defgroup qv QV
@brief
@ -47,13 +47,13 @@ Given the simplicity, portability, and low-resource consumption, the QV schedule
*/
/*###########################################################################*/
/*##########################################################################*/
/*! @defgroup qk QK
@brief
Preemptive Non-Blocking Kernel
Preemptive Run-to-Completion Kernel
QK is a tiny **preemptive**, priority-based, non-blocking kernel designed specifically for executing active objects. QK runs active objects in the same way as prioritized interrupt controller (such as NVIC in ARM Cortex-M) runs interrupts using the single stack (MSP in Cortex-M). Active objects process their events in run-to-completion fashion and remove themselves from the call stack, the same way as nested interrupts. At the same time high-priority active objects can preempt lower-priority active objects, in the same way as interrupts can preempt each other under a prioritized interrupt controller. QK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis RMA) and can be used in hard real-time systems.
QK is a tiny **preemptive**, priority-based, non-blocking kernel designed specifically for executing active objects. QK runs active objects in the same way as prioritized interrupt controller (such as NVIC in ARM Cortex-M) runs interrupts using the single stack. Active objects process their events in run-to-completion (RTC) fashion and remove themselves from the call stack, the same way as nested interrupts remove themselves from the stack upon completion. At the same time high-priority active objects can preempt lower-priority active objects, just like interrupts can preempt each other under a prioritized interrupt controller. QK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis RMA) and can be used in hard real-time systems.
------------------------------------------------------------------------------
@ -63,10 +63,11 @@ Sometimes it is not practical to break up long RTC steps, and consequently the t
*/
/*###########################################################################*//*! @defgroup qxk QXK
/*##########################################################################*/
/*! @defgroup qxk QXK
@brief
Preemptive Dual-Mode Blocking RTOS Kernel
Preemptive Dual-Mode (Run-to-Completion/Blocking) RTOS Kernel
QXK is a small, preemptive, priority-based, dual-mode **blocking** kernel that executes active objects like the @ref qk "QK kernel", but can also execute traditional __blocking__ threads (extended threads). In this respect, QXK behaves exactly as a conventional __RTOS__ (Real-Time Operating System). QXK has been designed specifically for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software.
@ -77,13 +78,13 @@ Supported toolchains include: ARM-KEIL MDK, IAR-ARM, GNU-ARM, TI-ARM.
Currently, the QXK kernel is illustrated by the following examples:
- @ref arm-cm_dpp_efm32-slstk3401a@n
- @ref arm-cm_dpp_efm32-slstk3401a (ARM Cortex-M4F)@n
Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
- @ref arm-cm_dpp_ek-tm4c123gxl@n
- @ref arm-cm_dpp_ek-tm4c123gxl (ARM Cortex-M4F)@n
Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
- @ref arm-cm_dpp_nucleo-l053r8@n
- @ref arm-cm_dpp_nucleo-l053r8 (ARM Cortex-M0+)@n
Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
@ -96,13 +97,13 @@ QXK distinguishes two kinds of threads: **basic**-threads (non-blocking, run-to-
@subsection qxk_classes Classes in QXK
The figure below shows the main classes introduced in the QXK kernel and their relation to the classes of the QP framework.
@image html qxk_classes.gif "Classes of the QXK blocking kernel"
@image html qxk_classes.gif "Classes of the QXK dual-mode kernel"
<ul class="tag">
<li><span class="tag">0</span> The abstract ::QActive class represents active objects in QP. This class contains the @c thread object of the underlying kernel (QXK thread-control-block in this case) as well as the event queue and the unique priority of the active object.
</li>
<li><span class="tag">1</span> The ::QXThread class represents the "naked" blocking threads of the QXK kernel. It inherits ::QActive, so that extended-threads can be treated as active objects internally in the framework. However, the extended-threads do not implement state machines. Instead, the data fields used for storing the current state in active objects are re-used to store the private stack of the extended-thread. The ::QXThread class also contains the @c timeEvt object (see ::QTimeEvt) for generating timeouts when the extended-thread is blocked.
<li><span class="tag">1</span> The ::QXThread class represents the extended (blocking) threads of the QXK kernel. It inherits ::QActive, so that extended-threads can be treated as active objects internally in the framework. However, the extended-threads do not implement state machines. Instead, the data fields used for storing the current state in active objects are re-used to store the private stack of the extended-thread. The ::QXThread class also contains the @c timeEvt object (see ::QTimeEvt) for generating timeouts when the extended-thread is blocked.
</li>
<li><span class="tag">2</span> The ::QXMutex class represents the @ref qxk_mutex "priority-ceiling mutex" of the QXK kernel. The mutex can be used by both the extended-threads and active object threads (in case they share resources that need to be protected). However, using any blocking mechanism inside active objects is not recommended, because it delays run-to-completion event processing.
@ -113,16 +114,16 @@ The figure below shows the main classes introduced in the QXK kernel and their r
</ul>
@note
The main takeaway from the QXK class diagram is QXK's **optimal, tight integration** with the QP/C framework. The QXK kernel reuses all mechanisms already provided in QP, thus avoiding any code duplication, inefficient layers of indirection, and additional licensing costs, which are inevitable when using @ref ports_rtos "3rd-party RTOS kernels" to run QP/C applications.
The main takeaway from the QXK class diagram is QXK's **optimal, tight integration** with the QP framework. The QXK kernel reuses all mechanisms already provided in QP, thus avoiding any code duplication, inefficient layers of indirection, and additional licensing costs, which are inevitable when using @ref ports_rtos "3rd-party RTOS kernels" to run QP applications.
------------------------------------------------------------------------------
@section qxk_features QXK Features
As you can see in the list below, <span class="highlight">QXK provides most features you might expect of a traditional blocking **RTOS** kernel and is <strong>recommended</strong> as the preferred RTOS kernel for QP/C applications</span> that need to mix active objects with traditional blocking code.
As you can see in the list below, <span class="highlight">QXK provides most features you might expect of a traditional blocking **RTOS** kernel and is <strong>recommended</strong> as the preferred RTOS kernel for QP applications</span> that need to mix active objects with traditional blocking code.
<ul class="tag">
<li><span class="bullet">&gt;</span>Preemptive, priority-based scheduling of up to 64 threads. Each thread must be provided with its own private stack space and must be assigned its own unique priority (1..::QF_MAX_ACTIVE);
<li><span class="bullet">&gt;</span>Preemptive, priority-based scheduling of up to 64 threads. Each thread must be assigned its own unique priority (1 .. #QF_MAX_ACTIVE);
</li>
> NOTE: QXK always executes the highest-priority thread that is ready to run (is not blocked). The scheduling algorithm used in QXK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis — RMA) and can be used in hard real-time systems.
@ -130,16 +131,16 @@ As you can see in the list below, <span class="highlight">QXK provides most feat
<li><span class="bullet">&gt;</span>All threads in QXK are capable of **blocking**. However, QXK distinguishes between two types of threads:
</li>
- active object threads that can block only while waiting on events from the private event queue and should not block otherwise (e.g., inside state machines). QXK asserts when an active object thread attempts to use a timed-delay or attempts to block on a semaphore. This is because active objects have non-blocking alternatives for these operations (time-events and event posting, respectively).
- **basic threads** of active objects that are made ready-to-run by events posted to the active objects. Such basic threads are non-blocking, run-to-completion activations that cannot block in the middle of the RTC step. QXK asserts when a basic thread attempts to use a blocking mechanism, such as a time-delay or a semaphore-wait. All basic threads share the common stack.
- extended-threads, that can block anywhere in their thread-handler function, whereas QXK provides a typical assortments of blocking primitives for extended-threads, such as time-delay, message queue, semaphore, or a mutex;
- **extended threads** that can block anywhere in their thread-handler function, whereas QXK provides a typical assortments of blocking primitives for extended-threads, such as time-delay, blocking message queue, counting semaphore, or a mutex. Each extended thread must be provided with its own private stack.
<li><span class="bullet">&gt;</span>Tightly integrated mechanisms for communication between event-driven active objects and "naked" blocking threads:
<li><span class="bullet">&gt;</span>Tightly integrated mechanisms for communication between event-driven active objects and extended blocking threads:
</li>
- Active objects can signal semaphores and send messages to extended-threads.
- Basic threads (Active Objects) can signal semaphores and send messages to extended threads.
- "Naked" threads can post or publish events to active objects;
- Extended threads can post or publish events to active objects;
<li><span class="bullet">&gt;</span>Priority-Ceiling Mutexes with optional timeout;
</li>
@ -158,13 +159,18 @@ As you can see in the list below, <span class="highlight">QXK provides most feat
<li><span class="bullet">&gt;</span>Interrupt management, including "zero-latency", kernel-unaware interrupts that are never disabled;
</li>
> NOTE: This feature is only supported on CPUs that allow selective interrupt disabling, such as ARM Cortex-M3/M4 (but not ARM Cortex-M0).
> NOTE: This feature is only supported on CPUs that allow selective interrupt disabling, such as ARM Cortex-M3/M4 (but not ARM Cortex-M0);
<li><span class="bullet">&gt;</span> @ref qxk_tls "Thread-Local Storage" for all threads (basic threads and extended threads).
</li>
</ul>
<div class="separate"></div>
@subsection qxk_kernel Kernel Initialization and Control
@sa
- QXK_init()
- QF_run()
- QXK_onIdle()
@ -172,6 +178,8 @@ As you can see in the list below, <span class="highlight">QXK provides most feat
<div class="separate"></div>
@subsection qxk_thread Thread Management
@sa
- ::QXThread structure (Thread Control Block)
- QXThread_ctor()
- QXTHREAD_START()
@ -180,11 +188,15 @@ As you can see in the list below, <span class="highlight">QXK provides most feat
<div class="separate"></div>
@subsection qxk_isr Interrupt Management
@sa
- QXK_ISR_ENTRY()
- QXK_ISR_EXIT()
<div class="separate"></div>
@subsection qxk_mutex Mutexes
@sa
- ::QXMutex structure (Mutex Control Block)
- QXMutex_init()
- QXMutex_lock()
@ -192,12 +204,16 @@ As you can see in the list below, <span class="highlight">QXK provides most feat
<div class="separate"></div>
@subsection qxk_queue Message Queues
@sa
- QXTHREAD_POST_X() - posting messages to blocking threads
- QACTIVE_POST_X() - posting events to Active Objects
- QXThread_queueGet() - waiting (blocking) on message queue
<div class="separate"></div>
@subsection qxk_sema Semaphores
@sa
- ::QXSemaphore structure (Semaphore Control Block)
- QXSemaphore_init()
- QXSemaphore_wait()
@ -205,31 +221,59 @@ As you can see in the list below, <span class="highlight">QXK provides most feat
<div class="separate"></div>
@subsection qxk_mem Memory Pools
@sa
- ::QMPool structure
- QMPool_init()
- QMPool_get()
- QMPool_put()
<div class="separate"></div>
@subsection qxk_tls Thread Local Storage
<b>Thread-local storage (TLS)</b> is a programming method that uses static or global memory local to a thread. TLS is specifically useful for writing library-type code, which is used in a multithreaded environment and needs to access per-thread data in an independent way.
TLS is used in some places where ordinary, single-threaded programs would use static or global variables, but where this would be inappropriate in multithreaded cases. An example of such situations is where library-type functions use a global variable to set an error condition (for example the global variable errno used by many functions of the C library). If errno were simply a global variable, a call of a system function on one thread may overwrite the value previously set by a call of a system function on a different thread, possibly before following code on that different thread could check for the error condition. The solution is to have errno be a variable that looks like it is global, but in fact exists once per thread—i.e., it lives in *thread-local storage*. A second use case would be multiple threads accumulating information into a global variable. To avoid a race condition, every access to this global variable would have to be protected by a mutual-exclusion mechanism. Alternatively, each thread might accumulate into a thread-local variable (that, by definition, cannot be read from or written to from other threads, implying that there can be no race conditions). Threads then only have to synchronize a final accumulation from their own thread-local variable into a single, truly global variable.
The TLS implementations vary, but many systems, including QXK, implement TLS by providing a pointer-sized variable thread-local. This pointer can be set to arbitrarily sized memory blocks in a thread-local manner, by allocating such a memory block (statically or dynamically) and storing the memory address of that block in the thread-local variable.
Typical usage of TLS in QXK is illustrated in the example <span class="img folder">qpc/examples/arm-cm/dpp_efm32-slstk3401a/qxk/</span>, <span class="img file_c">test.c</span>, and consists:
- define the TLS structure
@code{c}
typedef struct {
uint32_t foo;
uint8_t bar[10];
} TLS_test;
@endcode
- allocate the TLS storage for all participating threads (extended or basic threads)
@code{c}
static TLS_test l_tls1;
static TLS_test l_tls2;
@endcode
- initialize the TLS per-thread pointer in each thread routine (for extended threads) or the top-most initial transition (for basic threads of active objects):
@code{c}
static void Thread1_run(QXThread * const me) {
me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */
. . .
}
. . .
static void Thread2_run(QXThread * const me) {
me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */
. . .
}
@endcode
- access the TLS from your code:
@code{c}
void lib_fun(uint32_t x) {
QXK_TLS(TLS_test *)->foo = x;
}
@endcode
@sa
- QXK_current()
- QXK_TLS()
*/
/*###########################################################################*//*! @dir ../include
Platform-independent QP/C API
@note
The QP/C <span class="img folder">include</span> directory needs to be added to the compiler's include path in the applications using QP/C.
*/
/*###########################################################################*//*! @dir ../source
Platform-independent QP/C implementation
Files from this directory need to be added to the project, to build the QP/C framework from source code.
@attention
Not all QP/C source files should be added to every project. For example, native QP/C ports to the preemptive QK kernel should **not** contain the file <span class="img file_c">qv.c</span> and conversely, QP/C ports to the cooperative QV kernel should not contain the files <span class="img file_c">qk.c</span> and <span class="img file_c">qk_mutex.c</span>.
@note
The QP/C <span class="img folder">source</span> directory needs to be added to the compiler's include path in the applications using QP/C, because QP/C is built from sources.
*/

1586
doxygen/ports_arm-cm.dox Normal file

File diff suppressed because it is too large Load Diff

View File

@ -22,60 +22,6 @@
@image html under_construction.jpg
*/
/*##########################################################################*/
/*! @page arm-cm ARM Cortex-M
------------------------------------------------------------------------------
@section arm-cm_qv Cooperative QV Kernel
The QV port to ARM Cortex-M has been described in detail in Section 3 of the Quantum Leaps Application Note: <a href="https://www.state-machine.com/doc/AN_QP_and_ARM-Cortex-M-ARM-KEIL.pdf" target="_blank" class="extern" title="Read PDF">QP and ARM Cortex-M with ARM-KEIL</a>. The Application Note focuses on the ARM-KEIL toolset, but the general principles apply to all supported toolsets, such as IAR-ARM, GNU-ARM, and TI-ARM.
------------------------------------------------------------------------------
@section arm-cm_qk Preemptive Non-Blocking QK Kernel
The QK port to ARM Cortex-M has been described in detail in Section 4 of the Quantum Leaps Application Note: <a href="https://www.state-machine.com/doc/AN_QP_and_ARM-Cortex-M-ARM-KEIL.pdf" target="_blank" class="extern" title="Read PDF">QP and ARM Cortex-M with ARM-KEIL</a>. The Application Note focuses on the ARM-KEIL toolset, but the general principles apply to all supported toolsets, such as IAR-ARM, GNU-ARM, and TI-ARM.
------------------------------------------------------------------------------
@section arm-cm_qxk Preemptive Blocking QXK Kernel
The preemptive, blocking QXK kernel works on ARM Cortex-M as follows:
1. The ARM Cortex-M processor executes application code in the Privileged Thread mode, which is exactly the mode entered out of reset. The exceptions (including all interrupts) are always processed in the Privileged Handler mode.
2. QXK uses the Process Stack Pointer (PSP) for handling threads (both active object threads and "naked" blocking-threads) and the Main Stack Pointer (MSP) for handling interrupts and exceptions (such as the PendSV exception).
3. The QXK port uses the @c PendSV (exception number 14) to perform thread-to-thread context switch. The application code (your code) must initialize the Interrupt Vector Table with the addresses of the @c PendSV_Handler exception handler. Additionally, the interrupt table must be initialized with the @c SysTick_Handler exception handler.
@n
> NOTE: QXK uses only the CMSIS-compliant exception and interrupt names, such as @c PendSV_Handler, @c SysTick_Handler, etc.@n
> NOTE: The QXK port specifically does **not** use the SVC exception (Supervisor Call). This makes the QXK ports compatible with various "hypervisors" (such as mbed uVisor or Nordic SoftDevice), which use the SVC exception.
4. The application code (your code) must call the function QXK_init() to set up the stack of the *idle thread* of the QXK kernel before calling QF_run().
@n
> NOTE: Right before starting multitasking, the QXK kernel re-uses the main C-stack as the Main Stack (for interrupts and exceptions), and assigns the provided idle stack to the internal idle thread.
5. You need to explicitly **assign priorities of the all interrupts** used in your application, according to the Application Note: <a href="https://www.state-machine.com/doc/AN_ARM-Cortex-M_Interrupt-Priorities.pdf" target="_blank" class="extern" title="Read PDF">Setting ARM Cortex-M Interrupt Priorities in QP 5.1 and Higher</a>.
6. It is strongly recommended that you do not assign the lowest NVIC priority (0xFF) to any interrupt in your application, because it is used by the PendSV handler. For example, with 3 bits of priority implemented in the NVIC, this leaves the following 7 priority levels for you (listed from the lowest to the highest urgency): 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, and 0x00 (the highest priority).
@n
> NOTE: The prioritization of interrupts, including the PendSV exception, is performed entirely by the NVIC. Because the PendSV has the lowest priority in the system, the NVIC tail-chains to the PendSV exception only after exiting the last nested interrupt.
7. ISRs are written as regular C functions, but they need to call QXK_ISR_ENTRY() before using any QF services, and they must call QXK_ISR_EXIT() after using any of the QF services.
8. ARM Cortex-M enters interrupt context without disabling interrupts. Generally, you should not disable interrupts inside your ISRs. In particular, the QF services (such as QF_PUBLISH(), QF_TICK_X(), and QACTIVE_POST()) should be called with interrupts enabled, to avoid nesting of critical sections.
@n
> NOTE: If you don't wish an interrupt to be preempted by another interrupt, you can always prioritize that interrupt in the NVIC to a higher or equal level as other interrupts (use a lower numerical value of priority).
9. In compliance with the ARM Application Procedure Call Standard (AAPCS), the QXK kernel always preserves the 8-byte alignment of the stack.
<div class="separate"></div>
@subsection arm-com_qxk_vfp Using the VFP
If you have the Cortex-M4F/M7 CPU and your application is compiled with the VFP present, the QXK kernel will enable the VFP along with the VFP automatic state preservation and lazy stacking features. This will case any thread that uses the VFP, to automatically use the Cortex-M exception stack frame with VFP (with 18 VFP registers S0-S15 plus VFP status and stack "aligner"). Also, the QXK context switch will add to this the rest of the VFP registers (S16-S31).
@note
A QXK thread (both an active object thread and a "naked" blocking thread) that uses the VFP will use 136 more bytes of its private stack space than a thread that does not use the VFP. Also, a thread that uses the VFP will take longer to perform the context switch.
*/
/*##########################################################################*/
/*! @page arm-cr ARM Cortex-R
@ -96,7 +42,7 @@ A QXK thread (both an active object thread and a "naked" blocking thread) that u
@section arm7-9_qk Preemptive QK Kernel
\includelineno ports/arm7-9/qk/iar/qk_port.s
@includelineno ports/arm7-9/qk/iar/qk_port.s
@section arm7-9_qv Cooperative QV Kernel

View File

@ -18,7 +18,9 @@ The following annotated directory tree lists the top-level directories provided
</li>
<li><span class="img folder">include/</span> &mdash; Platform-independent QP/C API (see <a href="dir_d44c64559bbebec7f509842c48db8b23.html"><strong>include</strong></a>)
</li>
<li><span class="img folder">source/</span> &mdash; Platform-independent QP/C source code (see @ref <a href="dir_b2f33c71d4aa5e7af42a1ca61ff5af1b.html"><strong>source</strong></a>)
<li><span class="img folder">src/</span> &mdash; Platform-independent QP/C source code (see @ref <a href="dir_68267d1309a1af8e8297ef4c3efbcdba.html"><strong>src</strong></a>)
</li>
<li><span class="img folder">source/</span> &mdash; Platform-independent QP/C source code for backwards compatibility (will be phased out in the future).
</li>
</ul>
</ul>
@ -171,3 +173,70 @@ The QP/C framework comes with extensive support for automatic rule checking by m
@next{exa}
*/
/*##########################################################################*/
/*! @dir ../include
Platform-independent QP/C API
@note
The QP/C <span class="img folder">include</span> directory needs to be added to the compiler's include path in the applications using QP/C.
*/
/*##########################################################################*/
/*! @dir ../src
Platform-independent QP/C source code
Files from this directory need to be added to the project, to build the QP/C framework from source code.
@note
The QP/C <span class="img folder">src</span> directory needs to be added to the compiler's include path in the applications that build QP/C framework from sources (as opposed to using QP as a pre-built library).
*/
/*##########################################################################*/
/*! @dir ../src/qf
Platform-independent implementation of the @ref qep and @ref qf components.
@note
Typically, files in this directory need to be added to the application build, but some QP ports might not need all the files in this directory. For example, a QP port to a 3rd-party RTOS kernel might be using a message queue of the RTOS instead of the native QP event queue, in which case the file qf_actq.c would not be needed and should be excluded from the build.
*/
/*##########################################################################*/
/*! @dir ../src/qv
Platform-independent implementation of the @ref qv built-in kernel.
@attention
Files in this directory need to be included in the QP application build only if the application uses the @ref qv kernel.
*/
/*##########################################################################*/
/*! @dir ../src/qk
Platform-independent implementation of the @ref qk built-in kernel.
@attention
Files in this directory need to be included in the QP application build only if the application uses the @ref qk kernel.
*/
/*##########################################################################*/
/*! @dir ../src/qxk
Platform-independent implementation of the @ref qxk built-in kernel.
@attention
Files in this directory need to be included in the QP application build only if the application uses the @ref qxk kernel.
*/
/*##########################################################################*/
/*! @dir ../src/qs
Platform-independent implementation of the @ref qs component (software tracing).
*/

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: DPP example, EFM32-SLSTK3401A board, cooperative QV kernel
* Last Updated for Version: 5.9.0
* Date of the Last Update: 2017-04-14
* Last Updated for Version: 5.9.3
* Date of the Last Update: 2017-06-30
*
* Q u a n t u m L e a P s
* ---------------------------
@ -414,15 +414,9 @@ uint8_t QS_onStartup(void const *arg) {
QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */
/* setup the QS filters... */
QS_FILTER_ON(QS_QEP_STATE_ENTRY);
QS_FILTER_ON(QS_QEP_STATE_EXIT);
QS_FILTER_ON(QS_QEP_STATE_INIT);
QS_FILTER_ON(QS_QEP_INIT_TRAN);
QS_FILTER_ON(QS_QEP_INTERN_TRAN);
QS_FILTER_ON(QS_QEP_TRAN);
QS_FILTER_ON(QS_QEP_IGNORED);
QS_FILTER_ON(QS_QEP_DISPATCH);
QS_FILTER_ON(QS_QEP_UNHANDLED);
QS_FILTER_ON(QS_SM_RECORDS);
QS_FILTER_ON(QS_AO_RECORDS);
QS_FILTER_ON(QS_UA_RECORDS);
QS_FILTER_ON(PHILO_STAT);
QS_FILTER_ON(COMMAND_STAT);

View File

@ -1,7 +1,7 @@
##############################################################################
# Product: Makefile for DPP on EMF32-SLSTK3401A, QV kernel, GNU-ARM
# Last Updated for Version: 5.9.2
# Date of the Last Update: 2017-06-03
# Last Updated for Version: 5.9.3
# Date of the Last Update: 2017-06-30
#
# Q u a n t u m L e a P s
# ---------------------------
@ -69,7 +69,9 @@ QP_PORT_DIR := $(QPC)/ports/arm-cm/qv/gnu
VPATH = \
.. \
../.. \
$(QPC)/source \
$(QPC)/src/qf \
$(QPC)/src/qv \
$(QPC)/src/qs \
$(QP_PORT_DIR) \
$(QPC)/3rd_party/efm32pg1b \
$(QPC)/3rd_party/efm32pg1b/gnu
@ -78,7 +80,7 @@ VPATH = \
INCLUDES = \
-I../.. \
-I$(QPC)/include \
-I$(QPC)/source \
-I$(QPC)/src \
-I$(QP_PORT_DIR) \
-I$(QPC)/3rd_party/CMSIS/Include \
-I$(QPC)/3rd_party/efm32pg1b

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: DPP example
* Last Updated for Version: 5.9.0
* Date of the Last Update: 2017-03-13
* Last Updated for Version: 5.9.3
* Date of the Last Update: 2017-06-30
*
* Q u a n t u m L e a P s
* ---------------------------
@ -54,6 +54,7 @@ int main() {
BSP_init(); /* initialize the Board Support Package */
/* object dictionaries... */
QS_OBJ_DICTIONARY(&l_ticker0);
QS_OBJ_DICTIONARY(smlPoolSto);
QS_OBJ_DICTIONARY(tableQueueSto);
QS_OBJ_DICTIONARY(philoQueueSto[0]);

View File

@ -1,7 +1,7 @@
##############################################################################
# Product: Makefile for DPP on EMF32-SLSTK3401A, QXK kernel, GNU-ARM
# Last Updated for Version: 5.9.2
# Date of the Last Update: 2017-06-03
# Last Updated for Version: 5.9.4
# Date of the Last Update: 2017-07-05
#
# Q u a n t u m L e a P s
# ---------------------------
@ -69,7 +69,9 @@ QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu
VPATH = \
.. \
../.. \
$(QPC)/source \
$(QPC)/src/qf \
$(QPC)/src/qxk \
$(QPC)/src/qs \
$(QP_PORT_DIR) \
$(QPC)/3rd_party/efm32pg1b \
$(QPC)/3rd_party/efm32pg1b/gnu
@ -78,7 +80,7 @@ VPATH = \
INCLUDES = \
-I../.. \
-I$(QPC)/include \
-I$(QPC)/source \
-I$(QPC)/src \
-I$(QP_PORT_DIR) \
-I$(QPC)/3rd_party/CMSIS/Include \
-I$(QPC)/3rd_party/efm32pg1b

View File

@ -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>
@ -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.70.1.11471</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.70.1.11471</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>
@ -3123,64 +3123,52 @@
<group>
<name>QP</name>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qep_hsm.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qep_msm.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_act.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_actq.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_defer.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_dyn.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_mem.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_pkg.h</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_ps.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qact.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qeq.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_qmact.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qf_time.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk.c</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\include\qxk.h</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_mutex.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_pkg.h</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_sema.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_xthr.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\include\qxthread.h</name>
<name>$PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.c</name>
</file>
</group>
<group>

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: DPP example
* Last Updated for Version: 5.7.2
* Date of the Last Update: 2016-09-27
* Last Updated for Version: 5.9.4
* Date of the Last Update: 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -35,12 +35,24 @@
#include "dpp.h"
#include "bsp.h"
/* local "naked" thread object .............................................*/
/* local "extended" thread object ..........................................*/
static QXThread l_test1;
static QXThread l_test2;
static QXMutex l_mutex;
static QXSemaphore l_sema;
/* Thread-Local Storage for the "extended" threads .........................*/
typedef struct {
uint32_t foo;
uint8_t bar[10];
} TLS_test;
static TLS_test l_tls1;
static TLS_test l_tls2;
static void lib_fun(uint32_t x) {
QXK_TLS(TLS_test *)->foo = x;
}
/* global pointer to the test thread .......................................*/
QXThread * const XT_Test1 = &l_test1;
QXThread * const XT_Test2 = &l_test2;
@ -48,6 +60,8 @@ QXThread * const XT_Test2 = &l_test2;
/*..........................................................................*/
static void Thread1_run(QXThread * const me) {
me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */
QXMutex_init(&l_mutex, 3U);
(void)me;
@ -68,6 +82,9 @@ static void Thread1_run(QXThread * const me) {
/* publish to thread2 */
QF_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1);
/* test TLS */
lib_fun(1U);
}
}
@ -79,6 +96,8 @@ void Test1_ctor(void) {
/*..........................................................................*/
static void Thread2_run(QXThread * const me) {
me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */
/* subscribe to the test signal */
QActive_subscribe(&me->super, TEST_SIG);
@ -108,6 +127,9 @@ static void Thread2_run(QXThread * const me) {
QXThread_delay(BSP_TICKS_PER_SEC/2, 0U); /* wait more (BLOCK) */
QXSemaphore_signal(&l_sema); /* signal Thread1 */
}
/* test TLS */
lib_fun(2U);
}
}

View File

@ -4,8 +4,8 @@
* @ingroup qep
* @cond
******************************************************************************
* Last updated for version 5.9.3
* Last updated on 2017-06-17
* Last updated for version 5.9.4
* Last updated on 2017-07-05
*
* Q u a n t u m L e a P s
* ---------------------------
@ -45,16 +45,16 @@
* major version number, Y is a 1-digit minor version number, and Z is
* a 1-digit release number.
*/
#define QP_VERSION 593
#define QP_VERSION 594
/*! The current QP version number string of the form X.Y.Z, where X is
* a 1-digit major version number, Y is a 1-digit minor version number,
* and Z is a 1-digit release number.
*/
#define QP_VERSION_STR "5.9.3"
#define QP_VERSION_STR "5.9.4"
/*! Tamperproof current QP release (5.9.3) and date (2017-06-19) */
#define QP_RELEASE 0x9A4D98FEU
/*! Tamperproof current QP release (5.9.4) and date (2017-07-07) */
#define QP_RELEASE 0x9A402B7DU
/****************************************************************************/
/* typedefs for basic numerical types; MISRA-C 2004 rule 6.3(req). */

View File

@ -4,8 +4,8 @@
* @ingroup qf
* @cond
******************************************************************************
* Last updated for version 5.9.3
* Last updated on 2017-06-17
* Last updated for version 5.9.4
* Last updated on 2017-07-05
*
* Q u a n t u m L e a P s
* ---------------------------
@ -107,7 +107,7 @@ struct QEQueue; /* forward declaration */
* __first__ member of the derived struct (see @ref oop).
* @include qf_qactive.c
*/
typedef struct {
typedef struct QActive {
QHsm super; /*!< inherits ::QHsm */
#ifdef QF_EQUEUE_TYPE
@ -156,7 +156,6 @@ typedef struct {
/*! protected "constructor" of an ::QActive active object */
void QActive_ctor(QActive * const me, QStateHandler initial);
/*! Virtual table for the ::QActive class */
typedef struct {
struct QHsmVtbl super; /*!< inherits ::QHsmVtbl */

View File

@ -1,7 +1,7 @@
//============================================================================
// Product: PC-Lint 9.x option file for linting QP/C applications
// Last updated for version 5.9.3
// Last updated on 2017-06-19
// Last updated for version 5.9.4
// Last updated on 2017-07-05
//
// Q u a n t u m L e a P s
// ---------------------------
@ -313,6 +313,7 @@
QXK_ISR_ENTRY,
QXK_ISR_EXIT,
QXK_getVersion,
QXK_TLS,
QXTHREAD_START,
QXTHREAD_POST_X,
Q_XTHREAD_CAST)

View File

@ -5,8 +5,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.8.1
* Last updated on 2016-12-14
* Last updated for version 5.9.4
* Last updated on 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -56,19 +56,33 @@
*/
#define QF_EQUEUE_TYPE QEQueue
/*! OS-dependent representation of the private thread */
/*! Private OS-object attribute of active objects in QXK */
/**
* @description
* QXK uses this member to store the private stack poiner for the thread.
* (The private stack pointer is NULL for AO-threads).
*/
#define QF_OS_OBJECT_TYPE void*
/*! Private thread attribute of active objects in QXK */
/**
* @description
* QXK uses this member to store the private Thread-Local Storage pointer.
*/
#define QF_THREAD_TYPE void*
/*! Access Thread-Local Storage (TLS) and cast it on the given @p type_ */
#define QXK_TLS(type_) ((type_)QXK_current()->thread)
/****************************************************************************/
struct QActive; /* forward declaration */
/****************************************************************************/
/*! attributes of the QXK kernel */
typedef struct {
void *curr; /*!< pointer to the current thread (0 for basic) */
void *next; /*!< pointer to the next thread to execute */
struct QActive *curr; /*!< pointer to the current thread (0 for basic) */
struct QActive *next; /*!< pointer to the next thread to execute */
uint_fast8_t volatile actPrio; /*!< prio of the active basic thread */
uint_fast8_t volatile lockPrio; /*!< lock prio (0 == no-lock) */
uint_fast8_t volatile lockHolder; /*!< prio of the lock holder */
@ -104,6 +118,10 @@ uint_fast8_t QXK_sched_(void);
*/
void QXK_activate_(void);
/****************************************************************************/
/*! return the currently executing active-object/thread */
struct QActive *QXK_current(void);
/****************************************************************************/
/*! QXK priority-ceiling mutex class */
typedef struct {

View File

@ -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.0
* Date of the Last Update: 2017-03-17
* Last Updated for Version: 5.9.3
* Date of the Last Update: 2017-06-17
*
* Q u a n t u m L e a P s
* ---------------------------
@ -192,7 +192,6 @@ PendSV_Handler:
LDR r1,=Thread_ret /* return address after the call (new lr) */
SUB sp,sp,#8*4 /* reserve space for exception stack frame */
STR r0,[sp] /* save the prio argument (new r0) */
ADD r0,sp,#5*4 /* r0 := 5 registers below the top of stack */
STM r0!,{r1-r3} /* save xpsr,pc,lr */

View File

@ -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.0
; Date of the Last Update: 2017-03-17
; Last Updated for Version: 5.9.4
; Date of the Last Update: 2017-07-06
;
; Q u a n t u m L e a P s
; ---------------------------
@ -51,8 +51,8 @@ QXK_NEXT EQU 4
QXK_TOP_PRIO EQU 8
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!!
QMACTIVE_THREAD EQU 40
QMACTIVE_PRIO EQU 44
QMACTIVE_OSOBJ EQU 40
QMACTIVE_PRIO EQU 48
AREA |.text|, CODE, READONLY
@ -198,13 +198,13 @@ PendSV_Handler FUNCTION
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
LDR r2,[r0,#QMACTIVE_THREAD] ; r2 := QXK_attr_.next->thread
LDR r2,[r0,#QMACTIVE_OSOBJ] ; r2 := QXK_attr_.next->osObject
LDR r1,[r3,#QXK_CURR] ; r1 := QXK_attr_.curr
CMP r1,#0 ; (QXK_attr_.curr != 0)?
BNE PendSV_save_ex ; branch if (current thread is extended)
CMP r2,#0 ; (QXK_attr_.next->thread != 0)?
CMP r2,#0 ; (QXK_attr_.next->osObject != 0)?
BNE PendSV_save_ao ; branch if (next tread is extended)
PendSV_activate
@ -243,7 +243,7 @@ PendSV_error
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ao
@ -266,14 +266,14 @@ PendSV_save_ao
ENDIF ; M3/M4/M7
CMP r2,#0
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->thread != 0)
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->osObject != 0)
; otherwise continue to restoring next AO-thread...
;-------------------------------------------------------------------------
; Restoring AO-thread after crossing from eXtended-thread
; expected register contents:
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ao
@ -328,7 +328,7 @@ PendSV_restore_ao
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ex
@ -357,11 +357,11 @@ PendSV_save_ex
ENDIF ; M3/M4/M7
; store the SP of the current extended-thread
STR r0,[r1,#QMACTIVE_THREAD] ; QXK_attr_.curr->thread := r0
STR r0,[r1,#QMACTIVE_OSOBJ] ; QXK_attr_.curr->osObject := r0
MOV r0,r12 ; QXK_attr_.next (restore value)
CMP r2,#0
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->thread == 0)
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->osObject == 0)
; otherwise continue to restoring next extended-thread...
;-------------------------------------------------------------------------
@ -369,7 +369,7 @@ PendSV_save_ex
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ex
@ -496,7 +496,7 @@ QXK_stackInit_ FUNCTION
; r3 - size of stack [bytes]
MOV r12,r0 ; temporarily save r0 in r12 (act)
STR r1,[r0,#QMACTIVE_THREAD] ; temporarily save the thread routine
STR r1,[r0,#QMACTIVE_OSOBJ] ; temporarily save the thread routine
ADDS r3,r2,r3 ; r3 := end of stack (top of stack)
; round up the beginning of stack to the 8-byte boundary
@ -527,9 +527,9 @@ QXK_stackInit_fill
; prepare the standard exception (without VFP) stack frame................
MOV r0,r12 ; restore r0 from r12 (act)
LDR r1,[r0,#QMACTIVE_THREAD] ; restore the thread routine
LDR r1,[r0,#QMACTIVE_OSOBJ] ; restore the thread routine
STR r3,[r0,#QMACTIVE_THREAD] ; act->thread := top of stack
STR r3,[r0,#QMACTIVE_OSOBJ] ; act->osObject := top of stack
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
MOVS r2,#0

View File

@ -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.0
* Date of the Last Update: 2017-03-17
* Last Updated for Version: 5.9.4
* Date of the Last Update: 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -44,8 +44,8 @@
.equ QXK_TOP_PRIO,8
/* NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!! */
.equ QMACTIVE_THREAD,40
.equ QMACTIVE_PRIO,44
.equ QMACTIVE_OSOBJ,40
.equ QMACTIVE_PRIO,48
/*****************************************************************************
* The QXK_init() function sets the priority of PendSV to 0xFF (lowest urgency).
@ -196,13 +196,13 @@ PendSV_Handler:
/* Load pointers into registers... */
MOV r12,r0 /* save QXK_attr_.next in r12 */
LDR r2,[r0,#QMACTIVE_THREAD] /* r2 := QXK_attr_.next->thread */
LDR r2,[r0,#QMACTIVE_OSOBJ] /* r2 := QXK_attr_.next->osObject */
LDR r1,[r3,#QXK_CURR] /* r1 := QXK_attr_.curr */
CMP r1,#0 /* (QXK_attr_.curr != 0)? */
BNE PendSV_save_ex /* branch if (current thread is extended) */
CMP r2,#0 /* (QXK_attr_.next->thread != 0)? */
CMP r2,#0 /* (QXK_attr_.next->osObject != 0)? */
BNE PendSV_save_ao /* branch if (next tread is extended) */
PendSV_activate:
@ -242,7 +242,7 @@ PendSV_error:
* expected register contents:
* r0 -> QXK_attr_.next
* r1 -> QXK_attr_.curr
* r2 -> QXK_attr_.next->thread (SP)
* r2 -> QXK_attr_.next->osObject (SP)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
@ -266,14 +266,14 @@ PendSV_save_ao:
.endif /* M3/M4/M7 */
CMP r2,#0
BNE PendSV_restore_ex /* branch if (QXK_attr_.next->thread != 0) */
BNE PendSV_restore_ex /* branch if (QXK_attr_.next->osObject != 0) */
/* otherwise continue to restoring next AO-thread... */
/*------------------------------------------------------------------------
* Restoring AO-thread after crossing from eXtended-thread
* expected register contents:
* r1 -> QXK_attr_.curr
* r2 -> QXK_attr_.next->thread (SP)
* r2 -> QXK_attr_.next->osObject (SP)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
@ -329,7 +329,7 @@ PendSV_restore_ao:
* expected register contents:
* r0 -> QXK_attr_.next
* r1 -> QXK_attr_.curr
* r2 -> QXK_attr_.next->thread (SP)
* r2 -> QXK_attr_.next->osObject (SP)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
@ -359,11 +359,11 @@ PendSV_save_ex:
.endif /* M3/M4/M7 */
/* store the SP of the current extended-thread */
STR r0,[r1,#QMACTIVE_THREAD] /* QXK_attr_.curr->thread := r0 */
STR r0,[r1,#QMACTIVE_OSOBJ] /* QXK_attr_.curr->osObject := r0 */
MOV r0,r12 /* QXK_attr_.next (restore value) */
CMP r2,#0
BEQ PendSV_restore_ao /* branch if (QXK_attr_.next->thread == 0) */
BEQ PendSV_restore_ao /* branch if (QXK_attr_.next->osObject == 0) */
/* otherwise continue to restoring next extended-thread... */
/*------------------------------------------------------------------------
@ -371,7 +371,7 @@ PendSV_save_ex:
* expected register contents:
* r0 -> QXK_attr_.next
* r1 -> QXK_attr_.curr
* r2 -> QXK_attr_.next->thread (SP)
* r2 -> QXK_attr_.next->osObject (SP)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
@ -512,7 +512,7 @@ QXK_stackInit_:
*/
MOV r12,r0 /* temporarily save r0 in r12 (act) */
STR r1,[r0,#QMACTIVE_THREAD] /* temporarily save the thread routine */
STR r1,[r0,#QMACTIVE_OSOBJ] /* temporarily save the thread routine */
ADDS r3,r2,r3 /* r3 := end of stack (top of stack) */
/* round up the beginning of stack to the 8-byte boundary
@ -545,9 +545,9 @@ QXK_stackInit_fill:
/* prepare the standard exception (without VFP) stack frame.............*/
MOV r0,r12 /* restore r0 from r12 (act) */
LDR r1,[r0,#QMACTIVE_THREAD] /* restore the thread routine */
LDR r1,[r0,#QMACTIVE_OSOBJ] /* restore the thread routine */
STR r3,[r0,#QMACTIVE_THREAD] /* act->thread := top of stack */
STR r3,[r0,#QMACTIVE_OSOBJ] /* act->osObject := top of stack */
.ifdef __FPU_PRESENT /* if VFP available... */
MOVS r2,#0

View File

@ -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.0
; Date of the Last Update: 2017-03-17
; Last Updated for Version: 5.9.4
; Date of the Last Update: 2017-07-06
;
; Q u a n t u m L e a P s
; ---------------------------
@ -51,8 +51,8 @@ QXK_NEXT EQU 4
QXK_TOP_PRIO EQU 8
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!!
QMACTIVE_THREAD EQU 40
QMACTIVE_PRIO EQU 44
QMACTIVE_OSOBJ EQU 40
QMACTIVE_PRIO EQU 48
RSEG CODE:CODE:NOROOT(2)
@ -196,13 +196,13 @@ PendSV_Handler:
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
LDR r2,[r0,#QMACTIVE_THREAD] ; r2 := QXK_attr_.next->thread
LDR r2,[r0,#QMACTIVE_OSOBJ] ; r2 := QXK_attr_.next->osObject
LDR r1,[r3,#QXK_CURR] ; r1 := QXK_attr_.curr
CMP r1,#0 ; (QXK_attr_.curr != 0)?
BNE PendSV_save_ex ; branch if (current thread is extended)
CMP r2,#0 ; (QXK_attr_.next->thread != 0)?
CMP r2,#0 ; (QXK_attr_.next->osObject != 0)?
BNE PendSV_save_ao ; branch if (next tread is extended)
PendSV_activate:
@ -241,7 +241,7 @@ PendSV_error:
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ao:
@ -264,14 +264,14 @@ PendSV_save_ao:
#endif ; M3/M4/M7
CMP r2,#0
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->thread != 0)
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->osObject != 0)
; otherwise continue to restoring next AO-thread...
;-------------------------------------------------------------------------
; Restoring AO-thread after crossing from eXtended-thread
; expected register contents:
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ao:
@ -326,7 +326,7 @@ PendSV_restore_ao:
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ex:
@ -355,11 +355,11 @@ PendSV_save_ex:
#endif ; M3/M4/M7
; store the SP of the current extended-thread
STR r0,[r1,#QMACTIVE_THREAD] ; QXK_attr_.curr->thread := r0
STR r0,[r1,#QMACTIVE_OSOBJ] ; QXK_attr_.curr->osObject := r0
MOV r0,r12 ; QXK_attr_.next (restore value)
CMP r2,#0
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->thread == 0)
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->osObject == 0)
; otherwise continue to restoring next extended-thread...
;-------------------------------------------------------------------------
@ -367,7 +367,7 @@ PendSV_save_ex:
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ex:
@ -492,7 +492,7 @@ QXK_stackInit_:
; r3 - size of stack [bytes]
MOV r12,r0 ; temporarily save r0 in r12 (act)
STR r1,[r0,#QMACTIVE_THREAD] ; temporarily save the thread routine
STR r1,[r0,#QMACTIVE_OSOBJ] ; temporarily save the thread routine
ADDS r3,r2,r3 ; r3 := end of stack (top of stack)
; round up the beginning of stack to the 8-byte boundary
@ -523,9 +523,9 @@ QXK_stackInit_fill:
; prepare the standard exception (without VFP) stack frame................
MOV r0,r12 ; restore r0 from r12 (act)
LDR r1,[r0,#QMACTIVE_THREAD] ; restore the thread routine
LDR r1,[r0,#QMACTIVE_OSOBJ] ; restore the thread routine
STR r3,[r0,#QMACTIVE_THREAD] ; act->thread := top of stack
STR r3,[r0,#QMACTIVE_OSOBJ] ; act->osObject := top of stack
#ifdef __ARMVFP__ ; if VFP available...
MOVS r2,#0

View File

@ -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.0
; Date of the Last Update: 2017-03-17
; Last Updated for Version: 5.9.4
; Date of the Last Update: 2017-07-06
;
; Q u a n t u m L e a P s
; ---------------------------
@ -59,8 +59,8 @@ QXK_NEXT .equ 4
QXK_TOP_PRIO .equ 8
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!!
QMACTIVE_THREAD .equ 40
QMACTIVE_PRIO .equ 44
QMACTIVE_OSOBJ .equ 44
QMACTIVE_PRIO .equ 48
.text
.thumb
@ -201,13 +201,13 @@ PendSV_Handler: .asmfunc
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
LDR r2,[r0,#QMACTIVE_THREAD] ; r2 := QXK_attr_.next->thread
LDR r2,[r0,#QMACTIVE_OSOBJ] ; r2 := QXK_attr_.next->osObject
LDR r1,[r3,#QXK_CURR] ; r1 := QXK_attr_.curr
CMP r1,#0 ; (QXK_attr_.curr != 0)?
BNE PendSV_save_ex ; branch if (current thread is extended)
CMP r2,#0 ; (QXK_attr_.next->thread != 0)?
CMP r2,#0 ; (QXK_attr_.next->osObject != 0)?
BNE PendSV_save_ao ; branch if (next tread is extended)
PendSV_activate:
@ -246,7 +246,7 @@ PendSV_error:
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ao:
@ -269,14 +269,14 @@ PendSV_save_ao:
.endif ; M0/M0+
CMP r2,#0
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->thread != 0)
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->osObject != 0)
; otherwise continue to restoring next AO-thread...
;-------------------------------------------------------------------------
; Restoring AO-thread after crossing from eXtended-thread
; expected register contents:
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ao:
@ -331,7 +331,7 @@ PendSV_restore_ao:
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ex:
@ -360,11 +360,11 @@ PendSV_save_ex:
.endif ; M0/M0+
; store the SP of the current extended-thread
STR r0,[r1,#QMACTIVE_THREAD] ; QXK_attr_.curr->thread := r0
STR r0,[r1,#QMACTIVE_OSOBJ] ; QXK_attr_.curr->osObject := r0
MOV r0,r12 ; QXK_attr_.next (restore value)
CMP r2,#0
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->thread == 0)
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->osObject == 0)
; otherwise continue to restoring next extended-thread...
;-------------------------------------------------------------------------
@ -372,7 +372,7 @@ PendSV_save_ex:
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r2 -> QXK_attr_.next->osObject (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ex:
@ -500,7 +500,7 @@ QXK_stackInit_: .asmfunc
; r3 - size of stack [bytes]
MOV r12,r0 ; temporarily save r0 in r12 (act)
STR r1,[r0,#QMACTIVE_THREAD] ; temporarily save the thread routine
STR r1,[r0,#QMACTIVE_OSOBJ] ; temporarily save the thread routine
ADDS r3,r2,r3 ; r3 := end of stack (top of stack)
; round up the beginning of stack to the 8-byte boundary
@ -531,9 +531,9 @@ QXK_stackInit_fill:
; prepare the standard exception (without VFP) stack frame................
MOV r0,r12 ; restore r0 from r12 (act)
LDR r1,[r0,#QMACTIVE_THREAD] ; restore the thread routine
LDR r1,[r0,#QMACTIVE_OSOBJ] ; restore the thread routine
STR r3,[r0,#QMACTIVE_THREAD] ; act->thread := top of stack
STR r3,[r0,#QMACTIVE_OSOBJ] ; act->osObject := top of stack
.if __TI_VFP_SUPPORT__ ; if VFP available...
MOVS r2,#0

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.6.0
* Last updated on 2015-12-14
* Last updated for version 5.9.4
* Last updated on 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -44,7 +44,7 @@
/**
* @description
* This macro *must* be defined in the QF port and should be in range
* of 1..63, inclusive. The value of this macro determines the maximum
* of 1..64, inclusive. The value of this macro determines the maximum
* priority level of an active object in the system. Not all priority
* levels must be used, but the maximum priority cannot exceed
* #QF_MAX_ACTIVE.
@ -55,7 +55,7 @@
* this macro only once in the qf_port.h header file and henceforth include
* this header file in all builds.
*/
#define QF_MAX_ACTIVE 63
#define QF_MAX_ACTIVE 64
/*! The maximum number of event pools in the application. */
/**
@ -75,7 +75,7 @@
* this macro only once in the qf_port.h header file and henceforth include
* this header file in all builds.
*/
#define QF_MAX_EPOOL 3
#define QF_MAX_EPOOL 3
/*! The size (in bytes) of the event-size representation in the QF.
* Valid values: 1, 2, or 4; default 2
@ -258,7 +258,7 @@ void critExit(QF_CRIT_STAT_TYPE stat);
#include "qep_port.h" /* QEP port */
#include "qxk_port.h" /* QXK port */
#include "qf.h" /* QF platform-independent public interface */
#include "qxthread.h" /* QXK naked thread */
#include "qxthread.h" /* QXK extended thread */
#endif /* qf_port_h */

View File

@ -270,7 +270,7 @@ QEvt const *QActive_get_(QActive * const me) {
QACTIVE_EQUEUE_WAIT_(me); /* wait for event to arrive directly */
e = me->eQueue.frontEvt; /* always remove event from the front location */
nFree= me->eQueue.nFree + (QEQueueCtr)1; /* get volatile into tmp */
nFree = me->eQueue.nFree + (QEQueueCtr)1; /* get volatile into tmp */
me->eQueue.nFree = nFree; /* update the number of free */
/* any events in the ring buffer? */

View File

@ -68,7 +68,7 @@ int_t QF_run(void) {
QS_onTestLoop(); /* run the test loop */
QS_onCleanup(); /* application cleanup */
return 0; /* return no error */
return (int_t)0; /* return no error */
}
/*..........................................................................*/
@ -98,7 +98,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e,
{
QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO,
QS_priv_.locFilter[AO_OBJ], me)
//printf("QS_QF_ACTIVE_POST_FIFO\n");
/*printf("QS_QF_ACTIVE_POST_FIFO\n");*/
QS_TIME_(); /* timestamp */
QS_OBJ_(sender); /* the sender object */
QS_SIG_(e->sig); /* the signal of the event */
@ -139,7 +139,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e,
QF_gc(e); /* recycle the event to avoid a leak */
status = false; /* event not posted */
}
}
return status;
}
/*..........................................................................*/
@ -391,7 +391,7 @@ void QF_tickX_(uint_fast8_t const tickRate, void const * const sender) {
QACTIVE_POST(act, &t->super, sender);
/* explicitly dispatch the time event */
QHSM_DISPATCH((QHsm *)act, &t->super);
QHSM_DISPATCH(&act->super, &t->super);
}
else {
QF_CRIT_EXIT_();
@ -399,8 +399,8 @@ void QF_tickX_(uint_fast8_t const tickRate, void const * const sender) {
}
/****************************************************************************/
void Q_onAssert(char const * const module, int_t loc) {
QS_ASSERTION(module, loc, (uint32_t)0); /* report assertion to QSPY */
void Q_onAssert(char_t const * const module, int_t location) {
QS_ASSERTION(module, location, (uint32_t)0); /* report to QSPY */
QS_onTestLoop(); /* loop to wait for commands (typically reset) */
QS_onReset(); /* in case the QUTEST loop ever returns, reset manually */
}

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.9.0
* Last updated on 2017-03-13
* Last updated for version 5.9.4
* Last updated on 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -189,7 +189,7 @@ void QActive_start_(QActive * const me, uint_fast8_t prio,
&& (stkSize == (uint_fast16_t)0));
QEQueue_init(&me->eQueue, qSto, qLen); /* initialize the built-in queue */
me->thread = (void *)0; /* no private stack for AO */
me->osObject = (void *)0; /* no private stack for AO */
me->prio = prio; /* set the current priority of the AO */
QF_add_(me); /* make QF aware of this active object */
@ -260,12 +260,12 @@ uint_fast8_t QXK_sched_(void) {
Q_ASSERT_ID(610, next != (QActive *)0);
/* is the current thread a basic-thread? */
if (QXK_attr_.curr == (void *)0) {
if (QXK_attr_.curr == (struct QActive *)0) {
/* is the next a basic-thread? */
if (next->thread == (void *)0) {
if (next->osObject == (void *)0) {
if (p <= QXK_attr_.actPrio) {
QXK_attr_.next = (void *)0;
QXK_attr_.next = (struct QActive *)0;
p = (uint_fast8_t)0; /* no activation needed */
}
else {
@ -290,14 +290,14 @@ uint_fast8_t QXK_sched_(void) {
else { /* currently executing an extended-thread */
/* is the new prio different from the current prio? */
if (p != ((QActive volatile *)QXK_attr_.curr)->prio) {
if (p != QXK_attr_.curr->prio) {
QS_BEGIN_NOCRIT_(QS_SCHED_NEXT, QS_priv_.locFilter[AO_OBJ],
QXK_attr_.next)
QS_TIME_(); /* timestamp */
QS_2U8_((uint8_t)p, /* priority of the next AO */
/* priority of the curent AO */
(uint8_t)((QActive *)QXK_attr_.curr)->prio);
(uint8_t)QXK_attr_.curr->prio);
QS_END_NOCRIT_()
QXK_attr_.next = next;
@ -305,7 +305,7 @@ uint_fast8_t QXK_sched_(void) {
QXK_CONTEXT_SWITCH_();
}
else {
QXK_attr_.next = (void *)0;
QXK_attr_.next = (struct QActive *)0;
p = (uint_fast8_t)0; /* no activation needed */
}
}
@ -324,7 +324,7 @@ uint_fast8_t QXK_sched_(void) {
*/
void QXK_activate_(void) {
uint_fast8_t pin = QXK_attr_.actPrio; /* save the initial active prio */
uint_fast8_t p = ((QActive volatile *)QXK_attr_.next)->prio;
uint_fast8_t p = QXK_attr_.next->prio;
QActive *a;
/* QS tracing or thread-local storage? */
@ -339,7 +339,7 @@ void QXK_activate_(void) {
a = QF_active_[p]; /* obtain the pointer to the AO */
QXK_attr_.actPrio = p; /* this becomes the active prio */
QXK_attr_.next = (void *)0; /* clear the next AO */
QXK_attr_.next = (struct QActive *)0; /* clear the next AO */
QS_BEGIN_NOCRIT_(QS_SCHED_NEXT, QS_priv_.locFilter[AO_OBJ], a)
QS_TIME_(); /* timestamp */
@ -381,9 +381,9 @@ void QXK_activate_(void) {
Q_ASSERT_ID(710, a != (QActive *)0); /* must be registered */
/* is the next an AO-thread? */
if (a->thread == (void *)0) {
if (a->osObject == (void *)0) {
if (p <= pin) {
QXK_attr_.next = (void *)0;
QXK_attr_.next = (struct QActive *)0;
p = (uint_fast8_t)0; /* no activation needed */
}
else {
@ -426,3 +426,16 @@ void QXK_activate_(void) {
}
#endif /* Q_SPY */
}
/****************************************************************************/
struct QActive *QXK_current(void) {
struct QActive *curr;
QF_CRIT_STAT_
QF_CRIT_ENTRY_();
curr = QXK_attr_.curr;
QF_CRIT_EXIT_();
return curr;
}

View File

@ -4,8 +4,8 @@
* @brief QXMutex_init(), QXMutex_lock and QXMutex_unlock() definitions.
* @cond
******************************************************************************
* Last updated for version 5.9.0
* Last updated on 2017-03-02
* Last updated for version 5.9.4
* Last updated on 2017-07-05
*
* Q u a n t u m L e a P s
* ---------------------------
@ -124,8 +124,8 @@ void QXMutex_lock(QXMutex * const me) {
QXK_attr_.lockPrio = me->lockPrio;
}
QXK_attr_.lockHolder =
(QXK_attr_.curr != (void *)0)
? ((QActive volatile *)QXK_attr_.curr)->prio
(QXK_attr_.curr != (struct QActive *)0)
? QXK_attr_.curr->prio
: (uint_fast8_t)0;
QS_BEGIN_NOCRIT_(QS_SCHED_LOCK, (void *)0, (void *)0)
@ -180,10 +180,15 @@ void QXMutex_unlock(QXMutex * const me) {
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK, (void *)0, (void *)0)
QS_TIME_(); /* timestamp */
QS_2U8_((uint8_t)QXK_attr_.lockPrio, /* the previouis lock priority */
(uint8_t)((QXK_attr_.lockPrio > p) /* the new lock priority */
? p
: QXK_attr_.lockPrio));
if (QXK_attr_.lockPrio > p) {
QS_2U8_((uint8_t)QXK_attr_.lockPrio, /* previouis lock priority */
(uint8_t)p); /* new lock priority */
}
else {
p = QXK_attr_.lockPrio;
QS_2U8_((uint8_t)p, /* previouis lock priority */
(uint8_t)p); /* new lock priority */
}
QS_END_NOCRIT_()
if (QXK_attr_.lockPrio > p) {

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.7.4
* Last updated on 2016-11-01
* Last updated for version 5.9.4
* Last updated on 2017-07-05
*
* Q u a n t u m L e a P s
* ---------------------------
@ -169,7 +169,7 @@ void QXSemaphore_signal(QXSemaphore * const me) {
thr = (QXThread *)QF_active_[p]; /* thread waiting on the semaphore */
Q_ASSERT_ID(210,
(thr->super.thread != (void *)0) /* must be extended thread */
(thr->super.thread != (struct QActive *)0) /* must be extended */
&& (me->count == (uint_fast16_t)0)); /* sema counter must be 0 */
/* disarm the internal time event */

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.9.0
* Last updated on 2017-05-06
* Last updated for version 5.9.4
* Last updated on 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -622,7 +622,7 @@ void QXK_threadRet_(void) {
QF_CRIT_STAT_
QF_CRIT_ENTRY_();
p = ((QActive volatile *)QXK_attr_.curr)->prio;
p = QXK_attr_.curr->prio;
/* remove this thread from the QF */
QF_active_[p] = (QActive *)0;
QPSet_remove(&QXK_attr_.readySet, p);

View File

@ -270,7 +270,7 @@ QEvt const *QActive_get_(QActive * const me) {
QACTIVE_EQUEUE_WAIT_(me); /* wait for event to arrive directly */
e = me->eQueue.frontEvt; /* always remove event from the front location */
nFree= me->eQueue.nFree + (QEQueueCtr)1; /* get volatile into tmp */
nFree = me->eQueue.nFree + (QEQueueCtr)1; /* get volatile into tmp */
me->eQueue.nFree = nFree; /* update the number of free */
/* any events in the ring buffer? */

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.9.0
* Last updated on 2017-03-13
* Last updated for version 5.9.4
* Last updated on 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -189,7 +189,7 @@ void QActive_start_(QActive * const me, uint_fast8_t prio,
&& (stkSize == (uint_fast16_t)0));
QEQueue_init(&me->eQueue, qSto, qLen); /* initialize the built-in queue */
me->thread = (void *)0; /* no private stack for AO */
me->osObject = (void *)0; /* no private stack for AO */
me->prio = prio; /* set the current priority of the AO */
QF_add_(me); /* make QF aware of this active object */
@ -260,12 +260,12 @@ uint_fast8_t QXK_sched_(void) {
Q_ASSERT_ID(610, next != (QActive *)0);
/* is the current thread a basic-thread? */
if (QXK_attr_.curr == (void *)0) {
if (QXK_attr_.curr == (struct QActive *)0) {
/* is the next a basic-thread? */
if (next->thread == (void *)0) {
if (next->osObject == (void *)0) {
if (p <= QXK_attr_.actPrio) {
QXK_attr_.next = (void *)0;
QXK_attr_.next = (struct QActive *)0;
p = (uint_fast8_t)0; /* no activation needed */
}
else {
@ -290,14 +290,14 @@ uint_fast8_t QXK_sched_(void) {
else { /* currently executing an extended-thread */
/* is the new prio different from the current prio? */
if (p != ((QActive volatile *)QXK_attr_.curr)->prio) {
if (p != QXK_attr_.curr->prio) {
QS_BEGIN_NOCRIT_(QS_SCHED_NEXT, QS_priv_.locFilter[AO_OBJ],
QXK_attr_.next)
QS_TIME_(); /* timestamp */
QS_2U8_((uint8_t)p, /* priority of the next AO */
/* priority of the curent AO */
(uint8_t)((QActive *)QXK_attr_.curr)->prio);
(uint8_t)QXK_attr_.curr->prio);
QS_END_NOCRIT_()
QXK_attr_.next = next;
@ -305,7 +305,7 @@ uint_fast8_t QXK_sched_(void) {
QXK_CONTEXT_SWITCH_();
}
else {
QXK_attr_.next = (void *)0;
QXK_attr_.next = (struct QActive *)0;
p = (uint_fast8_t)0; /* no activation needed */
}
}
@ -324,7 +324,7 @@ uint_fast8_t QXK_sched_(void) {
*/
void QXK_activate_(void) {
uint_fast8_t pin = QXK_attr_.actPrio; /* save the initial active prio */
uint_fast8_t p = ((QActive volatile *)QXK_attr_.next)->prio;
uint_fast8_t p = QXK_attr_.next->prio;
QActive *a;
/* QS tracing or thread-local storage? */
@ -339,7 +339,7 @@ void QXK_activate_(void) {
a = QF_active_[p]; /* obtain the pointer to the AO */
QXK_attr_.actPrio = p; /* this becomes the active prio */
QXK_attr_.next = (void *)0; /* clear the next AO */
QXK_attr_.next = (struct QActive *)0; /* clear the next AO */
QS_BEGIN_NOCRIT_(QS_SCHED_NEXT, QS_priv_.locFilter[AO_OBJ], a)
QS_TIME_(); /* timestamp */
@ -381,9 +381,9 @@ void QXK_activate_(void) {
Q_ASSERT_ID(710, a != (QActive *)0); /* must be registered */
/* is the next an AO-thread? */
if (a->thread == (void *)0) {
if (a->osObject == (void *)0) {
if (p <= pin) {
QXK_attr_.next = (void *)0;
QXK_attr_.next = (struct QActive *)0;
p = (uint_fast8_t)0; /* no activation needed */
}
else {
@ -426,3 +426,16 @@ void QXK_activate_(void) {
}
#endif /* Q_SPY */
}
/****************************************************************************/
struct QActive *QXK_current(void) {
struct QActive *curr;
QF_CRIT_STAT_
QF_CRIT_ENTRY_();
curr = QXK_attr_.curr;
QF_CRIT_EXIT_();
return curr;
}

View File

@ -4,8 +4,8 @@
* @brief QXMutex_init(), QXMutex_lock and QXMutex_unlock() definitions.
* @cond
******************************************************************************
* Last updated for version 5.9.0
* Last updated on 2017-03-02
* Last updated for version 5.9.4
* Last updated on 2017-07-05
*
* Q u a n t u m L e a P s
* ---------------------------
@ -124,8 +124,8 @@ void QXMutex_lock(QXMutex * const me) {
QXK_attr_.lockPrio = me->lockPrio;
}
QXK_attr_.lockHolder =
(QXK_attr_.curr != (void *)0)
? ((QActive volatile *)QXK_attr_.curr)->prio
(QXK_attr_.curr != (struct QActive *)0)
? QXK_attr_.curr->prio
: (uint_fast8_t)0;
QS_BEGIN_NOCRIT_(QS_SCHED_LOCK, (void *)0, (void *)0)
@ -180,10 +180,15 @@ void QXMutex_unlock(QXMutex * const me) {
QS_BEGIN_NOCRIT_(QS_SCHED_UNLOCK, (void *)0, (void *)0)
QS_TIME_(); /* timestamp */
QS_2U8_((uint8_t)QXK_attr_.lockPrio, /* the previouis lock priority */
(uint8_t)((QXK_attr_.lockPrio > p) /* the new lock priority */
? p
: QXK_attr_.lockPrio));
if (QXK_attr_.lockPrio > p) {
QS_2U8_((uint8_t)QXK_attr_.lockPrio, /* previouis lock priority */
(uint8_t)p); /* new lock priority */
}
else {
p = QXK_attr_.lockPrio;
QS_2U8_((uint8_t)p, /* previouis lock priority */
(uint8_t)p); /* new lock priority */
}
QS_END_NOCRIT_()
if (QXK_attr_.lockPrio > p) {

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.7.4
* Last updated on 2016-11-01
* Last updated for version 5.9.4
* Last updated on 2017-07-05
*
* Q u a n t u m L e a P s
* ---------------------------
@ -169,7 +169,7 @@ void QXSemaphore_signal(QXSemaphore * const me) {
thr = (QXThread *)QF_active_[p]; /* thread waiting on the semaphore */
Q_ASSERT_ID(210,
(thr->super.thread != (void *)0) /* must be extended thread */
(thr->super.thread != (struct QActive *)0) /* must be extended */
&& (me->count == (uint_fast16_t)0)); /* sema counter must be 0 */
/* disarm the internal time event */

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.9.0
* Last updated on 2017-05-06
* Last updated for version 5.9.4
* Last updated on 2017-07-06
*
* Q u a n t u m L e a P s
* ---------------------------
@ -622,7 +622,7 @@ void QXK_threadRet_(void) {
QF_CRIT_STAT_
QF_CRIT_ENTRY_();
p = ((QActive volatile *)QXK_attr_.curr)->prio;
p = QXK_attr_.curr->prio;
/* remove this thread from the QF */
QF_active_[p] = (QActive *)0;
QPSet_remove(&QXK_attr_.readySet, p);

View File

@ -1,2 +0,0 @@
QP/C 5.9.3
2017-06-19

2
version-5.9.4 Normal file
View File

@ -0,0 +1,2 @@
QP/C 5.9.4
2017-07-07