This commit is contained in:
Quantum Leaps 2016-04-25 10:55:26 -04:00
parent 7febc1a01b
commit bdc74240aa
28 changed files with 331 additions and 438 deletions

4
.gitignore vendored
View File

@ -21,6 +21,7 @@
*.log
*.chm
*.zip
*.pdb
*.ncb
*.suo
*.chw
@ -29,7 +30,7 @@
*.avrsuo
*.Debug
*.Release
lint*.out
lint*.txt
*.Miro
*.bak
@ -40,6 +41,7 @@ dbg/
rel/
spy/
settings/
.settings/
Debug/
Release/

View File

@ -2,7 +2,7 @@
; * @file startup_TM4C123GH6PM.s for IAR ARM assembler
; * @brief CMSIS Cortex-M4F Core Device Startup File for TM4C123GH6PM
; * @version CMSIS 4.3.0
; * @date 20 August 2015
; * @date 24 April 2016
; *
; * @description
; * Created from the CMSIS template for the specified device
@ -521,11 +521,10 @@ PWM1Gen2_IRQHandler
PWM1Gen3_IRQHandler
PWM1Fault_IRQHandler
MOVS r0,#0
MOVS r1,#-1 ; 0xFFFFFFF
MOVS r1,#0xFF
B assert_failed
;******************************************************************************
;
;*****************************************************************************
; The function assert_failed defines the error/assertion handling policy
; for the application. After making sure that the stack is OK, this function
; calls Q_onAssert, which should NOT return (typically reset the CPU).
@ -535,11 +534,12 @@ PWM1Fault_IRQHandler
; The C proptotype of the assert_failed() and Q_onAssert() functions are:
; void assert_failed(char const *file, int line);
; void Q_onAssert (char const *file, int line);
;******************************************************************************
;*****************************************************************************
PUBLIC assert_failed
EXTERN Q_onAssert
assert_failed
LDR sp,=sfe(CSTACK) ; re-set the SP in case of stack overflow
LDR r2,=sfe(CSTACK) ; load the original top of stack
MOV sp,r2 ; re-set the SP in case of stack overflow
BL Q_onAssert ; call the application-specific handler
B . ; should not be reached, but just in case...

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C++"
PROJECT_NUMBER = "5.6.3"
PROJECT_NUMBER = "5.6.4"
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.6.3"
PROJECT_NUMBER = "5.6.4"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =

View File

@ -1,8 +1,12 @@
namespace QP {
/** @page history Revision History
@section qpcpp_5_6_4 Version 5.6.4, 2016-04-25
This release fixes a serious Bug #128 (https://sourceforge.net/p/qpc/bugs/128 ) in the QK port to ARM Cortex-M introduced back in QP 5.6.1
------------------------------------------------------------------------------
@section qpcpp_5_6_3 Version 5.6.3, 2016-04-12
This release fixes a serious Bug #127 (https://sourceforge.net/p/qpc/bugs/127 ) in the QK preemptive scheduler introduced in QP 5.6.2.

View File

@ -1,8 +1,8 @@
@echo off
:: ==========================================================================
:: Product: QP/C++ script for generating Doxygen documentation
:: Last Updated for Version: 5.6.3
:: Date of the Last Update: 2016-04-12
:: Last Updated for Version: 5.6.4
:: Date of the Last Update: 2016-04-24
::
:: 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.6.3
set VERSION=5.6.4
:: Generate Resource Standard Metrics for QP/C++ .............................
set DOXHOME="C:\tools\doxygen\bin"

View File

@ -1,7 +1,7 @@
/** @page metrics Code Metrics
@code
Standard Code Metrics for QP/C++ 5.6.3
Standard Code Metrics for QP/C++ 5.6.4
Resource Standard Metrics (TM) for C, C++, C# and Java
Version 7.75 - mSquaredTechnologies.com
@ -9,7 +9,7 @@
License Type: Windows Single User License
Licensed To : Quantum Leaps, LLC
License No. : WS2975 License Date: Dec 15, 2013
Build Date : Sep 2 2009 Run Date: Apr 12, 2016
Build Date : Sep 2 2009 Run Date: Apr 24, 2016
(C)1996-2009 M Squared Technologies LLC
________________________________________________________________________

View File

@ -8,7 +8,6 @@
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 48 19 Warning 530: Symbol 'regIPSR' (line 46) not initialized [MISRA C++ Rule 8-5-1]
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 46 1 Info 830: Location cited in prior message
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 52 32 Note 1923: macro 'QK_ISR_ENTRY' could become const variable [MISRA C++ Rule 16-2-2]
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 65 33 Note 1960: Violates MISRA C++ 2008 Required Rule 7-3-1, Global declaration of symbol 'QK_nextPrio_'
"C:\qp\qpcpp\include\qpset.h" 128 58 Note 1960: Violates MISRA C++ 2008 Required Rule 5-0-8, Cast of integer cvalue expression to larger type
"C:\qp\qpcpp\include\qpset.h" 221 21 Note 1960: Violates MISRA C++ 2008 Required Rule 5-0-8, Cast of integer cvalue expression to larger type
"C:\qp\qpcpp\include\qpset.h" 224 21 Note 1960: Violates MISRA C++ 2008 Required Rule 5-0-8, Cast of integer cvalue expression to larger type
@ -57,7 +56,6 @@
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 48 19 Warning 530: Symbol 'regIPSR' (line 46) not initialized [MISRA C++ Rule 8-5-1]
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 46 1 Info 830: Location cited in prior message
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 52 32 Note 1923: macro 'QK_ISR_ENTRY' could become const variable [MISRA C++ Rule 16-2-2]
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qk_port.h" 65 33 Note 1960: Violates MISRA C++ 2008 Required Rule 7-3-1, Global declaration of symbol 'QK_nextPrio_'
"C:\qp\qpcpp\ports\arm-cm\qk\gnu\qs_port.h" 51 10 Warning 537: Repeated include file 'C:\qp\qpcpp\ports\arm-cm\qk\gnu\qf_port.h'
"C:\qp\qpcpp\include\qs.h" 61 9 Note 1960: Violates MISRA C++ 2008 Required Rule 16-0-4, Function-like macro defined: 'QS_PTR_AT_'
"C:\qp\qpcpp\include\qs.h" 61 37 Note 1960: Violates MISRA C++ 2008 Required Rule 16-0-6, unparenthesized macro parameter in definition of macro: 'QS_PTR_AT_'
@ -476,4 +474,4 @@ Count Type Number Text
2 Note 963 Qualifier const or volatile ___ a type; use ___ to reverse the test
1 Note 1914 Default constructor '___' (___) not referenced
2 Note 1923 macro '___' could become const variable
27 Note 1960 Violates MISRA C++ 2008 Required Rule ___, ___
25 Note 1960 Violates MISRA C++ 2008 Required Rule ___, ___

View File

@ -2,7 +2,7 @@
* Purpose: startup file for TM4C123GH6PM Cortex-M4 device.
* Should be used with TI CCS-ARM Compiler
* Version: CMSIS 4.3.0
* Date: 2015-Nov-10
* Date: 2016-Apr-22
*
* Created from the CMSIS template for the specified device
* Quantum Leaps, www.state-machine.com
@ -373,6 +373,7 @@ void Default_Handler(void) {
);
}
/*..........................................................................*/
/* defined in QK port
void NMI_Handler(void) {
__asm(
" .global assert_failed\n\r"
@ -381,6 +382,7 @@ void NMI_Handler(void) {
" b.w assert_failed\n\r"
);
}
*/
/*..........................................................................*/
void MemManage_Handler(void) {
__asm(

View File

@ -1,45 +0,0 @@
/******************************************************************************
*
* Default Linker Command file for the Texas Instruments TM4C123GH6PM
*
* This is derived from revision 14351 of the TivaWare Library.
*
*****************************************************************************/
--retain=g_pfnVectors
MEMORY
{
FLASH (RX) : origin = 0x00000000, length = 0x00040000
SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}
/* The following command line options are set as part of the CCS project. */
/* If you are building using the command line, or for some reason want to */
/* define them here, you can uncomment and modify these lines as needed. */
/* If you are using CCS for building, it is probably better to make any such */
/* modifications in your CCS project and leave this file alone. */
/* */
/* --heap_size=0 */
/* --stack_size=256 */
/* --library=rtsv7M4_T_le_eabi.lib */
/* Section allocation in memory */
SECTIONS
{
.intvecs: > 0x00000000
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.vtable : > 0x20000000
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}
__STACK_TOP = __stack + 512;

View File

@ -1,45 +0,0 @@
/******************************************************************************
*
* Default Linker Command file for the Texas Instruments TM4C123GH6PM
*
* This is derived from revision 14351 of the TivaWare Library.
*
*****************************************************************************/
--retain=g_pfnVectors
MEMORY
{
FLASH (RX) : origin = 0x00000000, length = 0x00040000
SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}
/* The following command line options are set as part of the CCS project. */
/* If you are building using the command line, or for some reason want to */
/* define them here, you can uncomment and modify these lines as needed. */
/* If you are using CCS for building, it is probably better to make any such */
/* modifications in your CCS project and leave this file alone. */
/* */
/* --heap_size=0 */
/* --stack_size=256 */
/* --library=rtsv7M4_T_le_eabi.lib */
/* Section allocation in memory */
SECTIONS
{
.intvecs: > 0x00000000
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.vtable : > 0x20000000
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}
__STACK_TOP = __stack + 512;

View File

@ -1,45 +0,0 @@
/******************************************************************************
*
* Default Linker Command file for the Texas Instruments TM4C123GH6PM
*
* This is derived from revision 14351 of the TivaWare Library.
*
*****************************************************************************/
--retain=g_pfnVectors
MEMORY
{
FLASH (RX) : origin = 0x00000000, length = 0x00040000
SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}
/* The following command line options are set as part of the CCS project. */
/* If you are building using the command line, or for some reason want to */
/* define them here, you can uncomment and modify these lines as needed. */
/* If you are using CCS for building, it is probably better to make any such */
/* modifications in your CCS project and leave this file alone. */
/* */
/* --heap_size=0 */
/* --stack_size=256 */
/* --library=rtsv7M4_T_le_eabi.lib */
/* Section allocation in memory */
SECTIONS
{
.intvecs: > 0x00000000
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.vtable : > 0x20000000
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}
__STACK_TOP = __stack + 512;

View File

@ -2,14 +2,14 @@
/// @brief QK/C++ port to ARM Cortex-M, ARM-KEIL toolset
/// @cond
///***************************************************************************
/// Last updated for version 5.5.2
/// Last updated on 2015-11-11
/// Last updated for version 5.6.4
/// Last updated on 2016-04-25
///
/// Q u a n t u m L e a P s
/// ---------------------------
/// innovating embedded systems
///
/// Copyright (C) Quantum Leaps, www.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
@ -30,7 +30,7 @@
/// along with this program. If not, see <http://www.gnu.org/licenses/>.
///
/// Contact information:
/// http:// www.state-machine.com
/// http://www.state-machine.com
/// mailto:info@state-machine.com
///***************************************************************************
/// @endcond
@ -49,19 +49,9 @@ static __inline uint32_t QK_get_IPSR(void) {
// QK interrupt entry and exit
#define QK_ISR_ENTRY() ((void)0)
#define QK_ISR_EXIT() do { \
QF_INT_DISABLE(); \
uint_fast8_t nextPrio_ = QK_schedPrio_(); \
if (nextPrio_ != static_cast<uint_fast8_t>(0)) { \
QK_nextPrio_ = nextPrio_; \
(*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) \
= static_cast<uint32_t>(1U << 28)); \
} \
QF_INT_ENABLE(); \
} while (false)
extern uint_fast8_t QK_nextPrio_; // priority of the next task to execute
#define QK_ISR_EXIT() \
((*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
static_cast<uint32_t>(1U << 28)))
#include "qk.h" // QK platform-independent public interface

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), ARM-Keil assembler
; Last Updated for Version: 5.6.0
; Date of the Last Update: 2015-12-14
; Last Updated for Version: 5.6.4
; Date of the Last Update: 2016-04-21
;
; Q u a n t u m L e a P s
; ---------------------------
@ -34,7 +34,7 @@
EXPORT QK_init
EXPORT PendSV_Handler ; CMSIS-compliant PendSV exception name
EXPORT QK_nextPrio_ ; priority of the next task to execute
EXPORT NMI_Handler ; CMSIS-compliant NMI exception name
IMPORT QK_schedPrio_ ; external reference
IMPORT QK_sched_ ; external reference
@ -42,14 +42,6 @@
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
QF_BASEPRI EQU (0xFF:SHR:2)
AREA |.data|, DATA, READWRITE
;*****************************************************************************
; Global priority of the next task to execute or zero to indicate return
; to the preempted task
;*****************************************************************************
QK_nextPrio_
DCD 0
AREA |.text|, CODE, READONLY
THUMB
@ -105,14 +97,15 @@ PendSV_Handler
ENDIF ; M3/M4/M7
ISB ; reset the instruction pipeline
LDR r0,=QK_nextPrio_
LDR r0,[r0]
CMP r0,#0
BNE.N PendSV_sched ; if QK_nextPrio_ != 0, branch to scheduler
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
ENDIF ; VFP available
; QK_nextPrio_ == 0: return to the preempted task...
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
BL QK_schedPrio_ ; call QK_schedPrio_()
CMP r0,#0 ; is the returned next prio 0?
BNE.N PendSV_sched ; if next prio != 0, branch to scheduler
PendSV_ret
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
MOVS r0,#6
@ -130,18 +123,20 @@ PendSV_Handler
ENDIF ; no VFP
ENDIF ; M3/M4/M7
PendSV_sched
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
ENDIF ; VFP available
PendSV_sched ; call the QK scheduler...
; NOTE: The QK scheduler must be called in a task context, while
; we are still in the PendSV exception context. The switch to the
; task context is accomplished by returning from PendSV using a
; fabricated exception stack frame, where the return address is
; the QK scheduler.
; NOTE: the QK scheduler is called with interrupts DISABLED.
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,=PendSV_sched_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)
STR r0,[sp] ; save the prio argument (new r0)
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
STM r0!,{r1-r3} ; save xpsr,pc,lr
@ -150,28 +145,53 @@ PendSV_sched
BX r0 ; exception-return to the QK scheduler
PendSV_sched_ret
LDR r0,=QK_nextPrio_
MOVS r1,#0
STR r1,[r0] ; QK_nextPrio_ = 0;
; NOTE: 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 NMI exception.
; NOTE: The NMI exception is triggered with nterrupts DISABLED,
; because QK scheduler disables interrutps before return.
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
ELSE ; M3/M4/M7
; 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
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
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) (PENDSVSET 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 ; no VFP
BX lr ; return to the preempted task
ENDIF ; no VFP
ENDIF ; M3/M4/M7
ALIGN ; make sure the END is properly aligned

View File

@ -2,14 +2,14 @@
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, GNU-ARM toolset
/// @cond
///***************************************************************************
/// Last updated for version 5.5.2
/// Last updated on 2015-11-11
/// Last updated for version 5.6.4
/// Last updated on 2016-04-25
///
/// Q u a n t u m L e a P s
/// ---------------------------
/// innovating embedded systems
///
/// Copyright (C) Quantum Leaps, www.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
@ -50,19 +50,9 @@ static inline uint32_t QK_get_IPSR(void) {
// QK interrupt entry and exit
#define QK_ISR_ENTRY() ((void)0)
#define QK_ISR_EXIT() do { \
QF_INT_DISABLE(); \
uint_fast8_t nextPrio_ = QK_schedPrio_(); \
if (nextPrio_ != static_cast<uint_fast8_t>(0)) { \
QK_nextPrio_ = nextPrio_; \
(*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) \
= static_cast<uint32_t>(1U << 28)); \
} \
QF_INT_ENABLE(); \
} while (false)
extern uint_fast8_t QK_nextPrio_; // priority of the next task to execute
#define QK_ISR_EXIT() \
((*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
static_cast<uint32_t>(1U << 28)))
#include "qk.h" // QK platform-independent public interface

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), GNU-ARM assembler
* Last Updated for Version: 5.6.0
* Date of the Last Update: 2015-12-14
* Last Updated for Version: 5.6.4
* Date of the Last Update: 2016-04-22
*
* Q u a n t u m L e a P s
* ---------------------------
@ -33,21 +33,12 @@
*****************************************************************************/
.syntax unified
.thumb
/* NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!! */
.equ QF_BASEPRI,(0xFF >> 2)
.section .data
/*****************************************************************************
* Global priority of the next task to execute or zero to indicate return
* to the preempted task
*****************************************************************************/
QK_nextPrio_:
.global QK_nextPrio_
.word 0
/*****************************************************************************
* The QK_init function sets the priorities of PendSV to 0xFF (lowest).
* The priority is set within a critical section.
@ -55,7 +46,6 @@ QK_nextPrio_:
.section .text.QK_init
.global QK_init
.type QK_init, %function
.thumb
QK_init:
MRS r0,PRIMASK /* store the state of the PRIMASK in r0 */
@ -103,20 +93,20 @@ PendSV_Handler:
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSID i /* disable interrupts at processor level */
.else /* M3/M4/M7 */
MOVS r0,#QF_BASEPRI
MSR BASEPRI,r0 /* selectively disable interrupts */
.endif /* M3/M4/M7 */
ISB /* reset the instruction pipeline */
LDR r0,=QK_nextPrio_
LDR r0,[r0]
CMP r0,#0
BNE.N PendSV_sched /* if QK_nextPrio_ != 0, branch to scheduler */
.ifdef __FPU_PRESENT /* if VFP available... */
PUSH {r0,lr} /* push lr (EXC_RETURN) plus stack "aligner" */
.endif /* VFP available */
/* QK_nextPrio_ == 0: return to the preempted task... */
ADD sp,sp,#(8*4) /* remove one 8-register exception frame */
BL QK_schedPrio_ /* call QK_schedPrio_() */
CMP r0,#0 /* is the returned next prio 0? */
BNE.N PendSV_sched /* if next prio != 0, branch to scheduler */
PendSV_ret:
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
MOVS r0,#6
@ -134,10 +124,14 @@ PendSV_Handler:
.endif /* VFP available */
.endif /* M3/M4/M7 */
PendSV_sched:
.ifdef __FPU_PRESENT /* if VFP available... */
PUSH {r0,lr} /* push lr (EXC_RETURN) plus stack "aligner" */
.endif /* VFP available */
PendSV_sched: /* call the QK scheduler... */
/* NOTE: The QK scheduler must be called in a task context, while
* we are still in the PendSV exception context. The switch to the
* task context is accomplished by returning from PendSV using a
* fabricated exception stack frame, where the return address is
* the QK scheduler.
* NOTE: the QK scheduler is called with interrupts DISABLED.
*/
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) */
@ -153,28 +147,59 @@ PendSV_sched:
BX r0 /* exception-return to the QK scheduler */
PendSV_sched_ret:
LDR r0,=QK_nextPrio_
MOVS r1,#0
STR r1,[r0] /* QK_nextPrio_ = 0; */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
.else /* M3/M4/M7 */
/* NOTE: 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 NMI exception.
* NOTE: The NMI exception is triggered with nterrupts DISABLED,
* because QK scheduler disables interrutps before return.
*/
/* 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 */
MOVS r0,#0
MSR BASEPRI,r0 /* enable interrupts (clear BASEPRI) */
.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) (PENDSVSET 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 */
.size PendSV_Handler, . - PendSV_Handler
/*****************************************************************************
* 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 /* CMSIS-compliant exception name */
.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 /* no VFP */
BX lr /* return to the preempted task */
.endif /* VFP available */
.endif /* M3/M4/M7 */
.size NMI_Handler, . - NMI_Handler
.end

View File

@ -2,8 +2,8 @@
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, IAR-ARM toolset
/// @cond
///***************************************************************************
/// Last updated for version 5.6.0
/// Last updated on 2015-12-28
/// Last updated for version 5.6.4
/// Last updated on 2016-04-25
///
/// Q u a n t u m L e a P s
/// ---------------------------
@ -43,19 +43,9 @@
/* QK interrupt entry and exit */
#define QK_ISR_ENTRY() ((void)0)
#define QK_ISR_EXIT() do { \
QF_INT_DISABLE(); \
uint_fast8_t nextPrio_ = QK_schedPrio_(); \
if (nextPrio_ != static_cast<uint_fast8_t>(0)) { \
QK_nextPrio_ = nextPrio_; \
(*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) \
= static_cast<uint32_t>(1U << 28)); \
} \
QF_INT_ENABLE(); \
} while (false)
extern uint_fast8_t QK_nextPrio_; // priority of the next task to execute
#define QK_ISR_EXIT() \
((*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
static_cast<uint32_t>(1U << 28)))
#include "qk.h" // QK platform-independent public interface

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), IAR ARM assembler
; Last Updated for Version: 5.6.0
; Date of the Last Update: 2015-12-11
; Last Updated for Version: 5.6.4
; Date of the Last Update: 2016-04-21
;
; Q u a n t u m L e a P s
; ---------------------------
@ -34,7 +34,7 @@
PUBLIC QK_init
PUBLIC PendSV_Handler ; CMSIS-compliant PendSV exception name
PUBLIC QK_nextPrio_ ; priority of the next task to execute
PUBLIC NMI_Handler ; CMSIS-compliant NMI exception name
EXTERN QK_schedPrio_ ; external reference
EXTERN QK_sched_ ; external reference
@ -42,21 +42,13 @@
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
QF_BASEPRI EQU (0xFF >> 2)
RSEG .data:DATA:NOROOT(2)
;*****************************************************************************
; Global priority of the next task to execute or zero to indicate return
; to the preempted task
;*****************************************************************************
QK_nextPrio_:
DC32 0
RSEG CODE:CODE:NOROOT(2)
;*****************************************************************************
; The QK_init function sets the priorities of PendSV to 0xFF (lowest).
; The priority is set within a critical section.
;*****************************************************************************
QK_init
QK_init:
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
CPSID i ; disable interrupts (set PRIMASK)
@ -92,7 +84,6 @@ QK_init
; check for the asynchronous preemption.
;*****************************************************************************
PendSV_Handler:
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSID i ; disable interrupts (set PRIMASK)
#else ; M3/M4/M7
@ -101,14 +92,15 @@ PendSV_Handler:
#endif ; M3/M4/M7
ISB ; reset the instruction pipeline
LDR r0,=QK_nextPrio_
LDR r0,[r0]
CMP r0,#0
BNE.N PendSV_sched ; if QK_nextPrio_ != 0, branch to scheduler
#ifdef __ARMVFP__ ; if VFP available...
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
#endif ; VFP available
; QK_nextPrio_ == 0: return to the preempted task...
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
BL QK_schedPrio_ ; call QK_schedPrio_()
CMP r0,#0 ; is the returned next prio 0?
BNE.N PendSV_sched ; if next prio != 0, branch to scheduler
PendSV_ret:
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
MOVS r0,#6
@ -126,18 +118,20 @@ PendSV_Handler:
#endif ; no VFP
#endif ; M3/M4/M7
PendSV_sched:
#ifdef __ARMVFP__ ; if VFP available...
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
#endif ; VFP available
PendSV_sched: ; call the QK scheduler...
; NOTE: The QK scheduler must be called in a task context, while
; we are still in the PendSV exception context. The switch to the
; task context is accomplished by returning from PendSV using a
; fabricated exception stack frame, where the return address is
; the QK scheduler.
; NOTE: the QK scheduler is called with interrupts DISABLED.
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,=PendSV_sched_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)
STR r0,[sp] ; save the prio argument (new r0)
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
STM r0!,{r1-r3} ; save xpsr,pc,lr
@ -146,28 +140,53 @@ PendSV_sched:
BX r0 ; exception-return to the QK scheduler
PendSV_sched_ret:
LDR r0,=QK_nextPrio_
MOVS r1,#0
STR r1,[r0] ; QK_nextPrio_ = 0;
; NOTE: 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 NMI exception.
; NOTE: The NMI exception is triggered with nterrupts DISABLED,
; because QK scheduler disables interrutps before return.
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
#else ; M3/M4/M7
; 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
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
#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) (PENDSVSET 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

@ -2,8 +2,8 @@
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, TI-ARM toolset
/// @cond
///***************************************************************************
/// Last updated for version 5.6.0
/// Last updated on 2015-12-30
/// Last updated for version 5.6.4
/// Last updated on 2016-04-25
///
/// Q u a n t u m L e a P s
/// ---------------------------
@ -38,11 +38,19 @@
#ifndef qk_port_h
#define qk_port_h
// QK interrupt entry and exit (defined in assembly)
// determination if the code executes in the ISR context
#define QK_ISR_CONTEXT_() (QK_get_IPSR() != static_cast<uint32_t>(0))
// QK interrupt entry and exit
#define QK_ISR_ENTRY() ((void)0)
#define QK_ISR_EXIT() \
((*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
static_cast<uint32_t>(1U << 28)))
extern "C" {
void QK_ISR_ENTRY(void);
void QK_ISR_EXIT(void);
} // extern "C"
// get the IPSR defined in assembly
uint32_t QK_get_IPSR(void);
}
#include "qk.h" // QK platform-independent public interface

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler
; Last Updated for Version: 5.6.1
; Date of the Last Update: 2015-12-30
; Last Updated for Version: 5.6.4
; Date of the Last Update: 2016-04-21
;
; Q u a n t u m L e a P s
; ---------------------------
@ -34,10 +34,10 @@
.global QK_init
.global PendSV_Handler ; CMSIS-compliant PendSV exception name
.global NMI_Handler ; CMSIS-compliant NMI exception name
.global QF_set_BASEPRI ; set BASEPRI register
.global QK_ISR_ENTRY ; inform QK about interrupt entry
.global QK_ISR_EXIT ; inform QK about interrupt exit
.global QK_get_IPSR ; get the IPSR
.global assert_failed ; low-level assert handler
.ref QK_schedPrio_ ; external reference
@ -48,16 +48,9 @@
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
QF_BASEPRI: .equ (0xFF >> 2)
.data
;*****************************************************************************
; Priority of the next task to execute or zero to indicate return
; to the preempted task
;*****************************************************************************
QK_nextPrio_: .word 0
.text
.thumb
;*****************************************************************************
; The QK_init function sets the priorities of PendSV to 0xFF (lowest).
; The priority is set within a critical section.
@ -107,14 +100,15 @@ PendSV_Handler: .asmfunc
.endif ; M0/M0+/M1
ISB ; reset the instruction pipeline
LDR r0,QK_nextPrio_addr
LDR r0,[r0]
CMP r0,#0
BNE.N PendSV_sched ; if QK_nextPrio_ != 0, branch to scheduler
.if __TI_VFP_SUPPORT__ ; if VFP available...
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
.endif ; VFP available
; QK_nextPrio_ == 0: return to the preempted task...
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
BL QK_schedPrio_ ; call QK_schedPrio_()
CMP r0,#0 ; is the returned next prio 0?
BNE.N PendSV_sched ; if next prio != 0, branch to scheduler
PendSV_ret:
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
; NOTE: r0 == 0 at this point
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
@ -132,18 +126,20 @@ PendSV_Handler: .asmfunc
BX r0 ; exception-return to the task
.endif ; M0/M0+/M1
PendSV_sched:
.if __TI_VFP_SUPPORT__ ; if VFP available...
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
.endif ; VFP available
PendSV_sched: ; call the QK scheduler...
; NOTE: The QK scheduler must be called in a task context, while
; we are still in the PendSV exception context. The switch to the
; task context is accomplished by returning from PendSV using a
; fabricated exception stack frame, where the return address is
; the QK scheduler.
; NOTE: the QK scheduler is called with interrupts DISABLED.
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,PendSV_sched_ret_addr ; ret 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)
STR r0,[sp] ; save the prio argument (new r0)
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
STM r0!,{r1-r3} ; save xpsr,pc,lr
@ -153,32 +149,59 @@ PendSV_sched:
.endasmfunc
PendSV_sched_ret: .asmfunc ; to ensure that the label is THUMB
LDR r0,QK_nextPrio_addr
MOVS r1,#0
STR r1,[r0] ; QK_nextPrio_ = 0;
; NOTE: 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 NMI exception.
; NOTE: The NMI exception is triggered with nterrupts DISABLED,
; because QK scheduler disables interrutps before return.
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
; 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
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
.endif ; VFP available
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
.else ; M0/M0+/M1
CPSIE i ; enable interrupts (clear BASEPRI)
.endif ; M0/M0+/M1
; trigger PendSV to return to preempted task...
; trigger NMI to return to preempted task...
LDR r0,ICSR_addr ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#28 ; r0 := (1 << 28) (PENDSVSET bit)
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
LSLS r1,r1,#31 ; r0 := (1 << 31) (NMI bit)
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
PendSV_sched_wait:
B PendSV_sched_wait ; wait for preemption by PendSV
B PendSV_sched_wait ; 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 ; no VFP
BX lr ; return to the preempted task
.endif ; VFP available
.else ; 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.
@ -191,80 +214,14 @@ QF_set_BASEPRI: .asmfunc
;*****************************************************************************
; Inform QK about interrupt entry.
; C prototype: void QK_ISR_ENTRY(void);
; The QK_get_IPSR function gets the IPSR register and returns it in r0.
; C prototype: uint32_t QK_get_IPSR(void);
;*****************************************************************************
QK_ISR_ENTRY: .asmfunc
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
MOVS r0,#QF_BASEPRI
MSR BASEPRI,r0 ; selectively disable interrupts
.else ; M0/M0+/M1
CPSID i ; disable interrupts (set PRIMASK)
.endif ; M0/M0+/M1
; ++QK_intNest_
LDR r1,QK_intNest_addr ; address of the QK_intNest_
LDR r0,[r1]
ADDS r0,r0,#1
STR r0,[r1]
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
MOVS r0,#0
MSR BASEPRI,r0 ; set BASEPRI (disable interrupts)
.else ; M0/M0+/M1
CPSIE i ; enable interrupts (set PRIMASK)
.endif ; M0/M0+/M1
QK_get_IPSR: .asmfunc
MRS r0,ipsr ; r0 := IPSR
BX lr ; return to the caller
.endasmfunc
;*****************************************************************************
; Inform QK about interrupt exit.
; C prototype: void QK_ISR_EXIT(void);
;*****************************************************************************
QK_ISR_EXIT: .asmfunc
PUSH {r0,lr} ; push lr (return address) plus stack "aligner"
; NOTE: because of the call to QK_schedPrio_()
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
MOVS r0,#QF_BASEPRI
MSR BASEPRI,r0 ; selectively disable interrupts
.else ; M0/M0+/M1
CPSID i ; disable interrupts (set PRIMASK)
.endif ; M0/M0+/M1
; --QK_intNest_
LDR r1,QK_intNest_addr ; address of the QK_intNest_
LDR r0,[r1]
SUBS r0,r0,#1
STR r0,[r1]
BL QK_schedPrio_ ; check if we have preemption
CMP r0,#0 ; is prio == 0 ?
BEQ.N no_preemption ; if prio == 0, branch to no_preemption
LDR r1,QK_nextPrio_addr ; address of the QK_nextPrio_
STR r0,[r1] ; QK_nextPrio_ = prio
; trigger PendSV to return to preempted task...
LDR r0,ICSR_addr ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#28 ; r0 := (1 << 28) (PENDSVSET bit)
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
no_preemption:
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
MOVS r0,#0
MSR BASEPRI,r0 ; set BASEPRI (disable interrupts)
.else ; M0/M0+/M1
CPSIE i ; enable interrupts (set PRIMASK)
.endif ; M0/M0+/M1
POP {r0,pc} ; pop the stack "aligner" and saved LR to PC
.endasmfunc
;*****************************************************************************
; The assert_failed() function restores the SP (in case stack is corrupted)
; and calls Q_onAssert(module, loc)
@ -289,7 +246,6 @@ VTOR_addr: .word 0xE000ED08
;*****************************************************************************
; Addresses for PC-relative LDR
;*****************************************************************************
QK_nextPrio_addr: .word QK_nextPrio_
QK_sched_addr: .word QK_sched_
QK_intNest_addr: .word QK_intNest_
PendSV_sched_ret_addr .word PendSV_sched_ret

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.6.0
; Date of the Last Update: 2015-12-14
; Last Updated for Version: 5.6.4
; Date of the Last Update: 2016-04-23
;
; Q u a n t u m L e a P s
; ---------------------------
@ -200,6 +200,12 @@ PendSV_Handler
ENDIF ; M3/M4/M7
ISB ; flush the instruction pipeline
; un-pend any PendSV pended from the time this PendSV was called...
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (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,[r1,#QXK_CURR]

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.6.0
* Date of the Last Update: 2015-12-10
* Last Updated for Version: 5.6.4
* Date of the Last Update: 2016-04-23
*
* Q u a n t u m L e a P s
* ---------------------------
@ -200,6 +200,12 @@ PendSV_Handler:
.endif /* M3/M4/M7 */
ISB /* reset the instruction pipeline */
/* un-pend any PendSV pended from the time this PendSV was called... */
LDR r2,=0xE000ED04 /* Interrupt Control and State Register */
MOVS r1,#1
LSLS r1,r1,#27 /* r0 := (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,[r1,#QXK_CURR]

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.6.0
; Date of the Last Update: 2015-12-09
; Last Updated for Version: 5.6.4
; Date of the Last Update: 2016-04-23
;
; Q u a n t u m L e a P s
; ---------------------------
@ -196,6 +196,12 @@ PendSV_Handler:
#endif ; M3/M4/M7
ISB ; flush the instruction pipeline
; un-pend any PendSV pended from the time this PendSV was called...
LDR r2,=0xE000ED04 ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (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,[r1,#QXK_CURR]

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler
; Last Updated for Version: 5.6.0
; Date of the Last Update: 2015-12-12
; Last Updated for Version: 5.6.4
; Date of the Last Update: 2016-04-24
;
; Q u a n t u m L e a P s
; ---------------------------
@ -206,6 +206,12 @@ PendSV_Handler: .asmfunc
.endif ; M0/M0+/M1
ISB ; flush the instruction pipeline
; un-pend any PendSV pended from the time this PendSV was called...
LDR r2,ICSR_addr ; Interrupt Control and State Register
MOVS r1,#1
LSLS r1,r1,#27 ; r0 := (1 << 27) (UNPENDSVSET bit)
STR r1,[r2] ; ICSR[27] := 1 (unpend PendSV)
; store the SP of the current QXK thread...
LDR r1,QXK_attr_addr
LDR r2,[r1,#QXK_CURR]

Binary file not shown.

Binary file not shown.

View File

@ -1,2 +0,0 @@
QP/C++ 5.6.3
2016-04-12

2
version-5.6.4 Normal file
View File

@ -0,0 +1,2 @@
QP/C++ 5.6.4
2016-04-25