5.7.1-beta

This commit is contained in:
Quantum Leaps 2016-09-23 12:08:21 -04:00
parent ca6e07e3f3
commit 637eed4519
131 changed files with 4903 additions and 3293 deletions

View File

@ -2,7 +2,7 @@
; * @file startup_efm32pg1b.s for IAR ARM assembler
; * @brief CMSIS Cortex-M4F Core Device Startup File for TM4C123GH6PM
; * @version CMSIS 4.3.0
; * @date 07 May 2016
; * @date 07 Sep 2016
; *
; * @description
; * Created from the CMSIS template for the specified device
@ -130,6 +130,17 @@ __Vectors_Size EQU __Vectors_End - __Vectors
EXTERN __iar_program_start
Reset_Handler
BL SystemInit ; CMSIS system initialization
; pre-fill the CSTACK with 0xDEADBEEF...................
LDR r0,=0xDEADBEEF
MOV r1,r0
LDR r2,=sfb(CSTACK)
LDR r3,=sfe(CSTACK)
Reset_stackInit_fill:
STMIA r2!,{r0,r1}
CMP r2,r3
BLT.N Reset_stackInit_fill
BL __iar_program_start ; IAR startup code
;.............................................................................
PUBWEAK NMI_Handler

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C"
PROJECT_NUMBER = "5.7.0"
PROJECT_NUMBER = "5.7.1-beta"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C"
PROJECT_NUMBER = "5.7.0"
PROJECT_NUMBER = "5.7.1-beta"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C"
PROJECT_NUMBER = "5.7.0"
PROJECT_NUMBER = "5.7.1-beta"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =

View File

@ -73,8 +73,10 @@ You can hover the mouse cursor over the <span class="board"></span>&nbsp;&nbsp;
@note
You can hover the mouse cursor over the <span class="board"></span>&nbsp;&nbsp; icon in the list below to see the picture of the board.
- @ref arm-cm_dpp_efm32-slstk3401a <a class="preview board" href="bd_EFM32-SLSTK3401A.jpg" title="EFM32-SLSTK3401A"></a>
- @ref arm-cm_dpp_ek-tm4c123gxl <a class="preview board" href="bd_EK-TM4C123GXL.jpg" title="EK-TM4C123GXL"></a>
- @ref arm-cm_dpp_efm32-slstk3401a <a class="preview board" href="bd_EFM32-SLSTK3401A.jpg" title="EFM32-SLSTK3401A"></a>
- @ref arm-cm_dpp_nucleo-l053r8 <a class="preview board" href="bd_nucleo-l053r8.jpg" title="NUCLEO-L053R8"></a>
*/
/*##########################################################################*/
/*! @page exa_arm-cm ARM Cortex-M (Cortex-M0/M0+/M3/M4F)

View File

@ -1,12 +1,35 @@
/**
@page history Revision History
@section qpc_5_7_1 Version 5.7.1-beta, 2016-09-23
This beta-release brings the first "dual-mode" version of the QXK kernel.
"Dual-mode" QXK means that QXK executes non-blocking active objects
like the QK kernel using the single stack (Main Stack on ARM Cortex-M),
but can also execute traditional *blocking* threads (extended threads).
Only the extended threads need their private stack spaces and the overhead
of the full context switch. The QXK examples have been updated for more
thourough demonstration of the QXK features. The QXK examples are available
in the following directories: dpp_efm32-slstk3401a, dpp_ek-tm4c123gxl, and
dpp_nucleo-l053r8.
This release also changes the implementation of the priority-set to use
32-bit bitmasks instead of 8-bit bitmasks. This is more efficient on
32-processors. The implementation of Log-base-2 (to quickly find the
highest-priority element in the priority-set) has been also changed
to use 32-bit bitmasks.
The internal automatic variable 'entry' has been renamed to 'epath' in
qep_msm.c, because 'entry' turns out to be an (obsolete) reserved word
in ANSI C. This avoids violating MISRA-C:2004 Rule 20.2.
------------------------------------------------------------------------------
@section qpc_5_7_0 Version 5.7.0, 2016-08-31
This release adds support for sub-machines and sub-machine states for reusing pieces of state machines (an advanced UML concept) to the QMsm-state machine implementation strategy. This feature is to match the upcoming QM 4.0.0.
Also, this release adds support for the ARM Cortex-R processor. Specifically, the release contains a generic port to ARM Cortex-R with the IAR and TI-CCS toolsets and examples for the TI Hercules TMS570LS12x safety MCU (LAUNCHPADXL2-TMS57012).
Also, this release changes once more the QK port to ARM Cortex-M, to reduce the interrupt latecy. This has been achieved by shortening the critical section in the PendSV exception. Also, this QK port to Cortex-M no longer uses the NMI exception.
Also, this release changes once more the QK port to ARM Cortex-M, to reduce the interrupt latecy. This has been achieved by shortening the critical section in the PendSV exception.
Also, this release changes slightly the QXK port to ARM Cortex-M, where again the critical section in PendSV has been slighly shortened.

View File

@ -1,8 +1,8 @@
@echo off
:: ==========================================================================
:: Product: QP/C script for generating Doxygen documentation
:: Last Updated for Version: 5.5.0
:: Date of the Last Update: 2016-08-30
:: Last Updated for Version: 5.7.1
:: Date of the Last Update: 2016-09-22
::
:: 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.7.0
set VERSION=5.7.1-beta
:: Generate Resource Standard Metrics for QP/C ...............................
set DOXHOME="C:\tools\doxygen\bin"

File diff suppressed because it is too large Load Diff

View File

@ -53,7 +53,7 @@ Given the simplicity, portability, and low-resource consumption, the QV schedule
@brief
Preemptive Non-Blocking Kernel
QK is a tiny **preemptive**, priority-based, non-blocking kernel designed specifically for executing active objects. 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 (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.
------------------------------------------------------------------------------
@ -66,9 +66,9 @@ Sometimes it is not practical to break up long RTC steps, and consequently the t
/*###########################################################################*/ /*! @defgroup qxk QXK
@brief
Preemptive Blocking RTOS Kernel
Preemptive Dual-Mode Blocking RTOS Kernel
QXK is a small, preemptive, priority-based, **blocking** kernel that provides typical services of 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.
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.
Currently, the QXK kernel has been ported to the following CPUs:
@ -77,20 +77,20 @@ 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
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
Example illustrates: 6 active objects plus one "naked" thread, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
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
Example illustrates: 6 active objects plus one "naked" thread, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
------------------------------------------------------------------------------
@section qxk_overview QXK Overview
QXK works as most conventional RTOS kernels, by frequently switching the CPU from one thread to another in the process called *context switching*. As shown in the diagram below, each thread of execution (a.k.a. task) in QXK is assigned its own private **stack** area in RAM and its own data structure (often called the *thread control block*). The use of multiple stacks allows the kernel to **block** (suspend) threads at any moment, because the top of the stack of each thread is always available.
@image html qxk_ctx-switch.gif "Context-switching among multiple threads with private stacks"
@n
QXK distinguishes two kinds of threads: basic-threads (non-blocking, run-to-completion activations) and extended-threads (blocking, typically structrued as endless loops). The basic threads all nest on the same stack (MSP in ARM Cortex-M). The extended-threads use private per-thread stacks, as in conventional RTOS kernels. Any switching from basic- to extended-thread or extended- to extended-thread requires full context switch. On the other hand, switching from basic-thread to another basic-thread requires only activation of the basic-thread, which is much simpler and faster.
<div class="separate"></div>
@subsection qxk_classes Classes in QXK

View File

@ -23,7 +23,7 @@ enum DPPSignals {
DONE_SIG, /* published by Philosopher when done eating */
PAUSE_SIG, /* published by BSP to pause serving forks */
SERVE_SIG, /* published by BSP to serve re-start serving forks */
TERMINATE_SIG, /* published by BSP to terminate the application */
TEST_SIG, /* published by BSP to test the application */
MAX_PUB_SIG, /* the last published signal */
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
@ -57,8 +57,10 @@ extern QMActive * const AO_Table;
#ifdef qxk_h
void Test_ctor(void);
extern QXThread * const XT_Test;
void Test1_ctor(void);
extern QXThread * const XT_Test1;
void Test2_ctor(void);
extern QXThread * const XT_Test2;
#endif /* qxk_h */
#endif /* dpp_h */

View File

@ -38,7 +38,8 @@ if (registered == (uint8_t)0) {
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
QActive_subscribe(&amp;me-&gt;super, EAT_SIG);</action>
QActive_subscribe(&amp;me-&gt;super, EAT_SIG);
QActive_subscribe(&amp;me-&gt;super, TEST_SIG);</action>
<initial_glyph conn="2,3,5,1,20,5,-3">
<action box="0,-2,6,2"/>
</initial_glyph>
@ -57,6 +58,11 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<tran trig="TEST">
<tran_glyph conn="2,20,3,-1,13">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<state_glyph node="2,5,17,16">
<entry box="1,2,5,2"/>
</state_glyph>
@ -131,14 +137,14 @@ QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
QActive_subscribe(&amp;me-&gt;super, DONE_SIG);
QActive_subscribe(&amp;me-&gt;super, PAUSE_SIG);
QActive_subscribe(&amp;me-&gt;super, SERVE_SIG);
QActive_subscribe(&amp;me-&gt;super, TERMINATE_SIG);
QActive_subscribe(&amp;me-&gt;super, TEST_SIG);
for (n = 0U; n &lt; N_PHILO; ++n) {
me-&gt;fork[n] = FREE;
@ -150,8 +156,7 @@ for (n = 0U; n &lt; N_PHILO; ++n) {
</initial_glyph>
</initial>
<state name="active">
<tran trig="TERMINATE">
<action>BSP_terminate(0);</action>
<tran trig="TEST">
<tran_glyph conn="2,11,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
@ -348,7 +353,7 @@ enum DPPSignals {
DONE_SIG, /* published by Philosopher when done eating */
PAUSE_SIG, /* published by BSP to pause serving forks */
SERVE_SIG, /* published by BSP to serve re-start serving forks */
TERMINATE_SIG, /* published by BSP to terminate the application */
TEST_SIG, /* published by BSP to test the application */
MAX_PUB_SIG, /* the last published signal */
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
@ -368,8 +373,10 @@ $declare(AOs::Table_ctor)
$declare(AOs::AO_Table)
#ifdef qxk_h
void Test_ctor(void);
extern QXThread * const XT_Test;
void Test1_ctor(void);
extern QXThread * const XT_Test1;
void Test2_ctor(void);
extern QXThread * const XT_Test2;
#endif /* qxk_h */
#endif /* dpp_h */</text>

View File

@ -133,6 +133,7 @@ static QState Philo_initial(Philo * const me, QEvt const * const e) {
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
QActive_subscribe(&me->super, EAT_SIG);
QActive_subscribe(&me->super, TEST_SIG);
return QM_TRAN_INIT(&tatbl_);
}
/*${AOs::Philo::SM::thinking} ..............................................*/
@ -168,11 +169,17 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) {
status_ = QM_HANDLED();
break;
}
/* ${AOs::Philo::SM::thinking::TEST} */
case TEST_SIG: {
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
(void)me; /* avoid compiler warning in case 'me' is not used */
return status_;
}
/*${AOs::Philo::SM::hungry} ................................................*/

View File

@ -143,7 +143,7 @@ void SysTick_Handler(void) {
QK_ISR_EXIT(); /* inform QK about exiting an ISR */
}
/*..........................................................................*/
void GPIO_EVEN_IRQHandler(void) {
void GPIO_EVEN_IRQHandler(void) { /* to be triggered from debugger, NOTE03 */
QK_ISR_ENTRY(); /* inform QK about entering an ISR */
QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */
@ -516,4 +516,8 @@ void QS_onCommand(uint8_t cmdId, uint32_t param) {
* of the LED is proportional to the frequency of invcations of the idle loop.
* Please note that the LED is toggled with interrupts locked, so no interrupt
* execution time contributes to the brightness of the User LED.
*
* NOTE03:
* To trigger GPIO_EVEN_IRQHandler() from debugger:
* IAR EWARM: go to the NVIC_ISPR0 register and write 0x200 to SETPEND.
*/

View File

@ -144,11 +144,22 @@ void SysTick_Handler(void) {
QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */
}
/*..........................................................................*/
/* The following IRQ handler is for testing various preemption scenarios
* in QXK. The general testing strategy is to trigger this IRQ manually
* from the debugger. To do so in IAR, you need to:
* 1. open the Register view
* 2. open NVIC registers
* 3. scroll down to NVIC_ISPR0 register
* 4. write 0x200 to NVIC_ISPR0.SETPEND register
*/
void GPIO_EVEN_IRQHandler(void) {
QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */
QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */
&l_GPIO_EVEN_IRQHandler);
// QACTIVE_POST(AO_Table, Q_NEW(QEvt, TEST_SIG), /* for testing... */
// &l_GPIO_EVEN_IRQHandler);
QF_PUBLISH(Q_NEW(QEvt, TEST_SIG), /* for testing... */
&l_GPIO_EVEN_IRQHandler);
QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */
}
@ -178,30 +189,7 @@ void BSP_init(void) {
*/
SystemCoreClockUpdate();
/* configure the FPU usage by choosing one of the options... */
#if 1
/* OPTION 1:
* Use the automatic FPU state preservation and the FPU lazy stacking.
*
* NOTE:
* Use the following setting when FPU is used in more than one task or
* in any ISRs. This setting is the safest and recommended, but requires
* extra stack space and CPU cycles.
*/
FPU->FPCCR |= (1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos);
#else
/* OPTION 2:
* Do NOT to use the automatic FPU state preservation and
* do NOT to use the FPU lazy stacking.
*
* NOTE:
* Use the following setting when FPU is used in ONE task only and not
* in any ISR. This setting is very efficient, but if more than one task
* (or ISR) start using the FPU, this can lead to corruption of the
* FPU registers. This option should be used with CAUTION.
*/
FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
#endif
/* NOTE: The VFP (hardware Floating Point) unit is configured by QXK */
/* enable clock for to the peripherals used by this application... */
CMU_ClockEnable(cmuClock_HFPER, true);
@ -253,6 +241,10 @@ void BSP_displayPaused(uint8_t paused) {
else {
GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN);
}
QS_BEGIN(PAUSED_STAT, (void *)0) /* application-specific record begin */
QS_U8(1, paused); /* Paused status */
QS_END()
}
/*..........................................................................*/
uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */
@ -262,20 +254,20 @@ uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */
float volatile x = 3.1415926F;
x = x + 2.7182818F;
QXMutex_lock(&l_rndMutex); /* lock the random-seed mutex */
QXMutex_lock(&l_rndMutex); /* lock the shared random seed */
/* "Super-Duper" Linear Congruential Generator (LCG)
* LCG(2^32, 3*7*11*13*23, 0, seed)
*/
rnd = l_rnd * (3U*7U*11U*13U*23U);
l_rnd = rnd; /* set for the next time */
QXMutex_unlock(&l_rndMutex); /* unlock the random-seed mutex */
QXMutex_unlock(&l_rndMutex); /* unlock the shared random seed */
return (rnd >> 8);
}
/*..........................................................................*/
void BSP_randomSeed(uint32_t seed) {
QXMutex_init(&l_rndMutex, N_PHILO); /* ceiling <== max Philo priority */
l_rnd = seed;
QXMutex_init(&l_rndMutex, N_PHILO); /* ceiling == max Philo priority */
}
/*..........................................................................*/
void BSP_wait4PB1(void) {
@ -325,12 +317,18 @@ void QF_onCleanup(void) {
}
/*..........................................................................*/
void QXK_onIdle(void) {
float volatile x;
/* toggle the User LED on and then off, see NOTE01 */
// QF_INT_DISABLE();
// GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN);
// GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN);
// QF_INT_ENABLE();
/* Some flating point code is to exercise the VFP... */
x = 1.73205F;
x = x * 1.73205F;
#ifdef Q_SPY
QS_rxParse(); /* parse all the received bytes */
@ -449,6 +447,7 @@ uint8_t QS_onStartup(void const *arg) {
QS_FILTER_ON(QS_QEP_UNHANDLED);
QS_FILTER_ON(PHILO_STAT);
QS_FILTER_ON(PAUSED_STAT);
QS_FILTER_ON(COMMAND_STAT);
return (uint8_t)1; /* return success */
@ -515,14 +514,14 @@ void QS_onCommand(uint8_t cmdId, uint32_t param) {
*
* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
* with the numerical values of priorities equal or higher than
* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY
* macros or any other QF/QK services. These ISRs are "QF-aware".
* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT
* macros or any other QF/QXK services. These ISRs are "QF-aware".
*
* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority
* level (i.e., with the numerical values of priorities less than
* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel.
* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they
* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism
* Such "QF-unaware" ISRs cannot call any QF/QXK services. In particular they
* can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism
* by which a "QF-unaware" ISR can communicate with the QF framework is by
* triggering a "QF-aware" ISR, which can post/publish events.
*

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: Linker script for EFM32-SLSTK3401A, GNU-ARM linker
* Last Updated for Version: 5.6.5
* Date of the Last Update: 2016-06-06
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-21
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,7 +41,7 @@ MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 512;
STACK_SIZE = 1024;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;

View File

@ -77,7 +77,7 @@
</option>
<option>
<name>OGLastSavedByProductVersion</name>
<state>7.60.1.11206</state>
<state>7.70.1.11471</state>
</option>
<option>
<name>GeneralEnableMisra</name>
@ -345,7 +345,7 @@
<option>
<name>CCOptStrategy</name>
<version>0</version>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CCOptLevelSlave</name>
@ -399,11 +399,11 @@
</option>
<option>
<name>IccStaticDestr</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>IccCppInlineSemantics</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>IccCmsis</name>
@ -420,7 +420,7 @@
<option>
<name>CCOptStrategySlave</name>
<version>0</version>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CCGuardCalls</name>
@ -1047,7 +1047,7 @@
</option>
<option>
<name>OGLastSavedByProductVersion</name>
<state>7.60.1.11206</state>
<state>7.70.1.11471</state>
</option>
<option>
<name>GeneralEnableMisra</name>
@ -1316,7 +1316,7 @@
<option>
<name>CCOptStrategy</name>
<version>0</version>
<state>1</state>
<state>2</state>
</option>
<option>
<name>CCOptLevelSlave</name>
@ -1374,7 +1374,7 @@
</option>
<option>
<name>IccCppInlineSemantics</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>IccCmsis</name>
@ -1391,7 +1391,7 @@
<option>
<name>CCOptStrategySlave</name>
<version>0</version>
<state>1</state>
<state>2</state>
</option>
<option>
<name>CCGuardCalls</name>
@ -2018,7 +2018,7 @@
</option>
<option>
<name>OGLastSavedByProductVersion</name>
<state>7.60.1.11206</state>
<state>7.70.1.11471</state>
</option>
<option>
<name>GeneralEnableMisra</name>
@ -3012,6 +3012,9 @@
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\include\qxk.h</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_mutex.c</name>
</file>
@ -3024,6 +3027,9 @@
<file>
<name>$PROJ_DIR$\..\..\..\..\..\source\qxk_xthr.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\include\qxthread.h</name>
</file>
</group>
<group>
<name>QP_port</name>

View File

@ -1,13 +1,13 @@
/*****************************************************************************
* Product: DPP example for QXK
* Last Updated for Version: 5.6.2
* Date of the Last Update: 2016-03-29
* Product: DPP example extened for QXK
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-07
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) Quantum Leaps, LLC. All rights reserved.
* Copyright (C) Quantum Leaps, LLC. state-machine.com.
*
* 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
@ -28,8 +28,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact information:
* http://www.state-machine.com
* mailto:info@state-machine.com
* Web : http://www.state-machine.com
* Email: info@state-machine.com
*****************************************************************************/
#include "qpc.h"
#include "dpp.h"
@ -38,27 +38,24 @@
/*..........................................................................*/
int main() {
static QEvt const *tableQueueSto[N_PHILO];
static uint64_t tableStackSto[64];
static QEvt const *philoQueueSto[N_PHILO][N_PHILO];
static uint64_t philoStackSto[N_PHILO][64];
static QSubscrList subscrSto[MAX_PUB_SIG];
static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */
/* stack for the "naked" test thread */
static void const *testQueueSto[5];
static uint64_t testStackSto[64];
/* stack for the QXK's idle thread */
static uint64_t idleStackSto[32];
/* stack for the extended test threads */
static void const *test1QueueSto[5];
static uint64_t test1StackSto[64];
static void const *test2QueueSto[5];
static uint64_t test2StackSto[64];
uint8_t n;
Philo_ctor(); /* instantiate all Philosopher active objects */
Table_ctor(); /* instantiate the Table active object */
Test_ctor(); /* instantiate the Test "naked" thread */
Test1_ctor(); /* instantiate the Test1 extended thread */
Test2_ctor(); /* instantiate the Test2 extended thread */
QF_init(); /* initialize the framework */
QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the Board Support Package */
/* object dictionaries... */
@ -70,40 +67,48 @@ int main() {
QS_OBJ_DICTIONARY(philoQueueSto[3]);
QS_OBJ_DICTIONARY(philoQueueSto[4]);
/* initialize QXK... */
QXK_init(idleStackSto, sizeof(idleStackSto));
/* initialize publish-subscribe... */
QF_psInit(subscrSto, Q_DIM(subscrSto));
/* initialize event pools... */
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
/* start the extended thread */
//#if 0
QXTHREAD_START(&XT_Test1->super, /* Thread to start */
(uint_fast8_t)1U, /* QP priority of the thread */
test1QueueSto, /* message queue storage */
Q_DIM(test1QueueSto), /* message length [events] */
test1StackSto, /* stack storage */
sizeof(test1StackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
//#endif
/* start the active objects... */
for (n = 0U; n < N_PHILO; ++n) {
QACTIVE_START(AO_Philo[n], /* AO to start */
(uint_fast8_t)(n + 1), /* QP priority of the AO */
philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */
philoStackSto[n], /* stack storage */
sizeof(philoStackSto[n]), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
(uint_fast8_t)(n + 2), /* QP priority of the AO */
philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */
(void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */
}
//#if 0
QXTHREAD_START(&XT_Test2->super, /* Thread to start */
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the thread */
test2QueueSto, /* message queue storage */
Q_DIM(test2QueueSto), /* message length [events] */
test2StackSto, /* stack storage */
sizeof(test2StackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
//#endif
QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */
(uint_fast8_t)(N_PHILO + 3), /* QP priority of the AO */
tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */
tableStackSto, /* stack storage */
sizeof(tableStackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
/* start the "naked" thread */
QXTHREAD_START(&XT_Test->super, /* Thread to start */
(uint_fast8_t)10U, /* QP priority of the thread */
testQueueSto, /* message queue storage */
Q_DIM(testQueueSto), /* message length [events] */
testStackSto, /* stack storage */
sizeof(testStackSto), /* stack size [bytes] */
(void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */
return QF_run(); /* run the QF application */

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: DPP example
* Last Updated for Version: 5.6.2
* Date of the Last Update: 2016-03-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-20
*
* Q u a n t u m L e a P s
* ---------------------------
@ -36,35 +36,80 @@
#include "bsp.h"
/* local "naked" thread object .............................................*/
static QXThread l_test;
static QXThread l_test1;
static QXThread l_test2;
static QXMutex l_mutex;
static QXSemaphore l_sema;
/* global pointer to the test thread .......................................*/
QXThread * const XT_Test = &l_test;
QXThread * const XT_Test1 = &l_test1;
QXThread * const XT_Test2 = &l_test2;
/*..........................................................................*/
static void thread_function(void *par) {
static void Thread1_run(QXThread * const me) {
QXMutex_init(&l_mutex, 3U);
(void)par;
(void)me;
for (;;) {
float volatile x;
(void)QXThread_queueGet(BSP_TICKS_PER_SEC*2U, 0U); /* block */
QXMutex_lock(&l_mutex);
/* wait on a semaphore (BLOCK) */
QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT, 0U);
BSP_ledOn();
/* NOTE: can't block while holding a mutex... */
/* some flating point code to exercise the VFP... */
QXMutex_lock(&l_mutex);
x = 1.4142135F;
x = x * 1.4142135F;
QXMutex_unlock(&l_mutex);
QXThread_delay(BSP_TICKS_PER_SEC/4U, 0U); /* block */
BSP_ledOff();
QXThread_delay(BSP_TICKS_PER_SEC/8U, 0U); /* BLOCK */
QXThread_delay(BSP_TICKS_PER_SEC*3U/4U, 0U);
/* publish to thread2 */
QF_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1);
}
}
/*..........................................................................*/
void Test_ctor(void) {
QXThread_ctor(&l_test, &thread_function, 0U);
void Test1_ctor(void) {
QXThread_ctor(&l_test1, Q_XTHREAD_CAST(&Thread1_run), 0U);
}
/*..........................................................................*/
static void Thread2_run(QXThread * const me) {
/* subscribe to the test signal */
QActive_subscribe(&me->super, TEST_SIG);
/* initialize the semaphore before using it
* NOTE: the semaphore is initialized in the highest-priority thread
* that uses it. Alternatively, the semaphore can be initialized
* before any thread runs.
*/
QXSemaphore_init(&l_sema, 0U); /* start with zero count */
for (;;) {
QEvt const *e;
float volatile x;
/* signal thread1... */
QXSemaphore_signal(&l_sema);
/* some flating point code to exercise the VFP... */
x = 1.4142135F;
x = x * 1.4142135F;
/* wait on the internal event queue (BLOCK) */
e = QXThread_queueGet(QXTHREAD_NO_TIMEOUT, 0U);
BSP_ledOff();
QF_gc(e); /* recycle the event manually! */
QXThread_delay(BSP_TICKS_PER_SEC, 0U); /* BLOCK */
}
}
/*..........................................................................*/
void Test2_ctor(void) {
QXThread_ctor(&l_test2, Q_XTHREAD_CAST(&Thread2_run), 0U);
}

View File

@ -115,14 +115,14 @@ static QState Table_initial(Table * const me, QEvt const * const e) {
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
QActive_subscribe(&me->super, DONE_SIG);
QActive_subscribe(&me->super, PAUSE_SIG);
QActive_subscribe(&me->super, SERVE_SIG);
QActive_subscribe(&me->super, TERMINATE_SIG);
QActive_subscribe(&me->super, TEST_SIG);
for (n = 0U; n < N_PHILO; ++n) {
me->fork[n] = FREE;
@ -136,9 +136,8 @@ static QState Table_initial(Table * const me, QEvt const * const e) {
static QState Table_active(Table * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${AOs::Table::SM::active::TERMINATE} */
case TERMINATE_SIG: {
BSP_terminate(0);
/* ${AOs::Table::SM::active::TEST} */
case TEST_SIG: {
status_ = QM_HANDLED();
break;
}

View File

@ -23,7 +23,7 @@ enum DPPSignals {
DONE_SIG, /* published by Philosopher when done eating */
PAUSE_SIG, /* published by BSP to pause serving forks */
SERVE_SIG, /* published by BSP to serve re-start serving forks */
TERMINATE_SIG, /* published by BSP to terminate the application */
TEST_SIG, /* published by BSP to test the application */
MAX_PUB_SIG, /* the last published signal */
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
@ -57,8 +57,10 @@ extern QMActive * const AO_Table;
#ifdef qxk_h
void Test_ctor(void);
extern QXThread * const XT_Test;
void Test1_ctor(void);
extern QXThread * const XT_Test1;
void Test2_ctor(void);
extern QXThread * const XT_Test2;
#endif /* qxk_h */
#endif /* dpp_h */

View File

@ -38,7 +38,8 @@ if (registered == (uint8_t)0) {
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
QActive_subscribe(&amp;me-&gt;super, EAT_SIG);</action>
QActive_subscribe(&amp;me-&gt;super, EAT_SIG);
QActive_subscribe(&amp;me-&gt;super, TEST_SIG);</action>
<initial_glyph conn="2,3,5,1,20,5,-3">
<action box="0,-2,6,2"/>
</initial_glyph>
@ -57,6 +58,11 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<tran trig="TEST">
<tran_glyph conn="2,20,3,-1,13">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<state_glyph node="2,5,17,16">
<entry box="1,2,5,2"/>
</state_glyph>
@ -131,14 +137,14 @@ QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
QActive_subscribe(&amp;me-&gt;super, DONE_SIG);
QActive_subscribe(&amp;me-&gt;super, PAUSE_SIG);
QActive_subscribe(&amp;me-&gt;super, SERVE_SIG);
QActive_subscribe(&amp;me-&gt;super, TERMINATE_SIG);
QActive_subscribe(&amp;me-&gt;super, TEST_SIG);
for (n = 0U; n &lt; N_PHILO; ++n) {
me-&gt;fork[n] = FREE;
@ -150,8 +156,7 @@ for (n = 0U; n &lt; N_PHILO; ++n) {
</initial_glyph>
</initial>
<state name="active">
<tran trig="TERMINATE">
<action>BSP_terminate(0);</action>
<tran trig="TEST">
<tran_glyph conn="2,11,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
@ -348,7 +353,7 @@ enum DPPSignals {
DONE_SIG, /* published by Philosopher when done eating */
PAUSE_SIG, /* published by BSP to pause serving forks */
SERVE_SIG, /* published by BSP to serve re-start serving forks */
TERMINATE_SIG, /* published by BSP to terminate the application */
TEST_SIG, /* published by BSP to test the application */
MAX_PUB_SIG, /* the last published signal */
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
@ -368,8 +373,10 @@ $declare(AOs::Table_ctor)
$declare(AOs::AO_Table)
#ifdef qxk_h
void Test_ctor(void);
extern QXThread * const XT_Test;
void Test1_ctor(void);
extern QXThread * const XT_Test1;
void Test2_ctor(void);
extern QXThread * const XT_Test2;
#endif /* qxk_h */
#endif /* dpp_h */</text>

View File

@ -133,6 +133,7 @@ static QState Philo_initial(Philo * const me, QEvt const * const e) {
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
QActive_subscribe(&me->super, EAT_SIG);
QActive_subscribe(&me->super, TEST_SIG);
return QM_TRAN_INIT(&tatbl_);
}
/*${AOs::Philo::SM::thinking} ..............................................*/
@ -168,11 +169,17 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) {
status_ = QM_HANDLED();
break;
}
/* ${AOs::Philo::SM::thinking::TEST} */
case TEST_SIG: {
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
(void)me; /* avoid compiler warning in case 'me' is not used */
return status_;
}
/*${AOs::Philo::SM::hungry} ................................................*/

View File

@ -100,7 +100,7 @@
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<nTsel>3</nTsel>
<nTsel>8</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -114,10 +114,6 @@
<pMon>BIN\lmidk-agdi.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
@ -193,6 +189,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -275,7 +274,7 @@
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<nTsel>3</nTsel>
<nTsel>8</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -370,6 +369,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -452,7 +454,7 @@
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<nTsel>3</nTsel>
<nTsel>8</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -541,6 +543,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -555,7 +560,6 @@
<FileNumber>1</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\bsp.c</PathWithFileName>
@ -568,7 +572,6 @@
<FileNumber>2</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\dpp.h</PathWithFileName>
@ -581,7 +584,6 @@
<FileNumber>3</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\bsp.h</PathWithFileName>
@ -594,7 +596,6 @@
<FileNumber>4</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\philo.c</PathWithFileName>
@ -607,7 +608,6 @@
<FileNumber>5</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\table.c</PathWithFileName>
@ -620,7 +620,6 @@
<FileNumber>6</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\include\qstamp.c</PathWithFileName>
@ -633,7 +632,6 @@
<FileNumber>7</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\main.c</PathWithFileName>
@ -654,7 +652,6 @@
<FileNumber>8</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c</PathWithFileName>
@ -667,7 +664,6 @@
<FileNumber>9</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h</PathWithFileName>
@ -680,7 +676,6 @@
<FileNumber>10</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s</PathWithFileName>
@ -693,7 +688,6 @@
<FileNumber>11</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h</PathWithFileName>
@ -706,7 +700,6 @@
<FileNumber>12</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h</PathWithFileName>
@ -719,7 +712,6 @@
<FileNumber>13</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h</PathWithFileName>
@ -732,7 +724,6 @@
<FileNumber>14</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h</PathWithFileName>
@ -753,7 +744,6 @@
<FileNumber>15</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qep_hsm.c</PathWithFileName>
@ -766,7 +756,6 @@
<FileNumber>16</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qep_msm.c</PathWithFileName>
@ -779,7 +768,6 @@
<FileNumber>17</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_act.c</PathWithFileName>
@ -792,7 +780,6 @@
<FileNumber>18</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_actq.c</PathWithFileName>
@ -805,7 +792,6 @@
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_defer.c</PathWithFileName>
@ -818,7 +804,6 @@
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_dyn.c</PathWithFileName>
@ -831,7 +816,6 @@
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_mem.c</PathWithFileName>
@ -844,7 +828,6 @@
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_ps.c</PathWithFileName>
@ -857,7 +840,6 @@
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qact.c</PathWithFileName>
@ -870,7 +852,6 @@
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qeq.c</PathWithFileName>
@ -883,7 +864,6 @@
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qmact.c</PathWithFileName>
@ -896,7 +876,6 @@
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_time.c</PathWithFileName>
@ -909,7 +888,6 @@
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qk.c</PathWithFileName>
@ -922,7 +900,6 @@
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qk_mutex.c</PathWithFileName>
@ -943,7 +920,6 @@
<FileNumber>29</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qk\arm\qk_port.s</PathWithFileName>
@ -964,7 +940,6 @@
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs.c</PathWithFileName>
@ -977,7 +952,6 @@
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_64bit.c</PathWithFileName>
@ -990,7 +964,6 @@
<FileNumber>32</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_fp.c</PathWithFileName>
@ -1003,7 +976,6 @@
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_rx.c</PathWithFileName>

View File

@ -15,7 +15,7 @@
<TargetCommonOption>
<Device>TM4C123GH6PM</Device>
<Vendor>Texas Instruments</Vendor>
<PackID>Keil.TM4C_DFP.1.0.0</PackID>
<PackID>Keil.TM4C_DFP.1.1.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -125,47 +125,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>0</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>3</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>BIN\lmidk-agdi.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -369,6 +328,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>__FPU_PRESENT</Define>
@ -618,6 +579,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
@ -678,7 +641,7 @@
<TargetCommonOption>
<Device>TM4C123GH6PM</Device>
<Vendor>Texas Instruments</Vendor>
<PackID>Keil.TM4C_DFP.1.0.0</PackID>
<PackID>Keil.TM4C_DFP.1.1.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -788,47 +751,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>0</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>3</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>BIN\lmidk-agdi.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -1032,6 +954,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>NDEBUG __FPU_PRESENT</Define>
@ -1281,6 +1205,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
@ -1341,7 +1267,7 @@
<TargetCommonOption>
<Device>TM4C123GH6PM</Device>
<Vendor>Texas Instruments</Vendor>
<PackID>Keil.TM4C_DFP.1.0.0</PackID>
<PackID>Keil.TM4C_DFP.1.1.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -1451,47 +1377,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>0</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>3</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>BIN\lmidk-agdi.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -1695,6 +1580,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>Q_SPY __FPU_PRESENT</Define>

View File

@ -212,16 +212,36 @@
</folderInfo>
<fileInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1276051254.QP/qxk_pkg.h" name="qxk_pkg.h" rcbsApplicability="disable" resourcePath="QP/qxk_pkg.h" toolsToInvoke=""/>
<fileInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1276051254.QP/qxk_xthr.c" name="qxk_xthr.c" rcbsApplicability="disable" resourcePath="QP/qxk_xthr.c" toolsToInvoke="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.7401819">
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.7401819" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.7401819" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963">
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS.1429724330" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS.1419351072" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS.1878765492" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS.784901507" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS"/>
</tool>
</fileInfo>
<fileInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1276051254.QP/qxk_sema.c" name="qxk_sema.c" rcbsApplicability="disable" resourcePath="QP/qxk_sema.c" toolsToInvoke="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.437105613">
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.437105613" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.437105613" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963">
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS.1796310379" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS.78485316" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS.1124398781" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS.894310345" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS"/>
</tool>
</fileInfo>
<fileInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1276051254.QP/qxk.c" name="qxk.c" rcbsApplicability="disable" resourcePath="QP/qxk.c" toolsToInvoke="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.1748481630">
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.1748481630" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.1748481630" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963">
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS.1188621443" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS.385632115" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS.156923434" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS.840698879" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS"/>
</tool>
</fileInfo>
<fileInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1276051254.QP/qxk_mutex.c" name="qxk_mutex.c" rcbsApplicability="disable" resourcePath="QP/qxk_mutex.c" toolsToInvoke="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.1509963911">
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.1509963911" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963.1509963911" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerRelease.1973824963">
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS.899090610" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS.1775916703" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS.62406525" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS.2002337522" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS"/>
</tool>
</fileInfo>
<sourceEntries>
<entry excluding="QP/qxk_xthr.c|QP/qxk_sema.c|QP/qxk.c|QP/qxk_pkg.h|QP/qxk_mutex.c|QP/qk.c|QP/qk_mutex.c|ek-tm4c123gxl/iar/startup_TM4C123GH6PM.s|ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c|ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s|QP/qs.c|QP/qs_rx.c|QP/qs_fp.c|QP/qs_64bit.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.ti.ccstudio.debug.launchType.device.debugging">
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_CPUS_WITH_PROJECT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;cpus_with_project&gt;&#13;&#10;&lt;id id=&quot;Stellaris In-Circuit Debug Interface/CORTEX_M4_0&quot; isa=&quot;CORTEX_M4&quot;/&gt;&#13;&#10;&lt;/cpus_with_project&gt;"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.Stellaris In-Circuit Debug Interface/CORTEX_M4_0" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot; ?&gt;&#10;&lt;PropertyValues&gt;&#10;&#10; &lt;property id=&quot;ConnectOnStartup&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;EnableInstalledBreakpoint&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;IgnoreSoftLaunchFailures&quot;&gt;&#10; &lt;curValue&gt;0&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10;&lt;/PropertyValues&gt;&#10;"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROGRAM.Stellaris In-Circuit Debug Interface/CORTEX_M4_0" value="${build_artifact:dpp-qv}"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROJECT.Stellaris In-Circuit Debug Interface/CORTEX_M4_0" value="dpp-qv"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_TARGET_CONFIG" value="${target_config_active_default:dpp-qv}"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.MRU_PROGRAM.Stellaris In-Circuit Debug Interface/CORTEX_M4_0" value="C:/qp_lab\qpc\examples\arm-cm\dpp_ek-tm4c123gxl\qv\ti\Debug\dpp-qv.out"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/dpp-qv"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="com.ti.ccstudio.debug.sourceLocator"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;cpuSpecificContainer cpuName=&amp;quot;Stellaris In-Circuit Debug Interface/CORTEX_M4_0&amp;quot;&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;project name=&amp;amp;quot;dpp-qv&amp;amp;quot; referencedProjects=&amp;amp;quot;true&amp;amp;quot;/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;org.eclipse.debug.core.containerType.project&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;default/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;org.eclipse.debug.core.containerType.default&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;childContainerEntry childMemento=&amp;quot;&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; standalone=&amp;amp;quot;no&amp;amp;quot;?&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;amp;lt;librarySource/&amp;amp;gt;&amp;amp;#13;&amp;amp;#10;&amp;quot; childType=&amp;quot;com.ti.ccstudio.debug.containerType.library.source&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&amp;lt;/cpuSpecificContainer&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;com.ti.ccstudio.debug.containerType.cpu.specific&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
</launchConfiguration>

View File

@ -28,7 +28,7 @@
<link>
<name>QP</name>
<type>2</type>
<location>C:/qp/qpc/source</location>
<location>PARENT-5-PROJECT_LOC/source</location>
</link>
<link>
<name>QP_include</name>

View File

@ -100,7 +100,7 @@
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<nTsel>3</nTsel>
<nTsel>8</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -189,6 +189,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -271,7 +274,7 @@
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<nTsel>3</nTsel>
<nTsel>8</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -366,6 +369,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -448,7 +454,7 @@
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<nTsel>3</nTsel>
<nTsel>8</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -537,6 +543,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -551,7 +560,6 @@
<FileNumber>1</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\bsp.c</PathWithFileName>
@ -564,7 +572,6 @@
<FileNumber>2</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\dpp.h</PathWithFileName>
@ -577,7 +584,6 @@
<FileNumber>3</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\bsp.h</PathWithFileName>
@ -590,7 +596,6 @@
<FileNumber>4</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\philo.c</PathWithFileName>
@ -603,7 +608,6 @@
<FileNumber>5</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\table.c</PathWithFileName>
@ -616,7 +620,6 @@
<FileNumber>6</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\include\qstamp.c</PathWithFileName>
@ -629,7 +632,6 @@
<FileNumber>7</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\main.c</PathWithFileName>
@ -642,7 +644,6 @@
<FileNumber>8</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\test.c</PathWithFileName>
@ -663,7 +664,6 @@
<FileNumber>9</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c</PathWithFileName>
@ -676,7 +676,6 @@
<FileNumber>10</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h</PathWithFileName>
@ -689,7 +688,6 @@
<FileNumber>11</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s</PathWithFileName>
@ -702,7 +700,6 @@
<FileNumber>12</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h</PathWithFileName>
@ -715,7 +712,6 @@
<FileNumber>13</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h</PathWithFileName>
@ -728,7 +724,6 @@
<FileNumber>14</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h</PathWithFileName>
@ -741,7 +736,6 @@
<FileNumber>15</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h</PathWithFileName>
@ -762,7 +756,6 @@
<FileNumber>16</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qep_hsm.c</PathWithFileName>
@ -775,7 +768,6 @@
<FileNumber>17</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qep_msm.c</PathWithFileName>
@ -788,7 +780,6 @@
<FileNumber>18</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_act.c</PathWithFileName>
@ -801,7 +792,6 @@
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_actq.c</PathWithFileName>
@ -814,7 +804,6 @@
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_defer.c</PathWithFileName>
@ -827,7 +816,6 @@
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_dyn.c</PathWithFileName>
@ -840,7 +828,6 @@
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_mem.c</PathWithFileName>
@ -853,7 +840,6 @@
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_ps.c</PathWithFileName>
@ -866,7 +852,6 @@
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qact.c</PathWithFileName>
@ -879,7 +864,6 @@
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qeq.c</PathWithFileName>
@ -892,7 +876,6 @@
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qmact.c</PathWithFileName>
@ -905,7 +888,6 @@
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_time.c</PathWithFileName>
@ -918,7 +900,6 @@
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk.c</PathWithFileName>
@ -931,7 +912,6 @@
<FileNumber>29</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk_mutex.c</PathWithFileName>
@ -944,7 +924,6 @@
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk_sema.c</PathWithFileName>
@ -957,7 +936,6 @@
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk_xthr.c</PathWithFileName>
@ -978,7 +956,6 @@
<FileNumber>32</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qxk\arm\qxk_port.s</PathWithFileName>
@ -999,7 +976,6 @@
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs.c</PathWithFileName>
@ -1012,7 +988,6 @@
<FileNumber>34</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_64bit.c</PathWithFileName>
@ -1025,7 +1000,6 @@
<FileNumber>35</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_fp.c</PathWithFileName>
@ -1038,7 +1012,6 @@
<FileNumber>36</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_rx.c</PathWithFileName>

View File

@ -10,12 +10,12 @@
<TargetName>dpp-dbg</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060020::V5.06 (build 20)::ARMCC</pCCUsed>
<pCCUsed>5060183::V5.06 update 2 (build 183)::ARMCC</pCCUsed>
<TargetOption>
<TargetCommonOption>
<Device>TM4C123GH6PM</Device>
<Vendor>Texas Instruments</Vendor>
<PackID>Keil.TM4C_DFP.1.0.0</PackID>
<PackID>Keil.TM4C_DFP.1.1.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -125,47 +125,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>0</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>3</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>BIN\lmidk-agdi.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -369,6 +328,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>__FPU_PRESENT</Define>
@ -388,7 +349,7 @@
<useXO>0</useXO>
<VariousControls>
<MiscControls></MiscControls>
<Define>Stack_Size=512 Heap_Size=0</Define>
<Define>Stack_Size=1024 Heap_Size=0</Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
@ -633,6 +594,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
@ -693,7 +656,7 @@
<TargetCommonOption>
<Device>TM4C123GH6PM</Device>
<Vendor>Texas Instruments</Vendor>
<PackID>Keil.TM4C_DFP.1.0.0</PackID>
<PackID>Keil.TM4C_DFP.1.1.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -803,47 +766,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>0</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>3</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>BIN\lmidk-agdi.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -1047,6 +969,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>NDEBUG __FPU_PRESENT</Define>
@ -1066,7 +990,7 @@
<useXO>0</useXO>
<VariousControls>
<MiscControls></MiscControls>
<Define>Stack_Size=512 Heap_Size=0</Define>
<Define>Stack_Size=1024 Heap_Size=0</Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
@ -1311,6 +1235,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
@ -1366,12 +1292,12 @@
<TargetName>dpp-spy</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060020::V5.06 (build 20)::ARMCC</pCCUsed>
<pCCUsed>5060183::V5.06 update 2 (build 183)::ARMCC</pCCUsed>
<TargetOption>
<TargetCommonOption>
<Device>TM4C123GH6PM</Device>
<Vendor>Texas Instruments</Vendor>
<PackID>Keil.TM4C_DFP.1.0.0</PackID>
<PackID>Keil.TM4C_DFP.1.1.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -1481,47 +1407,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>0</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>3</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>BIN\lmidk-agdi.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -1725,6 +1610,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>Q_SPY __FPU_PRESENT</Define>
@ -1744,7 +1631,7 @@
<useXO>0</useXO>
<VariousControls>
<MiscControls></MiscControls>
<Define>Stack_Size=512 Heap_Size=0</Define>
<Define>Stack_Size=1024 Heap_Size=0</Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>

View File

@ -112,7 +112,7 @@ void SysTick_Handler(void) {
uint32_t current;
uint32_t tmp;
QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */
QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */
#ifdef Q_SPY
{
@ -144,14 +144,16 @@ void SysTick_Handler(void) {
}
}
QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */
QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */
}
/*..........................................................................*/
void GPIOPortA_IRQHandler(void) {
QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */
QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */
&l_GPIOPortA_IRQHandler);
//QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */
// &l_GPIOPortA_IRQHandler);
QF_PUBLISH(Q_NEW(QEvt, TEST_SIG), /* for testing... */
&l_GPIOPortA_IRQHandler);
QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */
}
@ -160,7 +162,7 @@ void GPIOPortA_IRQHandler(void) {
/*
* ISR for receiving bytes from the QSPY Back-End
* NOTE: This ISR is "QF-unaware" meaning that it does not interact with
* the QF/QXK and is never disabled. Such ISRs don't need to call QXK_ISR_ENTRY/
* the QF/QXK and is not disabled. Such ISRs don't need to call QXK_ISR_ENTRY/
* QXK_ISR_EXIT and they cannot post or publish events.
*/
void UART0_IRQHandler(void) {
@ -217,16 +219,18 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) {
//GPIOF->DATA_Bits[LED_RED] = ((stat[0] == 'e') ? 0xFFU : 0U);
QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */
QS_U8(1, n); /* Philosopher number */
QS_STR(stat); /* Philosopher status */
QS_U8(1, n); /* Philosopher number */
QS_STR(stat); /* Philosopher status */
QS_END()
}
/*..........................................................................*/
void BSP_displayPaused(uint8_t paused) {
static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U};
//GPIOF->DATA_Bits[LED_RED] = ((paused != 0U) ? LED_RED : 0U);
QXTHREAD_POST_X(XT_Test, &pauseEvt, 1U, (void *)0);
//QXThread_unblock(XT_Test); /*??? unblock the Test thread */
if (paused != 0U) {
GPIOF->DATA_Bits[LED_GREEN] = 0xFFU;
}
else {
GPIOF->DATA_Bits[LED_GREEN] = 0x0U;
}
QS_BEGIN(PAUSED_STAT, (void *)0) /* application-specific record begin */
QS_U8(1, paused); /* Paused status */
@ -255,11 +259,6 @@ void BSP_randomSeed(uint32_t seed) {
QXMutex_init(&l_rndMutex, N_PHILO); /* ceiling <== max Philo priority */
l_rnd = seed;
}
/*..........................................................................*/
void BSP_terminate(int16_t result) {
(void)result;
}
/*..........................................................................*/
void BSP_wait4SW1(void) {
while (GPIOF->DATA_Bits[BTN_SW1] != 0) {
@ -275,6 +274,10 @@ void BSP_ledOn(void) {
void BSP_ledOff(void) {
GPIOF->DATA_Bits[LED_RED] = 0x00U;
}
/*..........................................................................*/
void BSP_terminate(int16_t result) {
(void)result;
}
/*..........................................................................*/
void QF_onStartup(void) {
@ -307,12 +310,18 @@ void QF_onCleanup(void) {
}
/*..........................................................................*/
void QXK_onIdle(void) {
float volatile x;
/* toggle the User LED on and then off, see NOTE01 */
QF_INT_DISABLE();
GPIOF->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the Blue LED on */
GPIOF->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */
QF_INT_ENABLE();
/* Some flating point code is to exercise the VFP... */
x = 1.73205F;
x = x * 1.73205F;
#ifdef Q_SPY
QS_rxParse(); /* parse all the received bytes */
@ -324,8 +333,8 @@ void QXK_onIdle(void) {
block = QS_getBlock(&fifo); /* try to get next block to transmit */
QF_INT_ENABLE();
while (fifo-- != 0) { /* any bytes in the block? */
UART0->DR = *block++; /* put into the FIFO */
while (fifo-- != 0) { /* any bytes in the block? */
UART0->DR = *block++; /* put into the FIFO */
}
}
#elif defined NDEBUG
@ -349,6 +358,7 @@ void Q_onAssert(char const *module, int loc) {
#ifndef NDEBUG
BSP_wait4SW1();
#endif
NVIC_SystemReset();
}
@ -481,7 +491,7 @@ void QS_onCommand(uint8_t cmdId, uint32_t param) {
*
* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
* with the numerical values of priorities equal or higher than
* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_ENTRY
* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT
* macros or any other QF/QXK services. These ISRs are "QF-aware".
*
* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: Linker script for for DPP on EK-TM4C123GXL, QXK kernel, GNU-ARM
* Last Updated for Version: 5.6.1
* Date of the Last Update: 2015-12-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,7 +41,7 @@ MEMORY { /* memory map of Tiva TM4C123GH6PM */
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 512;
STACK_SIZE = 1024;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;

View File

@ -1,13 +1,13 @@
/*****************************************************************************
* Product: DPP example for QXK
* Last Updated for Version: 5.6.2
* Date of the Last Update: 2016-03-29
* Product: DPP example extened for QXK
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-07
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) Quantum Leaps, LLC. All rights reserved.
* Copyright (C) Quantum Leaps, LLC. state-machine.com.
*
* 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
@ -28,8 +28,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact information:
* http://www.state-machine.com
* mailto:info@state-machine.com
* Web : http://www.state-machine.com
* Email: info@state-machine.com
*****************************************************************************/
#include "qpc.h"
#include "dpp.h"
@ -38,27 +38,24 @@
/*..........................................................................*/
int main() {
static QEvt const *tableQueueSto[N_PHILO];
static uint64_t tableStackSto[64];
static QEvt const *philoQueueSto[N_PHILO][N_PHILO];
static uint64_t philoStackSto[N_PHILO][64];
static QSubscrList subscrSto[MAX_PUB_SIG];
static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */
/* stack for the "naked" test thread */
static void const *testQueueSto[5];
static uint64_t testStackSto[64];
/* stack for the QXK's idle thread */
static uint64_t idleStackSto[32];
/* stack for the extended test threads */
static void const *test1QueueSto[5];
static uint64_t test1StackSto[64];
static void const *test2QueueSto[5];
static uint64_t test2StackSto[64];
uint8_t n;
Philo_ctor(); /* instantiate all Philosopher active objects */
Table_ctor(); /* instantiate the Table active object */
Test_ctor(); /* instantiate the Test "naked" thread */
Test1_ctor(); /* instantiate the Test1 extended thread */
Test2_ctor(); /* instantiate the Test2 extended thread */
QF_init(); /* initialize the framework */
QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the Board Support Package */
/* object dictionaries... */
@ -70,40 +67,48 @@ int main() {
QS_OBJ_DICTIONARY(philoQueueSto[3]);
QS_OBJ_DICTIONARY(philoQueueSto[4]);
/* initialize QXK... */
QXK_init(idleStackSto, sizeof(idleStackSto));
/* initialize publish-subscribe... */
QF_psInit(subscrSto, Q_DIM(subscrSto));
/* initialize event pools... */
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
/* start the extended thread */
//#if 0
QXTHREAD_START(&XT_Test1->super, /* Thread to start */
(uint_fast8_t)1U, /* QP priority of the thread */
test1QueueSto, /* message queue storage */
Q_DIM(test1QueueSto), /* message length [events] */
test1StackSto, /* stack storage */
sizeof(test1StackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
//#endif
/* start the active objects... */
for (n = 0U; n < N_PHILO; ++n) {
QACTIVE_START(AO_Philo[n], /* AO to start */
(uint_fast8_t)(n + 1), /* QP priority of the AO */
philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */
philoStackSto[n], /* stack storage */
sizeof(philoStackSto[n]), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
(uint_fast8_t)(n + 2), /* QP priority of the AO */
philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */
(void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */
}
//#if 0
QXTHREAD_START(&XT_Test2->super, /* Thread to start */
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the thread */
test2QueueSto, /* message queue storage */
Q_DIM(test2QueueSto), /* message length [events] */
test2StackSto, /* stack storage */
sizeof(test2StackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
//#endif
QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */
(uint_fast8_t)(N_PHILO + 3), /* QP priority of the AO */
tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */
tableStackSto, /* stack storage */
sizeof(tableStackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
/* start the "naked" thread */
QXTHREAD_START(&XT_Test->super, /* Thread to start */
(uint_fast8_t)10U, /* QP priority of the thread */
testQueueSto, /* message queue storage */
Q_DIM(testQueueSto), /* message length [events] */
testStackSto, /* stack storage */
sizeof(testStackSto), /* stack size [bytes] */
(void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */
return QF_run(); /* run the QF application */

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: DPP example
* Last Updated for Version: 5.6.2
* Date of the Last Update: 2016-03-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-20
*
* Q u a n t u m L e a P s
* ---------------------------
@ -36,35 +36,80 @@
#include "bsp.h"
/* local "naked" thread object .............................................*/
static QXThread l_test;
static QXThread l_test1;
static QXThread l_test2;
static QXMutex l_mutex;
static QXSemaphore l_sema;
/* global pointer to the test thread .......................................*/
QXThread * const XT_Test = &l_test;
QXThread * const XT_Test1 = &l_test1;
QXThread * const XT_Test2 = &l_test2;
/*..........................................................................*/
static void thread_function(void *par) {
static void Thread1_run(QXThread * const me) {
QXMutex_init(&l_mutex, 3U);
(void)par;
(void)me;
for (;;) {
float volatile x;
(void)QXThread_queueGet(BSP_TICKS_PER_SEC*2U, 0U); /* block */
QXMutex_lock(&l_mutex);
/* wait on a semaphore (BLOCK) */
QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT, 0U);
BSP_ledOn();
/* NOTE: can't block while holding a mutex... */
/* some flating point code to exercise the VFP... */
QXMutex_lock(&l_mutex);
x = 1.4142135F;
x = x * 1.4142135F;
QXMutex_unlock(&l_mutex);
QXThread_delay(BSP_TICKS_PER_SEC/4U, 0U); /* block */
BSP_ledOff();
QXThread_delay(BSP_TICKS_PER_SEC/8U, 0U); /* BLOCK */
QXThread_delay(BSP_TICKS_PER_SEC*3U/4U, 0U);
/* publish to thread2 */
QF_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1);
}
}
/*..........................................................................*/
void Test_ctor(void) {
QXThread_ctor(&l_test, &thread_function, 0U);
void Test1_ctor(void) {
QXThread_ctor(&l_test1, Q_XTHREAD_CAST(&Thread1_run), 0U);
}
/*..........................................................................*/
static void Thread2_run(QXThread * const me) {
/* subscribe to the test signal */
QActive_subscribe(&me->super, TEST_SIG);
/* initialize the semaphore before using it
* NOTE: the semaphore is initialized in the highest-priority thread
* that uses it. Alternatively, the semaphore can be initialized
* before any thread runs.
*/
QXSemaphore_init(&l_sema, 0U); /* start with zero count */
for (;;) {
QEvt const *e;
float volatile x;
/* signal thread1... */
QXSemaphore_signal(&l_sema);
/* some flating point code to exercise the VFP... */
x = 1.4142135F;
x = x * 1.4142135F;
/* wait on the internal event queue (BLOCK) */
e = QXThread_queueGet(QXTHREAD_NO_TIMEOUT, 0U);
BSP_ledOff();
QF_gc(e); /* recycle the event manually! */
QXThread_delay(BSP_TICKS_PER_SEC, 0U); /* BLOCK */
}
}
/*..........................................................................*/
void Test2_ctor(void) {
QXThread_ctor(&l_test2, Q_XTHREAD_CAST(&Thread2_run), 0U);
}

View File

@ -83,7 +83,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="QP/qk.c|QP/qk_mutex.c|ek-tm4c123gxl/iar/startup_TM4C123GH6PM.s|ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c|ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s|QP/qv.c|QP/qs.c|QP/qs_rx.c|QP/qs_fp.c|QP/qs_64bit.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry excluding="QP/qk_mutex.c|QP/qk.c|ek-tm4c123gxl/iar/startup_TM4C123GH6PM.s|ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c|ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s|QP/qv.c|QP/qs.c|QP/qs_rx.c|QP/qs_fp.c|QP/qs_64bit.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>

View File

@ -115,14 +115,14 @@ static QState Table_initial(Table * const me, QEvt const * const e) {
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
QActive_subscribe(&me->super, DONE_SIG);
QActive_subscribe(&me->super, PAUSE_SIG);
QActive_subscribe(&me->super, SERVE_SIG);
QActive_subscribe(&me->super, TERMINATE_SIG);
QActive_subscribe(&me->super, TEST_SIG);
for (n = 0U; n < N_PHILO; ++n) {
me->fork[n] = FREE;
@ -136,9 +136,8 @@ static QState Table_initial(Table * const me, QEvt const * const e) {
static QState Table_active(Table * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${AOs::Table::SM::active::TERMINATE} */
case TERMINATE_SIG: {
BSP_terminate(0);
/* ${AOs::Table::SM::active::TEST} */
case TEST_SIG: {
status_ = QM_HANDLED();
break;
}

View File

@ -23,7 +23,7 @@ enum DPPSignals {
DONE_SIG, /* published by Philosopher when done eating */
PAUSE_SIG, /* published by BSP to pause serving forks */
SERVE_SIG, /* published by BSP to serve re-start serving forks */
TERMINATE_SIG, /* published by BSP to terminate the application */
TEST_SIG, /* published by BSP to test the application */
MAX_PUB_SIG, /* the last published signal */
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
@ -57,8 +57,10 @@ extern QMActive * const AO_Table;
#ifdef qxk_h
void Test_ctor(void);
extern QXThread * const XT_Test;
void Test1_ctor(void);
extern QXThread * const XT_Test1;
void Test2_ctor(void);
extern QXThread * const XT_Test2;
#endif /* qxk_h */
#endif /* dpp_h */

View File

@ -38,7 +38,8 @@ if (registered == (uint8_t)0) {
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
QActive_subscribe(&amp;me-&gt;super, EAT_SIG);</action>
QActive_subscribe(&amp;me-&gt;super, EAT_SIG);
QActive_subscribe(&amp;me-&gt;super, TEST_SIG);</action>
<initial_glyph conn="2,3,5,1,20,5,-3">
<action box="0,-2,6,2"/>
</initial_glyph>
@ -57,6 +58,11 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<tran trig="TEST">
<tran_glyph conn="2,20,3,-1,13">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<state_glyph node="2,5,17,16">
<entry box="1,2,5,2"/>
</state_glyph>
@ -131,14 +137,14 @@ QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
QActive_subscribe(&amp;me-&gt;super, DONE_SIG);
QActive_subscribe(&amp;me-&gt;super, PAUSE_SIG);
QActive_subscribe(&amp;me-&gt;super, SERVE_SIG);
QActive_subscribe(&amp;me-&gt;super, TERMINATE_SIG);
QActive_subscribe(&amp;me-&gt;super, TEST_SIG);
for (n = 0U; n &lt; N_PHILO; ++n) {
me-&gt;fork[n] = FREE;
@ -150,8 +156,7 @@ for (n = 0U; n &lt; N_PHILO; ++n) {
</initial_glyph>
</initial>
<state name="active">
<tran trig="TERMINATE">
<action>BSP_terminate(0);</action>
<tran trig="TEST">
<tran_glyph conn="2,11,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
@ -348,7 +353,7 @@ enum DPPSignals {
DONE_SIG, /* published by Philosopher when done eating */
PAUSE_SIG, /* published by BSP to pause serving forks */
SERVE_SIG, /* published by BSP to serve re-start serving forks */
TERMINATE_SIG, /* published by BSP to terminate the application */
TEST_SIG, /* published by BSP to test the application */
MAX_PUB_SIG, /* the last published signal */
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
@ -368,8 +373,10 @@ $declare(AOs::Table_ctor)
$declare(AOs::AO_Table)
#ifdef qxk_h
void Test_ctor(void);
extern QXThread * const XT_Test;
void Test1_ctor(void);
extern QXThread * const XT_Test1;
void Test2_ctor(void);
extern QXThread * const XT_Test2;
#endif /* qxk_h */
#endif /* dpp_h */</text>

View File

@ -133,6 +133,7 @@ static QState Philo_initial(Philo * const me, QEvt const * const e) {
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
QActive_subscribe(&me->super, EAT_SIG);
QActive_subscribe(&me->super, TEST_SIG);
return QM_TRAN_INIT(&tatbl_);
}
/*${AOs::Philo::SM::thinking} ..............................................*/
@ -168,11 +169,17 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) {
status_ = QM_HANDLED();
break;
}
/* ${AOs::Philo::SM::thinking::TEST} */
case TEST_SIG: {
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
(void)me; /* avoid compiler warning in case 'me' is not used */
return status_;
}
/*${AOs::Philo::SM::hungry} ................................................*/

View File

@ -661,7 +661,7 @@
<TargetCommonOption>
<Device>STM32L053R8</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32L0xx_DFP.1.3.0</PackID>
<PackID>Keil.STM32L0xx_DFP.1.6.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x08000000,0x10000) IRAM(0x20000000,0x2000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -1307,7 +1307,7 @@
<TargetCommonOption>
<Device>STM32L053R8</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32L0xx_DFP.1.3.0</PackID>
<PackID>Keil.STM32L0xx_DFP.1.6.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x08000000,0x10000) IRAM(0x20000000,0x2000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>

View File

@ -82,17 +82,17 @@
<Book>
<Number>0</Number>
<Title>User Manual (STM32L053-Discovery)</Title>
<Path>C:\tools\Keil_v5\ARM\PACK\Keil\STM32L0xx_DFP\1.3.0\Boards\ST\STM32L053-Discovery\Documents\DM00118944.pdf</Path>
<Path>C:\tools\Keil_v5\ARM\PACK\Keil\STM32L0xx_DFP\1.6.0\Boards\ST\STM32L053-Discovery\Documents\DM00118944.pdf</Path>
</Book>
<Book>
<Number>1</Number>
<Title>Data Brief (STM32L053-Discovery)</Title>
<Path>C:\tools\Keil_v5\ARM\PACK\Keil\STM32L0xx_DFP\1.3.0\Boards\ST\STM32L053-Discovery\Documents\DM00122138.pdf</Path>
<Path>C:\tools\Keil_v5\ARM\PACK\Keil\STM32L0xx_DFP\1.6.0\Boards\ST\STM32L053-Discovery\Documents\DM00122138.pdf</Path>
</Book>
<Book>
<Number>2</Number>
<Title>Schematics (STM32L053-Discovery)</Title>
<Path>C:\tools\Keil_v5\ARM\PACK\Keil\STM32L0xx_DFP\1.3.0\Boards\ST\STM32L053-Discovery\Documents\MB1143.pdf</Path>
<Path>C:\tools\Keil_v5\ARM\PACK\Keil\STM32L0xx_DFP\1.6.0\Boards\ST\STM32L053-Discovery\Documents\MB1143.pdf</Path>
</Book>
<Book>
<Number>3</Number>
@ -122,7 +122,7 @@
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<nTsel>11</nTsel>
<nTsel>5</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -221,6 +221,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -424,6 +427,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -627,6 +633,9 @@
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
</TargetOption>
</Target>
@ -641,7 +650,6 @@
<FileNumber>1</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\bsp.c</PathWithFileName>
@ -654,7 +662,6 @@
<FileNumber>2</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\bsp.h</PathWithFileName>
@ -667,7 +674,6 @@
<FileNumber>3</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\dpp.h</PathWithFileName>
@ -680,7 +686,6 @@
<FileNumber>4</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\philo.c</PathWithFileName>
@ -693,7 +698,6 @@
<FileNumber>5</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\table.c</PathWithFileName>
@ -706,7 +710,6 @@
<FileNumber>6</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\include\qstamp.c</PathWithFileName>
@ -719,7 +722,6 @@
<FileNumber>7</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\main.c</PathWithFileName>
@ -732,7 +734,6 @@
<FileNumber>8</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\test.c</PathWithFileName>
@ -753,7 +754,6 @@
<FileNumber>9</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h</PathWithFileName>
@ -766,7 +766,6 @@
<FileNumber>10</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h</PathWithFileName>
@ -779,7 +778,6 @@
<FileNumber>11</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c</PathWithFileName>
@ -792,7 +790,6 @@
<FileNumber>12</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.h</PathWithFileName>
@ -805,7 +802,6 @@
<FileNumber>13</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s</PathWithFileName>
@ -826,7 +822,6 @@
<FileNumber>14</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qep_hsm.c</PathWithFileName>
@ -839,7 +834,6 @@
<FileNumber>15</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qep_msm.c</PathWithFileName>
@ -852,7 +846,6 @@
<FileNumber>16</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_act.c</PathWithFileName>
@ -865,7 +858,6 @@
<FileNumber>17</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_actq.c</PathWithFileName>
@ -878,7 +870,6 @@
<FileNumber>18</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_defer.c</PathWithFileName>
@ -891,7 +882,6 @@
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_dyn.c</PathWithFileName>
@ -904,7 +894,6 @@
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_mem.c</PathWithFileName>
@ -917,7 +906,6 @@
<FileNumber>21</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_pkg.h</PathWithFileName>
@ -930,7 +918,6 @@
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_ps.c</PathWithFileName>
@ -943,7 +930,6 @@
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qact.c</PathWithFileName>
@ -956,7 +942,6 @@
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qeq.c</PathWithFileName>
@ -969,7 +954,6 @@
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_qmact.c</PathWithFileName>
@ -982,7 +966,6 @@
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qf_time.c</PathWithFileName>
@ -995,7 +978,6 @@
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk.c</PathWithFileName>
@ -1008,7 +990,6 @@
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk_mutex.c</PathWithFileName>
@ -1021,7 +1002,6 @@
<FileNumber>29</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk_pkg.h</PathWithFileName>
@ -1034,7 +1014,6 @@
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk_sema.c</PathWithFileName>
@ -1047,7 +1026,6 @@
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qxk_xthr.c</PathWithFileName>
@ -1068,7 +1046,6 @@
<FileNumber>32</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qxk\arm\qep_port.h</PathWithFileName>
@ -1081,7 +1058,6 @@
<FileNumber>33</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qxk\arm\qf_port.h</PathWithFileName>
@ -1094,7 +1070,6 @@
<FileNumber>34</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qxk\arm\qxk_port.h</PathWithFileName>
@ -1107,7 +1082,6 @@
<FileNumber>35</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qxk\arm\qxk_port.s</PathWithFileName>
@ -1120,7 +1094,6 @@
<FileNumber>36</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qxk\arm\qs_port.h</PathWithFileName>
@ -1141,7 +1114,6 @@
<FileNumber>37</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs.c</PathWithFileName>
@ -1154,7 +1126,6 @@
<FileNumber>38</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_64bit.c</PathWithFileName>
@ -1167,7 +1138,6 @@
<FileNumber>39</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_fp.c</PathWithFileName>
@ -1180,7 +1150,6 @@
<FileNumber>40</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\source\qs_pkg.h</PathWithFileName>

View File

@ -10,12 +10,12 @@
<TargetName>dpp-dbg</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060020::V5.06 (build 20)::ARMCC</pCCUsed>
<pCCUsed>5060183::V5.06 update 2 (build 183)::ARMCC</pCCUsed>
<TargetOption>
<TargetCommonOption>
<Device>STM32L053R8</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32L0xx_DFP.1.3.0</PackID>
<PackID>Keil.STM32L0xx_DFP.1.6.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x08000000,0x10000) IRAM(0x20000000,0x2000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -125,47 +125,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>11</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>STLink\ST-LINKIII-KEIL_SWO.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -369,6 +328,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
@ -653,6 +614,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
@ -713,7 +676,7 @@
<TargetCommonOption>
<Device>STM32L053R8</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32L0xx_DFP.1.3.0</PackID>
<PackID>Keil.STM32L0xx_DFP.1.6.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x08000000,0x10000) IRAM(0x20000000,0x2000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -823,47 +786,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>11</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>STLink\ST-LINKIII-KEIL_SWO.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -1067,6 +989,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>NDEBUG</Define>
@ -1351,6 +1275,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
@ -1411,7 +1337,7 @@
<TargetCommonOption>
<Device>STM32L053R8</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32L0xx_DFP.1.3.0</PackID>
<PackID>Keil.STM32L0xx_DFP.1.6.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IROM(0x08000000,0x10000) IRAM(0x20000000,0x2000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@ -1521,47 +1447,6 @@
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
<UseSimulator>0</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
<RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
<UseTarget>1</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
<RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
<TargetSelection>11</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
</SimDlls>
<TargetDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<PeripheralDll></PeripheralDll>
<PeripheralDllArguments></PeripheralDllArguments>
<InitializationFile></InitializationFile>
<Driver>STLink\ST-LINKIII-KEIL_SWO.dll</Driver>
</TargetDlls>
</DebugOption>
<Utilities>
<Flash1>
@ -1765,6 +1650,8 @@
<v6LangP>0</v6LangP>
<vShortEn>0</vShortEn>
<vShortWch>0</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<VariousControls>
<MiscControls></MiscControls>
<Define>Q_SPY</Define>

View File

@ -183,7 +183,7 @@ void BSP_displayPaused(uint8_t paused) {
else {
//GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */
}
QXTHREAD_POST_X(XT_Test, &pauseEvt, 1U, (void *)0);
//QXTHREAD_POST_X(XT_Test, &pauseEvt, 1U, (void *)0);
//QXThread_unblock(XT_Test); /*??? unblock the Test thread */
}
/*..........................................................................*/
@ -211,11 +211,11 @@ void BSP_wait4SW1(void) {
}
/*..........................................................................*/
void BSP_ledOn(void) {
GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */
//GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */
}
/*..........................................................................*/
void BSP_ledOff(void) {
GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */
//GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */
}
/* QF callbacks ============================================================*/

View File

@ -1,13 +1,13 @@
/*****************************************************************************
* Product: DPP example for QXK
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-09
* Product: DPP example extened for QXK
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-07
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) Quantum Leaps, LLC. All rights reserved.
* Copyright (C) Quantum Leaps, LLC. state-machine.com.
*
* 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
@ -28,8 +28,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact information:
* http://www.state-machine.com
* mailto:info@state-machine.com
* Web : http://www.state-machine.com
* Email: info@state-machine.com
*****************************************************************************/
#include "qpc.h"
#include "dpp.h"
@ -38,27 +38,24 @@
/*..........................................................................*/
int main() {
static QEvt const *tableQueueSto[N_PHILO];
static uint64_t tableStackSto[32];
static QEvt const *philoQueueSto[N_PHILO][N_PHILO];
static uint64_t philoStackSto[N_PHILO][32];
static QSubscrList subscrSto[MAX_PUB_SIG];
static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */
/* stack for the "naked" test thread */
static void const *testQueueSto[5];
static uint64_t testStackSto[32];
/* stack for the QXK's idle thread */
static uint64_t idleStackSto[16];
/* stack for the extended test threads */
static void const *test1QueueSto[5];
static uint64_t test1StackSto[64];
static void const *test2QueueSto[5];
static uint64_t test2StackSto[64];
uint8_t n;
Philo_ctor(); /* instantiate all Philosopher active objects */
Table_ctor(); /* instantiate the Table active object */
Test_ctor(); /* instantiate the Test "naked" thread */
Test1_ctor(); /* instantiate the Test1 extended thread */
Test2_ctor(); /* instantiate the Test2 extended thread */
QF_init(); /* initialize the framework */
QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the Board Support Package */
/* object dictionaries... */
@ -70,41 +67,48 @@ int main() {
QS_OBJ_DICTIONARY(philoQueueSto[3]);
QS_OBJ_DICTIONARY(philoQueueSto[4]);
/* initialize QXK... */
QXK_init(idleStackSto, sizeof(idleStackSto));
/* initialize publish-subscribe... */
QF_psInit(subscrSto, Q_DIM(subscrSto));
/* initialize event pools... */
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
/* start the extended thread */
//#if 0
QXTHREAD_START(&XT_Test1->super, /* Thread to start */
(uint_fast8_t)1U, /* QP priority of the thread */
test1QueueSto, /* message queue storage */
Q_DIM(test1QueueSto), /* message length [events] */
test1StackSto, /* stack storage */
sizeof(test1StackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
//#endif
/* start the active objects... */
for (n = 0U; n < N_PHILO; ++n) {
QACTIVE_START(AO_Philo[n], /* AO to start */
(uint_fast8_t)(n + 1), /* QP priority of the AO */
philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */
philoStackSto[n], /* stack storage */
sizeof(philoStackSto[n]), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
(uint_fast8_t)(n + 2), /* QP priority of the AO */
philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */
(void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */
}
//#if 0
QXTHREAD_START(&XT_Test2->super, /* Thread to start */
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the thread */
test2QueueSto, /* message queue storage */
Q_DIM(test2QueueSto), /* message length [events] */
test2StackSto, /* stack storage */
sizeof(test2StackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
//#endif
QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */
(uint_fast8_t)(N_PHILO + 3), /* QP priority of the AO */
tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */
tableStackSto, /* stack storage */
sizeof(tableStackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
/* start the "naked" thread */
QXTHREAD_START(&XT_Test->super, /* Thread to start */
(uint_fast8_t)7U, /* QP priority of the thread */
testQueueSto, /* message queue storage */
Q_DIM(testQueueSto), /* message length [events] */
testStackSto, /* stack storage */
sizeof(testStackSto), /* stack size [bytes] */
(void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */
return QF_run(); /* run the QF application */

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: DPP example
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-11-24
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-20
*
* Q u a n t u m L e a P s
* ---------------------------
@ -36,34 +36,80 @@
#include "bsp.h"
/* local "naked" thread object .............................................*/
static QXThread l_test;
static QXMutex l_mux;
static QXThread l_test1;
static QXThread l_test2;
static QXMutex l_mutex;
static QXSemaphore l_sema;
/* global pointer to the test thread .......................................*/
QXThread * const XT_Test = &l_test;
QXThread * const XT_Test1 = &l_test1;
QXThread * const XT_Test2 = &l_test2;
/*..........................................................................*/
static void thread_function(void *par) {
(void)par;
static void Thread1_run(QXThread * const me) {
QXMutex_init(&l_mux, 8U);
QXMutex_init(&l_mutex, 3U);
(void)me;
for (;;) {
float volatile x;
(void)QXThread_queueGet(BSP_TICKS_PER_SEC*2U, 0U);
QXMutex_lock(&l_mux);
/* wait on a semaphore (BLOCK) */
QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT, 0U);
BSP_ledOn();
QXMutex_unlock(&l_mux);
QXThread_delay(BSP_TICKS_PER_SEC/4U, 0U);
BSP_ledOff();
QXThread_delay(BSP_TICKS_PER_SEC*3U/4U, 0U);
/* some flating point code to exercise the VFP... */
QXMutex_lock(&l_mutex);
x = 1.4142135F;
x = x * 1.4142135F;
QXMutex_unlock(&l_mutex);
QXThread_delay(BSP_TICKS_PER_SEC/8U, 0U); /* BLOCK */
/* publish to thread2 */
QF_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1);
}
}
/*..........................................................................*/
void Test_ctor(void) {
QXThread_ctor(&l_test, &thread_function, 0U);
void Test1_ctor(void) {
QXThread_ctor(&l_test1, Q_XTHREAD_CAST(&Thread1_run), 0U);
}
/*..........................................................................*/
static void Thread2_run(QXThread * const me) {
/* subscribe to the test signal */
QActive_subscribe(&me->super, TEST_SIG);
/* initialize the semaphore before using it
* NOTE: the semaphore is initialized in the highest-priority thread
* that uses it. Alternatively, the semaphore can be initialized
* before any thread runs.
*/
QXSemaphore_init(&l_sema, 0U); /* start with zero count */
for (;;) {
QEvt const *e;
float volatile x;
/* signal thread1... */
QXSemaphore_signal(&l_sema);
/* some flating point code to exercise the VFP... */
x = 1.4142135F;
x = x * 1.4142135F;
/* wait on the internal event queue (BLOCK) */
e = QXThread_queueGet(QXTHREAD_NO_TIMEOUT, 0U);
BSP_ledOff();
QF_gc(e); /* recycle the event manually! */
QXThread_delay(BSP_TICKS_PER_SEC, 0U); /* BLOCK */
}
}
/*..........................................................................*/
void Test2_ctor(void) {
QXThread_ctor(&l_test2, Q_XTHREAD_CAST(&Thread2_run), 0U);
}

View File

@ -115,14 +115,14 @@ static QState Table_initial(Table * const me, QEvt const * const e) {
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
QActive_subscribe(&me->super, DONE_SIG);
QActive_subscribe(&me->super, PAUSE_SIG);
QActive_subscribe(&me->super, SERVE_SIG);
QActive_subscribe(&me->super, TERMINATE_SIG);
QActive_subscribe(&me->super, TEST_SIG);
for (n = 0U; n < N_PHILO; ++n) {
me->fork[n] = FREE;
@ -136,9 +136,8 @@ static QState Table_initial(Table * const me, QEvt const * const e) {
static QState Table_active(Table * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${AOs::Table::SM::active::TERMINATE} */
case TERMINATE_SIG: {
BSP_terminate(0);
/* ${AOs::Table::SM::active::TEST} */
case TEST_SIG: {
status_ = QM_HANDLED();
break;
}

View File

@ -82,7 +82,12 @@
<toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.DebugToolchain.363367738" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.DebugToolchain" unusedChildren="">
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1682510837.318787666" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1682510837"/>
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1564803014.380196186" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1564803014"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerDebug.1108121072" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerDebug.1003408666"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerDebug.1108121072" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.compilerDebug.1003408666">
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS.1114653967" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS.1362797755" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS.1230381801" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS.874113384" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.compiler.inputType__ASM2_SRCS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.linkerDebug.774697730" name="ARM Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.exe.linkerDebug.1462830843"/>
<tool id="com.ti.ccstudio.buildDefinitions.TMS470_15.12.hex.967376319" name="ARM Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.TMS470_15.12.hex.846218579"/>
</toolChain>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="Texas Instruments XDS110 USB Debug Probe" href="connections/TIXDS110_Connection.xml" id="Texas Instruments XDS110 USB Debug Probe" xml="TIXDS110_Connection.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="Texas Instruments XDS110 USB Debug Probe">
<instance XML_version="1.2" href="drivers/tixds510icepick_c.xml" id="drivers" xml="tixds510icepick_c.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds510cs_dap.xml" id="drivers" xml="tixds510cs_dap.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds510cortexR.xml" id="drivers" xml="tixds510cortexR.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="TMS570LS1224" href="devices/tms570ls1224.xml" id="TMS570LS1224" xml="tms570ls1224.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="Texas Instruments XDS110 USB Debug Probe" href="connections/TIXDS110_Connection.xml" id="Texas Instruments XDS110 USB Debug Probe" xml="TIXDS110_Connection.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="Texas Instruments XDS110 USB Debug Probe">
<instance XML_version="1.2" href="drivers/tixds510icepick_c.xml" id="drivers" xml="tixds510icepick_c.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds510cs_dap.xml" id="drivers" xml="tixds510cs_dap.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds510cortexR.xml" id="drivers" xml="tixds510cortexR.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="TMS570LS1224" href="devices/tms570ls1224.xml" id="TMS570LS1224" xml="tms570ls1224.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -128,10 +128,10 @@ QK_IRQ_END()
/*..........................................................................*/
#ifdef Q_SPY
/*
* ISR for receiving bytes from the QSPY Back-End
* NOTE: This ISR is "QP-unaware" meaning that it does not interact with
* the QP and is not disabled. Such ISRs don't need to be defined with
* QK_IRQ_BEGIN()/QK_IRQ_END().
* ISR for receiving bytes from the QSPY Back-End
* NOTE: This ISR is "QP-unaware" meaning that it does not interact with
* the QP and is not disabled. Such ISRs don't need to be defined with
* QK_IRQ_BEGIN()/QK_IRQ_END().
*/
#if defined __IAR_SYSTEMS_ICC__
FIQ

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="Texas Instruments XDS110 USB Debug Probe" href="connections/TIXDS110_Connection.xml" id="Texas Instruments XDS110 USB Debug Probe" xml="TIXDS110_Connection.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="Texas Instruments XDS110 USB Debug Probe">
<instance XML_version="1.2" href="drivers/tixds510icepick_c.xml" id="drivers" xml="tixds510icepick_c.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds510cs_dap.xml" id="drivers" xml="tixds510cs_dap.xml" xmlpath="drivers"/>
<instance XML_version="1.2" href="drivers/tixds510cortexR.xml" id="drivers" xml="tixds510cortexR.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="TMS570LS1224" href="devices/tms570ls1224.xml" id="TMS570LS1224" xml="tms570ls1224.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -171,7 +171,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="QP/qk.c|QP/qxk.c|QP/qxk_xthr.c|QP/qxk_sema.c|QP/qxk_mutex.c|QP/qs.c|QP/qs_rx.c|QP/qs_fp.c|QP/qs_64bit.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry excluding="QP/qk_mutex.c|QP/qk.c|QP/qxk.c|QP/qxk_xthr.c|QP/qxk_sema.c|QP/qxk_mutex.c|QP/qs.c|QP/qs_rx.c|QP/qs_fp.c|QP/qs_64bit.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="TI MSP430 USB1" href="connections/TIMSP430-USB.xml" id="TI MSP430 USB1" xml="TIMSP430-USB.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="TI MSP430 USB1">
<instance XML_version="1.2" href="drivers/msp430_emu.xml" id="drivers" xml="msp430_emu.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="MSP430F5529" href="devices/MSP430F5529.xml" id="MSP430F5529" xml="MSP430F5529.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="TI MSP430 USB1" href="connections/TIMSP430-USB.xml" id="TI MSP430 USB1" xml="TIMSP430-USB.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="TI MSP430 USB1">
<instance XML_version="1.2" href="drivers/msp430_emu.xml" id="drivers" xml="msp430_emu.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="MSP430F5529" href="devices/MSP430F5529.xml" id="MSP430F5529" xml="MSP430F5529.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="TI MSP430 USB1" href="connections/TIMSP430-USB.xml" id="TI MSP430 USB1" xml="TIMSP430-USB.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="TI MSP430 USB1">
<instance XML_version="1.2" href="drivers/msp430_emu.xml" id="drivers" xml="msp430_emu.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="MSP430G2553" href="devices/MSP430G2553.xml" id="MSP430G2553" xml="MSP430G2553.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -1101,7 +1101,11 @@
<debug>1</debug>
<option>
<name>CUTest</name>
<state>###Uninitialized###</state>
<state>-I$TOOLKIT_DIR$\inc</state>
<state>-@$TOOLKIT_DIR$\bin\iar.cmd</state>
<state>-@$PROJ_DIR$\source.txt</state>
<state>-@$PROJ_DIR$\include.txt</state>
<state>--preinclude=$PROJ_DIR$\IAR_ULPAdvisor_Defs.h</state>
</option>
<option>
<name>ULPRules</name>
@ -1114,7 +1118,7 @@
</option>
<option>
<name>OutputFile</name>
<state></state>
<state>$PROJ_FNAME$.ulp</state>
</option>
<option>
<name>ULPStatus</name>
@ -1553,7 +1557,7 @@
<option>
<name>CCOptStrategy</name>
<version>0</version>
<state>1</state>
<state>2</state>
</option>
<option>
<name>CCOptLevelSlave</name>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="TI MSP430 USB1" href="connections/TIMSP430-USB.xml" id="TI MSP430 USB1" xml="TIMSP430-USB.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="TI MSP430 USB1">
<instance XML_version="1.2" href="drivers/msp430_emu.xml" id="drivers" xml="msp430_emu.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="MSP430G2553" href="devices/MSP430G2553.xml" id="MSP430G2553" xml="MSP430G2553.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configurations XML_version="1.2" id="configurations_0">
<configuration XML_version="1.2" id="configuration_0">
<instance XML_version="1.2" desc="TI MSP430 USB1" href="connections/TIMSP430-USB.xml" id="TI MSP430 USB1" xml="TIMSP430-USB.xml" xmlpath="connections"/>
<connection XML_version="1.2" id="TI MSP430 USB1">
<instance XML_version="1.2" href="drivers/msp430_emu.xml" id="drivers" xml="msp430_emu.xml" xmlpath="drivers"/>
<platform XML_version="1.2" id="platform_0">
<instance XML_version="1.2" desc="MSP430G2553" href="devices/MSP430G2553.xml" id="MSP430G2553" xml="MSP430G2553.xml" xmlpath="devices"/>
</platform>
</connection>
</configuration>
</configurations>

View File

@ -0,0 +1,9 @@
The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based
on the device and connection settings specified in your project on the Properties > General page.
Please note that in automatic target-configuration management, changes to the project's device and/or
connection settings will either modify an existing or generate a new target-configuration file. Thus,
if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively,
you may create your own target-configuration file for this project and manage it manually. You can
always switch back to automatic target-configuration management by checking the "Manage the project's
target-configuration automatically" checkbox on the project's Properties > General page.

View File

@ -87,7 +87,12 @@
<toolChain id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.DebugToolchain.292510104" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.DebugToolchain" unusedChildren="">
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1571354006.643112801" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1571354006"/>
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1554216566.1063199799" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1554216566"/>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.compilerDebug.1829799444" name="MSP430 Compiler" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.compilerDebug.1435444484"/>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.compilerDebug.1829799444" name="MSP430 Compiler" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.compilerDebug.1435444484">
<inputType id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__C_SRCS.1115602689" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__C_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__CPP_SRCS.1485535414" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__CPP_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__ASM_SRCS.1028195772" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__ASM_SRCS"/>
<inputType id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__ASM2_SRCS.235662519" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.compiler.inputType__ASM2_SRCS"/>
</tool>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.linkerDebug.1241155951" name="MSP430 Linker" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.exe.linkerDebug.1604557830"/>
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_15.12.hex.1895305275" name="MSP430 Hex Utility" superClass="com.ti.ccstudio.buildDefinitions.MSP430_15.12.hex.1117907512"/>
</toolChain>

View File

@ -4,8 +4,8 @@
* @ingroup qep
* @cond
******************************************************************************
* Last updated for version 5.7.0
* Last updated on 2016-08-09
* Last updated for version 5.7.1
* Last updated on 2016-09-18
*
* 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 570
#define QP_VERSION 571
/*! 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.7.0"
#define QP_VERSION_STR "5.7.1"
/*! Tamperproof current QP release (5.7.0) and date (16-08-31) */
#define QP_RELEASE 0xA02320D5U
/*! Tamperproof current QP release (5.7.1) and date (16-09-23) */
#define QP_RELEASE 0xA0151714U
/****************************************************************************/
#ifndef Q_SIGNAL_SIZE

View File

@ -4,8 +4,8 @@
* @ingroup qf
* @cond
******************************************************************************
* Last updated for version 5.6.2
* Last updated on 2016-03-29
* Last updated for version 5.7.1
* Last updated on 2016-09-17
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,7 +41,7 @@
#define qf_h
/****************************************************************************/
#if (QF_MAX_ACTIVE < 1) || (63 < QF_MAX_ACTIVE)
#if (QF_MAX_ACTIVE < 1) || (64 < QF_MAX_ACTIVE)
#error "QF_MAX_ACTIVE not defined or out of range. Valid range is 1..63"
#endif
@ -82,6 +82,10 @@
#define QF_TIMEEVT_CTR_SIZE 2
#endif
#ifndef qpset_h
#include "qpset.h"
#endif
/****************************************************************************/
struct QEQueue; /* forward declaration */
@ -491,6 +495,7 @@ bool QTimeEvt_disarm(QTimeEvt * const me);
/*! Get the current value of the down-counter of a time event. */
QTimeEvtCtr QTimeEvt_ctr(QTimeEvt const * const me);
/****************************************************************************/
/* QF facilities */
@ -503,21 +508,7 @@ QTimeEvtCtr QTimeEvt_ctr(QTimeEvt const * const me);
*
* @sa ::QSubscrList for the description of the data members
*/
typedef struct {
/*! An array of bits representing subscriber active objects. */
/**
* @description
* Each bit in the array corresponds to the unique priority of the AO.
* The size of the array is determined of the maximum number of AOs
* in the application configured by the #QF_MAX_ACTIVE macro.
* For example, an active object of priority p is a subscriber if the
* following is true: ((bits[QF_div8Lkup[p]] & QF_pwr2Lkup[p]) != 0)
*
* @sa QF_psInit(), ::QF_div8Lkup, ::QF_pwr2Lkup, #QF_MAX_ACTIVE
*/
uint8_t bits[((QF_MAX_ACTIVE - 1) / 8) + 1];
} QSubscrList;
typedef QPSet QSubscrList;
/* public functions */
@ -806,58 +797,6 @@ void QF_bzero(void * const start, uint_fast16_t len);
#define QF_CRIT_EXIT_NOP() ((void)0)
#endif
/****************************************************************************/
/* Useful lookup tables ...*/
/*! Lookup table for @c (1 << ((n-1) % 8)), where n is the index into
* the table. */
/**
* @note Index range n = 0..64. The first index (n == 0) should never be used.
*/
extern uint8_t const QF_pwr2Lkup[65];
/*! Lookup table for @c ~(1 << ((n-1) % 8)), where n is the index
* into the table. */
/**
* @note Index range n = 0..64. The first index (n == 0) should never be used.
*/
extern uint8_t const QF_invPwr2Lkup[65];
/*! Lookup table for @c (n-1)/8 , where n is the index into the table. */
/**
* @note Index range n = 0..64. The first index (n == 0) should never be used.
*/
extern uint8_t const QF_div8Lkup[65];
/* Log-base-2 calculations ...*/
#ifndef QF_LOG2
/*! Macro to return (log2(n_) + 1), where @p n_ = 0..255. */
/**
* @description
* This macro delivers the 1-based number of the most significant 1-bit
* of a byte. This macro can be re-implemented in the QP ports, if the CPU
* supports special instructions, such as CLZ (count leading zeros).
*
* If the macro is not defined in the port, the default implementation
* uses a lookup table.
*/
#define QF_LOG2(n_) (QF_log2Lkup[(n_)])
/*! Lookup table for (log2(n) + 1), where n is the index into the table */
/**
* @description
* This lookup delivers the 1-based number of the most significant 1-bit
* of a byte.
*/
extern uint8_t const QF_log2Lkup[256];
/*! Macro to include the QF_log2Lkup table in the code or skip it,
* if undefined.
*/
#define QF_LOG2LKUP 1
#endif /* QF_LOG2 */
/*! array of registered active objects */
/**
* @note Not to be used by Clients directly, only in ports of QF

View File

@ -5,8 +5,8 @@
* @ingroup qk
* @cond
******************************************************************************
* Last updated for version 5.7.0
* Last updated on 2016-08-08
* Last updated for version 5.7.1
* Last updated on 2016-09-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,9 +41,9 @@
#ifndef qk_h
#define qk_h
#include "qequeue.h" /* QK kernel uses the native QF event queue */
#include "qmpool.h" /* QK kernel uses the native QF memory pool */
#include "qpset.h" /* QK kernel uses the native QF priority set */
#include "qequeue.h" /* QK kernel uses the native QP event queue */
#include "qmpool.h" /* QK kernel uses the native QP memory pool */
#include "qpset.h" /* QK kernel uses the native QP priority set */
/****************************************************************************/
/* QF configuration for QK */
@ -61,17 +61,12 @@
typedef struct {
uint_fast8_t volatile curr; /*!< priority of the current executing AO */
uint_fast8_t volatile next; /*!< priority of the next AO to execute */
void volatile *aux; /*!< auxiliary attribute used in the port */
uint_fast8_t volatile lockPrio; /*!< lock prio (0 == no-lock) */
uint_fast8_t volatile lockHolder; /*!< prio of the lock holder */
#ifndef QK_ISR_CONTEXT_
uint_fast8_t volatile intNest; /*!< ISR nesting level */
#endif /* QK_ISR_CONTEXT_ */
#if (QF_MAX_ACTIVE <= 8)
QPSet8 readySet; /*!< QK ready-set of AOs and "naked" threads */
#else
QPSet64 readySet; /*!< QK ready-set of AOs and "naked" threads */
#endif
QPSet readySet; /*!< QK ready-set of AOs */
} QK_Attr;
/*! global attributes of the QK kernel */
@ -158,25 +153,11 @@ void QMutex_unlock(QMutex * const me);
/*! Internal port-specific macro for selective scheduler unlocking. */
#define QF_SCHED_UNLOCK_(pLockStat_) QMutex_unlock((pLockStat_))
#if (QF_MAX_ACTIVE <= 8)
#define QK_prioNotEmpty(set_) QPSet8_notEmpty((set_))
#define QK_prioIsSet(set_, p_) QPSet8_hasElement((set_), (p_))
#define QK_prioFindMax(set_, p_) QPSet8_findMax((set_), (p_))
#define QK_prioInsert(set_, p_) QPSet8_insert((set_), (p_))
#define QK_prioRemove(set_, p_) QPSet8_remove((set_), (p_))
#else
#define QK_prioNotEmpty(set_) QPSet64_notEmpty((set_))
#define QK_prioIsSet(set_, p_) QPSet64_hasElement((set_), (p_))
#define QK_prioFindMax(set_, p_) QPSet64_findMax((set_), (p_))
#define QK_prioInsert(set_, p_) QPSet64_insert((set_), (p_))
#define QK_prioRemove(set_, p_) QPSet64_remove((set_), (p_))
#endif
#define QACTIVE_EQUEUE_WAIT_(me_) \
(Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0))
#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
QK_prioInsert(&QK_attr_.readySet, (me_)->prio); \
QPSet_insert(&QK_attr_.readySet, (me_)->prio); \
if (!QK_ISR_CONTEXT_()) { \
uint_fast8_t p = QK_schedPrio_(); \
if (p != (uint_fast8_t)0) { \
@ -186,7 +167,7 @@ void QMutex_unlock(QMutex * const me);
} while (0)
#define QACTIVE_EQUEUE_ONEMPTY_(me_) \
QK_prioRemove(&QK_attr_.readySet, (me_)->prio)
QPSet_remove(&QK_attr_.readySet, (me_)->prio)
/* native QF event pool operations */
#define QF_EPOOL_TYPE_ QMPool

View File

@ -1,7 +1,7 @@
//============================================================================
// Product: PC-Lint 9.x option file for linting QP/C applications
// Last updated for version 5.6.2
// Last updated on 2016-03-23
// Last updated for version 5.7.1
// Last updated on 2016-09-21
//
// Q u a n t u m L e a P s
// ---------------------------
@ -203,21 +203,16 @@
QACTIVE_POST_X,
QACTIVE_POST_LIFO)
-estring(961, // MISRA04-19.7(adv) function-like macro
QPSet_setEmpty,
QPSet_isEmpty,
QPSet_notEmpty,
QPSet_hasElement,
QPSet_insert,
QPSet_remove,
QPSet_findMax,
QEQueue_getNFree,
QEQueue_getNMin,
QEQueue_isEmpty,
QPSet8_isEmpty,
QPSet8_notEmpty,
QPSet8_hasElement,
QPSet8_insert,
QPSet8_remove,
QPSet8_findMax,
QPSet64_isEmpty,
QPSet64_notEmpty,
QPSet64_hasElement,
QPSet64_insert,
QPSet64_remove,
QPSet64_findMax,
QTimeEvt_ctor,
QTimeEvt_postIn,
QTimeEvt_postEvery,
@ -256,7 +251,6 @@
QF_EPOOL_TYPE_,
QF_ACTIVE_SUPER_,
QF_ACTIVE_STATE_,
QPSet8_findMax,
QTimeEvt_ctor)
-emacro(929, // MISRA04-11.4(adv) cast from pointer to pointer
Q_NEW,
@ -267,9 +261,9 @@
-emacro(960, // MISRA04-17.4(req) pointer increment
QF_PTR_INC_)
-emacro(717, // do ... while(0)
QPSet64_insert,
QPSet64_remove,
QPSet64_findMax,
QPSet_setEmpty,
QPSet_insert,
QPSet_remove,
QTimeEvt_postIn,
QTimeEvt_postEvery)
-estring(960, // MISRA04-8.7(req) could use block scope
@ -314,12 +308,19 @@
QXK_ISR_EXIT,
QXK_getVersion,
QXTHREAD_START,
QXTHREAD_POST_X)
QXTHREAD_POST_X,
Q_XTHREAD_CAST)
-emacro(960, // MISRA04-11.1(req) Conversions involving
Q_XTHREAD_CAST) // fun. pointers must be to/from integral types
-emacro(929, // MISRA04-11.4(adv) cast pointer to pointer
Q_XTHREAD_CAST)
-esym(960, // MISRA04-19.4(req) Disallowed macro definition
QXTHREAD_START,
QXTHREAD_POST_X)
-estring(960, // MISRA04-8.7(req) could use block scope
QXK_intNest_)
-esym(960, // MISRA04-20.2(req) Re-use of C90 identifier pattern
topPrio)
// QS
-emacro(506, QS_*) // MISRA04-13.7(req) constant value boolean

View File

@ -1,11 +1,11 @@
/**
* @file
* @brief QP native, platform-independent priority sets of 8 or 64 elements.
* @brief QP native, platform-independent priority sets of 32 or 64 elements.
* @ingroup qf
* @cond
******************************************************************************
* Last updated for version 5.6.0
* Last updated on 2015-12-18
* Last updated for version 5.7.1
* Last updated on 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -40,128 +40,175 @@
#ifndef qpset_h
#define qpset_h
#if (QF_MAX_ACTIVE <= 32)
/****************************************************************************/
/*! Priority Set of up to 8 elements for building various schedulers */
/*! Priority Set of up to 32 elements */
/**
* The priority set represents the set of active objects that are ready to
* run and need to be considered by the scheduling algorithm. The set is
* capable of storing up to 8 priority levels.
*
* The priority set allows to build cooperative multitasking schedulers
* to manage up to 8 tasks.
* capable of storing up to 32 priority levels.
*/
typedef struct {
uint_fast8_t volatile bits; /*!< bitmask with a bit for each element */
} QPSet8;
uint32_t bits; /*!< bitmask with a bit for each element */
} QPSet;
/*! Evaluates to TRUE if the priority set @p me_ has elements */
#define QPSet8_isEmpty(me_) ((me_)->bits == (uint_fast8_t)0)
/*! Makes the priority set @p me_ empty */
#define QPSet_setEmpty(me_) ((me_)->bits = (uint32_t)0)
/*! Evaluates to TRUE if the priority set @p me_ is empty */
#define QPSet8_notEmpty(me_) ((me_)->bits != (uint_fast8_t)0)
#define QPSet_isEmpty(me_) ((me_)->bits == (uint32_t)0)
/*! Evaluates to TRUE if the priority set @p me_ is not empty */
#define QPSet_notEmpty(me_) ((me_)->bits != (uint32_t)0)
/*! Evaluates to TRUE if the priority set @p me_ has element @p n_ */
#define QPSet8_hasElement(me_, n_) \
(((me_)->bits & (uint_fast8_t)QF_pwr2Lkup[(n_)]) \
!= (uint_fast8_t)0)
#define QPSet_hasElement(me_, n_) \
(((me_)->bits & ((uint32_t)1 << ((n_) - (uint_fast8_t)1))) != (uint32_t)0)
/*! Insert element @p n_ into the set @p me_, n_= 1..8 */
#define QPSet8_insert(me_, n_) \
((me_)->bits |= (uint_fast8_t)QF_pwr2Lkup[(n_)])
/*! Insert element @p n_ into the set @p me_, n_= 1..32 */
#define QPSet_insert(me_, n_) \
((me_)->bits |= (uint32_t)((uint32_t)1 << ((n_) - (uint_fast8_t)1)))
/*! Remove element n_ from the set @p me_, n_= 1..8 */
#define QPSet8_remove(me_, n_) \
((me_)->bits &= (uint_fast8_t)QF_invPwr2Lkup[(n_)])
/*! Remove element n_ from the set @p me_, n_= 1..32 */
#define QPSet_remove(me_, n_) \
((me_)->bits &= (uint32_t)(~((uint32_t)1U << ((n_) - (uint_fast8_t)1))))
/*! Find the maximum element in the set, and assign it to n_ */
/** @note if the set @p me_ is empty, @p n_ is set to zero.
*/
#define QPSet8_findMax(me_, n_) \
((n_) = (uint_fast8_t)QF_LOG2((me_)->bits))
#define QPSet_findMax(me_, n_) \
((n_) = QF_LOG2((me_)->bits))
#else /* QF_MAX_ACTIVE > 32 */
/****************************************************************************/
/*! Priority Set of up to 64 elements for building various schedulers */
/*! Priority Set of up to 64 elements */
/**
* The priority set represents the set of active objects that are ready to
* run and need to be considered by the scheduling algorithm. The set is
* capable of storing up to 64 priority levels.
*
* The priority set allows to build cooperative multitasking schedulers
* to manage up to 64 tasks. It is also used in the Quantum Kernel (QK)
* preemptive scheduler.
*/
typedef struct {
uint32_t bits[2];
} QPSet;
/** @brief bimask representing 8-element subsets of the set
*
* Each bit in the bytes set represents a subset (8-elements)
* as follows: @n
* bit 0 in bytes is 1 when bits[0] is not empty @n
* bit 1 in bytes is 1 when bits[1] is not empty @n
* bit 2 in bytes is 1 when bits[2] is not empty @n
* bit 3 in bytes is 1 when bits[3] is not empty @n
* bit 4 in bytes is 1 when bits[4] is not empty @n
* bit 5 in bytes is 1 when bits[5] is not empty @n
* bit 6 in bytes is 1 when bits[6] is not empty @n
* bit 7 in bytes is 1 when bits[7] is not empty @n
*/
uint_fast8_t volatile bytes;
/*! Makes the priority set @p me_ empty */
#define QPSet_setEmpty(me_) do { \
(me_)->bits[0] = (uint32_t)0; \
(me_)->bits[1] = (uint32_t)0; \
} while (0)
/** @brief bits representing elements in the set as follows: @n
* bits[0] represent elements 1..8 @n
* bits[1] represent elements 9..16 @n
* bits[2] represent elements 17..24 @n
* bits[3] represent elements 25..32 @n
* bits[4] represent elements 33..40 @n
* bits[5] represent elements 41..48 @n
* bits[6] represent elements 49..56 @n
* bits[7] represent elements 57..64 @n
*/
uint_fast8_t volatile bits[8];
} QPSet64;
/*! Evaluates to TRUE if the priority set @p me_ is empty */
#define QPSet_isEmpty(me_) \
(((me_)->bits[0] == (uint32_t)0) && ((me_)->bits[1] == (uint32_t)0))
/*! Evaluates to TRUE if the priority set @p me_ has elements */
#define QPSet64_isEmpty(me_) ((me_)->bytes == (uint_fast8_t)0)
/*! Evaluates to TRUE if the priority set @p me is empty */
#define QPSet64_notEmpty(me_) ((me_)->bytes != (uint_fast8_t)0)
/*! Evaluates to TRUE if the priority set @p me_ is not empty */
#define QPSet_notEmpty(me_) \
(((me_)->bits[0] != (uint32_t)0) || ((me_)->bits[1] != (uint32_t)0))
/*! Evaluates to TRUE if the priority set @p me_ has element @p n_. */
#define QPSet64_hasElement(me_, n_) \
(((me_)->bits[QF_div8Lkup[(n_)]] \
& (uint_fast8_t)QF_pwr2Lkup[(n_)]) != (uint_fast8_t)0)
#define QPSet_hasElement(me_, n_) \
(((n_) <= (uint_fast8_t)32) \
? (((me_)->bits[0] & ((uint32_t)1 << ((n_) - (uint_fast8_t)1 ))) \
!= (uint32_t)0) \
: (((me_)->bits[1] & ((uint32_t)1 << ((n_) - (uint_fast8_t)33))) \
!= (uint32_t)0))
/*! insert element @p n_ into the set @p me_, n_= 1..64 */
#define QPSet64_insert(me_, n_) do { \
uint_fast8_t m_ = (uint_fast8_t)QF_div8Lkup[(n_)]; \
(me_)->bits[m_] |= (uint_fast8_t)QF_pwr2Lkup[(n_)]; \
(me_)->bytes |= (uint_fast8_t)QF_pwr2Lkup[m_ \
+ (uint_fast8_t)1]; \
/*! insert element @p n_ into the set @p me_, n_ = 1..64 */
#define QPSet_insert(me_, n_) do { \
if ((n_) <= (uint_fast8_t)32) { \
((me_)->bits[0] |= ((uint32_t)1 << ((n_) - (uint_fast8_t)1 ))); \
} \
else { \
((me_)->bits[1] |= ((uint32_t)1 << ((n_) - (uint_fast8_t)33))); \
} \
} while (0)
/*! Remove element n_ from the set @p me_, n_= 1..64 */
#define QPSet64_remove(me_, n_) do { \
uint_fast8_t m_ = (uint_fast8_t)QF_div8Lkup[(n_)]; \
if (((me_)->bits[m_] &= (uint_fast8_t)QF_invPwr2Lkup[(n_)]) \
== (uint_fast8_t)0) { \
(me_)->bytes &= (uint_fast8_t)QF_invPwr2Lkup[m_ + (uint_fast8_t)1]; \
#define QPSet_remove(me_, n_) do { \
if ((n_) <= (uint_fast8_t)32) { \
((me_)->bits[0] &= \
(uint32_t)(~((uint32_t)1 << ((n_) - (uint_fast8_t)1 )))); \
} \
else { \
((me_)->bits[1] &= \
(uint32_t)(~((uint32_t)1 << ((n_) - (uint_fast8_t)33)))); \
} \
} while (0)
/*! Find the maximum element in the set, and assign it to @p n_ */
/** @note if the set @p me_ is empty, @p n_ is set to zero.
*/
#define QPSet64_findMax(me_, n_) do { \
if ((me_)->bytes != (uint_fast8_t)0) { \
(n_) = (uint_fast8_t)QF_LOG2((me_)->bytes) - (uint_fast8_t)1; \
(n_) = (uint_fast8_t)QF_LOG2((me_)->bits[(n_)]) \
+ (uint_fast8_t)((n_) << 3); \
} \
else { \
(n_) = (uint_fast8_t)0; \
} \
} while (0)
#define QPSet_findMax(me_, n_) \
((n_) = ((me_)->bits[1] != (uint32_t)0) \
? (QF_LOG2((me_)->bits[1]) + (uint_fast8_t)32) \
: (QF_LOG2((me_)->bits[0])))
#endif /* QF_MAX_ACTIVE */
/****************************************************************************/
/* Log-base-2 calculations ...*/
#ifndef QF_LOG2
/*! Lookup table for (log2(n) + 1), where n = 0..255 */
/**
* @description
* This lookup delivers the 1-based number of the most significant 1-bit
* of a byte.
*/
extern uint8_t const QF_log2Lkup[256];
#if (__STDC_VERSION__ >= 199901L) /* is it C99 compiler? */
/*! function that returns (log2(x_) + 1), where @p x_ is uint32_t */
/**
* @description
* This function returns the 1-based number of the most significant 1-bit
* of a 32-bit number. This function can be replaced in the QP ports, if
* the CPU supports special instructions, such as CLZ (count leading zeros).
*/
inline uint_fast8_t QF_LOG2(uint32_t x) {
uint_fast8_t n;
uint_fast8_t i;
if ((x >> 16) != (uint32_t)0) {
if ((x >> 24) != (uint32_t)0) {
i = (uint_fast8_t)(x >> 24);
n = (uint_fast8_t)24;
}
else {
i = (uint_fast8_t)(x >> 16);
n = (uint_fast8_t)16;
}
}
else {
if ((x >> 8) != (uint32_t)0) {
i = (uint_fast8_t)(x >> 8);
n = (uint_fast8_t)8;
}
else {
i = (uint_fast8_t)(x);
n = (uint_fast8_t)0;
}
}
return (uint_fast8_t)QF_log2Lkup[i] + n;
}
#else /* older C compiler */
/*! function that returns (log2(x_) + 1), where @p x_ is uint32_t */
/**
* @description
* This function returns the 1-based number of the most significant 1-bit
* of a 32-bit number. This function can be replaced in the QP ports, if
* the CPU supports special instructions, such as CLZ (count leading zeros).
*/
uint_fast8_t QF_LOG2(uint32_t x);
#endif /* __STDC_VERSION__ */
#endif /* QF_LOG2 */
#endif /* qpset_h */

View File

@ -5,8 +5,8 @@
* @ingroup qv
* @cond
******************************************************************************
* Last updated for version 5.6.2
* Last updated on 2016-03-31
* Last updated for version 5.7.1
* Last updated on 2016-09-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,9 +41,9 @@
#ifndef qv_h
#define qv_h
#include "qequeue.h" /* QV kernel uses the native QP event queue */
#include "qmpool.h" /* QV kernel uses the native QP memory pool */
#include "qpset.h" /* QV kernel uses the native QP priority set */
#include "qequeue.h" /* QV kernel uses the native QP event queue */
#include "qmpool.h" /* QV kernel uses the native QP memory pool */
#include "qpset.h" /* QV kernel uses the native QP priority set */
/*! This macro defines the type of the event queue used for the
* active objects. For the built-in QV kernel, this is ::QEqueue.
@ -94,17 +94,11 @@ void QV_onIdle(void);
#define QACTIVE_EQUEUE_WAIT_(me_) \
Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0)
#if (QF_MAX_ACTIVE <= 8)
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
QPSet8_insert(&QV_readySet_, (me_)->prio)
#define QACTIVE_EQUEUE_ONEMPTY_(me_) \
QPSet8_remove(&QV_readySet_, (me_)->prio)
#else
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
QPSet64_insert(&QV_readySet_, (me_)->prio)
#define QACTIVE_EQUEUE_ONEMPTY_(me_) \
QPSet64_remove(&QV_readySet_, (me_)->prio)
#endif
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
QPSet_insert(&QV_readySet_, (me_)->prio)
#define QACTIVE_EQUEUE_ONEMPTY_(me_) \
QPSet_remove(&QV_readySet_, (me_)->prio)
/* native QF event pool operations */
#define QF_EPOOL_TYPE_ QMPool
@ -114,11 +108,7 @@ void QV_onIdle(void);
#define QF_EPOOL_GET_(p_, e_, m_) ((e_) = (QEvt *)QMPool_get(&(p_), (m_)))
#define QF_EPOOL_PUT_(p_, e_) (QMPool_put(&(p_), (e_)))
#if (QF_MAX_ACTIVE <= 8)
extern QPSet8 QV_readySet_; /*!< QV-ready set of AOs */
#else
extern QPSet64 QV_readySet_; /*!< QV-ready set of AOs */
#endif
extern QPSet QV_readySet_; /*!< QV ready-set of AOs */
#endif /* QP_IMPL */

View File

@ -1,12 +1,12 @@
/**
* @file
* @brief QXK/C (preemptive extended (blocking) kernel) platform-independent
* @brief QXK/C (preemptive dual-mode kernel) platform-independent
* public interface.
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.7.0
* Last updated on 2016-07-14
* Last updated for version 5.7.1
* Last updated on 2016-09-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,56 +41,41 @@
#ifndef qxk_h
#define qxk_h
#include "qequeue.h" /* QXK kernel uses the native QF event queue */
#include "qmpool.h" /* QXK kernel uses the native QF memory pool */
#include "qpset.h" /* QXK kernel uses the native QF priority set */
#include "qequeue.h" /* QXK kernel uses the native QP event queue */
#include "qmpool.h" /* QXK kernel uses the native QP memory pool */
#include "qpset.h" /* QXK kernel uses the native QP priority set */
/****************************************************************************/
/* QXK-specific data members of the ::QMActive class... */
/* QF configuration for QXK */
/*! This macro defines the type of the event queue used for the AOs */
/*! This macro defines the type of the event queue used for the
* active objects. */
/**
* @description
* QXK uses the native QF event queue QEQueue.
*/
#define QF_EQUEUE_TYPE QEQueue
/*! OS-dependent per-thread operating-system object */
/**
* @description
* The use of this member depends on the CPU. For example, in port to
* ARM Cortex-M with FPU this member is used to store the LR.
*/
#define QF_OS_OBJECT_TYPE void*
/*! OS-dependent representation of the private thread */
/**
* @description
* QXK uses this member to store thread attributes.
* QXK uses this member to store the private stack poiner for the thread.
* (The private stack pointer is NULL for AO-threads).
*/
#define QF_THREAD_TYPE QXK_ThreadType
#define QF_THREAD_TYPE void*
/****************************************************************************/
/*! Type of the QMActive.thread member for the QXK kernel */
typedef struct {
void *stack; /*!< top of the per-thread stack */
/* ... possibly other thread attributes in the future */
} QXK_ThreadType;
/*! attributes of the QXK kernel */
typedef struct {
void volatile *curr; /*!< currently executing thread */
void volatile *next; /*!< next thread to execute */
uint_fast8_t volatile lockPrio; /*!< lock prio (0 == no-lock) */
uint_fast8_t volatile lockHolder; /*!< prio of the lock holder */
void *curr; /*!< pointer to the current thread to execute */
void *next; /*!< pointer to the next thread to execute */
uint_fast8_t topPrio; /*!< prio of the AO at the top of stack */
uint_fast8_t lockPrio; /*!< lock prio (0 == no-lock) */
uint_fast8_t lockHolder; /*!< prio of the lock holder */
#ifndef QXK_ISR_CONTEXT_
uint_fast8_t volatile intNest; /*!< ISR nesting level */
uint_fast8_t intNest; /*!< ISR nesting level */
#endif /* QXK_ISR_CONTEXT_ */
#if (QF_MAX_ACTIVE <= 8)
QPSet8 readySet; /*!< QXK ready-set of AOs and "naked" threads */
#else
QPSet64 readySet; /*!< QXK ready-set of AOs and "naked" threads */
#endif
QPSet readySet; /*!< QXK ready-set of AOs and extended-threads */
} QXK_Attr;
/*! global attributes of the QXK kernel */
@ -99,10 +84,10 @@ extern QXK_Attr QXK_attr_;
/****************************************************************************/
/*! QXK initialization */
/**
* QXK_init() must be called from the application before QF_run()
* to initialize the QXK idle thread.
* QXK_init() is called from QF_init() in qxk.c. This function is
* defined in the QXK ports.
*/
void QXK_init(void *idleStkSto, uint_fast16_t idleStkSize);
void QXK_init(void);
/*! QXK idle callback (customized in BSPs for QXK) */
/**
@ -113,13 +98,18 @@ void QXK_init(void *idleStkSto, uint_fast16_t idleStkSize);
* @note QXK_onIdle() is invoked with interrupts enabled and must also
* return with interrupts enabled.
*
* @sa QK_onIdle() QV_onIdle()
* @sa QK_onIdle()
*/
void QXK_onIdle(void);
/****************************************************************************/
/*! QXK scheduler */
void QXK_sched_(void);
/*! QXK scheduler finds the highest-priority thread ready to run */
uint_fast8_t QXK_sched_(void);
/*! QXK activator activates the next active object. The activated AO preempts
* the currently executing AOs.
*/
void QXK_activate_(void);
/****************************************************************************/
/*! QXK priority-ceiling mutex class */
@ -175,35 +165,20 @@ void QXMutex_unlock(QXMutex * const me);
/*! Internal port-specific macro for selective scheduler unlocking. */
#define QF_SCHED_UNLOCK_(pLockStat_) QXMutex_unlock((pLockStat_))
#if (QF_MAX_ACTIVE <= 8)
#define QXK_prioNotEmpty(set_) QPSet8_notEmpty((set_))
#define QXK_prioFindMax(set_, p_) QPSet8_findMax((set_), (p_))
#define QXK_prioInsert(set_, p_) QPSet8_insert((set_), (p_))
#define QXK_prioRemove(set_, p_) QPSet8_remove((set_), (p_))
#else
#define QXK_prioNotEmpty(set_) QPSet64_notEmpty((set_))
#define QXK_prioFindMax(set_, p_) QPSet64_findMax((set_), (p_))
#define QXK_prioInsert(set_, p_) QPSet64_insert((set_), (p_))
#define QXK_prioRemove(set_, p_) QPSet64_remove((set_), (p_))
#endif
#define QACTIVE_EQUEUE_WAIT_(me_) \
if ((me_)->eQueue.frontEvt == (QEvt *)0) { \
QXK_prioRemove(&QXK_attr_.readySet, (me_)->prio); \
QXK_sched_(); \
QF_CRIT_EXIT_(); \
QF_CRIT_EXIT_NOP(); \
QF_CRIT_ENTRY_(); \
}
(Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0))
#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
QXK_prioInsert(&QXK_attr_.readySet, (me_)->prio); \
QPSet_insert(&QXK_attr_.readySet, (me_)->prio); \
if (!QXK_ISR_CONTEXT_()) { \
QXK_sched_(); \
if (QXK_sched_() != (uint_fast8_t)0) { \
QXK_activate_(); \
} \
} \
} while (0)
#define QACTIVE_EQUEUE_ONEMPTY_(me_) ((void)0)
#define QACTIVE_EQUEUE_ONEMPTY_(me_) \
QPSet_remove(&QXK_attr_.readySet, (me_)->prio)
/* native QF event pool operations */
#define QF_EPOOL_TYPE_ QMPool

View File

@ -1,11 +1,11 @@
/**
* @file
* @brief QXK/C naked (blocking) thread.
* @brief QXK/C eXtended (blocking) thread.
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.6.0
* Last updated on 2015-12-04
* Last updated for version 5.7.1
* Last updated on 2016-09-21
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,11 +41,11 @@
#define qxthread_h
/****************************************************************************/
/*! Extended (blocking) thread of the QXK preemptive kernel */
/*! eXtended (blocking) thread of the QXK preemptive kernel */
/**
* @description
* QXThread represents the "naked" (blocking) thread of the QXK preemptive
* kernel. Each blocking thread in the application must be represented by
* QXThread represents the eXtended (blocking) thread of the QXK preemptive
* kernel. Each extended thread in the application must be represented by
* the corresponding ::QXThread instance
*
* @note
@ -56,13 +56,13 @@
* @sa ::QMActive
*
* @usage
* The following example illustrates how to instantiate a "naked" thread
* The following example illustrates how to instantiate an extended thread
* in your application.
* @include qf_qxthread.c
*/
typedef struct {
QMActive super;
QTimeEvt timeEvt;
QMActive super; /* inherit QMactive */
QTimeEvt timeEvt; /* time event to handle timeouts */
} QXThread;
/*! Virtual Table for the ::QXThread class (inherited from ::QMActiveVtbl) */
@ -73,13 +73,13 @@ typedef struct {
*/
typedef QMActiveVtbl QXThreadVtbl;
/*! Polymorphically start a "naked" extended thread. */
/*! Polymorphically start an extended thread. */
/**
* @description
* Starts execution of the thread and registers the thread with the framework.
*
* @param[in,out] me_ pointer (see @ref oop)
* @param[in] prio_ priority at which to start the "naked" thread
* @param[in] prio_ priority of the extended-thread
* @param[in] qSto_ pointer to the storage for the ring buffer of the
* message queue (possibly NULL)
* @param[in] qLen_ length of the message queue [events] (possibly 0)
@ -95,9 +95,9 @@ typedef QMActiveVtbl QXThreadVtbl;
(stkSto_), (stkLen_), (param_))
/*! Thread handler pointer-to-function */
typedef void (*QXThreadHandler)(void *par);
typedef void (*QXThreadHandler)(QXThread * const me);
/*! constructor of a "naked" thread */
/*! constructor of an extended-thread */
void QXThread_ctor(QXThread * const me, QXThreadHandler handler,
uint_fast8_t tickRate);
@ -145,21 +145,26 @@ bool QXThread_delay(uint_fast16_t const nTicks, uint_fast8_t const tickRate);
bool QXThread_delayCancel(QXThread * const me);
/*! obtain a message from the private message queue (block if no messages) */
void const *QXThread_queueGet(uint_fast16_t const nTicks,
QEvt const *QXThread_queueGet(uint_fast16_t const nTicks,
uint_fast8_t const tickRate);
/*! no-timeout sepcification when blocking on queues or semaphores */
/*! no-timeout special timeout value when blocking on queues or semaphores */
#define QXTHREAD_NO_TIMEOUT ((uint_fast16_t)0)
/*! Perform cast to QXThreadHandler. */
/**
* @description
* This macro encapsulates the cast of a specific thread handler function
* pointer to ::QXThreadHandler, which violates MISRA-C 2004 rule 11.4(adv).
* This macro helps to localize this deviation.
*/
#define Q_XTHREAD_CAST(handler_) ((QXThreadHandler)(handler_))
/****************************************************************************/
/*! Counting Semaphore of the QXK preemptive kernel */
typedef struct {
uint_fast16_t count;
#if (QF_MAX_ACTIVE <= 8)
QPSet8 waitSet; /*!< set of "naked" threads waiting on this semaphore */
#else
QPSet64 waitSet; /*!< set of "naked" threads waiting on this semaphore */
#endif
QPSet waitSet; /*!< set of extended-threads waiting on this semaphore */
} QXSemaphore;
/*! initialize the counting semaphore */

View File

@ -1,7 +1,7 @@
//============================================================================
// Product: PC-Lint 9.x standard option file
// Last Updated for Version: 5.4.0
// Date of the Last Update: 2015-03-11
// Last Updated for Version: 5.7.1
// Date of the Last Update: 2016-09-18
//
// Q u a n t u m L e a P s
// ---------------------------
@ -40,6 +40,10 @@
-width(0,0) // do not break lines
+flm // make sure no foreign includes change the format
-D__STDC_VERSION__=199409L // C89 Standard last ammended 1994-04
//-D__STDC_VERSION__=199901L // C99 Standard 1999-01
+rw(inline, entry)
-zero(99) // don't stop make because of warnings
-passes(2) // make two passes (for better error messages)

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, preemptive QK kernel, ARM-KEIL toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -66,7 +66,7 @@
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M4F provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __clz(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __clz(n_)))
/* inline function for setting the BASEPRI register */
static __inline void QF_set_BASEPRI(unsigned basePri) {

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR ARM assembler
; Last Updated for Version: 5.7.0
; Date of the Last Update: 2016-08-08
; Last Updated for Version: 5.7.1
; Date of the Last Update: 2016-09-22
;
; Q u a n t u m L e a P s
; ---------------------------
@ -34,6 +34,7 @@
EXPORT QK_init
EXPORT PendSV_Handler ; CMSIS-compliant PendSV exception name
EXPORT NMI_Handler ; CMSIS-compliant NMI exception name
IMPORT QK_sched_ ; external reference
IMPORT QK_attr_ ; QK attribute structure
@ -44,7 +45,6 @@ QF_BASEPRI EQU (0xFF:SHR:2)
; NOTE: keep in synch with the QK_Attr struct in "qk.h" !!!
QK_CURR EQU 0
QK_NEXT EQU 4
QK_AUX EQU 8
AREA |.text|, CODE, READONLY
THUMB
@ -53,8 +53,7 @@ QK_AUX EQU 8
;*****************************************************************************
; The QK_init() function sets the priority of PendSV to 0xFF (lowest).
; Also, it initializes QK_attr_.aux to zero. Both these operations
; are performed in a critical section.
; This operation is performed in a critical section.
;*****************************************************************************
QK_init
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
@ -67,15 +66,6 @@ QK_init
ORRS r2,r3 ; set PRI_14 (PendSV) to 0xFF
STR r2,[r1,#8] ; write the System 12-15 Priority Register
; The QK_attr_.aux attribute is used to determine the purpose of the
; PendSV exception. When (QK_attr_.aux == 0), PendSV is used for
; scheduling the next thread. Otherwise (QK_attr_.aux != 0), it is
; used for returning to the preempted thread. Here QK_attr_.aux is
; initialized to zero.
LDR r3,=QK_attr_
MOVS r2,#0
STR r2,[r3,#QK_AUX] ; QK_attr_.aux := 0
MSR PRIMASK,r0 ; restore the original PRIMASK
BX lr ; return to the caller
@ -101,48 +91,9 @@ QK_init
; check for the asynchronous preemption.
;*****************************************************************************
PendSV_Handler
; Check QK_attr_.aux to determine the purpose of this PendSV exception.
; When (QK_attr_.aux == 0), PendSV is used for scheduling the next thread.
; Otherwise (QK_attr_.aux != 0), it is used for returning to the
; preempted thread.
;
; NOTE: no critical section is necessary, because the only other place
; QK_attr_.aux is accessed is inside a critical section and no other
; instance of PendSV can preempt itself.
;
LDR r3,=QK_attr_
LDR r0,[r3,#QK_AUX] ; r0 := QK_attr_.aux
CMP r0,#0 ; if (QK_attr_.aux == 0) ...
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
BEQ PendSV_save_lr ; save lr before checking QK_attr_.next
ELSE
BEQ PendSV_check_next ; go straight to checking QK_attr_.next
ENDIF ; VFP available
; Here you know that (QK_attr_.aux != 0), meaning that this PendSV
; instance has been triggered for returning to the preempted thread.
; The no-FPU exception stack frame of this PendSV instance is removed
; from the stack
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
; clear QK_attr_.aux for the next time
MOVS r1,#0
STR r1,[r3,#QK_AUX] ; QK_attr_.aux = 0
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
B PendSV_check_next
PendSV_save_lr
; When FPU is available, the lr of this exception needs to be saved,
; because it contains the information about the type of the exception
; stack frame (FPU/no-FPU registers).
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
ENDIF ; VFP available
PendSV_check_next
; Prepare some constants (an address and a bitmask) before entering
; a critical section...
LDR r3,=QK_attr_
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (1 << 27) (UNPENDSVSET bit)
@ -175,6 +126,10 @@ PendSV_check_next
STR r1,[r3,#QK_NEXT] ; QK_attr_.next := 0
PendSV_call_sched
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
PUSH {r0,lr} ; ... push lr (EXC_RETURN) plus stack-aligner
ENDIF ; VFP available
; The QK scheduler must be called in a thread context, while this code
; executes in the handler contex of the PendSV exception. The switch
; to the thread context is accomplished by returning from PendSV using
@ -186,7 +141,7 @@ PendSV_call_sched
MOVS r3,#1
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
LDR r2,=QK_sched_ ; address of the QK scheduler (new pc)
LDR r1,=Thread_sched_ret ; return address after the call (new lr)
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)
@ -213,28 +168,22 @@ PendSV_ret
BX lr ; return to the preempted task
ENDIF ; VFP available
; NOTE: the following code does not execute in the PendSV context!
;=========================================================================
; NOTE: QK scheduler returns with interrupts DISABLED.
Thread_sched_ret
;*****************************************************************************
; Thread_ret is a helper function executed when the QXK activator returns.
;
; NOTE: Thread_ret does not execute in the PendSV context!
; NOTE: Thread_ret executes entirely with interrupts DISABLED.
;*****************************************************************************
Thread_ret
; After the QK scheduler returns, we need to resume the preempted
; task. However, this must be accomplished by a return-from-exception,
; while we are still in the task context. The switch to the exception
; contex is accomplished by triggering the PendSV exception.
; contex is accomplished by triggering the NMI exception.
; NOTE: The NMI exception is triggered with nterrupts DISABLED,
; because QK scheduler disables interrutps before return.
; set QK_attr_.aux to non-zero to tell the next PendSV instance
; to remove its own stack frame
LDR r3,=QK_attr_
MOVS r1,#0xFF
STR r1,[r3,#QK_AUX] ; QK_attr_.aux = 0xFF (not zero)
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
ELSE ; M3/M4/M7
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
; before triggering the PendSV exception, make sure that the
; before triggering the NMI exception, make sure that the
; VFP stack frame will NOT be used...
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
MRS r0,CONTROL ; r0 := CONTROL
@ -242,14 +191,38 @@ Thread_sched_ret
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
ENDIF ; VFP available
ENDIF ; M3/M4/M7
; trigger PendSV to return to preempted task...
; trigger NMI to return to preempted task...
LDR r0,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#28 ; r0 := (1 << 28) (PendSV bit)
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
B . ; wait for preemption by PendSV
LSLS r1,r1,#31 ; r0 := (1 << 31) (NMI bit)
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
B . ; wait for preemption by NMI
;*****************************************************************************
; The NMI_Handler exception handler is used for returning back to the
; interrupted task. The NMI exception simply removes its own interrupt
; stack frame from the stack and returns to the preempted task using the
; interrupt stack frame that must be at the top of the stack.
;
; NOTE: The NMI exception is entered with interrupts DISABLED, so it needs
; to re-enable interrupts before it returns to the preempted task.
;*****************************************************************************
NMI_Handler
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
BX lr ; return to the preempted task
ELSE ; M3/M4/M7
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
POP {r0,pc} ; pop stack "aligner" and EXC_RETURN to PC
ELSE
BX lr ; return to the preempted task
ENDIF ; VFP available ENDIF
ENDIF ; M3/M4/M7
ALIGN ; make sure the END is properly aligned

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, preemptive QK kernel, GNU-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-11
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -69,7 +69,7 @@
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M4F provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __builtin_clz(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz(n_)))
#endif

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.7.0
* Date of the Last Update: 2016-08-08
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -41,13 +41,11 @@
/* NOTE: keep in synch with the QK_Attr struct in "qk.h" !!! */
.equ QK_CURR,0
.equ QK_NEXT,4
.equ QK_AUX,8
/*****************************************************************************
* The QK_init() function sets the priority of PendSV to 0xFF (lowest).
* Also, it initializes QK_attr_.aux to zero. Both these operations
* are performed in a critical section.
* This operation is performed in a critical section.
*****************************************************************************/
.section .text.QK_init
.global QK_init
@ -64,16 +62,6 @@ QK_init:
ORRS r2,r3 /* set PRI_14 (PendSV) to 0xFF */
STR r2,[r1,#8] /* write the System 12-15 Priority Register */
/* The QK_attr_.aux attribute is used to determine the purpose of the
* PendSV exception. When (QK_attr_.aux == 0), PendSV is used for
* scheduling the next thread. Otherwise (QK_attr_.aux != 0), it is
* used for returning to the preempted thread. Here QK_attr_.aux is
* initialized to zero.
*/
LDR r3,=QK_attr_
MOVS r2,#0
STR r2,[r3,#QK_AUX] /* QK_attr_.aux := 0 */
MSR PRIMASK,r0 /* restore the original PRIMASK */
BX lr /* return to the caller */
.size QK_init, . - QK_init
@ -102,54 +90,12 @@ QK_init:
.section .text.PendSV_Handler
.global PendSV_Handler /* CMSIS-compliant exception name */
.type PendSV_Handler, %function
.type Thread_sched_ret, %function /* to ensure the label is THUMB */
PendSV_Handler:
/* Check QK_attr_.aux to determine the purpose of this PendSV exception.
* When (QK_attr_.aux == 0), PendSV is used for scheduling the next thread.
* Otherwise (QK_attr_.aux != 0), it is used for returning to the
* preempted thread.
*
* NOTE: no critical section is necessary, because the only other place
* QK_attr_.aux is accessed is inside a critical section and no other
* instance of PendSV can preempt itself.
*/
LDR r3,=QK_attr_
LDR r0,[r3,#QK_AUX] /* r0 := QK_attr_.aux */
CMP r0,#0 /* if (QK_attr_.aux == 0) ... */
.ifdef __FPU_PRESENT /* if VFP available... */
BEQ PendSV_save_lr /* save lr before checking QK_attr_.next */
.else
BEQ PendSV_check_next /* go straight to checking QK_attr_.next */
.endif /* VFP available */
/* Here you know that (QK_attr_.aux != 0), meaning that this PendSV
* instance has been triggered for returning to the preempted thread.
* The no-FPU exception stack frame of this PendSV instance is removed
* from the stack
*/
ADD sp,sp,#(8*4) /* remove one 8-register exception frame */
/* clear QK_attr_.aux for the next time */
MOVS r1,#0
STR r1,[r3,#QK_AUX] /* QK_attr_.aux = 0 */
.ifdef __FPU_PRESENT /* if VFP available... */
B PendSV_check_next
PendSV_save_lr:
/* When FPU is available, the lr of this exception needs to be saved,
* because it contains the information about the type of the exception
* stack frame (FPU/no-FPU registers).
*/
PUSH {r0,lr} /* push lr (EXC_RETURN) plus stack "aligner" */
.endif /* VFP available */
PendSV_check_next:
/* Prepare some constants (an address and a bitmask) before entering
* a critical section...
*/
LDR r3,=QK_attr_
LDR r2,=0xE000ED04 /* Interrupt Control and State Register */
MOVS r1,#1
LSLS r1,r1,#27 /* r0 := (1 << 27) (UNPENDSVSET bit) */
@ -183,6 +129,10 @@ PendSV_check_next:
STR r1,[r3,#QK_NEXT] /* QK_attr_.next := 0 */
PendSV_call_sched:
.ifdef __FPU_PRESENT /* if VFP available... */
PUSH {r0,lr} /* ... push EXC_RETURN plus stack-aligner */
.endif /* VFP */
/* The QK scheduler must be called in a thread context, while this code
* executes in the handler contex of the PendSV exception. The switch
* to the thread context is accomplished by returning from PendSV using
@ -195,7 +145,7 @@ PendSV_call_sched:
MOVS r3,#1
LSLS r3,r3,#24 /* r3:=(1 << 24), set the T bit (new xpsr) */
LDR r2,=QK_sched_ /* address of the QK scheduler (new pc) */
LDR r1,=Thread_sched_ret /* return address after the call (new lr) */
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) */
@ -221,29 +171,26 @@ PendSV_ret:
.else
BX lr /* return to the preempted task */
.endif /* VFP */
.size PendSV_Handler, . - PendSV_Handler
/* NOTE: the following code does not execute in the PendSV context!
*=========================================================================
* NOTE: QK scheduler returns with interrupts DISABLED.
*/
Thread_sched_ret:
/*****************************************************************************
* Thread_ret is a helper function executed when the QXK activator returns.
*
* NOTE: Thread_ret does not execute in the PendSV context!
* NOTE: Thread_ret executes entirely with interrupts DISABLED.
****************************************************************************/
.section .text.Thread_ret
.type Thread_ret, %function
Thread_ret:
/* After the QK scheduler returns, we need to resume the preempted
* task. However, this must be accomplished by a return-from-exception,
* while we are still in the task context. The switch to the exception
* contex is accomplished by triggering the PendSV exception.
* contex is accomplished by triggering the NMI exception.
* NOTE: The NMI exception is triggered with nterrupts DISABLED,
* because QK scheduler disables interrutps before return.
*/
/* set QK_attr_.aux to non-zero to tell the next PendSV instance
* to remove its own stack frame
*/
LDR r3,=QK_attr_
MOVS r1,#0xFF
STR r1,[r3,#QK_AUX] /* QK_attr_.aux = 0xFF (not zero) */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
.else /* M3/M4/M7 */
MOVS r0,#0
MSR BASEPRI,r0 /* enable interrupts (clear BASEPRI) */
/* before triggering the PendSV exception, make sure that the
* VFP stack frame will NOT be used...
@ -254,14 +201,44 @@ Thread_sched_ret:
MSR CONTROL,r0 /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
.endif /* VFP available */
.endif /* M3/M4/M7 */
/* trigger PendSV to return to preempted task... */
/* trigger NMI to return to preempted task... */
LDR r0,=0xE000ED04 /* Interrupt Control and State Register */
MOVS r1,#1
LSLS r1,r1,#28 /* r0 := (1 << 28) (PendSV bit) */
STR r1,[r0] /* ICSR[28] := 1 (pend PendSV) */
B . /* wait for preemption by PendSV */
.size PendSV_Handler, . - PendSV_Handler
LSLS r1,r1,#31 /* r0 := (1 << 31) (NMI bit) */
STR r1,[r0] /* ICSR[31] := 1 (pend NMI) */
B . /* wait for preemption by NMI */
.size Thread_ret, . - Thread_ret
/*****************************************************************************
* The NMI_Handler exception handler is used for returning back to the
* interrupted task. The NMI exception simply removes its own interrupt
* stack frame from the stack and returns to the preempted task using the
* interrupt stack frame that must be at the top of the stack.
*
* NOTE: The NMI exception is entered with interrupts DISABLED, so it needs
* to re-enable interrupts before it returns to the preempted task.
*****************************************************************************/
.section .text.NMI_Handler
.global NMI_Handler
.type NMI_Handler, %function
NMI_Handler:
ADD sp,sp,#(8*4) /* remove one 8-register exception frame */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
BX lr /* return to the preempted task */
.else /* M3/M4/M7 */
MOVS r0,#0
MSR BASEPRI,r0 /* enable interrupts (clear BASEPRI) */
.ifdef __FPU_PRESENT /* if VFP available... */
POP {r0,pc} /* pop stack "aligner" and EXC_RETURN to PC */
.else
BX lr /* return to the preempted task */
.endif /* VFP available */
.endif /* M3/M4/M7 */
.size NMI_Handler, . - NMI_Handler
.end

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, preemptive QK kernel, IAR-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -66,7 +66,7 @@
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __CLZ(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ(n_)))
#endif
/* QF critical section entry/exit... */

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR ARM assembler
; Last Updated for Version: 5.7.0
; Date of the Last Update: 2016-08-08
; Last Updated for Version: 5.7.1
; Date of the Last Update: 2016-09-22
;
; Q u a n t u m L e a P s
; ---------------------------
@ -34,6 +34,7 @@
PUBLIC QK_init
PUBLIC PendSV_Handler ; CMSIS-compliant PendSV exception name
PUBLIC NMI_Handler ; CMSIS-compliant NMI exception name
EXTERN QK_sched_ ; external reference
EXTERN QK_attr_ ; QK attribute structure
@ -44,13 +45,11 @@ QF_BASEPRI EQU (0xFF >> 2)
; NOTE: keep in synch with the QK_Attr struct in "qk.h" !!!
QK_CURR EQU 0
QK_NEXT EQU 4
QK_AUX EQU 8
RSEG CODE:CODE:NOROOT(2)
;*****************************************************************************
; The QK_init() function sets the priority of PendSV to 0xFF (lowest).
; Also, it initializes QK_attr_.aux to zero. Both these operations
; are performed in a critical section.
; This operation is performed in a critical section.
;*****************************************************************************
QK_init:
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
@ -63,15 +62,6 @@ QK_init:
ORRS r2,r3 ; set PRI_14 (PendSV) to 0xFF
STR r2,[r1,#8] ; write the System 12-15 Priority Register
; The QK_attr_.aux attribute is used to determine the purpose of the
; PendSV exception. When (QK_attr_.aux == 0), PendSV is used for
; scheduling the next thread. Otherwise (QK_attr_.aux != 0), it is
; used for returning to the preempted thread. Here QK_attr_.aux is
; initialized to zero.
LDR r3,=QK_attr_
MOVS r2,#0
STR r2,[r3,#QK_AUX] ; QK_attr_.aux := 0
MSR PRIMASK,r0 ; restore the original PRIMASK
BX lr ; return to the caller
@ -97,48 +87,9 @@ QK_init:
; check for the asynchronous preemption.
;*****************************************************************************
PendSV_Handler:
; Check QK_attr_.aux to determine the purpose of this PendSV exception.
; When (QK_attr_.aux == 0), PendSV is used for scheduling the next thread.
; Otherwise (QK_attr_.aux != 0), it is used for returning to the
; preempted thread.
;
; NOTE: no critical section is necessary, because the only other place
; QK_attr_.aux is accessed is inside a critical section and no other
; instance of PendSV can preempt itself.
;
LDR r3,=QK_attr_
LDR r0,[r3,#QK_AUX] ; r0 := QK_attr_.aux
CMP r0,#0 ; if (QK_attr_.aux == 0) ...
#ifdef __ARMVFP__ ; if VFP available...
BEQ PendSV_save_lr ; save lr before checking QK_attr_.next
#else
BEQ PendSV_check_next ; go straight to checking QK_attr_.next
#endif
; Here you know that (QK_attr_.aux != 0), meaning that this PendSV
; instance has been triggered for returning to the preempted thread.
; The no-FPU exception stack frame of this PendSV instance is removed
; from the stack
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
; clear QK_attr_.aux for the next time
MOVS r1,#0
STR r1,[r3,#QK_AUX] ; QK_attr_.aux = 0
#ifdef __ARMVFP__ ; if VFP available...
B PendSV_check_next
PendSV_save_lr:
; When FPU is available, the lr of this exception needs to be saved,
; because it contains the information about the type of the exception
; stack frame (FPU/no-FPU registers).
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
#endif ; VFP available
PendSV_check_next:
; Prepare some constants (an address and a bitmask) before entering
; a critical section...
LDR r3,=QK_attr_
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (1 << 27) (UNPENDSVSET bit)
@ -171,6 +122,10 @@ PendSV_check_next:
STR r1,[r3,#QK_NEXT] ; QK_attr_.next := 0
PendSV_call_sched:
#ifdef __ARMVFP__ ; if VFP available...
PUSH {r0,lr} ; ... push lr (EXC_RETURN) plus stack-aligner
#endif ; VFP available
; The QK scheduler must be called in a thread context, while this code
; executes in the handler contex of the PendSV exception. The switch
; to the thread context is accomplished by returning from PendSV using
@ -182,7 +137,7 @@ PendSV_call_sched:
MOVS r3,#1
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
LDR r2,=QK_sched_ ; address of the QK scheduler (new pc)
LDR r1,=Thread_sched_ret ; return address after the call (new lr)
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)
@ -209,28 +164,22 @@ PendSV_ret:
BX lr ; return to the preempted task
#endif ; VFP
; NOTE: the following code does not execute in the PendSV context!
;=========================================================================
; NOTE: QK scheduler returns with interrupts DISABLED.
Thread_sched_ret:
;*****************************************************************************
; Thread_ret is a helper function executed when the QXK activator returns.
;
; NOTE: Thread_ret does not execute in the PendSV context!
; NOTE: Thread_ret executes entirely with interrupts DISABLED.
;*****************************************************************************
Thread_ret:
; After the QK scheduler returns, we need to resume the preempted
; task. However, this must be accomplished by a return-from-exception,
; while we are still in the task context. The switch to the exception
; contex is accomplished by triggering the PendSV exception.
; contex is accomplished by triggering the NMI exception.
; NOTE: The NMI exception is triggered with nterrupts DISABLED,
; because QK scheduler disables interrutps before return.
; set QK_attr_.aux to non-zero to tell the next PendSV instance
; to remove its own stack frame
LDR r3,=QK_attr_
MOVS r1,#0xFF
STR r1,[r3,#QK_AUX] ; QK_attr_.aux = 0xFF (not zero)
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
#else ; M3/M4/M7
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
; before triggering the PendSV exception, make sure that the
; before triggering the NMI exception, make sure that the
; VFP stack frame will NOT be used...
#ifdef __ARMVFP__ ; if VFP available...
MRS r0,CONTROL ; r0 := CONTROL
@ -238,14 +187,38 @@ Thread_sched_ret:
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
#endif ; VFP available
#endif ; M3/M4/M7
; trigger PendSV to return to preempted task...
; trigger NMI to return to preempted task...
LDR r0,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#28 ; r0 := (1 << 28) (PendSV bit)
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
B . ; wait for preemption by PendSV
LSLS r1,r1,#31 ; r0 := (1 << 31) (NMI bit)
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
B . ; wait for preemption by NMI
;*****************************************************************************
; The NMI_Handler exception handler is used for returning back to the
; interrupted task. The NMI exception simply removes its own interrupt
; stack frame from the stack and returns to the preempted task using the
; interrupt stack frame that must be at the top of the stack.
;
; NOTE: The NMI exception is entered with interrupts DISABLED, so it needs
; to re-enable interrupts before it returns to the preempted task.
;*****************************************************************************
NMI_Handler:
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
BX lr ; return to the preempted task
#else ; M3/M4/M7
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
#ifdef __ARMVFP__ ; if VFP available...
POP {r0,pc} ; pop stack "aligner" and EXC_RETURN to PC
#else ; no VFP
BX lr ; return to the preempted task
#endif ; no VFP
#endif ; M3/M4/M7
ALIGNROM 2,0xFF ; make sure the END is properly aligned

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, preemptive QK kernel, TI-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.1
* Date of the Last Update: 2015-12-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -60,14 +60,8 @@
#define QF_INT_DISABLE() QF_set_BASEPRI(QF_BASEPRI)
#define QF_INT_ENABLE() QF_set_BASEPRI(0U)
/* the intrinsic function _norm() generates the CLZ instruction */
#define QF_LOG2(n_) ((uint8_t)(32U - _norm(n_)))
/* assembly function for setting the BASEPRI register */
//__attribute__((always_inline))
//static inline void __set_BASEPRI(unsigned basePri) {
// __asm (" msr basepri, basePri");
//}
/* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __clz(n_)))
void QF_set_BASEPRI(unsigned basePri);
@ -84,7 +78,7 @@
#endif /* not M3/M4/M7 */
/* QF critical section entry/exit */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt enabling" policy */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt disabling policy */
#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE()
#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE()
#define QF_CRIT_EXIT_NOP() __asm(" ISB")

View File

@ -3,8 +3,8 @@
* @brief QK/C port to Cortex-M, TI-ARM (CCS) toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.7.0
* Date of the Last Update: 2016-07-11
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -44,6 +44,7 @@
/* QK interrupt entry and exit */
#define QK_ISR_ENTRY() ((void)0)
#define QK_ISR_EXIT() do { \
uint_fast8_t nextPrio_; \
QF_INT_DISABLE(); \

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
; Last Updated for Version: 5.7.0
; Date of the Last Update: 2016-08-08
; Last Updated for Version: 5.7.1
; Date of the Last Update: 2016-09-22
;
; Q u a n t u m L e a P s
; ---------------------------
@ -34,13 +34,17 @@
.global QK_init
.global PendSV_Handler ; CMSIS-compliant PendSV exception name
.global NMI_Handler ; CMSIS-compliant NMI exception name
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
.global QF_set_BASEPRI ; set BASEPRI register
.endif ; M3/M4/M7
.global QK_get_IPSR ; get the IPSR
.global assert_failed ; low-level assert handler
.ref QK_sched_ ; external reference
.ref QK_attr_ ; external reference
.ref QK_sched_ ; external reference
.ref Q_onAssert ; external reference
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
@ -49,15 +53,13 @@ QF_BASEPRI: .equ (0xFF >> 2)
; NOTE: keep in synch with the QK_Attr struct in "qk.h" !!!
QK_CURR: .equ 0
QK_NEXT: .equ 4
QK_AUX: .equ 8
.text
.thumb
;*****************************************************************************
; The QK_init() function sets the priority of PendSV to 0xFF (lowest).
; Also, it initializes QK_attr_.aux to zero. Both these operations
; are performed in a critical section.
; This operation is performed in a nestable critical section.
;*****************************************************************************
QK_init: .asmfunc
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
@ -70,15 +72,6 @@ QK_init: .asmfunc
ORRS r2,r3 ; set PRI_14 (PendSV) to 0xFF
STR r2,[r1,#8] ; write the System 12-15 Priority Register
; The QK_attr_.aux attribute is used to determine the purpose of the
; PendSV exception. When (QK_attr_.aux == 0), PendSV is used for
; scheduling the next thread. Otherwise (QK_attr_.aux != 0), it is
; used for returning to the preempted thread. Here QK_attr_.aux is
; initialized to zero.
LDR r3,QK_attr_addr
MOVS r2,#0
STR r2,[r3,#QK_AUX] ; QK_attr_.aux := 0
MSR PRIMASK,r0 ; restore the original PRIMASK
BX lr ; return to the caller
.endasmfunc
@ -105,47 +98,9 @@ QK_init: .asmfunc
;*****************************************************************************
PendSV_Handler: .asmfunc
; Check QK_attr_.aux to determine the purpose of this PendSV exception.
; When (QK_attr_.aux == 0), PendSV is used for scheduling the next thread.
; Otherwise (QK_attr_.aux != 0), it is used for returning to the
; preempted thread.
;
; NOTE: no critical section is necessary, because the only other place
; QK_attr_.aux is accessed is inside a critical section and no other
; instance of PendSV can preempt itself.
;
LDR r3,QK_attr_addr
LDR r0,[r3,#QK_AUX] ; r0 := QK_attr_.aux
CMP r0,#0 ; if (QK_attr_.aux == 0) ...
.if __TI_VFP_SUPPORT__ ; if VFP available...
BEQ PendSV_save_lr ; save lr before checking QK_attr_.next
.else
BEQ PendSV_check_next ; go straight to checking QK_attr_.next
.endif ; VFP available
; Here you know that (QK_attr_.aux != 0), meaning that this PendSV
; instance has been triggered for returning to the preempted thread.
; The no-FPU exception stack frame of this PendSV instance is removed
; from the stack
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
; clear QK_attr_.aux for the next time
MOVS r1,#0
STR r1,[r3,#QK_AUX] ; QK_attr_.aux = 0
.if __TI_VFP_SUPPORT__ ; if VFP available...
B PendSV_check_next
PendSV_save_lr:
; When FPU is available, the lr of this exception needs to be saved,
; because it contains the information about the type of the exception
; stack frame (FPU/no-FPU registers).
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
.endif ; VFP available
PendSV_check_next:
; Prepare some constants (an address and a bitmask) before entering
; a critical section...
LDR r3,QK_attr_addr
LDR r2,ICSR_addr ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (1 << 27) (UNPENDSVSET bit)
@ -178,6 +133,10 @@ PendSV_check_next:
STR r1,[r3,#QK_NEXT] ; QK_attr_.next := 0
PendSV_call_sched:
.if __TI_VFP_SUPPORT__ ; if VFP available...
PUSH {r0,lr} ; ... push lr (EXC_RETURN) plus stack-aligner
.endif ; VFP available
; The QK scheduler must be called in a thread context, while this code
; executes in the handler contex of the PendSV exception. The switch
; to the thread context is accomplished by returning from PendSV using
@ -189,7 +148,7 @@ PendSV_call_sched:
MOVS r3,#1
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
LDR r2,QK_sched_addr ; address of the QK scheduler (new pc)
LDR r1,Thread_sched_ret_addr ; return address after the call (new lr)
LDR r1,Thread_ret_addr ; 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)
@ -217,26 +176,21 @@ PendSV_ret:
.endif ; VFP
.endasmfunc
; NOTE: the following code does not execute in the PendSV context!
;=========================================================================
; NOTE: QK scheduler returns with interrupts DISABLED.
Thread_sched_ret: .asmfunc ; to ensure that the label is THUMB
;*****************************************************************************
; Thread_ret is a helper function executed when the QXK activator returns.
;
; NOTE: Thread_ret does not execute in the PendSV context!
; NOTE: Thread_ret executes entirely with interrupts DISABLED.
;*****************************************************************************
Thread_ret: .asmfunc ; to ensure that the label is THUMB
; After the QK scheduler returns, we need to resume the preempted
; task. However, this must be accomplished by a return-from-exception,
; while we are still in the task context. The switch to the exception
; contex is accomplished by triggering the PendSV exception.
; contex is accomplished by triggering the NMI exception.
; NOTE: The NMI exception is triggered with nterrupts DISABLED,
; because QK scheduler disables interrutps before return.
; set QK_attr_.aux to non-zero to tell the next PendSV instance
; to remove its own stack frame
LDR r3,QK_attr_addr
MOVS r1,#0xFF
STR r1,[r3,#QK_AUX] ; QK_attr_.aux = 0xFF (not zero)
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
; before triggering the PendSV exception, make sure that the
; before triggering the NMI exception, make sure that the
; VFP stack frame will NOT be used...
.if __TI_VFP_SUPPORT__ ; if VFP available...
MRS r0,CONTROL ; r0 := CONTROL
@ -244,29 +198,57 @@ Thread_sched_ret: .asmfunc ; to ensure that the label is THUMB
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
.endif ; VFP
.else ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
.endif ; M0/M0+/M1
; trigger PendSV to return to preempted thread...
; trigger NMI to return to preempted thread...
LDR r0,ICSR_addr ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#28 ; r0 := (1 << 28) (PendSV bit)
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
Thread_wait_PendSV:
B Thread_wait_PendSV ; wait for preemption by PendSV
LSLS r1,r1,#31 ; r0 := (1 << 31) (NMI bit)
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
Thread_wait_NMI:
B Thread_wait_NMI ; wait for preemption by NMI
.endasmfunc
;*****************************************************************************
; The NMI_Handler exception handler is used for returning back to the
; interrupted task. The NMI exception simply removes its own interrupt
; stack frame from the stack and returns to the preempted task using the
; interrupt stack frame that must be at the top of the stack.
;
; NOTE: The NMI exception is entered with interrupts DISABLED, so it needs
; to re-enable interrupts before it returns to the preempted task.
;*****************************************************************************
NMI_Handler: .asmfunc
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
.if __TI_VFP_SUPPORT__ ; if VFP available...
POP {r0,pc} ; pop stack "aligner" and EXC_RETURN to PC
.else
BX lr ; return to the preempted task
.endif
.else ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
BX lr ; return to the preempted task
.endif ; M0/M0+/M1
.endasmfunc
;*****************************************************************************
; The QF_set_BASEPRI function sets the BASEPRI register to the value
; passed in r0.
; NOTE: The BASEPRI register is implemented only in ARMv7 architecture
; and is **not** available in ARMv6 (M0/M0+/M1)
;
; C prototype: void QF_set_BASEPRI(unsigned basePri);
;*****************************************************************************
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
QF_set_BASEPRI: .asmfunc
MSR BASEPRI,r0 ; set BASEPRI
BX lr ; return to the caller
.endasmfunc
.endif ; M3/M4/M7
;*****************************************************************************
@ -303,4 +285,4 @@ VTOR_addr: .word 0xE000ED08
;*****************************************************************************
QK_attr_addr: .word QK_attr_
QK_sched_addr: .word QK_sched_
Thread_sched_ret_addr .word Thread_sched_ret
Thread_ret_addr .word Thread_ret

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, cooperative QV kernel, ARM-KEIL toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -66,7 +66,7 @@
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M4F provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __clz(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __clz(n_)))
/* inline function for setting the BASEPRI register */
static __inline void QF_set_BASEPRI(unsigned basePri) {

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, cooperative QV kernel, GNU-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-11
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -69,7 +69,7 @@
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M4F provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __builtin_clz(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz(n_)))
#endif

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, cooperative QV kernel, IAR-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -66,12 +66,12 @@
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M4F provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __CLZ(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ(n_)))
#endif
/* QF critical section entry/exit... */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt disabling" policy */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt disabling policy */
#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE()
#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE()
#define QF_CRIT_EXIT_NOP() __ISB()

View File

@ -3,8 +3,8 @@
* @brief QF/C port to Cortex-M, cooperative QV kernel, TI-ARM CCS toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.1
* Date of the Last Update: 2015-12-30
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -60,8 +60,8 @@
#define QF_INT_DISABLE() QF_set_BASEPRI(QF_BASEPRI)
#define QF_INT_ENABLE() QF_set_BASEPRI(0U)
/* the intrinsic function _norm() generates the CLZ instruction */
#define QF_LOG2(n_) ((uint8_t)(32U - _norm(n_)))
/* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __clz(n_)))
/* assembly function for setting the BASEPRI register */
void QF_set_BASEPRI(unsigned basePri);
@ -79,7 +79,7 @@
#endif /* not M3/M4/M7 */
/* QF critical section entry/exit */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt enabling" policy */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt disabling policy */
#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE()
#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE()
#define QF_CRIT_EXIT_NOP() __asm(" ISB")
@ -94,7 +94,13 @@
* up to 63, if necessary. Here it is set to a lower level to save some RAM.
*
* NOTE2:
* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI
* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling
* policy uses the PRIMASK register to disable interrupts globally. The
* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are
* "kernel-aware".
*
* NOTE3:
* On Cortex-M3/M4/M4F, the interrupt disable/enable policy uses the BASEPRI
* register (which is not implemented in Cortex-M0/M0+/M1) to disable
* interrupts only with priority lower than the level specified by the
* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e.,
@ -104,13 +110,13 @@
* "QF-aware" interrupts, with numerical values of priorities eqal to or
* higher than QF_BASEPRI, can call QF services.
*
* NOTE3:
* For Cortex-M3/M4/M7, the macro QF_BASEPRI leaves the top 2 priority bits
* NOTE4:
* For Cortex-M3/M4/M4F, the macro QF_BASEPRI leaves the top 2 priority bits
* empty for QF-aware interrupts. This is the highest-possible priority
* (lowest possible numerical value) for the guaranteed 3 priority bits
* implemented in the NVIC.
*
* NOTE4:
* NOTE5:
* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating
* the QF-aware interrupt priority levels in the applications, whereas the
* numerical values of the QF-aware interrupts must be greater or equal to
@ -122,12 +128,6 @@
* the macro QF_AWARE_ISR_CMSIS_PRI is intended only for applications and
* is not used inside the QF port, which remains generic and not dependent
* on the number of implemented priority bits in the NVIC.
*
* NOTE5:
* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling
* policy uses the PRIMASK register to disable interrupts globally. The
* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are
* "kernel-aware".
*/
#endif /* qf_port_h */

View File

@ -1,10 +1,10 @@
/**
* @file
* @brief QF/C port to Cortex-M, preemptive QXK kernel, ARM-KEIL toolset
* @brief QF/C port to Cortex-M, dual-mode QXK kernel, ARM-KEIL toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-09
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -59,14 +59,14 @@
#define QF_INT_DISABLE() QF_set_BASEPRI(QF_BASEPRI)
#define QF_INT_ENABLE() QF_set_BASEPRI(0U)
/* NOTE: keep in synch with the value defined in qxk_port.s, see NOTE4 */
/* NOTE: keep in synch with the value defined in "qxk_port.s", NOTE4 */
#define QF_BASEPRI (0xFFU >> 2)
/* QF-aware ISR priority for CMSIS function NVIC_SetPriority(), NOTE5 */
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __clz(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __clz(n_)))
/* inline function for setting the BASEPRI register */
static __inline void QF_set_BASEPRI(unsigned basePri) {
@ -85,7 +85,7 @@
#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 interface */
/*****************************************************************************
* NOTE1:

View File

@ -3,8 +3,8 @@
* @brief QXK/C port to ARM Cortex-M, ARM-KEIL toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-09
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-15
*
* Q u a n t u m L e a P s
* ---------------------------
@ -56,7 +56,9 @@ static __inline uint32_t QXK_get_IPSR(void) {
#define QXK_ISR_EXIT() do { \
QF_INT_DISABLE(); \
QXK_sched_(); \
if (QXK_sched_() != (uint_fast8_t)0) { \
QXK_CONTEXT_SWITCH_(); \
} \
QF_INT_ENABLE(); \
} while (0)

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.7.0
; Date of the Last Update: 2016-07-14
; Last Updated for Version: 5.7.1
; Date of the Last Update: 2016-09-16
;
; Q u a n t u m L e a P s
; ---------------------------
@ -32,23 +32,27 @@
; mailto:info@state-machine.com
;*****************************************************************************
EXPORT QXK_start_ ; start the QXK multitasking
EXPORT QXK_stackInit_ ; initialize the stack of each thread
EXPORT PendSV_Handler ; CMSIS-compliant PendSV exception
EXPORT QXK_init ; initialze the QXK kernel
EXPORT QXK_stackInit_ ; initialize the stack of an extended thread
EXPORT PendSV_Handler ; CMSIS-compliant PendSV exception name
EXPORT NMI_Handler ; CMSIS-compliant NMI exception name
IMPORT QXK_attr_ ; QXK attribute structure
IMPORT QXK_activate_ ; external reference
IMPORT QXK_threadRet_ ; return from a thread function
IMPORT assert_failed ; assert-failure handler
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
QF_BASEPRI EQU (0xFF:SHR:2)
; NOTE: keep in synch with the QXK struct in "qxk.h" !!!
QXK_CURR EQU 0
QXK_NEXT EQU 4
; NOTE: keep in synch with the QXK_Attr struct in "qxk.h" !!!
QXK_CURR EQU 0
QXK_NEXT EQU 4
QXK_TOP_PRIO EQU 8
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!!
QMACTIVE_OSOBJECT EQU 40
QMACTIVE_THREAD EQU 44
QMACTIVE_THREAD EQU 40
QMACTIVE_PRIO EQU 44
AREA |.text|, CODE, READONLY
@ -57,13 +61,13 @@ QMACTIVE_THREAD EQU 44
PRESERVE8 ; this code preserves 8-byte stack alignment
;*****************************************************************************
; The QXK_start_ function starts QXK multitasking.
; The C signature: void QXK_start_(void);
;
; NOTE: QXK_start_() must be called with interrupts disabled and
; returns with interrupts **enabled**.
; The QXK_init() function sets the priority of PendSV to 0xFF (lowest).
; This operation is performed in a nestable critical section.
;*****************************************************************************
QXK_start_
QXK_init
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
CPSID i ; disable interrupts (set PRIMASK)
LDR r1,=0xE000ED18 ; System Handler Priority Register
LDR r2,[r1,#8] ; load the System 12-15 Priority Register
MOVS r3,#0xFF
@ -71,112 +75,195 @@ QXK_start_
ORRS r2,r3 ; set PRI_14 (PendSV) to 0xFF
STR r2,[r1,#8] ; write the System 12-15 Priority Register
; set the MSP to the top of the C-STACK, which is the first entry
; in the vector table. (This recovers any stack used so far by main().)
LDR r0,=0xE000ED08 ; r0 := address of Vector Table Offset register
LDR r0,[r0,#0] ; r0 := contents of VTOR
LDR r0,[r0] ; r0 := VT[0] (first entry is the top of stack)
MSR MSP,r0 ; main SP := initial top of stack
MSR PRIMASK,r0 ; restore the original PRIMASK
BX lr ; return to the caller
; set the current QXK thread to the next QXK thread
LDR r1,=QXK_attr_
LDR r2,[r1,#QXK_NEXT] ; r2 := QXK_attr_.next
STR r2,[r1,#QXK_CURR] ; QXK_attr_.curr := r2
; get the top of stack of the current QXK thread
LDR r0,[r2,#QMACTIVE_THREAD] ; r0 := QXK_attr_.next->thread (SP)
; pop r4-r11 from the PSP
MOVS r1,r0 ; r1 := top of stack
ADDS r0,r0,#(4*4) ; point r0 to the 4 high registers r7-r11
LDMIA r0!,{r4-r7} ; pop the 4 high registers into low registers
;*****************************************************************************
; The PendSV_Handler exception handler is used for handling context switch
; and asynchronous preemption in QXK. The use of the PendSV exception is
; the recommended and most efficient method for performing context switches
; with ARM Cortex-M.
;
; The PendSV exception should have the lowest priority in the whole system
; (0xFF, see QXK_init). All other exceptions and interrupts should have higher
; priority. For example, for NVIC with 2 priority bits all interrupts and
; exceptions must have numerical value of priority lower than 0xC0. In this
; case the interrupt priority levels available to your applications are (in
; the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00.
;
; Also, *all* "kernel aware" ISRs in the QXK application must call the
; QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for
; a context switch or asynchronous preemption.
;
; Due to tail-chaining and its lowest priority, the PendSV exception will be
; entered immediately after the exit from the *last* nested interrupt (or
; exception). In QXK, this is exactly the time when the QXK scheduler needs to
; check for the asynchronous preemption.
;*****************************************************************************
PendSV_Handler
; Prepare some constants (an address and a bitmask) before entering
; a critical section...
LDR r3,=QXK_attr_
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (1 << 27) (UNPENDSVSET bit)
; <<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<<
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSID i ; disable interrupts (set PRIMASK)
ELSE ; M3/M4/M7
MOVS r0,#QF_BASEPRI
MSR BASEPRI,r0 ; selectively disable interrupts
ENDIF ; M3/M4/M7
; The PendSV exception handler can be preempted by an interrupt,
; which might pend PendSV exception again. The following write to
; ICSR[27] un-pends any such spurious instance of PendSV.
STR r1,[r2] ; ICSR[27] := 1 (unpend PendSV)
; Check QXK_attr_.next, which contains the pointer to the next thread
; to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
LDR r0,[r3,#QXK_NEXT] ; r1 := QXK_attr_.next
CMP r0,#0 ; is (QXK_attr_.next == 0)?
BEQ PendSV_error ; branch if (QXK_attr_.next == 0)
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
LDR r2,[r0,#QMACTIVE_THREAD] ; r2 := QXK_attr_.next->thread
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)?
BNE PendSV_save_ao ; branch if (next tread is extended)
PendSV_activate
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
PUSH {r0,lr} ; ... push lr (EXC_RETURN) plus stack-aligner
ENDIF ; VFP available
; The QXK activator must be called in a thread context, while this code
; executes in the handler contex of the PendSV exception. The switch
; to the Thread mode is accomplished by returning from PendSV using
; a fabricated exception stack frame, where the return address is the
; QXK activator QXK_activate_().
;
; NOTE: the QXK activator is called with interrupts DISABLED and also
; it returns with interrupts DISABLED.
MOVS r3,#1
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
LDR r2,=QXK_activate_ ; address of the QXK activator (new pc)
LDR r1,=Thread_ret ; return address after the call (new lr)
SUB sp,sp,#8*4 ; reserve space for exception stack frame
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
STM r0!,{r1-r3} ; save xpsr,pc,lr
MOVS r0,#6
MVNS r0,r0 ; r0 := ~6 == 0xFFFFFFF9
BX r0 ; exception-return to the QXK activator
;-------------------------------------------------------------------------
PendSV_error
LDR r3,=assert_failed
BX r3 ; long-branch to the assertion-handler
;=========================================================================
; Saving AO-thread before crossing to eXtended-thread
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ao
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
PUSH {r4-r7} ; save the low registers
MOV r4,r8 ; move the high registers to low registers...
MOV r5,r9
MOV r6,r10
MOV r7,r11
PUSH {r4-r7} ; save the high registers
ELSE ; M3/M4/M7
PUSH {r4-r11} ; save r4-r11 on top of the exception frame
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
TST lr,#(1 << 4) ; is it return with the VFP exception frame?
IT EQ ; if lr[4] is zero...
VSTMDBEQ sp!,{s16-s31} ; ... save VFP registers s16..s31
PUSH {r0,lr} ; save the "aligner" and the EXC_RETURN value
ENDIF ; VFP available
ENDIF ; M3/M4/M7
CMP r2,#0
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->thread != 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)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ao
MOVS r0,#0
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0 (QXK_attr_.next)
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
MOV r0,sp ; r0 := top of stack
MOV r1,r0
ADDS r1,r1,#(4*4) ; point r0 to the 4 high registers r7-r11
LDMIA r1!,{r4-r7} ; pop the 4 high registers into low registers
MOV r8,r4 ; move low registers into high registers
MOV r9,r5
MOV r10,r6
MOV r11,r7
LDMIA r1!,{r4-r7} ; pop the low registers
; NOTE: at this point r0 holds the new top of stack
LDMIA r0!,{r4-r7} ; pop the low registers
ADD sp,sp,#(8*4) ; remove 8 registers from the stack
MSR PSP,r0 ; set PSP to the thread's SP
ISB ; flush the instruction pipeline
MOVS r1,#6
MVNS r1,r1 ; r2 := ~6 == 0xFFFFFFF9
MOV lr,r1 ; make sure MSP is used
ELSE ; M3/M4/M7
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
POP {r0,lr} ; restore alighner and EXC_RETURN into lr
TST lr,#(1 << 4) ; is it return to the VFP exception frame?
IT EQ ; if EXC_RETURN[4] is zero...
VLDMIAEQ sp!,{s16-s31} ; ... restore VFP registers s16..s31
ELSE
BIC lr,lr,#(1 << 2) ; make sure MSP is used
ENDIF ; VFP available
POP {r4-r11} ; restore r4-r11 from the next thread's stack
ENDIF ; M3/M4/M7
; switch CPU to using the Process Stack Pointer (PSP)
MRS r0,CONTROL
MOVS r1,#(1:SHL:1)
ORRS r0,r0,r1 ; set the Active Stack Pointer
MSR CONTROL,r0 ; switch to PSP
DSB ; make sure all data access completes
ISB ; flush the instruction pipeline
MOV r0,r12 ; r0 := QXK_attr_.next
LDR r0,[r0,#QMACTIVE_PRIO] ; r0 := QXK_attr_.next->prio
LDR r1,[r3,#QXK_TOP_PRIO] ; r1 := QXK_attr_.topPrio
CMP r1,r0
BCC PendSV_activate ; if (next->prio > topPrio) activate the next AO
; fake return from an exception...
POP {r0-r3} ; pop R0..R3
; NOTE: R0 holds the 'par' argument of the
; thread function
POP {r1,r2} ; pop R12 and LR into low registers r1,r2
MOV r12,r1
MOV lr,r2
POP {r1,r2} ; pop PC to R1 and xPSR to R2
; NOTE: it's OK to clobber R1 and R2
; otherwise re-enable interrupts and return to the preempted AO-thread
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
ELSE ; M3/M4/M7
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
; enable VFP by enabling CP10 and CP11 coprocessors
LDR.W r3,=0xE000ED88 ; r3 := &CPACR
LDR r2,[r3] ; r2 := CPACR
ORR r2,r2,#(0xF:SHL:20); r2 := r2 | (CP10 | CP11)
STR r2,[r3] ; CPACR = r2
DSB ; make sure all data access completes
ISB ; reset the instruction pipeline
; enable Automatic State Preservation and Lazy Stacking in the VFP
LDR r3,=0xE000EF34 ; r3 := &FPCCR
LDR r2,[r3] ; r2 := FPCCR
ORR r2,r2,#(3:SHL:30) ; set ASPEN | LSPEN
STR r2,[r3] ; FPCCR &= ~(ASPEN | LSPEN)
; clear the VFP Context Active (FPCA) bit in CONTROL
MRS r2,CONTROL ; r2 := CONTROL (NOTE: it's OK to clobber R2)
BICS r2,r2,#(1:SHL:2) ; r2 := r2 & ~(1 << 2) (FPCA bit)
MSR CONTROL,r2 ; CONTROL := r2 (clear CONTROL[2] FPCA bit)
ENDIF ; VFP available
MOVS r2,#0 ; NOTE: it's OK to clobber R2
MSR BASEPRI,r2 ; enable interrupts (clear BASEPRI)
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
ENDIF ; M3/M4/M7
; >>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>>
BX lr ; return to the preempted AO-thread
BX r1 ; return to the "interrupted" thread (PC)
;*****************************************************************************
; The PendSV_Handler exception handler is used for context switching in QXK.
; The use of the PendSV exception is the recommended and most efficient
; method for performing context switches with ARM Cortex-M.
;
; The PendSV exception should have the lowest priority in the whole system
; (0xFF, see QXK_start_). All other exceptions and interrupts should have
; higher priority. For example, for NVIC with 2 priority bits all interrupts
; and exceptions must have numerical value of priority lower than 0xC0.
; In this case the interrupt priority levels available to your applications
; are (in the order from the lowest to the highest urgency): 0x80, 0x40, 0x00.
;
; Also, *all* "kernel-aware" ISRs in the QXK application must call the
; QXK_ISR_EXIT() macro to trigger the PendSV exception.
;
; The C signature (CMSIS): void PendSV_Handler(void);
;
; NOTE:
; Due to tail-chaining and its lowest priority, the PendSV exception will be
; entered immediately after the exit from the *last* nested interrupt (or
; exception). In QXK, this is exactly the time when the QXK context switch
; must occur.
;*****************************************************************************
PendSV_Handler
;-------------------------------------------------------------------------
; Saving extended-thread before crossing to AO-thread
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ex
MRS r0,PSP ; r0 := Process Stack Pointer
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
LDR r3,=QXK_attr_
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
SUBS r0,r0,#(8*4) ; make room for 8 registers r4-r11
MOVS r1,r0 ; r1 := temporary PSP (do not clobber r0!)
@ -186,83 +273,128 @@ PendSV_Handler
MOV r6,r10
MOV r7,r11
STMIA r1!,{r4-r7} ; save the high registers
; NOTE: at this point r0 still holds the top of stack
CPSID i ; disable interrupts (set PRIMASK)
; NOTE: at this point r0 holds the top of stack
LDR r1,[r3,#QXK_CURR] ; r1 := QXK_attr_.curr (restore value)
ELSE ; M3/M4/M7
STMDB r0!,{r4-r11} ; save r4-r11 on top of the exception frame
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
TST lr,#(1:SHL:4) ; is it return with the VFP exception frame?
TST lr,#(1 << 4) ; is it return with the VFP exception frame?
IT EQ ; if lr[4] is zero...
VSTMDBEQ r0!,{s16-s31} ; ... save VFP registers s16..s31
STMDB r0!,{r1,lr} ; save the "aligner" and the EXC_RETURN value
ENDIF ; VFP available
MOVS r1,#QF_BASEPRI
MSR BASEPRI,r1 ; selectively disable interrupts
ENDIF ; M3/M4/M7
; NOTE: This PendSV exception handler can be preempted by an
; interrupt, which might pend PendSV exception again. This
; would be a problem, because the QK scheduler would run again
; after this PendSV instance, so the same AO would be scheduled
; twice. The following write to ICSR[7] un-pends any such spurious
; instance of PendSV.
MOVS r1,#1
LSLS r1,r1,#27 ; r1 := (1 << 27) (UNPENDSVSET bit)
STR r1,[r2] ; ICSR[27] := 1 (unpend PendSV)
; store the SP of the current extended-thread
STR r0,[r1,#QMACTIVE_THREAD] ; QXK_attr_.curr->thread := r0
MOV r0,r12 ; QXK_attr_.next (restore value)
; store the SP of the current QXK thread,
; which was set in QXK_ISR_EXIT().
LDR r2,[r3,#QXK_CURR]
STR r0,[r2,#QMACTIVE_THREAD] ; QXK_attr_.curr->thread := r0
CMP r2,#0
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->thread == 0)
; otherwise continue to restoring next extended-thread...
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
; store the LR of the current QXK thread...
STR lr,[r2,#QMACTIVE_OSOBJECT] ; QXK_attr_.curr->osObject := lr
ENDIF ; VFP available
; set current to the next...
LDR r2,[r3,#QXK_NEXT] ; r2 := QXK_attr_.next
STR r2,[r3,#QXK_CURR] ; QXK_attr_.curr := r2
; restore the SP of the next thread...
LDR r0,[r2,#QMACTIVE_THREAD] ; r0 := QXK_attr_.next->thread (SP)
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
; restore the LR of the next thread...
LDR lr,[r2,#QMACTIVE_OSOBJECT] ; lr := QXK_attr_.next->osObject
ENDIF ; VFP available
;-------------------------------------------------------------------------
; Restoring extended-thread after crossing from AO-thread
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ex
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := r0 (QXK_attr_.next)
; exit the critical section
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
MOVS r1,r0 ; r1 := top of stack
MOVS r0,r2 ; r2 := top of stack
ADDS r0,r0,#(4*4) ; point r0 to the 4 high registers r7-r11
LDMIA r0!,{r4-r7} ; pop the 4 high registers into low registers
MOV r8,r4 ; move low registers into high registers
MOV r9,r5
MOV r10,r6
MOV r11,r7
LDMIA r1!,{r4-r7} ; pop the low registers
; NOTE: at this point r0 holds the new top of stack
LDMIA r2!,{r4-r7} ; pop the low registers
MOVS r2,r0 ; r2 := holds the new top of stack
MOVS r1,#2
MVNS r1,r1 ; r1 := ~2 == 0xFFFFFFFD
MOV lr,r1 ; make sure PSP is used
ELSE ; M3/M4/M7
MOVS r3,#0
MSR BASEPRI,r3 ; enable interrupts (clear BASEPRI)
MOVS r1,#1
MSR BASEPRI,r1 ; enable interrupts (clear BASEPRI)
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
TST lr,#(1:SHL:4) ; is it return to the VFP exception frame?
LDMIA r2!,{r1,lr} ; restore aligner and EXC_RETURN into lr
TST lr,#(1 << 4) ; is it return to the VFP exception frame?
IT EQ ; if lr[4] is zero...
VLDMIAEQ r0!,{s16-s31} ; ... restore VFP registers s16..s31
VLDMIAEQ r2!,{s16-s31} ; ... restore VFP registers s16..s31
ELSE
ORR lr,lr,#(1 << 2) ; make sure PSP is used
ENDIF ; VFP available
LDMIA r0!,{r4-r11} ; restore r4-r11 from the next thread's stack
LDMIA r2!,{r4-r11} ; restore r4-r11 from the next thread's stack
ENDIF ; M3/M4/M7
; set the PSP to the next thread's SP
MSR PSP,r0 ; Process Stack Pointer := r0
MSR PSP,r2 ; Process Stack Pointer := r2
BX lr ; return to the next thread
BX lr ; return to the next extended-thread
;*****************************************************************************
; Thread_ret is a helper function executed when the QXK activator returns.
;
; NOTE: Thread_ret does not execute in the PendSV context!
; NOTE: Thread_ret executes entirely with interrupts DISABLED.
;*****************************************************************************
Thread_ret
; After the QXK activator returns, we need to resume the preempted
; thread. However, this must be accomplished by a return-from-exception,
; while we are still in the thread context. The switch to the exception
; contex is accomplished by triggering the NMI exception.
; before triggering the NMI exception, make sure that the
; VFP stack frame will NOT be used...
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
MRS r0,CONTROL ; r0 := CONTROL
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
ENDIF ; VFP available
; trigger NMI to return to preempted task...
; NOTE: The NMI exception is triggered with nterrupts DISABLED
LDR r0,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#31 ; r1 := (1 << 31) (NMI bit)
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
B . ; wait for preemption by NMI
;*****************************************************************************
; The NMI_Handler exception handler is used for returning back to the
; interrupted task. The NMI exception simply removes its own interrupt
; stack frame from the stack and returns to the preempted task using the
; interrupt stack frame that must be at the top of the stack.
;
; NOTE: The NMI exception is entered with interrupts DISABLED, so it needs
; to re-enable interrupts before it returns to the preempted task.
;*****************************************************************************
NMI_Handler
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
BX lr ; return to the preempted task
ELSE ; M3/M4/M7
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
POP {r0,pc} ; pop stack "aligner" and EXC_RETURN to PC
ELSE ; no VFP
BX lr ; return to the preempted task
ENDIF ; no VFP
ENDIF ; M3/M4/M7
;*****************************************************************************
@ -287,8 +419,8 @@ QXK_stackInit_
; r2 - begining of stack
; r3 - size of stack [bytes]
ADDS r3,r2,r3 ; r3 := end of stack (top of stack)
MOV r12,r0 ; save r0 in r12
MOV r12,r0 ; temporarily save r0 in r12 (act)
STR r1,[r0,#QMACTIVE_THREAD] ; temporarily save the thread routine
; round up the beginning of stack to the 8-byte boundary
; r2 := (((r2 -1) >> 3) + 1) << 3;
@ -299,80 +431,86 @@ QXK_stackInit_
; round down the end of stack to the 8-byte boundary
; r3 := (r3 >> 3) << 3;
ADDS r3,r2,r3 ; r3 := end of stack (top of stack)
LSRS r0,r3,#3
LSLS r3,r0,#3
; make room for the thread's stack frame...
SUBS r3,r3,#16*4 ; r3 := top of the 16-register stack frame
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
SUBS r3,r3,#2*4 ; r3 := top of the 18-register stack frame
ENDIF ; VFP available
MOV r0,r12
STR r1,[r0,#QMACTIVE_OSOBJECT] ; temporarily save the thread routine
; pre-fill the stack with 0xDEADBEEF
; pre-fill the unused part of the stack with 0xDEADBEEF...................
LDR r0,=0xDEADBEEF
MOV r1,r0
QXK_stackInit_fill
STMIA r2!,{r0,r1}
CMP r2,r3
BLT.N QXK_stackInit_fill
; prepare the standard exception (without VFP) stack frame...
MOV r0,r12 ; restore r0 from r12
MOVS r2,#0x04
STR r2,[r3,#0*4] ; r4
MOVS r2,#0x05
STR r2,[r3,#1*4] ; r5
MOVS r2,#0x06
STR r2,[r3,#2*4] ; r6
MOVS r2,#0x07
STR r2,[r3,#3*4] ; r7
MOVS r2,#0x08
STR r2,[r3,#4*4] ; r8
MOVS r2,#0x09
STR r2,[r3,#5*4] ; r9
MOVS r2,#0x0A
STR r2,[r3,#6*4] ; r10
MOVS r2,#0x0B
STR r2,[r3,#7*4] ; r11
STR r0,[r3,#8*4] ; r0 (argument to thread routine, act pointer)
MOVS r2,#0x01
STR r2,[r3,#9*4] ; r1
MOVS r2,#0x02
STR r2,[r3,#10*4] ; r2
MOVS r2,#0x03
STR r2,[r3,#11*4] ; r3
MOVS r2,#0x0C
STR r2,[r3,#12*4] ; r12
LDR r2,=QXK_threadRet_
STR r2,[r3,#13*4] ; LR (return address)
LDR r1,[r0,#QMACTIVE_OSOBJECT] ; r1 := saved thread routine
STR r1,[r3,#14*4] ; PC (entry point, thread routine)
MOVS r2,#1
LSLS r2,r2,#24 ; r2 := 0x01000000
STR r2,[r3,#15*4] ; xPSR
; 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
STR r3,[r0,#QMACTIVE_THREAD] ; act->thread := top of stack
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
MOVS r2,#0
STMIA r3!,{r2} ; stack "aligner"
; synthesize EXC_RETURN for return to Thread mode with no FPU-state
MOVS r2,#2
MVNS r2,r2 ; r2 := ~2 == 0xFFFFFFFD
STR r2,[r0,#QMACTIVE_OSOBJECT] ; act->thread.osObject := lr
STMIA r3!,{r2} ; save EXC_RETURN
ENDIF ; VFP available
MOVS r2,#0x04
STMIA r3!,{r2} ; r4
MOVS r2,#0x05
STMIA r3!,{r2} ; r5
MOVS r2,#0x06
STMIA r3!,{r2} ; r6
MOVS r2,#0x07
STMIA r3!,{r2} ; r7
MOVS r2,#0x08
STMIA r3!,{r2} ; r8
MOVS r2,#0x09
STMIA r3!,{r2} ; r9
MOVS r2,#0x0A
STMIA r3!,{r2} ; r10
MOVS r2,#0x0B
STMIA r3!,{r2} ; r11
STMIA r3!,{r0} ; r0 (argument to thread routine, me pointer)
MOVS r2,#0x01
STMIA r3!,{r2} ; r1
MOVS r2,#0x02
STMIA r3!,{r2} ; r2
MOVS r2,#0x03
STMIA r3!,{r2} ; r3
MOVS r2,#0x0C
STMIA r3!,{r2} ; r12
LDR r2,=QXK_threadRet_
STMIA r3!,{r2} ; LR (return address)
STMIA r3!,{r1} ; PC (entry point, thread routine)
MOVS r2,#1
LSLS r2,r2,#24 ; r2 := 0x01000000
STMIA r3!,{r2} ; xPSR
BX lr ; return to the caller

View File

@ -1,10 +1,10 @@
/**
* @file
* @brief QF/C port to Cortex-M, preemptive QXK kernel, GNU-ARM toolset
* @brief QF/C port to Cortex-M, dual-mode QXK kernel, GNU-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-11
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -62,14 +62,14 @@
#define QF_INT_DISABLE() QF_SET_BASEPRI(QF_BASEPRI)
#define QF_INT_ENABLE() QF_SET_BASEPRI(0U)
/* NOTE: keep in synch with the value defined in "qk_port.s", NOTE4 */
/* NOTE: keep in synch with the value defined in "qxk_port.s", NOTE4 */
#define QF_BASEPRI (0xFFU >> 2)
/* QF-aware ISR priority for CMSIS function NVIC_SetPriority(), NOTE5 */
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M4F provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __builtin_clz(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz(n_)))
#endif
@ -82,7 +82,7 @@
#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 interface */
/*****************************************************************************
* NOTE1:

View File

@ -3,8 +3,8 @@
* @brief QXK/C port to ARM Cortex-M, GNU-ARM compiler
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-09
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-15
*
* Q u a n t u m L e a P s
* ---------------------------
@ -57,7 +57,9 @@ static inline uint32_t QXK_get_IPSR(void) {
#define QXK_ISR_EXIT() do { \
QF_INT_DISABLE(); \
QXK_sched_(); \
if (QXK_sched_() != (uint_fast8_t)0) { \
QXK_CONTEXT_SWITCH_(); \
} \
QF_INT_ENABLE(); \
} while (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.7.0
* Date of the Last Update: 2016-07-14
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -37,28 +37,28 @@
/* NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!! */
.equ QF_BASEPRI,(0xFF >> 2)
/* NOTE: keep in synch with the QXK struct in "qxk.h" !!! */
/* NOTE: keep in synch with the QXK_Attr struct in "qxk.h" !!! */
.equ QXK_CURR,0
.equ QXK_NEXT,4
.equ QXK_TOP_PRIO,8
/* NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!! */
.equ QMACTIVE_OSOBJECT,40
.equ QMACTIVE_THREAD,44
.equ QMACTIVE_THREAD,40
.equ QMACTIVE_PRIO,44
/*****************************************************************************
* The QXK_start_ function starts QXK multitasking.
* The C signature: void QXK_start_(void);
*
* NOTE: QXK_start_() must be called with interrupts disabled and
* returns with interrupts **enabled**.
* The QXK_init() function sets the priority of PendSV to 0xFF (lowest).
* This operation is performed in a nestable critical section.
*****************************************************************************/
.section .text.QXK_start_
.global QXK_start_
.type QXK_start_, %function
.section .text.QXK_init
.global QXK_init
.type QXK_init, %function
.thumb
QXK_start_:
QXK_init:
MRS r0,PRIMASK /* store the state of the PRIMASK in r0 */
CPSID i /* disable interrupts (set PRIMASK) */
LDR r1,=0xE000ED18 /* System Handler Priority Register */
LDR r2,[r1,#8] /* load the System 12-15 Priority Register */
MOVS r3,#0xFF
@ -66,205 +66,355 @@ QXK_start_:
ORRS r2,r3 /* set PRI_14 (PendSV) to 0xFF */
STR r2,[r1,#8] /* write the System 12-15 Priority Register */
/* set the MSP to the top of the C-STACK, which is the first entry
* in the vector table. (This recovers any stack used so far by main()).
*/
LDR r0,=0xE000ED08 /* r0 := address of Vector Table Offset reg */
LDR r0,[r0,#0] /* r0 := contents of VTOR */
LDR r0,[r0] /* r0 := VT[0] (first entry is top of stack) */
MSR MSP,r0 /* main SP := initial top of stack */
/* set the current QXK thread to the next QXK thread */
LDR r1,=QXK_attr_
LDR r2,[r1,#QXK_NEXT] /* r2 := QXK_attr_.next */
STR r2,[r1,#QXK_CURR] /* QXK_attr_.curr := r2 */
/* get the top of stack of the current QXK thread */
LDR r0,[r2,#QMACTIVE_THREAD] /* r0 := QXK_attr_.next->thread (SP) */
/* pop r4-r11 from the PSP */
MOVS r1,r0 /* r1 := top of stack */
ADDS r0,r0,#(4*4) /* point r0 to the 4 high registers r7-r11 */
LDMIA r0!,{r4-r7} /* pop the 4 high registers into low regs */
MOV r8,r4 /* move low registers into high registers */
MOV r9,r5
MOV r10,r6
MOV r11,r7
LDMIA r1!,{r4-r7} /* pop the low registers */
/* NOTE: at this point r0 holds the new top of stack */
MSR PSP,r0 /* set PSP to the thread's SP */
ISB /* flush the instruction pipeline */
/* switch CPU to using the Process Stack Pointer (PSP) */
MRS r0,CONTROL
MOVS r1,#(1 << 1)
ORRS r0,r0,r1 /* set the Active Stack Pointer */
MSR CONTROL,r0 /* switch to PSP */
DSB /* make sure all data access completes */
ISB /* flush the instruction pipeline */
/* fake return from an exception... */
POP {r0-r3} /* pop R0..R3 */
/* NOTE: R0 holds the 'par' arg of thread fun */
POP {r1,r2} /* pop R12 and LR into low registers r1,r2 */
MOV r12,r1
MOV lr,r2
POP {r1,r2} /* pop PC to R1 and xPSR to R2 */
/* NOTE: it's OK to clobber R1 and R2 */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
.else /* M3/M4/M7 */
.ifdef __FPU_PRESENT /* if VFP available... */
/* enable the VFP by enabling CP10 and CP11 coprocessors */
LDR.W r3,=0xE000ED88 /* r3 := &CPACR */
LDR r2,[r3] /* r2 := CPACR */
ORR r2,r2,#(0xF << 20)/* r2 := r2 | (CP10 | CP11) */
STR r2,[r3] /* CPACR = r2 */
DSB /* make sure all data access completes */
ISB /* reset the instruction pipeline */
/* enable Automatic State Preservation and Lazy Stacking in the VFP */
LDR r3,=0xE000EF34 /* r3 := &FPCCR */
LDR r2,[r3] /* r2 := FPCCR */
ORR r2,r2,#(3 << 30) /* set ASPEN | LSPEN */
STR r2,[r3] /* FPCCR &= ~(ASPEN | LSPEN) */
/* clear the VFP Context Active (FPCA) bit in CONTROL */
MRS r2,CONTROL /* r2 := CONTROL (NOTE: it's OK to clobber R2)*/
BICS r2,r2,#(1 << 2) /* r2 := r2 & ~(1 << 2) (FPCA bit) */
MSR CONTROL,r2 /* CONTROL := r2 (clear CONTROL[2] FPCA bit) */
.endif /* VFP available */
MOVS r2,#0 /* NOTE: it's OK to clobber R2 */
MSR BASEPRI,r2 /* enable interrupts (clear BASEPRI) */
.endif /* M3/M4/M7 */
BX r1 /* return to the "interrupted" thread (PC) */
.size QXK_start_, . - QXK_start_
MSR PRIMASK,r0 /* restore the original PRIMASK */
BX lr /* return to the caller */
.size QXK_init, . - QXK_init
/*****************************************************************************
* The PendSV_Handler exception handler is used for context switching in QXK.
* The use of the PendSV exception is the recommended and most efficient
* method for performing context switches with ARM Cortex-M.
* The PendSV_Handler exception handler is used for handling context switch
* and asynchronous preemption in QXK. The use of the PendSV exception is
* the recommended and most efficient method for performing context switches
* with ARM Cortex-M.
*
* The PendSV exception should have the lowest priority in the whole system
* (0xFF, see QXK_start_). All other exceptions and interrupts should have
* higher priority. For example, for NVIC with 2 priority bits all interrupts
* and exceptions must have numerical value of priority lower than 0xC0.
* In this case the interrupt priority levels available to your applications
* are (in the order from the lowest to the highest urgency): 0x80, 0x40, 0x00.
* (0xFF, see QXK_init). All other exceptions and interrupts should have higher
* priority. For example, for NVIC with 2 priority bits all interrupts and
* exceptions must have numerical value of priority lower than 0xC0. In this
* case the interrupt priority levels available to your applications are (in
* the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00.
*
* Also, *all* "kernel-aware" ISRs in the QXK application must call the
* QXK_ISR_EXIT() macro to trigger the PendSV exception.
* Also, *all* "kernel aware" ISRs in the QXK application must call the
* QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for
* a context switch or asynchronous preemption.
*
* The C signature (CMSIS): void PendSV_Handler(void);
*
* NOTE:
* Due to tail-chaining and its lowest priority, the PendSV exception will be
* entered immediately after the exit from the *last* nested interrupt (or
* exception). In QXK, this is exactly the time when the QXK context switch
* must occur.
* exception). In QXK, this is exactly the time when the QXK scheduler needs to
* check for the asynchronous preemption.
*****************************************************************************/
.section .text.PendSV_Handler
.global PendSV_Handler /* CMSIS-compliant exception name */
.type PendSV_Handler, %function
PendSV_Handler:
MRS r0,PSP /* r0 := Process Stack Pointer */
LDR r2,=0xE000ED04 /* Interrupt Control and State Register */
/* Prepare some constants (an address and a bitmask) before entering
* a critical section...
*/
LDR r3,=QXK_attr_
LDR r2,=0xE000ED04 /* Interrupt Control and State Register */
MOVS r1,#1
LSLS r1,r1,#27 /* r0 := (1 << 27) (UNPENDSVSET bit) */
/*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<*/
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSID i /* disable interrupts (set PRIMASK) */
.else /* M3/M4/M7 */
MOVS r0,#QF_BASEPRI
MSR BASEPRI,r0 /* selectively disable interrupts */
.endif /* M3/M4/M7 */
/* The PendSV exception handler can be preempted by an interrupt,
* which might pend PendSV exception again. The following write to
* ICSR[27] un-pends any such spurious instance of PendSV.
*/
STR r1,[r2] /* ICSR[27] := 1 (unpend PendSV) */
/* Check QXK_attr_.next, which contains the pointer to the next thread
* to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
*/
LDR r0,[r3,#QXK_NEXT] /* r1 := QXK_attr_.next */
CMP r0,#0 /* is (QXK_attr_.next == 0)? */
BEQ PendSV_error /* branch if (QXK_attr_.next == 0) */
/* Load pointers into registers... */
MOV r12,r0 /* save QXK_attr_.next in r12 */
LDR r2,[r0,#QMACTIVE_THREAD] /* r2 := QXK_attr_.next->thread */
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)? */
BNE PendSV_save_ao /* branch if (next tread is extended) */
PendSV_activate:
.ifdef __FPU_PRESENT /* if VFP available... */
PUSH {r0,lr} /* ...push lr (EXC_RETURN) plus stack-aligner */
.endif /* VFP available */
/* The QXK activator must be called in a thread context, while this code
* executes in the handler contex of the PendSV exception. The switch
* to the Thread mode is accomplished by returning from PendSV using
* a fabricated exception stack frame, where the return address is the
* QXK activator QXK_activate_().
*
* NOTE: the QXK activator is called with interrupts DISABLED and also
* it returns with interrupts DISABLED.
*/
MOVS r3,#1
LSLS r3,r3,#24 /* r3:=(1 << 24), set the T bit (new xpsr) */
LDR r2,=QXK_activate_ /* address of the QXK activator (new pc) */
LDR r1,=Thread_ret /* return address after the call (new lr) */
SUB sp,sp,#8*4 /* reserve space for exception stack frame */
ADD r0,sp,#5*4 /* r0 := 5 registers below the top of stack */
STM r0!,{r1-r3} /* save xpsr,pc,lr */
MOVS r0,#6
MVNS r0,r0 /* r0 := ~6 == 0xFFFFFFF9 */
BX r0 /* exception-return to the QXK activator */
/*----------------------------------------------------------------------*/
PendSV_error:
LDR r3,=assert_failed
BX r3 /* long-branch to the assertion-handler */
/*========================================================================
* Saving AO-thread before crossing to eXtended-thread
* expected register contents:
* r0 -> QXK_attr_.next
* r1 -> QXK_attr_.curr
* r2 -> QXK_attr_.next->thread (SP)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
PendSV_save_ao:
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
PUSH {r4-r7} /* save the low registers */
MOV r4,r8 /* move the high registers to low registers...*/
MOV r5,r9
MOV r6,r10
MOV r7,r11
PUSH {r4-r7} /* save the high registers */
.else /* M3/M4/M7 */
PUSH {r4-r11} /* save r4-r11 on top of the exception frame */
.ifdef __FPU_PRESENT /* if VFP available... */
TST lr,#(1 << 4) /* is it return with the VFP exception frame? */
IT EQ /* if lr[4] is zero... */
VSTMDBEQ sp!,{s16-s31} /* ... save VFP registers s16..s31 */
PUSH {r0,lr} /* save the "aligner" and the EXC_RETURN */
.endif /* VFP available */
.endif /* M3/M4/M7 */
CMP r2,#0
BNE PendSV_restore_ex /* branch if (QXK_attr_.next->thread != 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)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
PendSV_restore_ao:
MOVS r0,#0
STR r0,[r3,#QXK_CURR] /* QXK_attr_.curr := 0 (QXK_attr_.next) */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
MOV r0,sp /* r0 := top of stack */
MOV r1,r0
ADDS r1,r1,#(4*4) /* point r0 to the 4 high registers r7-r11 */
LDMIA r1!,{r4-r7} /* pop the 4 high registers into low registers*/
MOV r8,r4 /* move low registers into high registers */
MOV r9,r5
MOV r10,r6
MOV r11,r7
LDMIA r0!,{r4-r7} /* pop the low registers */
ADD sp,sp,#(8*4) /* remove 8 registers from the stack */
MOVS r1,#6
MVNS r1,r1 /* r2 := ~6 == 0xFFFFFFF9 */
MOV lr,r1 /* make sure MSP is used */
.else /* M3/M4/M7 */
.ifdef __FPU_PRESENT /* if VFP available... */
POP {r0,lr} /* restore alighner and EXC_RETURN into lr */
TST lr,#(1 << 4) /* is it return to the VFP exception frame? */
IT EQ /* if EXC_RETURN[4] is zero... */
VLDMIAEQ sp!,{s16-s31} /* ... restore VFP registers s16..s31 */
.else
BIC lr,lr,#(1 << 2) /* make sure MSP is used */
.endif /* VFP available */
POP {r4-r11} /* restore r4-r11 from the next thread's stack*/
.endif /* M3/M4/M7 */
MOV r0,r12 /* r0 := QXK_attr_.next */
LDR r0,[r0,#QMACTIVE_PRIO] /* r0 := QXK_attr_.next->prio */
LDR r1,[r3,#QXK_TOP_PRIO] /* r1 := QXK_attr_.topPrio */
CMP r1,r0
BCC PendSV_activate /* if (next->prio > topPrio) activate next AO */
/* otherwise re-enable interrupts and return to the preempted AO-thread */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
.else /* M3/M4/M7 */
MOVS r0,#0
MSR BASEPRI,r0 /* enable interrupts (clear BASEPRI) */
.endif /* M3/M4/M7 */
/*>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>*/
BX lr /* return to the preempted AO-thread */
/*------------------------------------------------------------------------
* Saving extended-thread before crossing to AO-thread
* expected register contents:
* r0 -> QXK_attr_.next
* r1 -> QXK_attr_.curr
* r2 -> QXK_attr_.next->thread (SP)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
PendSV_save_ex:
MRS r0,PSP /* r0 := Process Stack Pointer */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
SUBS r0,r0,#(8*4) /* make room for 8 registers r4-r11 */
MOVS r1,r0 /* r1 := temporary PSP (do not clobber r0!) */
STMIA r1!,{r4-r7} /* save the low registers */
MOV r4,r8 /* move the high registers to low registers */
MOV r4,r8 /* move the high registers to low registers...*/
MOV r5,r9
MOV r6,r10
MOV r7,r11
STMIA r1!,{r4-r7} /* save the high registers */
/* NOTE: at this point r0 still holds the top of stack */
CPSID i /* disable interrupts (set PRIMASK) */
/* NOTE: at this point r0 holds the top of stack */
LDR r1,[r3,#QXK_CURR] /* r1 := QXK_attr_.curr (restore value) */
.else /* M3/M4/M7 */
STMDB r0!,{r4-r11} /* save r4-r11 on top of the exception frame */
.ifdef __FPU_PRESENT /* if VFP available... */
TST lr,#(1 << 4) /* is it return with the VFP exception frame? */
IT EQ /* if lr[4] is zero... */
VSTMDBEQ r0!,{s16-s31} /* ... save VFP registers s16..s31 */
STMDB r0!,{r1,lr} /* save the "aligner" and the EXC_RETURN */
.endif /* VFP available */
MOVS r1,#QF_BASEPRI
MSR BASEPRI,r1 /* selectively disable interrupts */
.endif /* M3/M4/M7 */
/* NOTE: This PendSV exception handler can be preempted by an
* interrupt, which might pend PendSV exception again. This
* would be a problem, because the QK scheduler would run again
* after this PendSV instance, so the same AO would be scheduled
* twice. The following write to ICSR[7] un-pends any such spurious
* instance of PendSV.
/* store the SP of the current extended-thread */
STR r0,[r1,#QMACTIVE_THREAD] /* QXK_attr_.curr->thread := r0 */
MOV r0,r12 /* QXK_attr_.next (restore value) */
CMP r2,#0
BEQ PendSV_restore_ao /* branch if (QXK_attr_.next->thread == 0) */
/* otherwise continue to restoring next extended-thread... */
/*------------------------------------------------------------------------
* Restoring extended-thread after crossing from AO-thread
* expected register contents:
* r0 -> QXK_attr_.next
* r1 -> QXK_attr_.curr
* r2 -> QXK_attr_.next->thread (SP)
* r3 -> &QXK_attr_
* r12 -> QXK_attr_.next
*/
MOVS r1,#1
LSLS r1,r1,#27 /* r1 := (1 << 27) (UNPENDSVSET bit) */
STR r1,[r2] /* ICSR[27] := 1 (unpend PendSV) */
/* store the SP of the current QXK thread... */
LDR r1,=QXK_attr_
LDR r2,[r3,#QXK_CURR]
STR r0,[r2,#QMACTIVE_THREAD] /* QXK_attr_.curr->thread := r0 */
.ifdef __FPU_PRESENT /* if VFP available... */
/* store the LR of the current QXK thread... */
STR lr,[r2,#QMACTIVE_OSOBJECT] /* QXK_attr_.curr->osObject := lr */
.endif /* VFP available */
/* set current to the next... */
LDR r2,[r3,#QXK_NEXT] /* r2 := QXK_attr_.next */
STR r2,[r3,#QXK_CURR] /* QXK_attr_.curr := r2 */
/* restore the SP of the next thread... */
LDR r0,[r2,#QMACTIVE_THREAD] /* r0 := QXK_attr_.next->thread (SP) */
.ifdef __FPU_PRESENT /* if VFP available... */
/* restore the LR of the next thread... */
LDR lr,[r2,#QMACTIVE_OSOBJECT] /* lr := QXK_attr_.next->osObject */
.endif /* VFP available */
PendSV_restore_ex:
STR r0,[r3,#QXK_CURR] /* QXK_attr_.curr := r0 (QXK_attr_.next) */
/* exit the critical section */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
MOVS r1,r0 /* r1 := top of stack */
MOVS r0,r2 /* r2 := top of stack */
ADDS r0,r0,#(4*4) /* point r0 to the 4 high registers r7-r11 */
LDMIA r0!,{r4-r7} /* pop the 4 high registers into low regs */
LDMIA r0!,{r4-r7} /* pop the 4 high registers into low registers*/
MOV r8,r4 /* move low registers into high registers */
MOV r9,r5
MOV r10,r6
MOV r11,r7
LDMIA r1!,{r4-r7} /* pop the low registers */
/* NOTE: at this point r0 holds the new top of stack */
.else /* M3/M4/M7 */
MOVS r3,#0
MSR BASEPRI,r3 /* enable interrupts (clear BASEPRI) */
LDMIA r2!,{r4-r7} /* pop the low registers */
MOVS r2,r0 /* r2 := holds the new top of stack */
MOVS r1,#2
MVNS r1,r1 /* r1 := ~2 == 0xFFFFFFFD */
MOV lr,r1 /* make sure PSP is used */
.else /* M3/M4/M7 */
MOVS r1,#1
MSR BASEPRI,r1 /* enable interrupts (clear BASEPRI) */
.ifdef __FPU_PRESENT /* if VFP available... */
LDMIA r2!,{r1,lr} /* restore aligner and EXC_RETURN into lr */
TST lr,#(1 << 4) /* is it return to the VFP exception frame? */
IT EQ /* if lr[4] is zero... */
VLDMIAEQ r0!,{s16-s31} /* ... restore VFP registers s16..s31 */
VLDMIAEQ r2!,{s16-s31} /* ... restore VFP registers s16..s31 */
.else
ORR lr,lr,#(1 << 2) /* make sure PSP is used */
.endif /* VFP available */
LDMIA r0!,{r4-r11} /* restore r4-r11 from next thread's stack */
LDMIA r2!,{r4-r11} /* restore r4-r11 from the next thread's stack*/
.endif /* M3/M4/M7 */
/* set the PSP to the next thread's SP */
MSR PSP,r0 /* Process Stack Pointer := r0 */
MSR PSP,r2 /* Process Stack Pointer := r2 */
BX lr /* return to the next thread */
BX lr /* return to the next extended-thread */
.size PendSV_Handler, . - PendSV_Handler
/*****************************************************************************
* Thread_ret is a helper function executed when the QXK activator returns.
*
* NOTE: Thread_ret does not execute in the PendSV context!
* NOTE: Thread_ret executes entirely with interrupts DISABLED.
*****************************************************************************/
.section .text.Thread_ret
.type Thread_ret, %function
Thread_ret:
/* After the QXK activator returns, we need to resume the preempted
* thread. However, this must be accomplished by a return-from-exception,
* while we are still in the thread context. The switch to the exception
* contex is accomplished by triggering the NMI exception.
*/
/* before triggering the NMI exception, make sure that the
* VFP stack frame will NOT be used...
*/
.ifdef __FPU_PRESENT /* if VFP available... */
MRS r0,CONTROL /* r0 := CONTROL */
BICS r0,r0,#4 /* r0 := r0 & ~4 (FPCA bit) */
MSR CONTROL,r0 /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
.endif /* VFP available */
/* trigger NMI to return to preempted task...
* NOTE: The NMI exception is triggered with nterrupts DISABLED
*/
LDR r0,=0xE000ED04 /* Interrupt Control and State Register */
MOVS r1,#1
LSLS r1,r1,#31 /* r1 := (1 << 31) (NMI bit) */
STR r1,[r0] /* ICSR[31] := 1 (pend NMI) */
B . /* wait for preemption by NMI */
.size Thread_ret, . - Thread_ret
/*****************************************************************************
* The NMI_Handler exception handler is used for returning back to the
* interrupted task. The NMI exception simply removes its own interrupt
* stack frame from the stack and returns to the preempted task using the
* interrupt stack frame that must be at the top of the stack.
*
* NOTE: The NMI exception is entered with interrupts DISABLED, so it needs
* to re-enable interrupts before it returns to the preempted task.
*****************************************************************************/
.section .text.NMI_Handler
.global NMI_Handler
.type NMI_Handler, %function
.thumb
NMI_Handler:
ADD sp,sp,#(8*4) /* remove one 8-register exception frame */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
BX lr /* return to the preempted task */
.else /* M3/M4/M7 */
MOVS r0,#0
MSR BASEPRI,r0 /* enable interrupts (clear BASEPRI) */
.ifdef __FPU_PRESENT /* if VFP available... */
POP {r0,pc} /* pop stack "aligner" and EXC_RETURN to PC */
.else /* no VFP */
BX lr /* return to the preempted task */
.endif /* VFP available */
.endif /* M3/M4/M7 */
.size NMI_Handler, . - NMI_Handler
/*****************************************************************************
* Initialize the private stack of a QXK thread.
*
@ -293,92 +443,100 @@ QXK_stackInit_:
* r3 - size of stack [bytes]
*/
ADDS r3,r2,r3 /* r3 := end of stack (top of stack) */
MOV r12,r0 /* save r0 in r12 */
MOV r12,r0 /* temporarily save r0 in r12 (act) */
STR r1,[r0,#QMACTIVE_THREAD] /* temporarily save the thread routine */
/* round up the beginning of stack to the 8-byte boundary */
/* r2 := (((r2 -1) >> 3) + 1) << 3 */
/* round up the beginning of stack to the 8-byte boundary
* r2 := (((r2 -1) >> 3) + 1) << 3;
*/
SUBS r0,r2,#1
LSRS r0,r0,#3
ADDS r0,r0,#1
LSLS r2,r0,#3
/* round down the end of stack to the 8-byte boundary */
/* r3 := (r3 >> 3) << 3 */
/* round down the end of stack to the 8-byte boundary
* r3 := (r3 >> 3) << 3;
*/
ADDS r3,r2,r3 /* r3 := end of stack (top of stack) */
LSRS r0,r3,#3
LSLS r3,r0,#3
/* make room for the thread's stack frame... */
SUBS r3,r3,#16*4 /* r3 := top of the 16-register stack frame */
.ifdef __FPU_PRESENT /* if VFP available... */
SUBS r3,r3,#2*4 /* r3 := top of the 18-register stack frame */
.endif /* VFP available */
MOV r0,r12
STR r1,[r0,#QMACTIVE_OSOBJECT] /* temporarily save thread routine */
/* pre-fill the stack with 0xDEADBEEF */
/* pre-fill the unused part of the stack with 0xDEADBEEF................*/
LDR r0,=0xDEADBEEF
MOV r1,r0
QXK_stackInit_fill:
STMIA r2!,{r0,r1}
CMP r2,r3
BLT.N QXK_stackInit_fill
/* prepare the standard exception (without VFP) stack frame... */
MOV r0,r12 /* restore r0 from r12 */
MOVS r2,#0x04
STR r2,[r3,#0*4] /* r4 */
MOVS r2,#0x05
STR r2,[r3,#1*4] /* r5 */
MOVS r2,#0x06
STR r2,[r3,#2*4] /* r6 */
MOVS r2,#0x07
STR r2,[r3,#3*4] /* r7 */
MOVS r2,#0x08
STR r2,[r3,#4*4] /* r8 */
MOVS r2,#0x09
STR r2,[r3,#5*4] /* r9 */
MOVS r2,#0x0A
STR r2,[r3,#6*4] /* r10 */
MOVS r2,#0x0B
STR r2,[r3,#7*4] /* r11 */
STR r0,[r3,#8*4] /* r0 (argument 'act' to thread routine) */
MOVS r2,#0x01
STR r2,[r3,#9*4] /* r1 */
MOVS r2,#0x02
STR r2,[r3,#10*4] /* r2 */
MOVS r2,#0x03
STR r2,[r3,#11*4] /* r3 */
MOVS r2,#0x0C
STR r2,[r3,#12*4] /* r12 */
LDR r2,=QXK_threadRet_
STR r2,[r3,#13*4] /* LR (return address) */
LDR r1,[r0,#QMACTIVE_OSOBJECT] /* r1 := saved thread routine */
STR r1,[r3,#14*4] /* PC (entry point, thread routine) */
MOVS r2,#1
LSLS r2,r2,#24 /* r2 := 0x01000000 */
STR r2,[r3,#15*4] /* xPSR */
/* 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 */
STR r3,[r0,#QMACTIVE_THREAD] /* act->thread := top of stack */
.ifdef __FPU_PRESENT /* if VFP available... */
MOVS r2,#0
STMIA r3!,{r2} /* stack "aligner" */
/* synthesize EXC_RETURN for return to Thread mode with no FPU-state */
MOVS r2,#2
MVNS r2,r2 /* r2 := ~2 == 0xFFFFFFFD */
STR r2,[r0,#QMACTIVE_OSOBJECT] /* act->thread.osObject := lr */
STMIA r3!,{r2} /* save EXC_RETURN */
.endif /* VFP available */
MOVS r2,#0x04
STMIA r3!,{r2} /* r4 */
MOVS r2,#0x05
STMIA r3!,{r2} /* r5 */
MOVS r2,#0x06
STMIA r3!,{r2} /* r6 */
MOVS r2,#0x07
STMIA r3!,{r2} /* r7 */
MOVS r2,#0x08
STMIA r3!,{r2} /* r8 */
MOVS r2,#0x09
STMIA r3!,{r2} /* r9 */
MOVS r2,#0x0A
STMIA r3!,{r2} /* r10 */
MOVS r2,#0x0B
STMIA r3!,{r2} /* r11 */
STMIA r3!,{r0} /* r0 (argument to thread routine, me pointer)*/
MOVS r2,#0x01
STMIA r3!,{r2} /* r1 */
MOVS r2,#0x02
STMIA r3!,{r2} /* r2 */
MOVS r2,#0x03
STMIA r3!,{r2} /* r3 */
MOVS r2,#0x0C
STMIA r3!,{r2} /* r12 */
LDR r2,=QXK_threadRet_
STMIA r3!,{r2} /* LR (return address) */
STMIA r3!,{r1} /* PC (entry point, thread routine) */
MOVS r2,#1
LSLS r2,r2,#24 /* r2 := 0x01000000 */
STMIA r3!,{r2} /* xPSR */
BX lr /* return to the caller */
.size QXK_stackInit_, . - QXK_stackInit_

View File

@ -1,10 +1,10 @@
/**
* @file
* @brief QF/C port to Cortex-M, preemptive QXK kernel, IAR-ARM toolset
* @brief QF/C port to Cortex-M, preemptive dual-mode QXK kernel, IAR-ARM
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-11-20
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -46,7 +46,7 @@
#define QF_MAX_TICK_RATE 2
/* QF interrupt disable/enable and log2()... */
#if (__CORE__ == __ARM6M__) /* Cortex-M0/M0+/M1 ?, see NOTE02 */
#if (__CORE__ == __ARM6M__) /* Cortex-M0/M0+/M1 ?, see NOTE2 */
#define QF_INT_DISABLE() __disable_interrupt()
#define QF_INT_ENABLE() __enable_interrupt()
@ -59,14 +59,14 @@
#define QF_INT_DISABLE() __set_BASEPRI(QF_BASEPRI)
#define QF_INT_ENABLE() __set_BASEPRI(0U)
/* NOTE: keep in synch with the value defined in qxk_port.s, see NOTE4 */
/* NOTE: keep in synch with the value defined in "qxk_port.s", NOTE4 */
#define QF_BASEPRI (0xFFU >> 2)
/* QF-aware ISR priority for CMSIS function NVIC_SetPriority(), NOTE5 */
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint8_t)(32U - __CLZ(n_)))
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ(n_)))
#endif
/* QF critical section entry/exit... */
@ -79,7 +79,7 @@
#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 interface */
/*****************************************************************************
* NOTE1:

View File

@ -3,8 +3,8 @@
* @brief QXK/C port to ARM Cortex-M, IAR-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-11-22
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-15
*
* Q u a n t u m L e a P s
* ---------------------------
@ -50,7 +50,9 @@
#define QXK_ISR_EXIT() do { \
QF_INT_DISABLE(); \
QXK_sched_(); \
if (QXK_sched_() != (uint_fast8_t)0) { \
QXK_CONTEXT_SWITCH_(); \
} \
QF_INT_ENABLE(); \
} while (0)

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), IAR ARM assembler
; Last Updated for Version: 5.7.0
; Date of the Last Update: 2016-07-14
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler
; Last Updated for Version: 5.7.1
; Date of the Last Update: 2016-09-16
;
; Q u a n t u m L e a P s
; ---------------------------
@ -32,34 +32,38 @@
; mailto:info@state-machine.com
;*****************************************************************************
PUBLIC QXK_start_ ; start the QXK multitasking
PUBLIC QXK_stackInit_ ; initialize the stack of each thread
PUBLIC PendSV_Handler ; CMSIS-compliant PendSV exception
PUBLIC QXK_init ; initialze the QXK kernel
PUBLIC QXK_stackInit_ ; initialize the stack of an extended thread
PUBLIC PendSV_Handler ; CMSIS-compliant PendSV exception name
PUBLIC NMI_Handler ; CMSIS-compliant NMI exception name
EXTERN QXK_attr_ ; QXK attribute structure
EXTERN QXK_activate_ ; external reference
EXTERN QXK_threadRet_ ; return from a thread function
EXTERN assert_failed ; assert-failure handler
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
QF_BASEPRI EQU (0xFF >> 2)
QF_BASEPRI EQU (0xFF >> 2)
; NOTE: keep in synch with the QXK struct in "qxk.h" !!!
QXK_CURR EQU 0
QXK_NEXT EQU 4
; NOTE: keep in synch with the QXK_Attr struct in "qxk.h" !!!
QXK_CURR EQU 0
QXK_NEXT EQU 4
QXK_TOP_PRIO EQU 8
; NOTE: keep in synch with the QMActive struct in "qf.h/qxk.h" !!!
QMACTIVE_OSOBJECT EQU 40
QMACTIVE_THREAD EQU 44
QMACTIVE_THREAD EQU 40
QMACTIVE_PRIO EQU 44
RSEG CODE:CODE:NOROOT(2)
;*****************************************************************************
; The QXK_start_ function starts QXK multitasking.
; The C signature: void QXK_start_(void);
;
; NOTE: QXK_start_() must be called with interrupts disabled and
; returns with interrupts **enabled**.
; The QXK_init() function sets the priority of PendSV to 0xFF (lowest).
; This operation is performed in a nestable critical section.
;*****************************************************************************
QXK_start_:
QXK_init:
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
CPSID i ; disable interrupts (set PRIMASK)
LDR r1,=0xE000ED18 ; System Handler Priority Register
LDR r2,[r1,#8] ; load the System 12-15 Priority Register
MOVS r3,#0xFF
@ -67,112 +71,195 @@ QXK_start_:
ORRS r2,r3 ; set PRI_14 (PendSV) to 0xFF
STR r2,[r1,#8] ; write the System 12-15 Priority Register
; set the MSP to the top of the C-STACK, which is the first entry
; in the vector table. (This recovers any stack used so far by main().)
LDR r0,=0xE000ED08 ; r0 := address of Vector Table Offset register
LDR r0,[r0,#0] ; r0 := contents of VTOR
LDR r0,[r0] ; r0 := VT[0] (first entry is the top of stack)
MSR MSP,r0 ; main SP := initial top of stack
MSR PRIMASK,r0 ; restore the original PRIMASK
BX lr ; return to the caller
; set the current QXK thread to the next QXK thread
LDR r1,=QXK_attr_
LDR r2,[r1,#QXK_NEXT] ; r2 := QXK_attr_.next
STR r2,[r1,#QXK_CURR] ; QXK_attr_.curr := r2
; get the top of stack of the current QXK thread
LDR r0,[r2,#QMACTIVE_THREAD] ; r0 := QXK_attr_.next->thread (SP)
; pop r4-r11 from the PSP
MOVS r1,r0 ; r1 := top of stack
ADDS r0,r0,#(4*4) ; point r0 to the 4 high registers r7-r11
LDMIA r0!,{r4-r7} ; pop the 4 high registers into low registers
;*****************************************************************************
; The PendSV_Handler exception handler is used for handling context switch
; and asynchronous preemption in QXK. The use of the PendSV exception is
; the recommended and most efficient method for performing context switches
; with ARM Cortex-M.
;
; The PendSV exception should have the lowest priority in the whole system
; (0xFF, see QXK_init). All other exceptions and interrupts should have higher
; priority. For example, for NVIC with 2 priority bits all interrupts and
; exceptions must have numerical value of priority lower than 0xC0. In this
; case the interrupt priority levels available to your applications are (in
; the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00.
;
; Also, *all* "kernel aware" ISRs in the QXK application must call the
; QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for
; a context switch or asynchronous preemption.
;
; Due to tail-chaining and its lowest priority, the PendSV exception will be
; entered immediately after the exit from the *last* nested interrupt (or
; exception). In QXK, this is exactly the time when the QXK scheduler needs to
; check for the asynchronous preemption.
;*****************************************************************************
PendSV_Handler:
; Prepare some constants (an address and a bitmask) before entering
; a critical section...
LDR r3,=QXK_attr_
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (1 << 27) (UNPENDSVSET bit)
; <<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<<
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSID i ; disable interrupts (set PRIMASK)
#else ; M3/M4/M7
MOVS r0,#QF_BASEPRI
MSR BASEPRI,r0 ; selectively disable interrupts
#endif ; M3/M4/M7
; The PendSV exception handler can be preempted by an interrupt,
; which might pend PendSV exception again. The following write to
; ICSR[27] un-pends any such spurious instance of PendSV.
STR r1,[r2] ; ICSR[27] := 1 (unpend PendSV)
; Check QXK_attr_.next, which contains the pointer to the next thread
; to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
LDR r0,[r3,#QXK_NEXT] ; r1 := QXK_attr_.next
CMP r0,#0 ; is (QXK_attr_.next == 0)?
BEQ PendSV_error ; branch if (QXK_attr_.next == 0)
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
LDR r2,[r0,#QMACTIVE_THREAD] ; r2 := QXK_attr_.next->thread
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)?
BNE PendSV_save_ao ; branch if (next tread is extended)
PendSV_activate:
#ifdef __ARMVFP__ ; if VFP available...
PUSH {r0,lr} ; ... push lr (EXC_RETURN) plus stack-aligner
#endif ; VFP available
; The QXK activator must be called in a thread context, while this code
; executes in the handler contex of the PendSV exception. The switch
; to the Thread mode is accomplished by returning from PendSV using
; a fabricated exception stack frame, where the return address is the
; QXK activator QXK_activate_().
;
; NOTE: the QXK activator is called with interrupts DISABLED and also
; it returns with interrupts DISABLED.
MOVS r3,#1
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
LDR r2,=QXK_activate_ ; address of the QXK activator (new pc)
LDR r1,=Thread_ret ; return address after the call (new lr)
SUB sp,sp,#8*4 ; reserve space for exception stack frame
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
STM r0!,{r1-r3} ; save xpsr,pc,lr
MOVS r0,#6
MVNS r0,r0 ; r0 := ~6 == 0xFFFFFFF9
BX r0 ; exception-return to the QXK activator
;-------------------------------------------------------------------------
PendSV_error:
LDR r3,=assert_failed
BX r3 ; long-branch to the assertion-handler
;=========================================================================
; Saving AO-thread before crossing to eXtended-thread
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ao:
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
PUSH {r4-r7} ; save the low registers
MOV r4,r8 ; move the high registers to low registers...
MOV r5,r9
MOV r6,r10
MOV r7,r11
PUSH {r4-r7} ; save the high registers
#else ; M3/M4/M7
PUSH {r4-r11} ; save r4-r11 on top of the exception frame
#ifdef __ARMVFP__ ; if VFP available...
TST lr,#(1 << 4) ; is it return with the VFP exception frame?
IT EQ ; if lr[4] is zero...
VSTMDBEQ sp!,{s16-s31} ; ... save VFP registers s16..s31
PUSH {r0,lr} ; save the "aligner" and the EXC_RETURN value
#endif ; VFP available
#endif ; M3/M4/M7
CMP r2,#0
BNE PendSV_restore_ex ; branch if (QXK_attr_.next->thread != 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)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ao:
MOVS r0,#0
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0 (QXK_attr_.next)
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
MOV r0,sp ; r0 := top of stack
MOV r1,r0
ADDS r1,r1,#(4*4) ; point r0 to the 4 high registers r7-r11
LDMIA r1!,{r4-r7} ; pop the 4 high registers into low registers
MOV r8,r4 ; move low registers into high registers
MOV r9,r5
MOV r10,r6
MOV r11,r7
LDMIA r1!,{r4-r7} ; pop the low registers
; NOTE: at this point r0 holds the new top of stack
LDMIA r0!,{r4-r7} ; pop the low registers
ADD sp,sp,#(8*4) ; remove 8 registers from the stack
MSR PSP,r0 ; set PSP to the thread's SP
ISB ; flush the instruction pipeline
MOVS r1,#6
MVNS r1,r1 ; r2 := ~6 == 0xFFFFFFF9
MOV lr,r1 ; make sure MSP is used
#else ; M3/M4/M7
#ifdef __ARMVFP__ ; if VFP available...
POP {r0,lr} ; restore alighner and EXC_RETURN into lr
TST lr,#(1 << 4) ; is it return to the VFP exception frame?
IT EQ ; if EXC_RETURN[4] is zero...
VLDMIAEQ sp!,{s16-s31} ; ... restore VFP registers s16..s31
#else
BIC lr,lr,#(1 << 2) ; make sure MSP is used
#endif ; VFP available
POP {r4-r11} ; restore r4-r11 from the next thread's stack
#endif ; M3/M4/M7
; switch CPU to using the Process Stack Pointer (PSP)
MRS r0,CONTROL
MOVS r1,#(1 << 1)
ORRS r0,r0,r1 ; set the Active Stack Pointer
MSR CONTROL,r0 ; switch to PSP
DSB ; make sure all data access completes
ISB ; flush the instruction pipeline
MOV r0,r12 ; r0 := QXK_attr_.next
LDR r0,[r0,#QMACTIVE_PRIO] ; r0 := QXK_attr_.next->prio
LDR r1,[r3,#QXK_TOP_PRIO] ; r1 := QXK_attr_.topPrio
CMP r1,r0
BCC PendSV_activate ; if (next->prio > topPrio) activate the next AO
; fake return from an exception...
POP {r0-r3} ; pop R0..R3
; NOTE: R0 holds the 'par' argument of the
; thread function
POP {r1,r2} ; pop R12 and LR into low registers r1,r2
MOV r12,r1
MOV lr,r2
POP {r1,r2} ; pop PC to R1 and xPSR to R2
; NOTE: it's OK to clobber R1 and R2
; otherwise re-enable interrupts and return to the preempted AO-thread
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
#else ; M3/M4/M7
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
#endif ; M3/M4/M7
; >>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>>
BX lr ; return to the preempted AO-thread
#ifdef __ARMVFP__ ; if VFP available...
; enable VFP by enabling CP10 and CP11 coprocessors
LDR.W r3,=0xE000ED88 ; r3 := &CPACR
LDR r2,[r3] ; r2 := CPACR
ORR r2,r2,#(0xF << 20); r2 := r2 | (CP10 | CP11)
STR r2,[r3] ; CPACR = r2
DSB ; make sure all data access completes
ISB ; reset the instruction pipeline
; enable Automatic State Preservation and Lazy Stacking in the VFP
LDR r3,=0xE000EF34 ; r3 := &FPCCR
LDR r2,[r3] ; r2 := FPCCR
ORR r2,r2,#(3 << 30) ; set ASPEN | LSPEN
STR r2,[r3] ; FPCCR &= ~(ASPEN | LSPEN)
; clear the VFP Context Active (FPCA) bit in CONTROL
MRS r2,CONTROL ; r2 := CONTROL (NOTE: it's OK to clobber R2)
BICS r2,r2,#(1 << 2) ; r2 := r2 & ~(1 << 2) (FPCA bit)
MSR CONTROL,r2 ; CONTROL := r2 (clear CONTROL[2] FPCA bit)
#endif ; VFP available
MOVS r2,#0 ; NOTE: it's OK to clobber R2
MSR BASEPRI,r2 ; enable interrupts (clear BASEPRI)
#endif ; M3/M4/M7
BX r1 ; return to the "interrupted" thread (PC)
;*****************************************************************************
; The PendSV_Handler exception handler is used for context switching in QXK.
; The use of the PendSV exception is the recommended and most efficient
; method for performing context switches with ARM Cortex-M.
;
; The PendSV exception should have the lowest priority in the whole system
; (0xFF, see QXK_start_). All other exceptions and interrupts should have
; higher priority. For example, for NVIC with 2 priority bits all interrupts
; and exceptions must have numerical value of priority lower than 0xC0.
; In this case the interrupt priority levels available to your applications
; are (in the order from the lowest to the highest urgency): 0x80, 0x40, 0x00.
;
; Also, *all* "kernel-aware" ISRs in the QXK application must call the
; QXK_ISR_EXIT() macro to trigger the PendSV exception.
;
; The C signature (CMSIS): void PendSV_Handler(void);
;
; NOTE:
; Due to tail-chaining and its lowest priority, the PendSV exception will be
; entered immediately after the exit from the *last* nested interrupt (or
; exception). In QXK, this is exactly the time when the QXK context switch
; must occur.
;*****************************************************************************
PendSV_Handler:
;-------------------------------------------------------------------------
; Saving extended-thread before crossing to AO-thread
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_save_ex:
MRS r0,PSP ; r0 := Process Stack Pointer
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
LDR r3,=QXK_attr_
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
SUBS r0,r0,#(8*4) ; make room for 8 registers r4-r11
MOVS r1,r0 ; r1 := temporary PSP (do not clobber r0!)
@ -182,83 +269,128 @@ PendSV_Handler:
MOV r6,r10
MOV r7,r11
STMIA r1!,{r4-r7} ; save the high registers
; NOTE: at this point r0 still holds the top of stack
CPSID i ; disable interrupts (set PRIMASK)
; NOTE: at this point r0 holds the top of stack
LDR r1,[r3,#QXK_CURR] ; r1 := QXK_attr_.curr (restore value)
#else ; M3/M4/M7
STMDB r0!,{r4-r11} ; save r4-r11 on top of the exception frame
#ifdef __ARMVFP__ ; if VFP available...
TST lr,#(1 << 4) ; is it return with the VFP exception frame?
IT EQ ; if lr[4] is zero...
VSTMDBEQ r0!,{s16-s31} ; ... save VFP registers s16..s31
STMDB r0!,{r1,lr} ; save the "aligner" and the EXC_RETURN value
#endif ; VFP available
MOVS r1,#QF_BASEPRI
MSR BASEPRI,r1 ; selectively disable interrupts
#endif ; M3/M4/M7
; NOTE: This PendSV exception handler can be preempted by an
; interrupt, which might pend PendSV exception again. This
; would be a problem, because the QK scheduler would run again
; after this PendSV instance, so the same AO would be scheduled
; twice. The following write to ICSR[7] un-pends any such spurious
; instance of PendSV.
MOVS r1,#1
LSLS r1,r1,#27 ; r1 := (1 << 27) (UNPENDSVSET bit)
STR r1,[r2] ; ICSR[27] := 1 (unpend PendSV)
; store the SP of the current extended-thread
STR r0,[r1,#QMACTIVE_THREAD] ; QXK_attr_.curr->thread := r0
MOV r0,r12 ; QXK_attr_.next (restore value)
; store the SP of the current QXK thread,
; which was set in QXK_ISR_EXIT().
LDR r2,[r3,#QXK_CURR]
STR r0,[r2,#QMACTIVE_THREAD] ; QXK_attr_.curr->thread := r0
CMP r2,#0
BEQ PendSV_restore_ao ; branch if (QXK_attr_.next->thread == 0)
; otherwise continue to restoring next extended-thread...
#ifdef __ARMVFP__ ; if VFP available...
; store the LR of the current QXK thread...
STR lr,[r2,#QMACTIVE_OSOBJECT] ; QXK_attr_.curr->osObject := lr
#endif ; VFP available
; set current to the next...
LDR r2,[r3,#QXK_NEXT] ; r2 := QXK_attr_.next
STR r2,[r3,#QXK_CURR] ; QXK_attr_.curr := r2
; restore the SP of the next thread...
LDR r0,[r2,#QMACTIVE_THREAD] ; r0 := QXK_attr_.next->thread (SP)
#ifdef __ARMVFP__ ; if VFP available...
; restore the LR of the next thread...
LDR lr,[r2,#QMACTIVE_OSOBJECT] ; lr := QXK_attr_.next->osObject
#endif ; VFP available
;-------------------------------------------------------------------------
; Restoring extended-thread after crossing from AO-thread
; expected register contents:
; r0 -> QXK_attr_.next
; r1 -> QXK_attr_.curr
; r2 -> QXK_attr_.next->thread (SP)
; r3 -> &QXK_attr_
; r12 -> QXK_attr_.next
PendSV_restore_ex:
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := r0 (QXK_attr_.next)
; exit the critical section
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
MOVS r1,r0 ; r1 := top of stack
MOVS r0,r2 ; r2 := top of stack
ADDS r0,r0,#(4*4) ; point r0 to the 4 high registers r7-r11
LDMIA r0!,{r4-r7} ; pop the 4 high registers into low registers
MOV r8,r4 ; move low registers into high registers
MOV r9,r5
MOV r10,r6
MOV r11,r7
LDMIA r1!,{r4-r7} ; pop the low registers
; NOTE: at this point r0 holds the new top of stack
#else ; M3/M4/M7
MOVS r3,#0
MSR BASEPRI,r3 ; enable interrupts (clear BASEPRI)
LDMIA r2!,{r4-r7} ; pop the low registers
MOVS r2,r0 ; r2 := holds the new top of stack
MOVS r1,#2
MVNS r1,r1 ; r1 := ~2 == 0xFFFFFFFD
MOV lr,r1 ; make sure PSP is used
#else ; M3/M4/M7
MOVS r1,#1
MSR BASEPRI,r1 ; enable interrupts (clear BASEPRI)
#ifdef __ARMVFP__ ; if VFP available...
LDMIA r2!,{r1,lr} ; restore aligner and EXC_RETURN into lr
TST lr,#(1 << 4) ; is it return to the VFP exception frame?
IT EQ ; if lr[4] is zero...
VLDMIAEQ r0!,{s16-s31} ; ... restore VFP registers s16..s31
VLDMIAEQ r2!,{s16-s31} ; ... restore VFP registers s16..s31
#else
ORR lr,lr,#(1 << 2) ; make sure PSP is used
#endif ; VFP available
LDMIA r0!,{r4-r11} ; restore r4-r11 from the next thread's stack
#endif ; M3/M4/M7
LDMIA r2!,{r4-r11} ; restore r4-r11 from the next thread's stack
#endif ; M3/M4/M7
; set the PSP to the next thread's SP
MSR PSP,r0 ; Process Stack Pointer := r0
MSR PSP,r2 ; Process Stack Pointer := r2
BX lr ; return to the next thread
BX lr ; return to the next extended-thread
;*****************************************************************************
; Thread_ret is a helper function executed when the QXK activator returns.
;
; NOTE: Thread_ret does not execute in the PendSV context!
; NOTE: Thread_ret executes entirely with interrupts DISABLED.
;*****************************************************************************
Thread_ret:
; After the QXK activator returns, we need to resume the preempted
; thread. However, this must be accomplished by a return-from-exception,
; while we are still in the thread context. The switch to the exception
; contex is accomplished by triggering the NMI exception.
; before triggering the NMI exception, make sure that the
; VFP stack frame will NOT be used...
#ifdef __ARMVFP__ ; if VFP available...
MRS r0,CONTROL ; r0 := CONTROL
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
#endif ; VFP available
; trigger NMI to return to preempted task...
; NOTE: The NMI exception is triggered with nterrupts DISABLED
LDR r0,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#31 ; r1 := (1 << 31) (NMI bit)
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
B . ; wait for preemption by NMI
;*****************************************************************************
; The NMI_Handler exception handler is used for returning back to the
; interrupted task. The NMI exception simply removes its own interrupt
; stack frame from the stack and returns to the preempted task using the
; interrupt stack frame that must be at the top of the stack.
;
; NOTE: The NMI exception is entered with interrupts DISABLED, so it needs
; to re-enable interrupts before it returns to the preempted task.
;*****************************************************************************
NMI_Handler:
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
BX lr ; return to the preempted task
#else ; M3/M4/M7
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
#ifdef __ARMVFP__ ; if VFP available...
POP {r0,pc} ; pop stack "aligner" and EXC_RETURN to PC
#else ; no VFP
BX lr ; return to the preempted task
#endif ; no VFP
#endif ; M3/M4/M7
;*****************************************************************************
@ -283,8 +415,8 @@ QXK_stackInit_:
; r2 - begining of stack
; r3 - size of stack [bytes]
ADDS r3,r2,r3 ; r3 := end of stack (top of stack)
MOV r12,r0 ; save r0 in r12
MOV r12,r0 ; temporarily save r0 in r12 (act)
STR r1,[r0,#QMACTIVE_THREAD] ; temporarily save the thread routine
; round up the beginning of stack to the 8-byte boundary
; r2 := (((r2 -1) >> 3) + 1) << 3;
@ -295,80 +427,86 @@ QXK_stackInit_:
; round down the end of stack to the 8-byte boundary
; r3 := (r3 >> 3) << 3;
ADDS r3,r2,r3 ; r3 := end of stack (top of stack)
LSRS r0,r3,#3
LSLS r3,r0,#3
; make room for the thread's stack frame...
SUBS r3,r3,#16*4 ; r3 := top of the 16-register stack frame
#ifdef __ARMVFP__ ; if VFP available...
SUBS r3,r3,#2*4 ; r3 := top of the 18-register stack frame
#endif ; VFP available
MOV r0,r12
STR r1,[r0,#QMACTIVE_OSOBJECT] ; temporarily save the thread routine
; pre-fill the stack with 0xDEADBEEF
; pre-fill the unused part of the stack with 0xDEADBEEF...................
LDR r0,=0xDEADBEEF
MOV r1,r0
QXK_stackInit_fill:
STMIA r2!,{r0,r1}
CMP r2,r3
BLT.N QXK_stackInit_fill
; prepare the standard exception (without VFP) stack frame...
MOV r0,r12 ; restore r0 from r12
MOVS r2,#0x04
STR r2,[r3,#0*4] ; r4
MOVS r2,#0x05
STR r2,[r3,#1*4] ; r5
MOVS r2,#0x06
STR r2,[r3,#2*4] ; r6
MOVS r2,#0x07
STR r2,[r3,#3*4] ; r7
MOVS r2,#0x08
STR r2,[r3,#4*4] ; r8
MOVS r2,#0x09
STR r2,[r3,#5*4] ; r9
MOVS r2,#0x0A
STR r2,[r3,#6*4] ; r10
MOVS r2,#0x0B
STR r2,[r3,#7*4] ; r11
STR r0,[r3,#8*4] ; r0 (argument to thread routine, act pointer)
MOVS r2,#0x01
STR r2,[r3,#9*4] ; r1
MOVS r2,#0x02
STR r2,[r3,#10*4] ; r2
MOVS r2,#0x03
STR r2,[r3,#11*4] ; r3
MOVS r2,#0x0C
STR r2,[r3,#12*4] ; r12
LDR r2,=QXK_threadRet_
STR r2,[r3,#13*4] ; LR (return address)
LDR r1,[r0,#QMACTIVE_OSOBJECT] ; r1 := saved thread routine
STR r1,[r3,#14*4] ; PC (entry point, thread routine)
MOVS r2,#1
LSLS r2,r2,#24 ; r2 := 0x01000000
STR r2,[r3,#15*4] ; xPSR
; 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
STR r3,[r0,#QMACTIVE_THREAD] ; act->thread := top of stack
#ifdef __ARMVFP__ ; if VFP available...
MOVS r2,#0
STMIA r3!,{r2} ; stack "aligner"
; synthesize EXC_RETURN for return to Thread mode with no FPU-state
MOVS r2,#2
MVNS r2,r2 ; r2 := ~2 == 0xFFFFFFFD
STR r2,[r0,#QMACTIVE_OSOBJECT] ; act->thread.osObject := lr
STMIA r3!,{r2} ; save EXC_RETURN
#endif ; VFP available
MOVS r2,#0x04
STMIA r3!,{r2} ; r4
MOVS r2,#0x05
STMIA r3!,{r2} ; r5
MOVS r2,#0x06
STMIA r3!,{r2} ; r6
MOVS r2,#0x07
STMIA r3!,{r2} ; r7
MOVS r2,#0x08
STMIA r3!,{r2} ; r8
MOVS r2,#0x09
STMIA r3!,{r2} ; r9
MOVS r2,#0x0A
STMIA r3!,{r2} ; r10
MOVS r2,#0x0B
STMIA r3!,{r2} ; r11
STMIA r3!,{r0} ; r0 (argument to thread routine, me pointer)
MOVS r2,#0x01
STMIA r3!,{r2} ; r1
MOVS r2,#0x02
STMIA r3!,{r2} ; r2
MOVS r2,#0x03
STMIA r3!,{r2} ; r3
MOVS r2,#0x0C
STMIA r3!,{r2} ; r12
LDR r2,=QXK_threadRet_
STMIA r3!,{r2} ; LR (return address)
STMIA r3!,{r1} ; PC (entry point, thread routine)
MOVS r2,#1
LSLS r2,r2,#24 ; r2 := 0x01000000
STMIA r3!,{r2} ; xPSR
BX lr ; return to the caller

View File

@ -4,14 +4,14 @@
* @ingroup ports
* @cond
******************************************************************************
* Last Updated for Version: 5.4.0
* Date of the Last Update: 2015-04-08
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-11-20
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) Quantum Leaps, LLC. state-machine.com.
* Copyright (C) Quantum Leaps, LLC. 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
@ -32,8 +32,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact information:
* Web: www.state-machine.com
* Email: info@state-machine.com
* http://www.state-machine.com
* mailto:info@state-machine.com
******************************************************************************
* @endcond
*/

View File

@ -1,10 +1,10 @@
/**
* @file
* @brief QF/C port to Cortex-M, preemptive QXK kernel, TI-ARM toolset
* @brief QF/C port to Cortex-M, dual-mode QXK kernel, TI-ARM toolset
* @cond
******************************************************************************
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-12
* Last Updated for Version: 5.7.1
* Date of the Last Update: 2016-09-18
*
* Q u a n t u m L e a P s
* ---------------------------
@ -56,17 +56,12 @@
/* QF-aware ISR priority for CMSIS function NVIC_SetPriority(), NOTE4 */
#define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS))
/* QF interrupt disable/enable */
#define QF_INT_DISABLE() QF_set_BASEPRI(QF_BASEPRI)
#define QF_INT_ENABLE() QF_set_BASEPRI(0U)
/* the intrinsic function _norm() generates the CLZ instruction */
#define QF_LOG2(n_) ((uint8_t)(32U - _norm(n_)))
/* assembly function for setting the BASEPRI register */
//__attribute__((always_inline))
//static inline void __set_BASEPRI(unsigned basePri) {
// __asm (" msr basepri, basePri");
//}
/* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */
#define QF_LOG2(n_) ((uint_fast8_t)(32U - __clz(n_)))
void QF_set_BASEPRI(unsigned basePri);
@ -83,7 +78,7 @@
#endif /* not M3/M4/M7 */
/* QF critical section entry/exit */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt enabling" policy */
/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt disabling policy */
#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE()
#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE()
#define QF_CRIT_EXIT_NOP() __asm(" ISB")
@ -91,7 +86,7 @@
#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 interface */
/*****************************************************************************
* NOTE1:

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