Skip to content

Commit

Permalink
Merge branch 'main' into 'main'
Browse files Browse the repository at this point in the history
🐛 fix immature context switch optimization on ARMv6/ARMv7

See merge request library/M5P01_Prokaron!22
  • Loading branch information
EDI-Systems committed Jul 13, 2024
2 parents 8c93b87 + 121cd3d commit c4931af
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 75 deletions.
10 changes: 3 additions & 7 deletions Include/Platform/A6M/rmp_platform_a6m.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,9 @@ typedef rmp_s32_t rmp_ret_t;
#define RMP_INT_MASK() RMP_Int_Disable()
#define RMP_INT_UNMASK() RMP_Int_Enable()
/* Yield operation */
#define RMP_YIELD() (RMP_A6M_NVIC_INT_CTRL=RMP_A6M_NVIC_PENDSVSET)
#define RMP_YIELD() _RMP_A6M_Yield()
#define RMP_YIELD_ISR() RMP_YIELD()
/* End System Macro **********************************************************/

/* ARMv6-M Macro *************************************************************/
/* PendSV trigger */
#define RMP_A6M_NVIC_INT_CTRL (*((volatile rmp_ptr_t*)0xE000ED04U))
#define RMP_A6M_NVIC_PENDSVSET (0x10000000U)
/* End ARMv6-M Macro *********************************************************/
/*****************************************************************************/
/* __RMP_PLATFORM_A6M_DEF__ */
#endif
Expand Down Expand Up @@ -189,6 +183,8 @@ RMP_EXTERN void RMP_Int_Enable(void);
RMP_EXTERN void _RMP_Start(rmp_ptr_t Entry,
rmp_ptr_t Stack);

RMP_EXTERN void _RMP_A6M_Yield(void);

/* Initialization */
__RMP_EXTERN__ rmp_ptr_t _RMP_Stack_Init(rmp_ptr_t Stack,
rmp_ptr_t Size,
Expand Down
10 changes: 4 additions & 6 deletions Include/Platform/A7M/rmp_platform_a7m.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ typedef rmp_s32_t rmp_ret_t;
#define RMP_INT_MASK() RMP_Int_Mask(RMP_A7M_INT_MASK_LVL)
#define RMP_INT_UNMASK() RMP_Int_Mask(0x00U)
/* Yield operation */
#define RMP_YIELD() (RMP_A7M_NVIC_INT_CTRL=RMP_A7M_NVIC_PENDSVSET)
#define RMP_YIELD() _RMP_A7M_Yield()
#define RMP_YIELD_ISR() RMP_YIELD()
/* End System Macro **********************************************************/

Expand All @@ -104,10 +104,6 @@ typedef rmp_s32_t rmp_ret_t;
#define RMP_A7M_NVIC_GROUPING_P2S6 (5U)
#define RMP_A7M_NVIC_GROUPING_P1S7 (6U)
#define RMP_A7M_NVIC_GROUPING_P0S8 (7U)

/* PendSV trigger */
#define RMP_A7M_NVIC_INT_CTRL (*((volatile rmp_ptr_t*)0xE000ED04U))
#define RMP_A7M_NVIC_PENDSVSET (0x10000000U)
/* End ARMv7-M Macro *********************************************************/
/*****************************************************************************/
/* __RMP_PLATFORM_A7M_DEF__ */
Expand Down Expand Up @@ -203,7 +199,9 @@ RMP_EXTERN void RMP_Int_Mask(rmp_ptr_t Level);

RMP_EXTERN rmp_ptr_t _RMP_A7M_MSB_Get(rmp_ptr_t Value);
RMP_EXTERN rmp_ptr_t _RMP_A7M_LSB_Get(rmp_ptr_t Value);
RMP_EXTERN void _RMP_Start(rmp_ptr_t Entry, rmp_ptr_t Stack);
RMP_EXTERN void _RMP_Start(rmp_ptr_t Entry,
rmp_ptr_t Stack);
RMP_EXTERN void _RMP_A7M_Yield(void);

/* Initialization */
__RMP_EXTERN__ rmp_ptr_t _RMP_Stack_Init(rmp_ptr_t Stack,
Expand Down
6 changes: 3 additions & 3 deletions Project/RVMDK-STM32F767IGT6/RMP.uvprojx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
<TargetName>RMP</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>6180000::V6.18::ARMCLANG</pCCUsed>
<pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
<uAC6>1</uAC6>
<TargetOption>
<TargetCommonOption>
<Device>STM32F767IGTx</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32F7xx_DFP.2.16.0</PackID>
<PackID>Keil.STM32F7xx_DFP.2.15.2</PackID>
<PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20020000,0x60000) IRAM2(0x20000000,0x20000) IROM(0x08000000,0x100000) IROM2(0x00200000,0x100000) CPUTYPE("Cortex-M7") FPU3(DFPU) CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
Expand Down Expand Up @@ -173,7 +173,7 @@
<AdsLven>1</AdsLven>
<AdsLsxf>1</AdsLsxf>
<RvctClst>1</RvctClst>
<GenPPlst>0</GenPPlst>
<GenPPlst>1</GenPPlst>
<AdsCpuType>"Cortex-M7"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<mOS>0</mOS>
Expand Down
6 changes: 3 additions & 3 deletions Project/RVMDK-STM32L071CBT6/RMP.uvprojx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
<TargetName>RMP</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>6180000::V6.18::ARMCLANG</pCCUsed>
<pCCUsed>6190000::V6.19::ARMCLANG</pCCUsed>
<uAC6>1</uAC6>
<TargetOption>
<TargetCommonOption>
<Device>STM32L071CBTx</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32L0xx_DFP.2.3.0</PackID>
<PackURL>https://www.keil.com/pack/</PackURL>
<PackID>Keil.STM32L0xx_DFP.2.2.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000,0x00005000) IROM(0x08000000,0x00020000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile>
Expand Down
33 changes: 19 additions & 14 deletions Source/Platform/A6M/rmp_platform_a6m_armcc.s
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
EXPORT RMP_Int_Enable
;Start the first thread
EXPORT _RMP_Start
;Yield to another thread
EXPORT _RMP_A6M_Yield
;The system pending service routine
EXPORT PendSV_Handler
;The systick timer routine
Expand Down Expand Up @@ -87,14 +89,23 @@ _RMP_Start PROC
ENDP
;/* End Function:_RMP_Start **************************************************/

;/* Function:_RMP_A6M_Yield ***************************************************
;Description : Trigger a yield to another thread.
;Input : None.
;Output : None.
;Return : None.
;*****************************************************************************/
_RMP_A6M_Yield PROC
LDR R0,=0xE000ED04 ;The NVIC_INT_CTRL register
LDR R1,=0x10000000 ;Trigger the PendSV
STR R1,[R0]
DSB
BX LR
ENDP
;/* End Function:_RMP_A6M_Yield **********************************************/

;/* Function:PendSV_Handler ***************************************************
;Description : The PendSV interrupt routine. In fact, it will call a C function
; directly. The reason why the interrupt routine must be an assembly
; function is that the compiler may deal with the stack in a different
; way when different optimization level is chosen. An assembly function
; can make way around this problem.
; However, if your compiler support inline assembly functions, this
; can also be written in C.
;Description : The PendSV interrupt handler.
; ARMv6-M only have STMIA, will have to live with it.
;Input : None.
;Output : None.
Expand Down Expand Up @@ -134,13 +145,7 @@ PendSV_Handler PROC
;/* End Function:PendSV_Handler **********************************************/

;/* Function:SysTick_Handler **************************************************
;Description : The SysTick interrupt routine. In fact, it will call a C function
; directly. The reason why the interrupt routine must be an assembly
; function is that the compiler may deal with the stack in a different
; way when different optimization level is chosen. An assembly function
; can make way around this problem.
; However, if your compiler support inline assembly functions, this
; can also be written in C.
;Description : The SysTick interrupt handler.
;Input : None.
;Output : None.
;Return : None.
Expand Down
33 changes: 19 additions & 14 deletions Source/Platform/A6M/rmp_platform_a6m_gcc.s
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ The above 3 registers are saved into the stack in combination(xPSR).
.global RMP_Int_Mask
/* Start the first thread */
.global _RMP_Start
/* Yield to another thread */
.global _RMP_A6M_Yield
/* The system pending service routine */
.global PendSV_Handler
/* The systick timer routine */
Expand Down Expand Up @@ -89,14 +91,23 @@ _RMP_Start:
BLX R0 /* Branch to our target */
/* End Function:_RMP_Start ***************************************************/

/* Function:_RMP_A6M_Yield ****************************************************
Description : Trigger a yield to another thread.
Input : None.
Output : None.
Return : None.
******************************************************************************/
.thumb_func
_RMP_A6M_Yield:
LDR R0,=0xE000ED04 /* The NVIC_INT_CTRL register */
LDR R1,=0x10000000 /* Trigger the PendSV */
STR R1,[R0]
DSB
BX LR
/* End Function:_RMP_A6M_Yield ***********************************************/

/* Function:PendSV_Handler ****************************************************
Description : The PendSV interrupt routine. In fact, it will call a C function
directly. The reason why the interrupt routine must be an assembly
function is that the compiler may deal with the stack in a different
way when different optimization level is chosen. An assembly function
can make way around this problem.
However, if your compiler support inline assembly functions, this
can also be written in C.
Description : The PendSV interrupt handler.
ARMv6-M only have STMIA, will have to live with it.
Input : None.
Output : None.
Expand Down Expand Up @@ -136,13 +147,7 @@ PendSV_Handler:
/* End Function:PendSV_Handler ***********************************************/

/* Function:SysTick_Handler ***************************************************
Description : The SysTick interrupt routine. In fact, it will call a C function
directly. The reason why the interrupt routine must be an assembly
function is that the compiler may deal with the stack in a different
way when different optimization level is chosen. An assembly function
can make way around this problem.
However, if your compiler support inline assembly functions, this
can also be written in C.
Description : The SysTick interrupt handler.
Input : None.
Output : None.
Return : None.
Expand Down
33 changes: 19 additions & 14 deletions Source/Platform/A7M/rmp_platform_a7m_armcc.s
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
EXPORT _RMP_A7M_LSB_Get
;Start the first thread
EXPORT _RMP_Start
;Yield to another thread
EXPORT _RMP_A7M_Yield
;The system pending service routine
EXPORT PendSV_Handler
;The systick timer routine
Expand Down Expand Up @@ -135,14 +137,23 @@ _RMP_Start PROC
ENDP
;/* End Function:_RMP_Start **************************************************/

;/* Function:_RMP_A7M_Yield ***************************************************
;Description : Trigger a yield to another thread.
;Input : None.
;Output : None.
;Return : None.
;*****************************************************************************/
_RMP_A7M_Yield PROC
LDR R0,=0xE000ED04 ;The NVIC_INT_CTRL register
LDR R1,=0x10000000 ;Trigger the PendSV
STR R1,[R0]
DSB
BX LR
ENDP
;/* End Function:_RMP_A7M_Yield **********************************************/

;/* Function:PendSV_Handler ***************************************************
;Description : The PendSV interrupt routine. In fact, it will call a C function
; directly. The reason why the interrupt routine must be an assembly
; function is that the compiler may deal with the stack in a different
; way when different optimization level is chosen. An assembly function
; can make way around this problem.
; However, if your compiler support inline assembly functions, this
; can also be written in C.
;Description : The PendSV interrupt handler.
;Input : None.
;Output : None.
;Return : None.
Expand Down Expand Up @@ -175,13 +186,7 @@ PendSV_Handler PROC
;/* End Function:PendSV_Handler **********************************************/

;/* Function:SysTick_Handler **************************************************
;Description : The SysTick interrupt routine. In fact, it will call a C function
; directly. The reason why the interrupt routine must be an assembly
; function is that the compiler may deal with the stack in a different
; way when different optimization level is chosen. An assembly function
; can make way around this problem.
; However, if your compiler support inline assembly functions, this
; can also be written in C.
;Description : The SysTick interrupt handler.
;Input : None.
;Output : None.
;Return : None.
Expand Down
33 changes: 19 additions & 14 deletions Source/Platform/A7M/rmp_platform_a7m_gcc.s
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ The ARM Cortex-M4/7 also include a FPU.
.global _RMP_A7M_LSB_Get
/* Start the first thread */
.global _RMP_Start
/* Yield to another thread */
.global _RMP_A7M_Yield
/* The system pending service routine */
.global PendSV_Handler
/* The systick timer routine */
Expand Down Expand Up @@ -135,14 +137,23 @@ _RMP_Start:
BLX R0 /* Branch to our target */
/* End Function:_RMP_Start ***************************************************/

/* Function:_RMP_A7M_Yield ****************************************************
Description : Trigger a yield to another thread.
Input : None.
Output : None.
Return : None.
******************************************************************************/
.thumb_func
_RMP_A7M_Yield:
LDR R0,=0xE000ED04 /* The NVIC_INT_CTRL register */
LDR R1,=0x10000000 /* Trigger the PendSV */
STR R1,[R0]
DSB
BX LR
/* End Function:_RMP_A7M_Yield ***********************************************/

/* Function:PendSV_Handler ****************************************************
Description : The PendSV interrupt routine. In fact, it will call a C function
directly. The reason why the interrupt routine must be an assembly
function is that the compiler may deal with the stack in a different
way when different optimization level is chosen. An assembly function
can make way around this problem.
However, if your compiler support inline assembly functions, this
can also be written in C.
Description : The PendSV interrupt handler.
Input : None.
Output : None.
Return : None.
Expand Down Expand Up @@ -175,13 +186,7 @@ PendSV_Handler:
/* End Function:PendSV_Handler ***********************************************/

/* Function:SysTick_Handler ***************************************************
Description : The SysTick interrupt routine. In fact, it will call a C function
directly. The reason why the interrupt routine must be an assembly
function is that the compiler may deal with the stack in a different
way when different optimization level is chosen. An assembly function
can make way around this problem.
However, if your compiler support inline assembly functions, this
can also be written in C.
Description : The SysTick interrupt handler.
Input : None.
Output : None.
Return : None.
Expand Down

0 comments on commit c4931af

Please sign in to comment.