mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-28 06:02:56 +08:00
5.6.4
This commit is contained in:
parent
7febc1a01b
commit
bdc74240aa
4
.gitignore
vendored
4
.gitignore
vendored
@ -21,6 +21,7 @@
|
|||||||
*.log
|
*.log
|
||||||
*.chm
|
*.chm
|
||||||
*.zip
|
*.zip
|
||||||
|
*.pdb
|
||||||
*.ncb
|
*.ncb
|
||||||
*.suo
|
*.suo
|
||||||
*.chw
|
*.chw
|
||||||
@ -29,7 +30,7 @@
|
|||||||
*.avrsuo
|
*.avrsuo
|
||||||
*.Debug
|
*.Debug
|
||||||
*.Release
|
*.Release
|
||||||
lint*.out
|
lint*.txt
|
||||||
*.Miro
|
*.Miro
|
||||||
*.bak
|
*.bak
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ dbg/
|
|||||||
rel/
|
rel/
|
||||||
spy/
|
spy/
|
||||||
settings/
|
settings/
|
||||||
|
.settings/
|
||||||
|
|
||||||
Debug/
|
Debug/
|
||||||
Release/
|
Release/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
; * @file startup_TM4C123GH6PM.s for IAR ARM assembler
|
; * @file startup_TM4C123GH6PM.s for IAR ARM assembler
|
||||||
; * @brief CMSIS Cortex-M4F Core Device Startup File for TM4C123GH6PM
|
; * @brief CMSIS Cortex-M4F Core Device Startup File for TM4C123GH6PM
|
||||||
; * @version CMSIS 4.3.0
|
; * @version CMSIS 4.3.0
|
||||||
; * @date 20 August 2015
|
; * @date 24 April 2016
|
||||||
; *
|
; *
|
||||||
; * @description
|
; * @description
|
||||||
; * Created from the CMSIS template for the specified device
|
; * Created from the CMSIS template for the specified device
|
||||||
@ -521,11 +521,10 @@ PWM1Gen2_IRQHandler
|
|||||||
PWM1Gen3_IRQHandler
|
PWM1Gen3_IRQHandler
|
||||||
PWM1Fault_IRQHandler
|
PWM1Fault_IRQHandler
|
||||||
MOVS r0,#0
|
MOVS r0,#0
|
||||||
MOVS r1,#-1 ; 0xFFFFFFF
|
MOVS r1,#0xFF
|
||||||
B assert_failed
|
B assert_failed
|
||||||
|
|
||||||
;******************************************************************************
|
;*****************************************************************************
|
||||||
;
|
|
||||||
; The function assert_failed defines the error/assertion handling policy
|
; The function assert_failed defines the error/assertion handling policy
|
||||||
; for the application. After making sure that the stack is OK, this function
|
; for the application. After making sure that the stack is OK, this function
|
||||||
; calls Q_onAssert, which should NOT return (typically reset the CPU).
|
; 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:
|
; The C proptotype of the assert_failed() and Q_onAssert() functions are:
|
||||||
; void assert_failed(char const *file, int line);
|
; void assert_failed(char const *file, int line);
|
||||||
; void Q_onAssert (char const *file, int line);
|
; void Q_onAssert (char const *file, int line);
|
||||||
;******************************************************************************
|
;*****************************************************************************
|
||||||
PUBLIC assert_failed
|
PUBLIC assert_failed
|
||||||
EXTERN Q_onAssert
|
EXTERN Q_onAssert
|
||||||
assert_failed
|
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
|
BL Q_onAssert ; call the application-specific handler
|
||||||
|
|
||||||
B . ; should not be reached, but just in case...
|
B . ; should not be reached, but just in case...
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
PROJECT_NAME = "QP/C++"
|
PROJECT_NAME = "QP/C++"
|
||||||
PROJECT_NUMBER = "5.6.3"
|
PROJECT_NUMBER = "5.6.4"
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF =
|
||||||
PROJECT_LOGO = images/header_logo_ql.png
|
PROJECT_LOGO = images/header_logo_ql.png
|
||||||
OUTPUT_DIRECTORY =
|
OUTPUT_DIRECTORY =
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
PROJECT_NAME = "QP/C++"
|
PROJECT_NAME = "QP/C++"
|
||||||
PROJECT_NUMBER = "5.6.3"
|
PROJECT_NUMBER = "5.6.4"
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF =
|
||||||
PROJECT_LOGO = images/header_logo_ql.png
|
PROJECT_LOGO = images/header_logo_ql.png
|
||||||
OUTPUT_DIRECTORY =
|
OUTPUT_DIRECTORY =
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
namespace QP {
|
namespace QP {
|
||||||
|
|
||||||
/** @page history Revision History
|
/** @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
|
@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.
|
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.
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
@echo off
|
@echo off
|
||||||
:: ==========================================================================
|
:: ==========================================================================
|
||||||
:: Product: QP/C++ script for generating Doxygen documentation
|
:: Product: QP/C++ script for generating Doxygen documentation
|
||||||
:: Last Updated for Version: 5.6.3
|
:: Last Updated for Version: 5.6.4
|
||||||
:: Date of the Last Update: 2016-04-12
|
:: Date of the Last Update: 2016-04-24
|
||||||
::
|
::
|
||||||
:: Q u a n t u m L e a P s
|
:: Q u a n t u m L e a P s
|
||||||
:: ---------------------------
|
:: ---------------------------
|
||||||
@ -38,7 +38,7 @@ echo usage:
|
|||||||
echo make
|
echo make
|
||||||
echo make -CHM
|
echo make -CHM
|
||||||
|
|
||||||
set VERSION=5.6.3
|
set VERSION=5.6.4
|
||||||
|
|
||||||
:: Generate Resource Standard Metrics for QP/C++ .............................
|
:: Generate Resource Standard Metrics for QP/C++ .............................
|
||||||
set DOXHOME="C:\tools\doxygen\bin"
|
set DOXHOME="C:\tools\doxygen\bin"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/** @page metrics Code Metrics
|
/** @page metrics Code Metrics
|
||||||
|
|
||||||
@code
|
@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
|
Resource Standard Metrics (TM) for C, C++, C# and Java
|
||||||
Version 7.75 - mSquaredTechnologies.com
|
Version 7.75 - mSquaredTechnologies.com
|
||||||
@ -9,7 +9,7 @@
|
|||||||
License Type: Windows Single User License
|
License Type: Windows Single User License
|
||||||
Licensed To : Quantum Leaps, LLC
|
Licensed To : Quantum Leaps, LLC
|
||||||
License No. : WS2975 License Date: Dec 15, 2013
|
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
|
(C)1996-2009 M Squared Technologies LLC
|
||||||
________________________________________________________________________
|
________________________________________________________________________
|
||||||
|
|
||||||
|
@ -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" 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" 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" 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" 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" 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
|
"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" 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" 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" 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\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 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_'
|
"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
|
2 Note 963 Qualifier const or volatile ___ a type; use ___ to reverse the test
|
||||||
1 Note 1914 Default constructor '___' (___) not referenced
|
1 Note 1914 Default constructor '___' (___) not referenced
|
||||||
2 Note 1923 macro '___' could become const variable
|
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 ___, ___
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Purpose: startup file for TM4C123GH6PM Cortex-M4 device.
|
* Purpose: startup file for TM4C123GH6PM Cortex-M4 device.
|
||||||
* Should be used with TI CCS-ARM Compiler
|
* Should be used with TI CCS-ARM Compiler
|
||||||
* Version: CMSIS 4.3.0
|
* Version: CMSIS 4.3.0
|
||||||
* Date: 2015-Nov-10
|
* Date: 2016-Apr-22
|
||||||
*
|
*
|
||||||
* Created from the CMSIS template for the specified device
|
* Created from the CMSIS template for the specified device
|
||||||
* Quantum Leaps, www.state-machine.com
|
* Quantum Leaps, www.state-machine.com
|
||||||
@ -373,6 +373,7 @@ void Default_Handler(void) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*..........................................................................*/
|
/*..........................................................................*/
|
||||||
|
/* defined in QK port
|
||||||
void NMI_Handler(void) {
|
void NMI_Handler(void) {
|
||||||
__asm(
|
__asm(
|
||||||
" .global assert_failed\n\r"
|
" .global assert_failed\n\r"
|
||||||
@ -381,6 +382,7 @@ void NMI_Handler(void) {
|
|||||||
" b.w assert_failed\n\r"
|
" b.w assert_failed\n\r"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/*..........................................................................*/
|
/*..........................................................................*/
|
||||||
void MemManage_Handler(void) {
|
void MemManage_Handler(void) {
|
||||||
__asm(
|
__asm(
|
||||||
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -2,14 +2,14 @@
|
|||||||
/// @brief QK/C++ port to ARM Cortex-M, ARM-KEIL toolset
|
/// @brief QK/C++ port to ARM Cortex-M, ARM-KEIL toolset
|
||||||
/// @cond
|
/// @cond
|
||||||
///***************************************************************************
|
///***************************************************************************
|
||||||
/// Last updated for version 5.5.2
|
/// Last updated for version 5.6.4
|
||||||
/// Last updated on 2015-11-11
|
/// Last updated on 2016-04-25
|
||||||
///
|
///
|
||||||
/// Q u a n t u m L e a P s
|
/// Q u a n t u m L e a P s
|
||||||
/// ---------------------------
|
/// ---------------------------
|
||||||
/// innovating embedded systems
|
/// 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
|
/// 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
|
/// 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/>.
|
/// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
///
|
///
|
||||||
/// Contact information:
|
/// Contact information:
|
||||||
/// http:// www.state-machine.com
|
/// http://www.state-machine.com
|
||||||
/// mailto:info@state-machine.com
|
/// mailto:info@state-machine.com
|
||||||
///***************************************************************************
|
///***************************************************************************
|
||||||
/// @endcond
|
/// @endcond
|
||||||
@ -49,19 +49,9 @@ static __inline uint32_t QK_get_IPSR(void) {
|
|||||||
|
|
||||||
// QK interrupt entry and exit
|
// QK interrupt entry and exit
|
||||||
#define QK_ISR_ENTRY() ((void)0)
|
#define QK_ISR_ENTRY() ((void)0)
|
||||||
|
#define QK_ISR_EXIT() \
|
||||||
#define QK_ISR_EXIT() do { \
|
((*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
|
||||||
QF_INT_DISABLE(); \
|
static_cast<uint32_t>(1U << 28)))
|
||||||
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
|
|
||||||
|
|
||||||
#include "qk.h" // QK platform-independent public interface
|
#include "qk.h" // QK platform-independent public interface
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), ARM-Keil assembler
|
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), ARM-Keil assembler
|
||||||
; Last Updated for Version: 5.6.0
|
; Last Updated for Version: 5.6.4
|
||||||
; Date of the Last Update: 2015-12-14
|
; Date of the Last Update: 2016-04-21
|
||||||
;
|
;
|
||||||
; Q u a n t u m L e a P s
|
; Q u a n t u m L e a P s
|
||||||
; ---------------------------
|
; ---------------------------
|
||||||
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
EXPORT QK_init
|
EXPORT QK_init
|
||||||
EXPORT PendSV_Handler ; CMSIS-compliant PendSV exception name
|
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_schedPrio_ ; external reference
|
||||||
IMPORT QK_sched_ ; external reference
|
IMPORT QK_sched_ ; external reference
|
||||||
@ -42,14 +42,6 @@
|
|||||||
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
|
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
|
||||||
QF_BASEPRI EQU (0xFF:SHR:2)
|
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
|
AREA |.text|, CODE, READONLY
|
||||||
THUMB
|
THUMB
|
||||||
@ -105,14 +97,15 @@ PendSV_Handler
|
|||||||
ENDIF ; M3/M4/M7
|
ENDIF ; M3/M4/M7
|
||||||
ISB ; reset the instruction pipeline
|
ISB ; reset the instruction pipeline
|
||||||
|
|
||||||
LDR r0,=QK_nextPrio_
|
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
|
||||||
LDR r0,[r0]
|
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
|
||||||
CMP r0,#0
|
ENDIF ; VFP available
|
||||||
BNE.N PendSV_sched ; if QK_nextPrio_ != 0, branch to scheduler
|
|
||||||
|
|
||||||
; QK_nextPrio_ == 0: return to the preempted task...
|
BL QK_schedPrio_ ; call QK_schedPrio_()
|
||||||
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
|
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)?
|
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
|
||||||
CPSIE i ; enable interrupts (clear PRIMASK)
|
CPSIE i ; enable interrupts (clear PRIMASK)
|
||||||
MOVS r0,#6
|
MOVS r0,#6
|
||||||
@ -130,18 +123,20 @@ PendSV_Handler
|
|||||||
ENDIF ; no VFP
|
ENDIF ; no VFP
|
||||||
ENDIF ; M3/M4/M7
|
ENDIF ; M3/M4/M7
|
||||||
|
|
||||||
PendSV_sched
|
PendSV_sched ; call the QK scheduler...
|
||||||
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
|
; NOTE: The QK scheduler must be called in a task context, while
|
||||||
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
|
; we are still in the PendSV exception context. The switch to the
|
||||||
ENDIF ; VFP available
|
; 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
|
MOVS r3,#1
|
||||||
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
|
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 r2,=QK_sched_ ; address of the QK scheduler (new pc)
|
||||||
LDR r1,=PendSV_sched_ret ; return address after the call (new lr)
|
LDR r1,=PendSV_sched_ret ; return address after the call (new lr)
|
||||||
|
|
||||||
SUB sp,sp,#8*4 ; reserve space for exception stack frame
|
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
|
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
|
||||||
STM r0!,{r1-r3} ; save xpsr,pc,lr
|
STM r0!,{r1-r3} ; save xpsr,pc,lr
|
||||||
|
|
||||||
@ -150,28 +145,53 @@ PendSV_sched
|
|||||||
BX r0 ; exception-return to the QK scheduler
|
BX r0 ; exception-return to the QK scheduler
|
||||||
|
|
||||||
PendSV_sched_ret
|
PendSV_sched_ret
|
||||||
LDR r0,=QK_nextPrio_
|
; NOTE: After the QK scheduler returns, we need to resume the preempted
|
||||||
MOVS r1,#0
|
; task. However, this must be accomplished by a return-from-exception,
|
||||||
STR r1,[r0] ; QK_nextPrio_ = 0;
|
; 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)?
|
; before triggering the NMI exception, make sure that the
|
||||||
CPSIE i ; enable interrupts (clear PRIMASK)
|
; VFP stack frame will NOT be used...
|
||||||
ELSE ; M3/M4/M7
|
|
||||||
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
|
IF {TARGET_FPU_VFP} == {TRUE} ; if VFP available...
|
||||||
MRS r0,CONTROL ; r0 := CONTROL
|
MRS r0,CONTROL ; r0 := CONTROL
|
||||||
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
|
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
|
||||||
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
|
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
|
||||||
ENDIF ; VFP available
|
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
|
LDR r0,=0xE000ED04 ; Interrupt Control and State Register
|
||||||
MOVS r1,#1
|
MOVS r1,#1
|
||||||
LSLS r1,r1,#28 ; r0 := (1 << 28) (PENDSVSET bit)
|
LSLS r1,r1,#31 ; r0 := (1 << 31) (NMI bit)
|
||||||
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
|
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
|
||||||
B . ; wait for preemption by PendSV
|
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
|
ALIGN ; make sure the END is properly aligned
|
||||||
|
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, GNU-ARM toolset
|
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, GNU-ARM toolset
|
||||||
/// @cond
|
/// @cond
|
||||||
///***************************************************************************
|
///***************************************************************************
|
||||||
/// Last updated for version 5.5.2
|
/// Last updated for version 5.6.4
|
||||||
/// Last updated on 2015-11-11
|
/// Last updated on 2016-04-25
|
||||||
///
|
///
|
||||||
/// Q u a n t u m L e a P s
|
/// Q u a n t u m L e a P s
|
||||||
/// ---------------------------
|
/// ---------------------------
|
||||||
/// innovating embedded systems
|
/// 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
|
/// 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
|
/// 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
|
// QK interrupt entry and exit
|
||||||
#define QK_ISR_ENTRY() ((void)0)
|
#define QK_ISR_ENTRY() ((void)0)
|
||||||
|
#define QK_ISR_EXIT() \
|
||||||
#define QK_ISR_EXIT() do { \
|
((*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
|
||||||
QF_INT_DISABLE(); \
|
static_cast<uint32_t>(1U << 28)))
|
||||||
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
|
|
||||||
|
|
||||||
#include "qk.h" // QK platform-independent public interface
|
#include "qk.h" // QK platform-independent public interface
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), GNU-ARM assembler
|
* Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), GNU-ARM assembler
|
||||||
* Last Updated for Version: 5.6.0
|
* Last Updated for Version: 5.6.4
|
||||||
* Date of the Last Update: 2015-12-14
|
* Date of the Last Update: 2016-04-22
|
||||||
*
|
*
|
||||||
* Q u a n t u m L e a P s
|
* Q u a n t u m L e a P s
|
||||||
* ---------------------------
|
* ---------------------------
|
||||||
@ -33,21 +33,12 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
.syntax unified
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
|
||||||
/* NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!! */
|
/* NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!! */
|
||||||
.equ QF_BASEPRI,(0xFF >> 2)
|
.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 QK_init function sets the priorities of PendSV to 0xFF (lowest).
|
||||||
* The priority is set within a critical section.
|
* The priority is set within a critical section.
|
||||||
@ -55,7 +46,6 @@ QK_nextPrio_:
|
|||||||
.section .text.QK_init
|
.section .text.QK_init
|
||||||
.global QK_init
|
.global QK_init
|
||||||
.type QK_init, %function
|
.type QK_init, %function
|
||||||
.thumb
|
|
||||||
|
|
||||||
QK_init:
|
QK_init:
|
||||||
MRS r0,PRIMASK /* store the state of the PRIMASK in r0 */
|
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)? */
|
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
|
||||||
CPSID i /* disable interrupts at processor level */
|
CPSID i /* disable interrupts at processor level */
|
||||||
.else /* M3/M4/M7 */
|
.else /* M3/M4/M7 */
|
||||||
|
|
||||||
MOVS r0,#QF_BASEPRI
|
MOVS r0,#QF_BASEPRI
|
||||||
MSR BASEPRI,r0 /* selectively disable interrupts */
|
MSR BASEPRI,r0 /* selectively disable interrupts */
|
||||||
.endif /* M3/M4/M7 */
|
.endif /* M3/M4/M7 */
|
||||||
ISB /* reset the instruction pipeline */
|
ISB /* reset the instruction pipeline */
|
||||||
|
|
||||||
LDR r0,=QK_nextPrio_
|
.ifdef __FPU_PRESENT /* if VFP available... */
|
||||||
LDR r0,[r0]
|
PUSH {r0,lr} /* push lr (EXC_RETURN) plus stack "aligner" */
|
||||||
CMP r0,#0
|
.endif /* VFP available */
|
||||||
BNE.N PendSV_sched /* if QK_nextPrio_ != 0, branch to scheduler */
|
|
||||||
|
|
||||||
/* QK_nextPrio_ == 0: return to the preempted task... */
|
BL QK_schedPrio_ /* call QK_schedPrio_() */
|
||||||
ADD sp,sp,#(8*4) /* remove one 8-register exception frame */
|
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)? */
|
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
|
||||||
CPSIE i /* enable interrupts (clear PRIMASK) */
|
CPSIE i /* enable interrupts (clear PRIMASK) */
|
||||||
MOVS r0,#6
|
MOVS r0,#6
|
||||||
@ -134,10 +124,14 @@ PendSV_Handler:
|
|||||||
.endif /* VFP available */
|
.endif /* VFP available */
|
||||||
.endif /* M3/M4/M7 */
|
.endif /* M3/M4/M7 */
|
||||||
|
|
||||||
PendSV_sched:
|
PendSV_sched: /* call the QK scheduler... */
|
||||||
.ifdef __FPU_PRESENT /* if VFP available... */
|
/* NOTE: The QK scheduler must be called in a task context, while
|
||||||
PUSH {r0,lr} /* push lr (EXC_RETURN) plus stack "aligner" */
|
* we are still in the PendSV exception context. The switch to the
|
||||||
.endif /* VFP available */
|
* 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
|
MOVS r3,#1
|
||||||
LSLS r3,r3,#24 /* r3:=(1 << 24), set the T bit (new xpsr) */
|
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 r2,=QK_sched_ /* address of the QK scheduler (new pc) */
|
||||||
@ -153,28 +147,59 @@ PendSV_sched:
|
|||||||
BX r0 /* exception-return to the QK scheduler */
|
BX r0 /* exception-return to the QK scheduler */
|
||||||
|
|
||||||
PendSV_sched_ret:
|
PendSV_sched_ret:
|
||||||
LDR r0,=QK_nextPrio_
|
/* NOTE: After the QK scheduler returns, we need to resume the preempted
|
||||||
MOVS r1,#0
|
* task. However, this must be accomplished by a return-from-exception,
|
||||||
STR r1,[r0] /* QK_nextPrio_ = 0; */
|
* while we are still in the task context. The switch to the exception
|
||||||
|
* contex is accomplished by triggering the NMI exception.
|
||||||
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
|
* NOTE: The NMI exception is triggered with nterrupts DISABLED,
|
||||||
CPSIE i /* enable interrupts (clear PRIMASK) */
|
* because QK scheduler disables interrutps before return.
|
||||||
.else /* M3/M4/M7 */
|
*/
|
||||||
|
/* before triggering the NMI exception, make sure that the
|
||||||
|
* VFP stack frame will NOT be used...
|
||||||
|
*/
|
||||||
.ifdef __FPU_PRESENT /* if VFP available... */
|
.ifdef __FPU_PRESENT /* if VFP available... */
|
||||||
MRS r0,CONTROL /* r0 := CONTROL */
|
MRS r0,CONTROL /* r0 := CONTROL */
|
||||||
BICS r0,r0,#4 /* r0 := r0 & ~4 (FPCA bit) */
|
BICS r0,r0,#4 /* r0 := r0 & ~4 (FPCA bit) */
|
||||||
MSR CONTROL,r0 /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
MSR CONTROL,r0 /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
||||||
.endif /* VFP available */
|
.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 */
|
LDR r0,=0xE000ED04 /* Interrupt Control and State Register */
|
||||||
MOVS r1,#1
|
MOVS r1,#1
|
||||||
LSLS r1,r1,#28 /* r0 := (1 << 28) (PENDSVSET bit) */
|
LSLS r1,r1,#31 /* r0 := (1 << 31) (NMI bit) */
|
||||||
STR r1,[r0] /* ICSR[28] := 1 (pend PendSV) */
|
STR r1,[r0] /* ICSR[31] := 1 (pend NMI) */
|
||||||
B . /* wait for preemption by PendSV */
|
B . /* wait for preemption by NMI */
|
||||||
.size PendSV_Handler, . - PendSV_Handler
|
.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
|
.end
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, IAR-ARM toolset
|
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, IAR-ARM toolset
|
||||||
/// @cond
|
/// @cond
|
||||||
///***************************************************************************
|
///***************************************************************************
|
||||||
/// Last updated for version 5.6.0
|
/// Last updated for version 5.6.4
|
||||||
/// Last updated on 2015-12-28
|
/// Last updated on 2016-04-25
|
||||||
///
|
///
|
||||||
/// Q u a n t u m L e a P s
|
/// Q u a n t u m L e a P s
|
||||||
/// ---------------------------
|
/// ---------------------------
|
||||||
@ -43,19 +43,9 @@
|
|||||||
|
|
||||||
/* QK interrupt entry and exit */
|
/* QK interrupt entry and exit */
|
||||||
#define QK_ISR_ENTRY() ((void)0)
|
#define QK_ISR_ENTRY() ((void)0)
|
||||||
|
#define QK_ISR_EXIT() \
|
||||||
#define QK_ISR_EXIT() do { \
|
((*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
|
||||||
QF_INT_DISABLE(); \
|
static_cast<uint32_t>(1U << 28)))
|
||||||
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
|
|
||||||
|
|
||||||
#include "qk.h" // QK platform-independent public interface
|
#include "qk.h" // QK platform-independent public interface
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), IAR ARM assembler
|
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), IAR ARM assembler
|
||||||
; Last Updated for Version: 5.6.0
|
; Last Updated for Version: 5.6.4
|
||||||
; Date of the Last Update: 2015-12-11
|
; Date of the Last Update: 2016-04-21
|
||||||
;
|
;
|
||||||
; Q u a n t u m L e a P s
|
; Q u a n t u m L e a P s
|
||||||
; ---------------------------
|
; ---------------------------
|
||||||
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
PUBLIC QK_init
|
PUBLIC QK_init
|
||||||
PUBLIC PendSV_Handler ; CMSIS-compliant PendSV exception name
|
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_schedPrio_ ; external reference
|
||||||
EXTERN QK_sched_ ; external reference
|
EXTERN QK_sched_ ; external reference
|
||||||
@ -42,21 +42,13 @@
|
|||||||
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
|
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
|
||||||
QF_BASEPRI EQU (0xFF >> 2)
|
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)
|
RSEG CODE:CODE:NOROOT(2)
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; The QK_init function sets the priorities of PendSV to 0xFF (lowest).
|
; The QK_init function sets the priorities of PendSV to 0xFF (lowest).
|
||||||
; The priority is set within a critical section.
|
; The priority is set within a critical section.
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
QK_init
|
QK_init:
|
||||||
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
|
MRS r0,PRIMASK ; store the state of the PRIMASK in r0
|
||||||
CPSID i ; disable interrupts (set PRIMASK)
|
CPSID i ; disable interrupts (set PRIMASK)
|
||||||
|
|
||||||
@ -92,7 +84,6 @@ QK_init
|
|||||||
; check for the asynchronous preemption.
|
; check for the asynchronous preemption.
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
PendSV_Handler:
|
PendSV_Handler:
|
||||||
|
|
||||||
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
|
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
|
||||||
CPSID i ; disable interrupts (set PRIMASK)
|
CPSID i ; disable interrupts (set PRIMASK)
|
||||||
#else ; M3/M4/M7
|
#else ; M3/M4/M7
|
||||||
@ -101,14 +92,15 @@ PendSV_Handler:
|
|||||||
#endif ; M3/M4/M7
|
#endif ; M3/M4/M7
|
||||||
ISB ; reset the instruction pipeline
|
ISB ; reset the instruction pipeline
|
||||||
|
|
||||||
LDR r0,=QK_nextPrio_
|
#ifdef __ARMVFP__ ; if VFP available...
|
||||||
LDR r0,[r0]
|
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
|
||||||
CMP r0,#0
|
#endif ; VFP available
|
||||||
BNE.N PendSV_sched ; if QK_nextPrio_ != 0, branch to scheduler
|
|
||||||
|
|
||||||
; QK_nextPrio_ == 0: return to the preempted task...
|
BL QK_schedPrio_ ; call QK_schedPrio_()
|
||||||
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
|
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 ?
|
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
|
||||||
CPSIE i ; enable interrupts (clear PRIMASK)
|
CPSIE i ; enable interrupts (clear PRIMASK)
|
||||||
MOVS r0,#6
|
MOVS r0,#6
|
||||||
@ -126,18 +118,20 @@ PendSV_Handler:
|
|||||||
#endif ; no VFP
|
#endif ; no VFP
|
||||||
#endif ; M3/M4/M7
|
#endif ; M3/M4/M7
|
||||||
|
|
||||||
PendSV_sched:
|
PendSV_sched: ; call the QK scheduler...
|
||||||
#ifdef __ARMVFP__ ; if VFP available...
|
; NOTE: The QK scheduler must be called in a task context, while
|
||||||
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
|
; we are still in the PendSV exception context. The switch to the
|
||||||
#endif ; VFP available
|
; 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
|
MOVS r3,#1
|
||||||
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
|
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 r2,=QK_sched_ ; address of the QK scheduler (new pc)
|
||||||
LDR r1,=PendSV_sched_ret ; return address after the call (new lr)
|
LDR r1,=PendSV_sched_ret ; return address after the call (new lr)
|
||||||
|
|
||||||
SUB sp,sp,#8*4 ; reserve space for exception stack frame
|
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
|
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
|
||||||
STM r0!,{r1-r3} ; save xpsr,pc,lr
|
STM r0!,{r1-r3} ; save xpsr,pc,lr
|
||||||
|
|
||||||
@ -146,28 +140,53 @@ PendSV_sched:
|
|||||||
BX r0 ; exception-return to the QK scheduler
|
BX r0 ; exception-return to the QK scheduler
|
||||||
|
|
||||||
PendSV_sched_ret:
|
PendSV_sched_ret:
|
||||||
LDR r0,=QK_nextPrio_
|
; NOTE: After the QK scheduler returns, we need to resume the preempted
|
||||||
MOVS r1,#0
|
; task. However, this must be accomplished by a return-from-exception,
|
||||||
STR r1,[r0] ; QK_nextPrio_ = 0;
|
; 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 ?
|
; before triggering the NMI exception, make sure that the
|
||||||
CPSIE i ; enable interrupts (clear PRIMASK)
|
; VFP stack frame will NOT be used...
|
||||||
#else ; M3/M4/M7
|
|
||||||
#ifdef __ARMVFP__ ; if VFP available...
|
#ifdef __ARMVFP__ ; if VFP available...
|
||||||
MRS r0,CONTROL ; r0 := CONTROL
|
MRS r0,CONTROL ; r0 := CONTROL
|
||||||
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
|
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
|
||||||
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
|
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
|
||||||
#endif ; VFP available
|
#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
|
LDR r0,=0xE000ED04 ; Interrupt Control and State Register
|
||||||
MOVS r1,#1
|
MOVS r1,#1
|
||||||
LSLS r1,r1,#28 ; r0 := (1 << 28) (PENDSVSET bit)
|
LSLS r1,r1,#31 ; r0 := (1 << 31) (NMI bit)
|
||||||
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
|
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
|
||||||
B . ; wait for preemption by PendSV
|
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
|
ALIGNROM 2,0xFF ; make sure the END is properly aligned
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, TI-ARM toolset
|
/// @brief QK/C++ port to ARM Cortex-M, preemptive QK kernel, TI-ARM toolset
|
||||||
/// @cond
|
/// @cond
|
||||||
///***************************************************************************
|
///***************************************************************************
|
||||||
/// Last updated for version 5.6.0
|
/// Last updated for version 5.6.4
|
||||||
/// Last updated on 2015-12-30
|
/// Last updated on 2016-04-25
|
||||||
///
|
///
|
||||||
/// Q u a n t u m L e a P s
|
/// Q u a n t u m L e a P s
|
||||||
/// ---------------------------
|
/// ---------------------------
|
||||||
@ -38,11 +38,19 @@
|
|||||||
#ifndef qk_port_h
|
#ifndef qk_port_h
|
||||||
#define 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" {
|
extern "C" {
|
||||||
void QK_ISR_ENTRY(void);
|
// get the IPSR defined in assembly
|
||||||
void QK_ISR_EXIT(void);
|
uint32_t QK_get_IPSR(void);
|
||||||
} // extern "C"
|
}
|
||||||
|
|
||||||
#include "qk.h" // QK platform-independent public interface
|
#include "qk.h" // QK platform-independent public interface
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler
|
; Product: QK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler
|
||||||
; Last Updated for Version: 5.6.1
|
; Last Updated for Version: 5.6.4
|
||||||
; Date of the Last Update: 2015-12-30
|
; Date of the Last Update: 2016-04-21
|
||||||
;
|
;
|
||||||
; Q u a n t u m L e a P s
|
; Q u a n t u m L e a P s
|
||||||
; ---------------------------
|
; ---------------------------
|
||||||
@ -34,10 +34,10 @@
|
|||||||
|
|
||||||
.global QK_init
|
.global QK_init
|
||||||
.global PendSV_Handler ; CMSIS-compliant PendSV exception name
|
.global PendSV_Handler ; CMSIS-compliant PendSV exception name
|
||||||
|
.global NMI_Handler ; CMSIS-compliant NMI exception name
|
||||||
|
|
||||||
.global QF_set_BASEPRI ; set BASEPRI register
|
.global QF_set_BASEPRI ; set BASEPRI register
|
||||||
.global QK_ISR_ENTRY ; inform QK about interrupt entry
|
.global QK_get_IPSR ; get the IPSR
|
||||||
.global QK_ISR_EXIT ; inform QK about interrupt exit
|
|
||||||
.global assert_failed ; low-level assert handler
|
.global assert_failed ; low-level assert handler
|
||||||
|
|
||||||
.ref QK_schedPrio_ ; external reference
|
.ref QK_schedPrio_ ; external reference
|
||||||
@ -48,16 +48,9 @@
|
|||||||
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
|
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
|
||||||
QF_BASEPRI: .equ (0xFF >> 2)
|
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
|
.text
|
||||||
.thumb
|
.thumb
|
||||||
|
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; The QK_init function sets the priorities of PendSV to 0xFF (lowest).
|
; The QK_init function sets the priorities of PendSV to 0xFF (lowest).
|
||||||
; The priority is set within a critical section.
|
; The priority is set within a critical section.
|
||||||
@ -107,14 +100,15 @@ PendSV_Handler: .asmfunc
|
|||||||
.endif ; M0/M0+/M1
|
.endif ; M0/M0+/M1
|
||||||
ISB ; reset the instruction pipeline
|
ISB ; reset the instruction pipeline
|
||||||
|
|
||||||
LDR r0,QK_nextPrio_addr
|
.if __TI_VFP_SUPPORT__ ; if VFP available...
|
||||||
LDR r0,[r0]
|
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
|
||||||
CMP r0,#0
|
.endif ; VFP available
|
||||||
BNE.N PendSV_sched ; if QK_nextPrio_ != 0, branch to scheduler
|
|
||||||
|
|
||||||
; QK_nextPrio_ == 0: return to the preempted task...
|
BL QK_schedPrio_ ; call QK_schedPrio_()
|
||||||
ADD sp,sp,#(8*4) ; remove one 8-register exception frame
|
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__
|
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
|
||||||
; NOTE: r0 == 0 at this point
|
; NOTE: r0 == 0 at this point
|
||||||
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
|
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
|
||||||
@ -132,18 +126,20 @@ PendSV_Handler: .asmfunc
|
|||||||
BX r0 ; exception-return to the task
|
BX r0 ; exception-return to the task
|
||||||
.endif ; M0/M0+/M1
|
.endif ; M0/M0+/M1
|
||||||
|
|
||||||
PendSV_sched:
|
PendSV_sched: ; call the QK scheduler...
|
||||||
.if __TI_VFP_SUPPORT__ ; if VFP available...
|
; NOTE: The QK scheduler must be called in a task context, while
|
||||||
PUSH {r0,lr} ; push lr (EXC_RETURN) plus stack "aligner"
|
; we are still in the PendSV exception context. The switch to the
|
||||||
.endif ; VFP available
|
; 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
|
MOVS r3,#1
|
||||||
LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
|
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 r2,QK_sched_addr ; address of the QK scheduler (new pc)
|
||||||
LDR r1,PendSV_sched_ret_addr ; ret address after the call (new lr)
|
LDR r1,PendSV_sched_ret_addr ; ret address after the call (new lr)
|
||||||
|
|
||||||
SUB sp,sp,#8*4 ; reserve space for exception stack frame
|
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
|
ADD r0,sp,#5*4 ; r0 := 5 registers below the top of stack
|
||||||
STM r0!,{r1-r3} ; save xpsr,pc,lr
|
STM r0!,{r1-r3} ; save xpsr,pc,lr
|
||||||
|
|
||||||
@ -153,32 +149,59 @@ PendSV_sched:
|
|||||||
.endasmfunc
|
.endasmfunc
|
||||||
|
|
||||||
PendSV_sched_ret: .asmfunc ; to ensure that the label is THUMB
|
PendSV_sched_ret: .asmfunc ; to ensure that the label is THUMB
|
||||||
LDR r0,QK_nextPrio_addr
|
; NOTE: After the QK scheduler returns, we need to resume the preempted
|
||||||
MOVS r1,#0
|
; task. However, this must be accomplished by a return-from-exception,
|
||||||
STR r1,[r0] ; QK_nextPrio_ = 0;
|
; 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...
|
.if __TI_VFP_SUPPORT__ ; if VFP available...
|
||||||
MRS r0,CONTROL ; r0 := CONTROL
|
MRS r0,CONTROL ; r0 := CONTROL
|
||||||
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
|
BICS r0,r0,#4 ; r0 := r0 & ~4 (FPCA bit)
|
||||||
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
|
MSR CONTROL,r0 ; CONTROL := r0 (clear CONTROL[2] FPCA bit)
|
||||||
.endif ; VFP available
|
.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
|
LDR r0,ICSR_addr ; Interrupt Control and State Register
|
||||||
MOVS r1,#1
|
MOVS r1,#1
|
||||||
LSLS r1,r1,#28 ; r0 := (1 << 28) (PENDSVSET bit)
|
LSLS r1,r1,#31 ; r0 := (1 << 31) (NMI bit)
|
||||||
STR r1,[r0] ; ICSR[28] := 1 (pend PendSV)
|
STR r1,[r0] ; ICSR[31] := 1 (pend NMI)
|
||||||
PendSV_sched_wait:
|
PendSV_sched_wait:
|
||||||
B PendSV_sched_wait ; wait for preemption by PendSV
|
B PendSV_sched_wait ; wait for preemption by NMI
|
||||||
.endasmfunc
|
.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
|
; The QF_set_BASEPRI function sets the BASEPRI register to the value
|
||||||
; passed in r0.
|
; passed in r0.
|
||||||
@ -191,80 +214,14 @@ QF_set_BASEPRI: .asmfunc
|
|||||||
|
|
||||||
|
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Inform QK about interrupt entry.
|
; The QK_get_IPSR function gets the IPSR register and returns it in r0.
|
||||||
; C prototype: void QK_ISR_ENTRY(void);
|
; C prototype: uint32_t QK_get_IPSR(void);
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
QK_ISR_ENTRY: .asmfunc
|
QK_get_IPSR: .asmfunc
|
||||||
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
|
MRS r0,ipsr ; r0 := IPSR
|
||||||
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
|
|
||||||
|
|
||||||
BX lr ; return to the caller
|
BX lr ; return to the caller
|
||||||
.endasmfunc
|
.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)
|
; The assert_failed() function restores the SP (in case stack is corrupted)
|
||||||
; and calls Q_onAssert(module, loc)
|
; and calls Q_onAssert(module, loc)
|
||||||
@ -289,7 +246,6 @@ VTOR_addr: .word 0xE000ED08
|
|||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Addresses for PC-relative LDR
|
; Addresses for PC-relative LDR
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
QK_nextPrio_addr: .word QK_nextPrio_
|
|
||||||
QK_sched_addr: .word QK_sched_
|
QK_sched_addr: .word QK_sched_
|
||||||
QK_intNest_addr: .word QK_intNest_
|
QK_intNest_addr: .word QK_intNest_
|
||||||
PendSV_sched_ret_addr .word PendSV_sched_ret
|
PendSV_sched_ret_addr .word PendSV_sched_ret
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), ARM-Keil assembler
|
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), ARM-Keil assembler
|
||||||
; Last Updated for Version: 5.6.0
|
; Last Updated for Version: 5.6.4
|
||||||
; Date of the Last Update: 2015-12-14
|
; Date of the Last Update: 2016-04-23
|
||||||
;
|
;
|
||||||
; Q u a n t u m L e a P s
|
; Q u a n t u m L e a P s
|
||||||
; ---------------------------
|
; ---------------------------
|
||||||
@ -200,6 +200,12 @@ PendSV_Handler
|
|||||||
ENDIF ; M3/M4/M7
|
ENDIF ; M3/M4/M7
|
||||||
ISB ; flush the instruction pipeline
|
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...
|
; store the SP of the current QXK thread...
|
||||||
LDR r1,=QXK_attr_
|
LDR r1,=QXK_attr_
|
||||||
LDR r2,[r1,#QXK_CURR]
|
LDR r2,[r1,#QXK_CURR]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), GNU-ARM assembler
|
* Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), GNU-ARM assembler
|
||||||
* Last Updated for Version: 5.6.0
|
* Last Updated for Version: 5.6.4
|
||||||
* Date of the Last Update: 2015-12-10
|
* Date of the Last Update: 2016-04-23
|
||||||
*
|
*
|
||||||
* Q u a n t u m L e a P s
|
* Q u a n t u m L e a P s
|
||||||
* ---------------------------
|
* ---------------------------
|
||||||
@ -200,6 +200,12 @@ PendSV_Handler:
|
|||||||
.endif /* M3/M4/M7 */
|
.endif /* M3/M4/M7 */
|
||||||
ISB /* reset the instruction pipeline */
|
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... */
|
/* store the SP of the current QXK thread... */
|
||||||
LDR r1,=QXK_attr_
|
LDR r1,=QXK_attr_
|
||||||
LDR r2,[r1,#QXK_CURR]
|
LDR r2,[r1,#QXK_CURR]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), IAR ARM assembler
|
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), IAR ARM assembler
|
||||||
; Last Updated for Version: 5.6.0
|
; Last Updated for Version: 5.6.4
|
||||||
; Date of the Last Update: 2015-12-09
|
; Date of the Last Update: 2016-04-23
|
||||||
;
|
;
|
||||||
; Q u a n t u m L e a P s
|
; Q u a n t u m L e a P s
|
||||||
; ---------------------------
|
; ---------------------------
|
||||||
@ -196,6 +196,12 @@ PendSV_Handler:
|
|||||||
#endif ; M3/M4/M7
|
#endif ; M3/M4/M7
|
||||||
ISB ; flush the instruction pipeline
|
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...
|
; store the SP of the current QXK thread...
|
||||||
LDR r1,=QXK_attr_
|
LDR r1,=QXK_attr_
|
||||||
LDR r2,[r1,#QXK_CURR]
|
LDR r2,[r1,#QXK_CURR]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler
|
; Product: QXK port to ARM Cortex-M (M0,M0+,M1,M3,M4,M7), TI-ARM assembler
|
||||||
; Last Updated for Version: 5.6.0
|
; Last Updated for Version: 5.6.4
|
||||||
; Date of the Last Update: 2015-12-12
|
; Date of the Last Update: 2016-04-24
|
||||||
;
|
;
|
||||||
; Q u a n t u m L e a P s
|
; Q u a n t u m L e a P s
|
||||||
; ---------------------------
|
; ---------------------------
|
||||||
@ -206,6 +206,12 @@ PendSV_Handler: .asmfunc
|
|||||||
.endif ; M0/M0+/M1
|
.endif ; M0/M0+/M1
|
||||||
ISB ; flush the instruction pipeline
|
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...
|
; store the SP of the current QXK thread...
|
||||||
LDR r1,QXK_attr_addr
|
LDR r1,QXK_attr_addr
|
||||||
LDR r2,[r1,#QXK_CURR]
|
LDR r2,[r1,#QXK_CURR]
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -1,2 +0,0 @@
|
|||||||
QP/C++ 5.6.3
|
|
||||||
2016-04-12
|
|
2
version-5.6.4
Normal file
2
version-5.6.4
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
QP/C++ 5.6.4
|
||||||
|
2016-04-25
|
Loading…
x
Reference in New Issue
Block a user