mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-14 05:42:57 +08:00
7.0.2
fixed bugs in QK/QXK ports to ARM Cortex-M
This commit is contained in:
parent
ea41985bf1
commit
d7225a6579
@ -297,7 +297,7 @@
|
||||
<bEvRecOn>1</bEvRecOn>
|
||||
<bSchkAxf>0</bSchkAxf>
|
||||
<bTchkAxf>0</bTchkAxf>
|
||||
<nTsel>3</nTsel>
|
||||
<nTsel>4</nTsel>
|
||||
<sDll></sDll>
|
||||
<sDllPa></sDllPa>
|
||||
<sDlgDll></sDlgDll>
|
||||
@ -491,7 +491,7 @@
|
||||
<bEvRecOn>1</bEvRecOn>
|
||||
<bSchkAxf>0</bSchkAxf>
|
||||
<bTchkAxf>0</bTchkAxf>
|
||||
<nTsel>3</nTsel>
|
||||
<nTsel>4</nTsel>
|
||||
<sDll></sDll>
|
||||
<sDllPa></sDllPa>
|
||||
<sDlgDll></sDlgDll>
|
||||
|
@ -337,7 +337,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define>
|
||||
<Define>QK_USE_IRQ_NUM=25 QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
|
||||
</VariousControls>
|
||||
@ -532,57 +532,6 @@
|
||||
<FileName>qk_port.cpp</FileName>
|
||||
<FileType>8</FileType>
|
||||
<FilePath>..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.cpp</FilePath>
|
||||
<FileOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>2</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>2</IncludeInBuild>
|
||||
<AlwaysBuild>2</AlwaysBuild>
|
||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
<Cads>
|
||||
<interw>2</interw>
|
||||
<Optim>0</Optim>
|
||||
<oTime>2</oTime>
|
||||
<SplitLS>2</SplitLS>
|
||||
<OneElfS>2</OneElfS>
|
||||
<Strict>2</Strict>
|
||||
<EnumInt>2</EnumInt>
|
||||
<PlainCh>2</PlainCh>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<wLevel>0</wLevel>
|
||||
<uThumb>2</uThumb>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<uC99>2</uC99>
|
||||
<uGnu>2</uGnu>
|
||||
<useXO>2</useXO>
|
||||
<v6Lang>0</v6Lang>
|
||||
<v6LangP>0</v6LangP>
|
||||
<vShortEn>2</vShortEn>
|
||||
<vShortWch>2</vShortWch>
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>QK_USE_IRQ_NUM=25 QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
@ -686,7 +635,7 @@
|
||||
<TargetName>dpp-rel</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<pCCUsed>5060183::V5.06 update 2 (build 183)::ARMCC</pCCUsed>
|
||||
<pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
|
||||
<uAC6>1</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
@ -1013,7 +962,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define>
|
||||
<Define>NDEBUG</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
|
||||
</VariousControls>
|
||||
@ -1311,7 +1260,7 @@
|
||||
<TargetName>dpp-spy</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<pCCUsed>6130001::V6.13.1::.\ARMCLANG</pCCUsed>
|
||||
<pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
|
||||
<uAC6>1</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
@ -1638,7 +1587,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define>
|
||||
<Define>Q_SPY</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
|
||||
</VariousControls>
|
||||
|
@ -138,8 +138,8 @@ LIBS :=
|
||||
|
||||
# defines
|
||||
DEFINES := -DEFM32PG1B200F256GM48=1 \
|
||||
-DQK_USE_IRQ_NUM=25 \
|
||||
-DQK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
|
||||
-DQK_USE_IRQ_HANDLER=CRYPTO_IRQHandler \
|
||||
-DQK_USE_IRQ_NUM=25
|
||||
|
||||
# ARM CPU, ARCH, FPU, and Float-ABI types...
|
||||
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
|
||||
|
@ -215,6 +215,8 @@
|
||||
<option>
|
||||
<name>CCDefines</name>
|
||||
<state>EFM32PG1B200F256GM48</state>
|
||||
<state>QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
|
||||
<state>QK_USE_IRQ_NUM=25</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCPreprocFile</name>
|
||||
|
@ -337,7 +337,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define>
|
||||
<Define>QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler QXK_USE_IRQ_NUM=25</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
|
||||
</VariousControls>
|
||||
@ -552,57 +552,6 @@
|
||||
<FileName>qxk_port.cpp</FileName>
|
||||
<FileType>8</FileType>
|
||||
<FilePath>..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.cpp</FilePath>
|
||||
<FileOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>2</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>2</IncludeInBuild>
|
||||
<AlwaysBuild>2</AlwaysBuild>
|
||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
<Cads>
|
||||
<interw>2</interw>
|
||||
<Optim>0</Optim>
|
||||
<oTime>2</oTime>
|
||||
<SplitLS>2</SplitLS>
|
||||
<OneElfS>2</OneElfS>
|
||||
<Strict>2</Strict>
|
||||
<EnumInt>2</EnumInt>
|
||||
<PlainCh>2</PlainCh>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<wLevel>0</wLevel>
|
||||
<uThumb>2</uThumb>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<uC99>2</uC99>
|
||||
<uGnu>2</uGnu>
|
||||
<useXO>2</useXO>
|
||||
<v6Lang>0</v6Lang>
|
||||
<v6LangP>0</v6LangP>
|
||||
<vShortEn>2</vShortEn>
|
||||
<vShortWch>2</vShortWch>
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>QXK_USE_IRQ_NUM=25 QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
@ -1033,7 +982,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define>
|
||||
<Define>NDEBUG</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
|
||||
</VariousControls>
|
||||
@ -1678,7 +1627,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define>
|
||||
<Define>Q_SPY</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
|
||||
</VariousControls>
|
||||
|
@ -143,8 +143,8 @@ LIBS :=
|
||||
|
||||
# defines
|
||||
DEFINES := -DEFM32PG1B200F256GM48=1 \
|
||||
-DQXK_USE_IRQ_NUM=25 \
|
||||
-DQXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
|
||||
-DQXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler \
|
||||
-DQXK_USE_IRQ_NUM=25
|
||||
|
||||
# ARM CPU, ARCH, FPU, and Float-ABI types...
|
||||
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
|
||||
|
@ -215,6 +215,8 @@
|
||||
<option>
|
||||
<name>CCDefines</name>
|
||||
<state>EFM32PG1B200F256GM48</state>
|
||||
<state>QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
|
||||
<state>QXK_USE_IRQ_NUM=25</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCPreprocFile</name>
|
||||
|
@ -299,7 +299,7 @@
|
||||
<bEvRecOn>1</bEvRecOn>
|
||||
<bSchkAxf>0</bSchkAxf>
|
||||
<bTchkAxf>0</bTchkAxf>
|
||||
<nTsel>5</nTsel>
|
||||
<nTsel>6</nTsel>
|
||||
<sDll></sDll>
|
||||
<sDllPa></sDllPa>
|
||||
<sDlgDll></sDlgDll>
|
||||
@ -495,7 +495,7 @@
|
||||
<bEvRecOn>1</bEvRecOn>
|
||||
<bSchkAxf>0</bSchkAxf>
|
||||
<bTchkAxf>0</bTchkAxf>
|
||||
<nTsel>5</nTsel>
|
||||
<nTsel>6</nTsel>
|
||||
<sDll></sDll>
|
||||
<sDllPa></sDllPa>
|
||||
<sDlgDll></sDlgDll>
|
||||
|
@ -337,7 +337,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls>-fno-exceptions</MiscControls>
|
||||
<Define></Define>
|
||||
<Define>QK_USE_IRQ_HANDLER=LCD_IRQHandler QK_USE_IRQ_NUM=30</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8</IncludePath>
|
||||
</VariousControls>
|
||||
@ -522,57 +522,6 @@
|
||||
<FileName>qk_port.cpp</FileName>
|
||||
<FileType>8</FileType>
|
||||
<FilePath>..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.cpp</FilePath>
|
||||
<FileOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>2</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>2</IncludeInBuild>
|
||||
<AlwaysBuild>2</AlwaysBuild>
|
||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
<Cads>
|
||||
<interw>2</interw>
|
||||
<Optim>0</Optim>
|
||||
<oTime>2</oTime>
|
||||
<SplitLS>2</SplitLS>
|
||||
<OneElfS>2</OneElfS>
|
||||
<Strict>2</Strict>
|
||||
<EnumInt>2</EnumInt>
|
||||
<PlainCh>2</PlainCh>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<wLevel>0</wLevel>
|
||||
<uThumb>2</uThumb>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<uC99>2</uC99>
|
||||
<uGnu>2</uGnu>
|
||||
<useXO>2</useXO>
|
||||
<v6Lang>0</v6Lang>
|
||||
<v6LangP>0</v6LangP>
|
||||
<vShortEn>2</vShortEn>
|
||||
<vShortWch>2</vShortWch>
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>QK_USE_IRQ_NUM=30 QK_USE_IRQ_HANDLER=LCD_IRQHandler</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
@ -1281,7 +1230,7 @@
|
||||
<TargetName>dpp-spy</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<pCCUsed>6130001::V6.13.1::.\ARMCLANG</pCCUsed>
|
||||
<pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
|
||||
<uAC6>1</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
|
@ -134,8 +134,8 @@ LIBS :=
|
||||
|
||||
# defines
|
||||
DEFINES := \
|
||||
-DQK_USE_IRQ_NUM=30 \
|
||||
-DQK_USE_IRQ_HANDLER=LCD_IRQHandler
|
||||
-DQK_USE_IRQ_HANDLER=LCD_IRQHandler \
|
||||
-DQK_USE_IRQ_NUM=30
|
||||
|
||||
# ARM CPU, ARCH, FPU, and Float-ABI types...
|
||||
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
|
||||
|
72
examples/arm-cm/dpp_nucleo-l053r8/qk/iar/README.txt
Normal file
72
examples/arm-cm/dpp_nucleo-l053r8/qk/iar/README.txt
Normal file
@ -0,0 +1,72 @@
|
||||
About this Example
|
||||
==================
|
||||
This example demonstrates how to use the IAR EWARM IDE to build
|
||||
a QP application.
|
||||
|
||||
|
||||
IAR Project File
|
||||
----------------
|
||||
The IAR EWARM project file provided with this example uses relative paths
|
||||
to the QP/C framework location (includes, port, and libraries. These
|
||||
relative paths must be modified when the project is moved to different
|
||||
relative location.
|
||||
|
||||
|
||||
Stack Size and Heap Size
|
||||
------------------------
|
||||
In this project, the size of the C stack and heap are determined in
|
||||
the linker script dpp-qk.icf (see the next section).
|
||||
|
||||
|
||||
Linker Script
|
||||
-------------
|
||||
The IAR linker script provides a template of the recommended linker script
|
||||
for QP applications. This file needs to be customized to set the
|
||||
application-specific sizes of the Stack and Heap. This file can be edited
|
||||
from the IAR EWARM IDE via the Project Options/Linker settings.
|
||||
|
||||
|
||||
Selecting QK Exception
|
||||
======================
|
||||
The QK kernel needs a dedicated exception to return to the thread
|
||||
context after preemption. The default is to use the NMI exception
|
||||
for that purpose. However, in case NMI is needed for some other
|
||||
purpose, the QK port allows you to select a any, otherwise unused
|
||||
IRQ for that purpose. To choose a given IRQ, you need to define
|
||||
the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can
|
||||
be provided on the command-line to the compiler.
|
||||
|
||||
For example, for the STM32L053 MCU, you might dedicate the IRQ
|
||||
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
|
||||
as follows:
|
||||
|
||||
QK_USE_IRQ_HANDLER=LCD_IRQHandler
|
||||
QK_USE_IRQ_NUM=30
|
||||
|
||||
|
||||
Startup Code
|
||||
============
|
||||
The startup code for the STM32L053 MCU used in this project is
|
||||
located in the "3rd_party" folder in the following location:
|
||||
|
||||
3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s
|
||||
|
||||
The file startup_efm32pg1b.s provides a template of the recommended
|
||||
startup for QP applications and should be easily customizable for other
|
||||
ARM Cortex-M microcontrollers.
|
||||
|
||||
The startup file typically does not need to be modified or adapted for
|
||||
applications. It provides only weak definitions of all exception and
|
||||
interrupt handlers, as well as the assert_failed() function.
|
||||
|
||||
The weak function assert_failed() defined in this file might be re-defined
|
||||
in the application to customize it for the application-specific error-
|
||||
handling policy.
|
||||
|
||||
***
|
||||
NOTE: The function assert_failed() typically should NOT use the stack,
|
||||
because stack might be corrupted by the time this function is called.
|
||||
Also, assert_failed() is intended to handle catastrophic errors and
|
||||
should NOT return.
|
||||
***
|
||||
|
@ -214,7 +214,8 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>CCDefines</name>
|
||||
<state></state>
|
||||
<state>QK_USE_IRQ_HANDLER=LCD_IRQHandler</state>
|
||||
<state>QK_USE_IRQ_NUM=30</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCPreprocFile</name>
|
||||
|
@ -32,10 +32,27 @@ C++ programs seem not to tolerate heap size of 0. Therefore it is
|
||||
recommended to set the Heap_Size symbol to a minimal value of 16.
|
||||
***
|
||||
|
||||
Selecting QXK Exception
|
||||
=======================
|
||||
The QXK kernel needs a dedicated exception to return to the thread
|
||||
context after preemption. The default is to use the NMI exception
|
||||
for that purpose. However, in case NMI is needed for some other
|
||||
purpose, the QXK port allows you to select a any, otherwise unused
|
||||
IRQ for that purpose. To choose a given IRQ, you need to define
|
||||
the macros QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER. These macros can
|
||||
be provided on the command-line to the compiler.
|
||||
|
||||
For example, for the STM32L053 MCU, you might dedicate the IRQ
|
||||
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
|
||||
as follows:
|
||||
|
||||
QXK_USE_IRQ_HANDLER=LCD_IRQHandler
|
||||
QXK_USE_IRQ_NUM=30
|
||||
|
||||
|
||||
Startup Code
|
||||
============
|
||||
The startup code for the STM32L1xx MCU used in this project is
|
||||
The startup code for the STM32L0xx MCU used in this project is
|
||||
located in the "3rd_party" folder in the following location:
|
||||
|
||||
3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s
|
||||
@ -74,4 +91,3 @@ on the solder bridge configuration. Please see Chapter 5.7 "OSC clock" in
|
||||
the STM32 NUCLEO Boards User Manual (ST document UM1724) for more information.
|
||||
***
|
||||
|
||||
|
@ -495,7 +495,7 @@
|
||||
<bEvRecOn>1</bEvRecOn>
|
||||
<bSchkAxf>0</bSchkAxf>
|
||||
<bTchkAxf>0</bTchkAxf>
|
||||
<nTsel>5</nTsel>
|
||||
<nTsel>6</nTsel>
|
||||
<sDll></sDll>
|
||||
<sDllPa></sDllPa>
|
||||
<sDlgDll></sDlgDll>
|
||||
|
@ -337,7 +337,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls>-fno-exceptions</MiscControls>
|
||||
<Define></Define>
|
||||
<Define>QXK_USE_IRQ_HANDLER=LCD_IRQHandler QXK_USE_IRQ_NUM=30</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8</IncludePath>
|
||||
</VariousControls>
|
||||
@ -542,57 +542,6 @@
|
||||
<FileName>qxk_port.cpp</FileName>
|
||||
<FileType>8</FileType>
|
||||
<FilePath>..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.cpp</FilePath>
|
||||
<FileOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>2</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>2</IncludeInBuild>
|
||||
<AlwaysBuild>2</AlwaysBuild>
|
||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
<Cads>
|
||||
<interw>2</interw>
|
||||
<Optim>0</Optim>
|
||||
<oTime>2</oTime>
|
||||
<SplitLS>2</SplitLS>
|
||||
<OneElfS>2</OneElfS>
|
||||
<Strict>2</Strict>
|
||||
<EnumInt>2</EnumInt>
|
||||
<PlainCh>2</PlainCh>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<wLevel>0</wLevel>
|
||||
<uThumb>2</uThumb>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<uC99>2</uC99>
|
||||
<uGnu>2</uGnu>
|
||||
<useXO>2</useXO>
|
||||
<v6Lang>0</v6Lang>
|
||||
<v6LangP>0</v6LangP>
|
||||
<vShortEn>2</vShortEn>
|
||||
<vShortWch>2</vShortWch>
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>QXK_USE_IRQ_NUM=30 QXK_USE_IRQ_HANDLER=LCD_IRQHandler</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
@ -1321,7 +1270,7 @@
|
||||
<TargetName>dpp-spy</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<pCCUsed>6130001::V6.13.1::.\ARMCLANG</pCCUsed>
|
||||
<pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
|
||||
<uAC6>1</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
|
@ -138,8 +138,8 @@ LIBS :=
|
||||
|
||||
# defines
|
||||
DEFINES := -DQXK_ON_CONTEXT_SW \
|
||||
-DQXK_USE_IRQ_NUM=30 \
|
||||
-DQXK_USE_IRQ_HANDLER=LCD_IRQHandler
|
||||
-DQXK_USE_IRQ_HANDLER=LCD_IRQHandler \
|
||||
-DQXK_USE_IRQ_NUM=30
|
||||
|
||||
# ARM CPU, ARCH, FPU, and Float-ABI types...
|
||||
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
|
||||
|
72
examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/README.txt
Normal file
72
examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/README.txt
Normal file
@ -0,0 +1,72 @@
|
||||
About this Example
|
||||
==================
|
||||
This example demonstrates how to use the IAR EWARM IDE to build
|
||||
a QP application.
|
||||
|
||||
|
||||
IAR Project File
|
||||
----------------
|
||||
The IAR EWARM project file provided with this example uses relative paths
|
||||
to the QP/C framework location (includes, port, and libraries. These
|
||||
relative paths must be modified when the project is moved to different
|
||||
relative location.
|
||||
|
||||
|
||||
Stack Size and Heap Size
|
||||
------------------------
|
||||
In this project, the size of the C stack and heap are determined in
|
||||
the linker script dpp-qxk.icf (see the next section).
|
||||
|
||||
|
||||
Linker Script
|
||||
-------------
|
||||
The IAR linker script provides a template of the recommended linker script
|
||||
for QP applications. This file needs to be customized to set the
|
||||
application-specific sizes of the Stack and Heap. This file can be edited
|
||||
from the IAR EWARM IDE via the Project Options/Linker settings.
|
||||
|
||||
|
||||
Selecting QXK Exception
|
||||
=======================
|
||||
The QXK kernel needs a dedicated exception to return to the thread
|
||||
context after preemption. The default is to use the NMI exception
|
||||
for that purpose. However, in case NMI is needed for some other
|
||||
purpose, the QXK port allows you to select a any, otherwise unused
|
||||
IRQ for that purpose. To choose a given IRQ, you need to define
|
||||
the macros QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER. These macros can
|
||||
be provided on the command-line to the compiler.
|
||||
|
||||
For example, for the STM32L053 MCU, you might dedicate the IRQ
|
||||
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
|
||||
as follows:
|
||||
|
||||
QXK_USE_IRQ_HANDLER=LCD_IRQHandler
|
||||
QXK_USE_IRQ_NUM=30
|
||||
|
||||
|
||||
Startup Code
|
||||
============
|
||||
The startup code for the STM32L053 MCU used in this project is
|
||||
located in the "3rd_party" folder in the following location:
|
||||
|
||||
3rd_party\nucleo-l053r8\iar\startup_stm32l053xx.s
|
||||
|
||||
The file startup_efm32pg1b.s provides a template of the recommended
|
||||
startup for QP applications and should be easily customizable for other
|
||||
ARM Cortex-M microcontrollers.
|
||||
|
||||
The startup file typically does not need to be modified or adapted for
|
||||
applications. It provides only weak definitions of all exception and
|
||||
interrupt handlers, as well as the assert_failed() function.
|
||||
|
||||
The weak function assert_failed() defined in this file might be re-defined
|
||||
in the application to customize it for the application-specific error-
|
||||
handling policy.
|
||||
|
||||
***
|
||||
NOTE: The function assert_failed() typically should NOT use the stack,
|
||||
because stack might be corrupted by the time this function is called.
|
||||
Also, assert_failed() is intended to handle catastrophic errors and
|
||||
should NOT return.
|
||||
***
|
||||
|
@ -215,6 +215,8 @@
|
||||
<option>
|
||||
<name>CCDefines</name>
|
||||
<state>QXK_ON_CONTEXT_SW</state>
|
||||
<state>QXK_USE_IRQ_HANDLER=LCD_IRQHandler</state>
|
||||
<state>QXK_USE_IRQ_NUM=30</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCPreprocFile</name>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*============================================================================
|
||||
* QK/C++ port to ARM Cortex-M, ARM-CLANG
|
||||
* QP/C Real-Time Embedded Framework (RTEF)
|
||||
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
@ -23,8 +23,8 @@
|
||||
* <info@state-machine.com>
|
||||
============================================================================*/
|
||||
/*!
|
||||
* @date Last updated on: 2022-05-13
|
||||
* @version Last updated for: @ref qpcpp_7_0_1
|
||||
* @date Last updated on: 2022-08-13
|
||||
* @version Last updated for: @ref qpc_7_0_2
|
||||
*
|
||||
* @file
|
||||
* @brief QK/C++ port to ARM Cortex-M, ARM-CLANG toolset
|
||||
@ -62,7 +62,7 @@ void NMI_Handler(void);
|
||||
* BASEPRI register. However, this method cannot disable interrupt
|
||||
* priority zero, which is the default for all interrupts out of reset.
|
||||
* The following code changes the SysTick priority and all IRQ priorities
|
||||
* to the safe value QF_BASEPRI, wich the QF critical section can disable.
|
||||
* to the safe value QF_BASEPRI, which the QF critical section can disable.
|
||||
* This avoids breaching of the QF critical sections in case the
|
||||
* application programmer forgets to explicitly set priorities of all
|
||||
* "kernel aware" interrupts.
|
||||
@ -71,7 +71,7 @@ void NMI_Handler(void);
|
||||
* changed by the application-level code.
|
||||
*/
|
||||
void QK_init(void) {
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M and higher... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */
|
||||
|
||||
/* set exception priorities to QF_BASEPRI...
|
||||
* SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault
|
||||
@ -92,25 +92,24 @@ void QK_init(void) {
|
||||
NVIC_IP[n] = QF_BASEPRI;
|
||||
}
|
||||
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- ARMv7-M or higher */
|
||||
|
||||
/* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */
|
||||
SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U));
|
||||
|
||||
#ifdef QK_USE_IRQ_NUM
|
||||
#ifdef QK_USE_IRQ_NUM /*--------- QK IRQ specified? */
|
||||
/* The QK port is configured to use a given ARM Cortex-M IRQ #
|
||||
* to return to thread mode (default is to use the NMI exception)
|
||||
*/
|
||||
NVIC_IP[QK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */
|
||||
NVIC_EN[QK_USE_IRQ_NUM / 32U] = (1U << (QK_USE_IRQ_NUM % 32U));
|
||||
#endif
|
||||
#endif /*--------- QK IRQ specified */
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* The PendSV_Handler exception handler is used for handling context switch
|
||||
* and asynchronous preemption in QK. The use of the PendSV exception is
|
||||
* the recommended and most efficient method for performing context switches
|
||||
* with ARM Cortex-M.
|
||||
/* The PendSV_Handler exception is used for handling the asynchronous
|
||||
* preemption in QK. The use of the PendSV exception is the recommended and
|
||||
* the most efficient method for performing context switches with ARM Cortex-M.
|
||||
*
|
||||
* The PendSV exception should have the lowest priority in the whole system
|
||||
* (0xFF, see QK_init). All other exceptions and interrupts should have higher
|
||||
@ -138,17 +137,17 @@ __asm volatile (
|
||||
" LSLS r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */
|
||||
|
||||
/*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSID i \n" /* disable interrupts (set PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */
|
||||
#endif /* VFP available */
|
||||
#endif /*--------- VFP available */
|
||||
" MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n"
|
||||
" CPSID i \n" /* disable interrutps with BASEPRI */
|
||||
" MSR BASEPRI,r0 \n" /* apply the Cortex-M7 erraturm */
|
||||
" CPSIE i \n" /* 837070, see SDEN-1068427. */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
|
||||
/* The PendSV exception handler can be preempted by an interrupt,
|
||||
* which might pend PendSV exception again. The following write to
|
||||
@ -168,7 +167,7 @@ __asm volatile (
|
||||
" LSRS r3,r1,#3 \n" /* r3 := (r1 >> 3), set the T bit (new xpsr) */
|
||||
" LDR r2,=QK_activate_ \n" /* address of QK_activate_ */
|
||||
" SUBS r2,r2,#1 \n" /* align Thumb-address at halfword (new pc) */
|
||||
" LDR r1,=QK_thread_ret \n" /* return address after the call (new lr) */
|
||||
" LDR r1,=QK_thread_ret \n" /* return address after the call (new lr) */
|
||||
|
||||
" SUB sp,sp,#8*4 \n" /* reserve space for exception stack frame */
|
||||
" ADD r0,sp,#5*4 \n" /* r0 := 5 registers below the SP */
|
||||
@ -176,9 +175,9 @@ __asm volatile (
|
||||
|
||||
" MOVS r0,#6 \n"
|
||||
" MVNS r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M and higher... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
" BX r0 \n" /* exception-return to the QK activator */
|
||||
);
|
||||
}
|
||||
@ -196,61 +195,77 @@ __asm volatile (
|
||||
/* After the QK activator returns, we need to resume the preempted
|
||||
* thread. However, this must be accomplished by a return-from-exception,
|
||||
* while we are still in the thread context. The switch to the exception
|
||||
* contex is accomplished by triggering the SVC or NMI exception.
|
||||
* context is accomplished by triggering the NMI exception or the selected
|
||||
* IRQ (if macro #QK_USE_IRQ_NUM is defined).
|
||||
*/
|
||||
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
/* before triggering the NMI/IRQ, make sure that the VFP stack frame
|
||||
* will NOT be used...
|
||||
*/
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
/* make sure that the VFP stack frame will NOT be used */
|
||||
" MRS r0,CONTROL \n" /* r0 := CONTROL */
|
||||
" BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */
|
||||
" MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
||||
" ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M and higher */
|
||||
|
||||
#ifdef QK_USE_IRQ_NUM /* if use IRQ... */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
" B . \n" /* wait for preemption by the IRQ */
|
||||
#else /* use the NMI */
|
||||
#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
" LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */
|
||||
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
|
||||
" B . \n" /* wait for preemption by NMI */
|
||||
#endif /* use NMI */
|
||||
|
||||
/* NOTE! interrupts are still disabled when NMI is used */
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
|
||||
/* now enable interrupts so that pended IRQ can be entered */
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
#endif /*--------- use IRQ */
|
||||
|
||||
" B . \n" /* wait for preemption by NMI/IRQ */
|
||||
);
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* This exception handler is used for returning back to the interrupted task.
|
||||
/* This exception handler is used for returning back to the preempted thread.
|
||||
* The exception handler simply removes its own interrupt stack frame from
|
||||
* the stack (MSP) and returns to the preempted task using the interrupt
|
||||
* stack frame that must be at the top of the stack.
|
||||
*/
|
||||
__attribute__ ((naked))
|
||||
#ifdef QK_USE_IRQ_HANDLER /* if use IRQ... */
|
||||
void QK_USE_IRQ_HANDLER(void)
|
||||
#else /* use NMI */
|
||||
void NMI_Handler(void)
|
||||
#endif /* use NMI */
|
||||
{
|
||||
#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
void NMI_Handler(void) {
|
||||
__asm volatile (
|
||||
/* enable interrupts */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
);
|
||||
|
||||
#else /* use the selected IRQ */
|
||||
void QK_USE_IRQ_HANDLER(void) {
|
||||
#endif /*--------- use IRQ */
|
||||
__asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */
|
||||
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" POP {r0,lr} \n" /* pop stack aligner and EXC_RETURN to LR */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- VFP available */
|
||||
" BX lr \n" /* return to the preempted task */
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*============================================================================
|
||||
* QK/C++ port to ARM Cortex-M, GNU-ARM
|
||||
* QP/C Real-Time Embedded Framework (RTEF)
|
||||
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
@ -23,8 +23,8 @@
|
||||
* <info@state-machine.com>
|
||||
============================================================================*/
|
||||
/*!
|
||||
* @date Last updated on: 2022-05-13
|
||||
* @version Last updated for: @ref qpcpp_7_0_1
|
||||
* @date Last updated on: 2022-08-13
|
||||
* @version Last updated for: @ref qpc_7_0_2
|
||||
*
|
||||
* @file
|
||||
* @brief QK/C++ port to ARM Cortex-M, GNU-ARM toolset
|
||||
@ -62,7 +62,7 @@ void NMI_Handler(void);
|
||||
* BASEPRI register. However, this method cannot disable interrupt
|
||||
* priority zero, which is the default for all interrupts out of reset.
|
||||
* The following code changes the SysTick priority and all IRQ priorities
|
||||
* to the safe value QF_BASEPRI, wich the QF critical section can disable.
|
||||
* to the safe value QF_BASEPRI, which the QF critical section can disable.
|
||||
* This avoids breaching of the QF critical sections in case the
|
||||
* application programmer forgets to explicitly set priorities of all
|
||||
* "kernel aware" interrupts.
|
||||
@ -71,7 +71,7 @@ void NMI_Handler(void);
|
||||
* changed by the application-level code.
|
||||
*/
|
||||
void QK_init(void) {
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */
|
||||
|
||||
/* set exception priorities to QF_BASEPRI...
|
||||
* SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault
|
||||
@ -92,25 +92,24 @@ void QK_init(void) {
|
||||
NVIC_IP[n] = QF_BASEPRI;
|
||||
}
|
||||
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- ARMv7-M or higher */
|
||||
|
||||
/* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */
|
||||
SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U));
|
||||
|
||||
#ifdef QK_USE_IRQ_NUM
|
||||
#ifdef QK_USE_IRQ_NUM /*--------- QK IRQ specified? */
|
||||
/* The QK port is configured to use a given ARM Cortex-M IRQ #
|
||||
* to return to thread mode (default is to use the NMI exception)
|
||||
*/
|
||||
NVIC_IP[QK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */
|
||||
NVIC_EN[QK_USE_IRQ_NUM / 32U] = (1U << (QK_USE_IRQ_NUM % 32U));
|
||||
#endif
|
||||
#endif /*--------- QK IRQ specified */
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* The PendSV_Handler exception handler is used for handling context switch
|
||||
* and asynchronous preemption in QK. The use of the PendSV exception is
|
||||
* the recommended and most efficient method for performing context switches
|
||||
* with ARM Cortex-M.
|
||||
/* The PendSV_Handler exception is used for handling the asynchronous
|
||||
* preemption in QK. The use of the PendSV exception is the recommended and
|
||||
* the most efficient method for performing context switches with ARM Cortex-M.
|
||||
*
|
||||
* The PendSV exception should have the lowest priority in the whole system
|
||||
* (0xFF, see QK_init). All other exceptions and interrupts should have higher
|
||||
@ -143,17 +142,17 @@ __asm volatile (
|
||||
" LSL r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */
|
||||
|
||||
/*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSID i \n" /* disable interrupts (set PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */
|
||||
#endif /* VFP available */
|
||||
#endif /*--------- VFP available */
|
||||
" MOV r0,#" STRINGIFY(QF_BASEPRI) "\n"
|
||||
" CPSID i \n" /* disable interrutps with BASEPRI */
|
||||
" MSR BASEPRI,r0 \n" /* apply the Cortex-M7 erraturm */
|
||||
" CPSIE i \n" /* 837070, see SDEN-1068427. */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
|
||||
/* The PendSV exception handler can be preempted by an interrupt,
|
||||
* which might pend PendSV exception again. The following write to
|
||||
@ -173,7 +172,7 @@ __asm volatile (
|
||||
" LSR r3,r1,#3 \n" /* r3 := (r1 >> 3), set the T bit (new xpsr) */
|
||||
" LDR r2,=QK_activate_ \n" /* address of QK_activate_ */
|
||||
" SUB r2,r2,#1 \n" /* align Thumb-address at halfword (new pc) */
|
||||
" LDR r1,=QK_thread_ret \n" /* return address after the call (new lr) */
|
||||
" LDR r1,=QK_thread_ret \n" /* return address after the call (new lr) */
|
||||
|
||||
" SUB sp,sp,#8*4 \n" /* reserve space for exception stack frame */
|
||||
" ADD r0,sp,#5*4 \n" /* r0 := 5 registers below the SP */
|
||||
@ -181,9 +180,9 @@ __asm volatile (
|
||||
|
||||
" MOV r0,#6 \n"
|
||||
" MVN r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M and higher... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
" BX r0 \n" /* exception-return to the QK activator */
|
||||
);
|
||||
}
|
||||
@ -201,61 +200,77 @@ __asm volatile (
|
||||
/* After the QK activator returns, we need to resume the preempted
|
||||
* thread. However, this must be accomplished by a return-from-exception,
|
||||
* while we are still in the thread context. The switch to the exception
|
||||
* contex is accomplished by triggering the SVC or NMI exception.
|
||||
* context is accomplished by triggering the NMI exception or the selected
|
||||
* IRQ (if macro #QK_USE_IRQ_NUM is defined).
|
||||
*/
|
||||
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
" MOV r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
/* before triggering the NMI/IRQ, make sure that the VFP stack frame
|
||||
* will NOT be used...
|
||||
*/
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
/* make sure that the VFP stack frame will NOT be used */
|
||||
" MRS r0,CONTROL \n" /* r0 := CONTROL */
|
||||
" BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */
|
||||
" MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
||||
" ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M and higher */
|
||||
|
||||
#ifdef QK_USE_IRQ_NUM /* if use IRQ... */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
" B . \n" /* wait for preemption by the IRQ */
|
||||
#else /* use the NMI */
|
||||
#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
" LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */
|
||||
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
|
||||
" B . \n" /* wait for preemption by NMI */
|
||||
#endif /* use NMI */
|
||||
|
||||
/* NOTE! interrupts are still disabled when NMI is used */
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
|
||||
/* now enable interrupts so that pended IRQ can be entered */
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
" MOV r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
#endif /*--------- use IRQ */
|
||||
|
||||
" B . \n" /* wait for preemption by NMI/IRQ */
|
||||
);
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* This exception handler is used for returning back to the interrupted task.
|
||||
/* This exception handler is used for returning back to the preempted thread.
|
||||
* The exception handler simply removes its own interrupt stack frame from
|
||||
* the stack (MSP) and returns to the preempted task using the interrupt
|
||||
* stack frame that must be at the top of the stack.
|
||||
*/
|
||||
__attribute__ ((naked, optimize("-fno-stack-protector")))
|
||||
#ifdef QK_USE_IRQ_HANDLER /* if use IRQ... */
|
||||
void QK_USE_IRQ_HANDLER(void)
|
||||
#else /* use NMI */
|
||||
void NMI_Handler(void)
|
||||
#endif /* use NMI */
|
||||
{
|
||||
__attribute__ ((naked))
|
||||
#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
void NMI_Handler(void) {
|
||||
__asm volatile (
|
||||
/* enable interrupts */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOV r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
);
|
||||
|
||||
#else /* use the selected IRQ */
|
||||
void QK_USE_IRQ_HANDLER(void) {
|
||||
#endif /*--------- use IRQ */
|
||||
__asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */
|
||||
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M and higher... */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" POP {r0,lr} \n" /* pop stack aligner and EXC_RETURN to LR */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- VFP available */
|
||||
" BX lr \n" /* return to the preempted task */
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*============================================================================
|
||||
* QK/C++ port to ARM Cortex-M, IAR
|
||||
* QP/C Real-Time Embedded Framework (RTEF)
|
||||
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
@ -23,8 +23,8 @@
|
||||
* <info@state-machine.com>
|
||||
============================================================================*/
|
||||
/*!
|
||||
* @date Last updated on: 2022-05-13
|
||||
* @version Last updated for: @ref qpcpp_7_0_1
|
||||
* @date Last updated on: 2022-08-13
|
||||
* @version Last updated for: @ref qpc_7_0_2
|
||||
*
|
||||
* @file
|
||||
* @brief QK/C++ port to ARM Cortex-M, IAR-ARM toolset
|
||||
@ -62,7 +62,7 @@ void NMI_Handler(void);
|
||||
* BASEPRI register. However, this method cannot disable interrupt
|
||||
* priority zero, which is the default for all interrupts out of reset.
|
||||
* The following code changes the SysTick priority and all IRQ priorities
|
||||
* to the safe value QF_BASEPRI, wich the QF critical section can disable.
|
||||
* to the safe value QF_BASEPRI, which the QF critical section can disable.
|
||||
* This avoids breaching of the QF critical sections in case the
|
||||
* application programmer forgets to explicitly set priorities of all
|
||||
* "kernel aware" interrupts.
|
||||
@ -71,7 +71,7 @@ void NMI_Handler(void);
|
||||
* changed by the application-level code.
|
||||
*/
|
||||
void QK_init(void) {
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */
|
||||
|
||||
/* set exception priorities to QF_BASEPRI...
|
||||
* SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault
|
||||
@ -92,25 +92,24 @@ void QK_init(void) {
|
||||
NVIC_IP[n] = QF_BASEPRI;
|
||||
}
|
||||
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- ARMv7-M or higher */
|
||||
|
||||
/* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */
|
||||
SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U));
|
||||
|
||||
#ifdef QK_USE_IRQ_NUM
|
||||
#ifdef QK_USE_IRQ_NUM /*--------- QK IRQ specified? */
|
||||
/* The QK port is configured to use a given ARM Cortex-M IRQ #
|
||||
* to return to thread mode (default is to use the NMI exception)
|
||||
*/
|
||||
NVIC_IP[QK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */
|
||||
NVIC_EN[QK_USE_IRQ_NUM / 32U] = (1U << (QK_USE_IRQ_NUM % 32U));
|
||||
#endif
|
||||
#endif /*--------- QK IRQ specified */
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* The PendSV_Handler exception handler is used for handling context switch
|
||||
* and asynchronous preemption in QK. The use of the PendSV exception is
|
||||
* the recommended and most efficient method for performing context switches
|
||||
* with ARM Cortex-M.
|
||||
/* The PendSV_Handler exception is used for handling the asynchronous
|
||||
* preemption in QK. The use of the PendSV exception is the recommended and
|
||||
* the most efficient method for performing context switches with ARM Cortex-M.
|
||||
*
|
||||
* The PendSV exception should have the lowest priority in the whole system
|
||||
* (0xFF, see QK_init). All other exceptions and interrupts should have higher
|
||||
@ -138,17 +137,17 @@ __asm volatile (
|
||||
" LSLS r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */
|
||||
|
||||
/*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSID i \n" /* disable interrupts (set PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */
|
||||
#endif /* VFP available */
|
||||
#endif /*--------- VFP available */
|
||||
" MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n"
|
||||
" CPSID i \n" /* disable interrutps with BASEPRI */
|
||||
" MSR BASEPRI,r0 \n" /* apply the Cortex-M7 erraturm */
|
||||
" CPSIE i \n" /* 837070, see SDEN-1068427. */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
|
||||
/* The PendSV exception handler can be preempted by an interrupt,
|
||||
* which might pend PendSV exception again. The following write to
|
||||
@ -176,9 +175,9 @@ __asm volatile (
|
||||
|
||||
" MOVS r0,#6 \n"
|
||||
" MVNS r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M and higher... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
" BX r0 \n" /* exception-return to the QK activator */
|
||||
);
|
||||
}
|
||||
@ -189,7 +188,6 @@ __asm volatile (
|
||||
* NOTE: QK_thread_ret does not execute in the PendSV context!
|
||||
* NOTE: QK_thread_ret is entered with interrupts DISABLED.
|
||||
*/
|
||||
|
||||
__stackless
|
||||
void QK_thread_ret(void) {
|
||||
__asm volatile (
|
||||
@ -197,24 +195,30 @@ __asm volatile (
|
||||
/* After the QK activator returns, we need to resume the preempted
|
||||
* thread. However, this must be accomplished by a return-from-exception,
|
||||
* while we are still in the thread context. The switch to the exception
|
||||
* contex is accomplished by triggering the SVC or NMI exception.
|
||||
* context is accomplished by triggering the NMI exception or the selected
|
||||
* IRQ (if macro #QK_USE_IRQ_NUM is defined).
|
||||
*/
|
||||
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M or higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
/* before triggering the NMI/IRQ, make sure that the VFP stack frame
|
||||
* will NOT be used...
|
||||
*/
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
/* make sure that the VFP stack frame will NOT be used */
|
||||
" MRS r0,CONTROL \n" /* r0 := CONTROL */
|
||||
" BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */
|
||||
" MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
||||
" ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
|
||||
#ifdef QK_USE_IRQ_NUM /* if use IRQ... */
|
||||
#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
" LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */
|
||||
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
|
||||
|
||||
/* NOTE! interrupts are still disabled when NMI is used */
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOVS r1,#1 \n"
|
||||
/* NOTE: the following IRQ bit calculation should be done simply as
|
||||
@ -223,39 +227,49 @@ __asm volatile (
|
||||
*/
|
||||
" LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM - (QK_USE_IRQ_NUM/32)*32) "\n"
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
" B . \n" /* wait for preemption by the IRQ */
|
||||
#else /* use the NMI */
|
||||
" LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */
|
||||
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
|
||||
" B . \n" /* wait for preemption by NMI */
|
||||
#endif /* use NMI */
|
||||
|
||||
/* now enable interrupts so that pended IRQ can be entered */
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
#endif /*--------- use IRQ */
|
||||
|
||||
" B . \n" /* wait for preemption by NMI/IRQ */
|
||||
);
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* This exception handler is used for returning back to the interrupted task.
|
||||
/* This exception handler is used for returning back to the preempted thread.
|
||||
* The exception handler simply removes its own interrupt stack frame from
|
||||
* the stack (MSP) and returns to the preempted task using the interrupt
|
||||
* stack frame that must be at the top of the stack.
|
||||
*/
|
||||
__stackless
|
||||
#ifdef QK_USE_IRQ_HANDLER /* if use IRQ... */
|
||||
void QK_USE_IRQ_HANDLER(void)
|
||||
#else /* use NMI */
|
||||
void NMI_Handler(void)
|
||||
#endif /* use NMI */
|
||||
{
|
||||
#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
void NMI_Handler(void) {
|
||||
__asm volatile (
|
||||
/* enable interrupts */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
);
|
||||
|
||||
#else /* use the selected IRQ */
|
||||
void QK_USE_IRQ_HANDLER(void) {
|
||||
#endif /*--------- use IRQ */
|
||||
__asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */
|
||||
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M and higher... */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" POP {r0,lr} \n" /* pop stack aligner and EXC_RETURN to LR */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M and higher */
|
||||
#endif /*--------- VFP available */
|
||||
" BX lr \n" /* return to the preempted task */
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*============================================================================
|
||||
* QXK/C++ port to ARM Cortex-M, ARM-CLANG
|
||||
* QXK/C++ Real-Time to ARM Cortex-M, ARM-CLANG
|
||||
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
@ -23,8 +23,8 @@
|
||||
* <info@state-machine.com>
|
||||
============================================================================*/
|
||||
/*!
|
||||
* @date Last updated on: 2022-06-30
|
||||
* @version Last updated for: @ref qpcpp_7_0_1
|
||||
* @date Last updated on: 2022-08-13
|
||||
* @version Last updated for: @ref qpc_7_0_2
|
||||
*
|
||||
* @file
|
||||
* @brief QXK/C++ port to ARM Cortex-M, ARM-CLANG toolset
|
||||
@ -220,7 +220,7 @@ __asm volatile (
|
||||
#else /* ARMv7-M or higher */
|
||||
" MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n"
|
||||
" CPSID i \n" /* selectively disable interrutps with BASEPRI */
|
||||
" MSR BASEPRI,r0 \n" /* apply the workaround the Cortex-M7 erraturm */
|
||||
" MSR BASEPRI,r0 \n" /* apply the workaround the Cortex-M7 erratum */
|
||||
" CPSIE i \n" /* 837070, see SDEN-1068427. */
|
||||
#endif /* ARMv7-M or higher */
|
||||
|
||||
@ -256,7 +256,7 @@ __asm volatile (
|
||||
" PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */
|
||||
#endif /* VFP available */
|
||||
/* The QXK activator must be called in a thread context, while this code
|
||||
* executes in the handler contex of the PendSV exception. The switch
|
||||
* executes in the handler context of the PendSV exception. The switch
|
||||
* to the Thread mode is accomplished by returning from PendSV using
|
||||
* a fabricated exception stack frame, where the return address is
|
||||
* QXK_activate_().
|
||||
@ -524,64 +524,82 @@ __asm volatile (
|
||||
/* After the QXK activator returns, we need to resume the preempted
|
||||
* thread. However, this must be accomplished by a return-from-exception,
|
||||
* while we are still in the thread context. The switch to the exception
|
||||
* contex is accomplished by triggering the SVC or NMI exception.
|
||||
* context is accomplished by triggering the NMI exception or the selected
|
||||
* IRQ (if macro #QXK_USE_IRQ_NUM is defined).
|
||||
*/
|
||||
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
/* before triggering the NMI/IRQ, make sure that the VFP stack frame
|
||||
* will NOT be used...
|
||||
*/
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
/* make sure that the VFP stack frame will NOT be used */
|
||||
" MRS r0,CONTROL \n" /* r0 := CONTROL */
|
||||
" BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */
|
||||
" MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
||||
" ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- VFP available */
|
||||
|
||||
#ifdef QXK_USE_IRQ_NUM /* if use IRQ... */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
" B . \n" /* wait for preemption by the IRQ */
|
||||
#else /* use the NMI */
|
||||
#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
" LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */
|
||||
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
|
||||
" B . \n" /* wait for preemption by NMI */
|
||||
#endif /* use NMI */
|
||||
|
||||
/* NOTE! interrupts are still disabled when NMI is used */
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
|
||||
/* now enable interrupts so that pended IRQ can be entered */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
#endif /*--------- use IRQ */
|
||||
|
||||
" B . \n" /* wait for preemption by NMI/IRQ */
|
||||
);
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* This exception handler is used for returning back to the interrupted task.
|
||||
/* This exception handler is used for returning back to the preempted thread.
|
||||
* The exception handler simply removes its own interrupt stack frame from
|
||||
* the stack (MSP) and returns to the preempted task using the interrupt
|
||||
* stack frame that must be at the top of the stack.
|
||||
*/
|
||||
__attribute__ ((naked))
|
||||
#ifdef QXK_USE_IRQ_HANDLER /* if use IRQ... */
|
||||
void QXK_USE_IRQ_HANDLER(void)
|
||||
#else /* use NMI */
|
||||
void NMI_Handler(void)
|
||||
#endif /* use NMI */
|
||||
{
|
||||
#ifndef QXK_USE_IRQ_NUM /* IRQ NOT defined, used NMI by default */
|
||||
void NMI_Handler(void) {
|
||||
__asm volatile (
|
||||
/* enable interrupts */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
);
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
void QXK_USE_IRQ_HANDLER(void) {
|
||||
#endif /*--------- use IRQ */
|
||||
__asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */
|
||||
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M or higher... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
" TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */
|
||||
" IT EQ \n" /* if EXC_RETURN[4] is zero... */
|
||||
" VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- VFP available */
|
||||
#endif /*--------- ARMv7-M or higher */
|
||||
" BX lr \n" /* return to the preempted task */
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*============================================================================
|
||||
* QXK/C++ port to ARM Cortex-M, GNU-ARM
|
||||
* QP/C Real-Time Embedded Framework (RTEF)
|
||||
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
@ -23,8 +23,8 @@
|
||||
* <info@state-machine.com>
|
||||
============================================================================*/
|
||||
/*!
|
||||
* @date Last updated on: 2022-06-30
|
||||
* @version Last updated for: @ref qpcpp_7_0_1
|
||||
* @date Last updated on: 2022-08-13
|
||||
* @version Last updated for: @ref qpc_7_0_2
|
||||
*
|
||||
* @file
|
||||
* @brief QXK/C++ port to ARM Cortex-M, GNU-ARM toolset
|
||||
@ -261,7 +261,7 @@ __asm volatile (
|
||||
" PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */
|
||||
#endif /* VFP available */
|
||||
/* The QXK activator must be called in a thread context, while this code
|
||||
* executes in the handler contex of the PendSV exception. The switch
|
||||
* executes in the handler context of the PendSV exception. The switch
|
||||
* to the Thread mode is accomplished by returning from PendSV using
|
||||
* a fabricated exception stack frame, where the return address is
|
||||
* QXK_activate_().
|
||||
@ -529,64 +529,82 @@ __asm volatile (
|
||||
/* After the QXK activator returns, we need to resume the preempted
|
||||
* thread. However, this must be accomplished by a return-from-exception,
|
||||
* while we are still in the thread context. The switch to the exception
|
||||
* contex is accomplished by triggering the SVC or NMI exception.
|
||||
* context is accomplished by triggering the NMI exception or the selected
|
||||
* IRQ (if macro #QXK_USE_IRQ_NUM is defined).
|
||||
*/
|
||||
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M and higher */
|
||||
" MOV r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
/* before triggering the NMI/IRQ, make sure that the VFP stack frame
|
||||
* will NOT be used...
|
||||
*/
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
/* make sure that the VFP stack frame will NOT be used */
|
||||
" MRS r0,CONTROL \n" /* r0 := CONTROL */
|
||||
" BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */
|
||||
" BIC r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */
|
||||
" MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
||||
" ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- VFP available */
|
||||
|
||||
#ifdef QXK_USE_IRQ_NUM /* if use IRQ... */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
" B . \n" /* wait for preemption by the IRQ */
|
||||
#else /* use the NMI */
|
||||
#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
" LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */
|
||||
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
|
||||
" B . \n" /* wait for preemption by NMI */
|
||||
#endif /* use NMI */
|
||||
|
||||
/* NOTE! interrupts are still disabled when NMI is used */
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
|
||||
/* now enable interrupts so that pended IRQ can be entered */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOV r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
#endif /*--------- use IRQ */
|
||||
|
||||
" B . \n" /* wait for preemption by NMI/IRQ */
|
||||
);
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* This exception handler is used for returning back to the interrupted task.
|
||||
/* This exception handler is used for returning back to the preempted thread.
|
||||
* The exception handler simply removes its own interrupt stack frame from
|
||||
* the stack (MSP) and returns to the preempted task using the interrupt
|
||||
* stack frame that must be at the top of the stack.
|
||||
*/
|
||||
__attribute__ ((naked, optimize("-fno-stack-protector")))
|
||||
#ifdef QXK_USE_IRQ_HANDLER /* if use IRQ... */
|
||||
void QXK_USE_IRQ_HANDLER(void)
|
||||
#else /* use NMI */
|
||||
void NMI_Handler(void)
|
||||
#endif /* use NMI */
|
||||
{
|
||||
#ifndef QXK_USE_IRQ_NUM /* IRQ NOT defined, used NMI by default */
|
||||
void NMI_Handler(void) {
|
||||
__asm volatile (
|
||||
/* enable interrupts */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOV r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
);
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
void QXK_USE_IRQ_HANDLER(void) {
|
||||
#endif /*--------- use IRQ */
|
||||
__asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */
|
||||
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M or higher... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
" TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */
|
||||
" IT EQ \n" /* if EXC_RETURN[4] is zero... */
|
||||
" VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- VFP available */
|
||||
#endif /*--------- ARMv7-M or higher */
|
||||
" BX lr \n" /* return to the preempted task */
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*============================================================================
|
||||
* QXK/C++ port to ARM Cortex-M, IAR
|
||||
* QP/C Real-Time Embedded Framework (RTEF)
|
||||
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
@ -23,8 +23,8 @@
|
||||
* <info@state-machine.com>
|
||||
============================================================================*/
|
||||
/*!
|
||||
* @date Last updated on: 2022-06-30
|
||||
* @version Last updated for: @ref qpcpp_7_0_1
|
||||
* @date Last updated on: 2022-08-13
|
||||
* @version Last updated for: @ref qpc_7_0_2
|
||||
*
|
||||
* @file
|
||||
* @brief QXK/C++ port to ARM Cortex-M, IAR-ARM toolset
|
||||
@ -206,7 +206,7 @@ void QXK_stackInit_(void *thr, QP::QXThreadHandler const handler,
|
||||
*/
|
||||
__stackless
|
||||
void PendSV_Handler(void) {
|
||||
__asm (
|
||||
__asm volatile (
|
||||
|
||||
/* Prepare some constants before entering a critical section... */
|
||||
" LDR r3,=QXK_attr_ \n"
|
||||
@ -220,7 +220,7 @@ __asm (
|
||||
#else /* ARMv7-M or higher */
|
||||
" MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n"
|
||||
" CPSID i \n" /* selectively disable interrutps with BASEPRI */
|
||||
" MSR BASEPRI,r0 \n" /* apply the workaround the Cortex-M7 erraturm */
|
||||
" MSR BASEPRI,r0 \n" /* apply the workaround the Cortex-M7 erratum */
|
||||
" CPSIE i \n" /* 837070, see SDEN-1068427. */
|
||||
#endif /* ARMv7-M or higher */
|
||||
|
||||
@ -256,7 +256,7 @@ __asm (
|
||||
" PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */
|
||||
#endif /* VFP available */
|
||||
/* The QXK activator must be called in a thread context, while this code
|
||||
* executes in the handler contex of the PendSV exception. The switch
|
||||
* executes in the handler context of the PendSV exception. The switch
|
||||
* to the Thread mode is accomplished by returning from PendSV using
|
||||
* a fabricated exception stack frame, where the return address is
|
||||
* QXK_activate_().
|
||||
@ -519,73 +519,91 @@ __asm (
|
||||
*/
|
||||
__stackless
|
||||
void QXK_thread_ret(void) {
|
||||
__asm (
|
||||
__asm volatile (
|
||||
|
||||
/* After the QXK activator returns, we need to resume the preempted
|
||||
* thread. However, this must be accomplished by a return-from-exception,
|
||||
* while we are still in the thread context. The switch to the exception
|
||||
* contex is accomplished by triggering the SVC or NMI exception.
|
||||
* context is accomplished by triggering the NMI exception or the selected
|
||||
* IRQ (if macro #QXK_USE_IRQ_NUM is defined).
|
||||
*/
|
||||
|
||||
#if (__ARM_ARCH == 6) /* if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /* ARMv7-M or higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
/* before triggering the NMI/IRQ, make sure that the VFP stack frame
|
||||
* will NOT be used...
|
||||
*/
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
/* make sure that the VFP stack frame will NOT be used */
|
||||
" MRS r0,CONTROL \n" /* r0 := CONTROL */
|
||||
" BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */
|
||||
" MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */
|
||||
" ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- VFP available */
|
||||
|
||||
#ifdef QXK_USE_IRQ_NUM /* if use IRQ... */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOVS r1,#1 \n"
|
||||
/* NOTE: the following IRQ bit calculation should be done simply as
|
||||
* (QK_USE_IRQ_NUM % 32), but the IAR assembler does not accept it.
|
||||
* As a workaround the modulo (%) operation is replaced with the following:
|
||||
*/
|
||||
" LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM - (QXK_USE_IRQ_NUM/32)*32) "\n"
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
" B . \n" /* wait for preemption by the IRQ */
|
||||
#else /* use the NMI */
|
||||
#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, used NMI by default */
|
||||
" LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */
|
||||
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
|
||||
" B . \n" /* wait for preemption by NMI */
|
||||
#endif /* use NMI */
|
||||
|
||||
/* NOTE! interrupts are still disabled when NMI is used */
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
|
||||
" MOVS r1,#1 \n"
|
||||
/* NOTE: the following IRQ bit calculation should be done simply as
|
||||
* (QXK_USE_IRQ_NUM % 32), but the IAR assembler does not accept it.
|
||||
* As a workaround the modulo (%) operation is replaced with the following:
|
||||
*/
|
||||
" LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM - (QXK_USE_IRQ_NUM/32)*32) "\n"
|
||||
" STR r1,[r0] \n" /* pend the IRQ */
|
||||
|
||||
/* now enable interrupts so that pended IRQ can be entered */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
#endif /*--------- use IRQ */
|
||||
|
||||
" B . \n" /* wait for preemption by NMI/IRQ */
|
||||
);
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* This exception handler is used for returning back to the interrupted task.
|
||||
/* This exception handler is used for returning back to the preempted thread.
|
||||
* The exception handler simply removes its own interrupt stack frame from
|
||||
* the stack (MSP) and returns to the preempted task using the interrupt
|
||||
* stack frame that must be at the top of the stack.
|
||||
*/
|
||||
__stackless
|
||||
#ifdef QXK_USE_IRQ_HANDLER /* if use IRQ... */
|
||||
void QXK_USE_IRQ_HANDLER(void)
|
||||
#else /* use NMI */
|
||||
void NMI_Handler(void)
|
||||
#endif /* use NMI */
|
||||
{
|
||||
#ifndef QXK_USE_IRQ_NUM /* IRQ NOT defined, used NMI by default */
|
||||
void NMI_Handler(void) {
|
||||
__asm volatile (
|
||||
/* enable interrupts */
|
||||
#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */
|
||||
" CPSIE i \n" /* enable interrupts (clear PRIMASK) */
|
||||
#else /*--------- ARMv7-M and higher */
|
||||
" MOVS r0,#0 \n"
|
||||
" MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */
|
||||
#endif /*--------- ARMv7-M and higher */
|
||||
);
|
||||
|
||||
#else /*--------- use the selected IRQ */
|
||||
void QXK_USE_IRQ_HANDLER(void) {
|
||||
#endif /*--------- use IRQ */
|
||||
__asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */
|
||||
|
||||
#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */
|
||||
#if (__ARM_FP != 0) /* if VFP available... */
|
||||
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M or higher... */
|
||||
#if (__ARM_FP != 0) /*--------- if VFP available... */
|
||||
" POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */
|
||||
" DSB \n" /* ARM Erratum 838869 */
|
||||
" TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */
|
||||
" IT EQ \n" /* if EXC_RETURN[4] is zero... */
|
||||
" VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */
|
||||
#endif /* VFP available */
|
||||
#endif /* ARMv7-M or higher */
|
||||
#endif /*--------- VFP available */
|
||||
#endif /*--------- ARMv7-M or higher */
|
||||
" BX lr \n" /* return to the preempted task */
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user