allows rewrite to interrupt enable/disable api to support independent interrupts management
This commit is contained in:
53
libcpu/arm/cortex-m4/README.md
Normal file
53
libcpu/arm/cortex-m4/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
## Independent Interrupts Management
|
||||
|
||||
### Introduction
|
||||
Calling `rt_hw_interrupt_disable` in multiple places on `rt-thread` may cause interruption delays when the application requires accurate interrupt responses. This is because the system cannot generate any interrupts except abnormal interrupts after disabling interrupts. This is a common problem in the interrupt management of the operating system. The independent interrupt management module is designed to solve this problem.
|
||||
|
||||
The independent interrupt management module is designed to solve the problem of interrupt delays caused by calling `rt_hw_interrupt_disable` in multiple places on `rt-thread`. The module is implemented by rewrite the `rt_hw_interrupt_disable` and `rt_hw_interrupt_enable` functions in the `libcpu` library.
|
||||
|
||||
|
||||
### Usage
|
||||
- Add the following code to the project's `board.c` file.
|
||||
```
|
||||
#ifdef RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT
|
||||
#define RT_NVIC_PRO_BITS __NVIC_PRIO_BITS
|
||||
|
||||
rt_base_t rt_hw_interrupt_disable(void)
|
||||
{
|
||||
rt_base_t level = __get_BASEPRI();
|
||||
__set_BASEPRI(RT_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - RT_NVIC_PRO_BITS));
|
||||
|
||||
__ISB();
|
||||
__DSB();
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_enable(rt_base_t level)
|
||||
{
|
||||
__set_BASEPRI(level);
|
||||
}
|
||||
|
||||
#endif /* RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT */
|
||||
```
|
||||
- Add the following configuration to the `Kconfig` file in the `board` directory.
|
||||
```
|
||||
menuconfig RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT
|
||||
bool "Enable independent interrupt management"
|
||||
default n
|
||||
|
||||
if RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT
|
||||
config RT_MAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
int "Set max syscall interrupt priority"
|
||||
range 0 7
|
||||
default 2
|
||||
endif
|
||||
```
|
||||
- Select `RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT` to enable this feature.
|
||||
- Select `RT_MAX_SYSCALL_INTERRUPT_PRIORITY` to set the maximum priority of the interrupt that can be called by the system call. The default value is 2.
|
||||
|
||||
### Description
|
||||
- The [basepri](https://developer.arm.com/documentation/107706/0100/Exceptions-and-interrupts-overview/Special-registers-for-exception-masking/BASEPRI) register is used in the functions to complete the interrupt management.
|
||||
- For example, if `RT_MAX_SYSCALL_INTERRUPT_PRIORITY` is set to 0x01, the system masking only interrupts with a priority of `0x01-0xFF`.
|
||||
- Interrupts with a priority of 0 are not managed by the system and can continue to respond to interrupts after `rt_hw_interrupt_disable` is called.
|
||||
- When using the [basepri](https://developer.arm.com/documentation/107706/0100/Exceptions-and-interrupts-overview/Special-registers-for-exception-masking/BASEPRI) register for independent interrupt management, note that interrupts with a priority value lower than `RT_MAX_SYSCALL_INTERRUPT_PRIORITY` cannot call any `system API`.
|
@ -10,6 +10,7 @@
|
||||
* 2013-06-18 aozima add restore MSP feature.
|
||||
* 2013-06-23 aozima support lazy stack optimized.
|
||||
* 2018-07-24 aozima enhancement hard fault exception handler.
|
||||
* 2024-08-13 Evlers allows rewrite to interrupt enable/disable api to support independent interrupts management
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -32,6 +33,7 @@
|
||||
* rt_base_t rt_hw_interrupt_disable();
|
||||
*/
|
||||
.global rt_hw_interrupt_disable
|
||||
.weak rt_hw_interrupt_disable
|
||||
.type rt_hw_interrupt_disable, %function
|
||||
rt_hw_interrupt_disable:
|
||||
MRS r0, PRIMASK
|
||||
@ -42,6 +44,7 @@ rt_hw_interrupt_disable:
|
||||
* void rt_hw_interrupt_enable(rt_base_t level);
|
||||
*/
|
||||
.global rt_hw_interrupt_enable
|
||||
.weak rt_hw_interrupt_enable
|
||||
.type rt_hw_interrupt_enable, %function
|
||||
rt_hw_interrupt_enable:
|
||||
MSR PRIMASK, r0
|
||||
@ -208,6 +211,10 @@ rt_hw_context_switch_to:
|
||||
CPSIE F
|
||||
CPSIE I
|
||||
|
||||
/* clear the BASEPRI register to disable masking priority */
|
||||
MOV r0, #0x00
|
||||
MSR BASEPRI, r0
|
||||
|
||||
/* ensure PendSV exception taken place before subsequent operation */
|
||||
DSB
|
||||
ISB
|
||||
|
@ -11,6 +11,7 @@
|
||||
; * 2013-06-18 aozima add restore MSP feature.
|
||||
; * 2013-06-23 aozima support lazy stack optimized.
|
||||
; * 2018-07-24 aozima enhancement hard fault exception handler.
|
||||
; * 2024-08-13 Evlers allows rewrite to interrupt enable/disable api to support independent interrupts management
|
||||
; */
|
||||
|
||||
;/**
|
||||
@ -36,7 +37,8 @@ NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV excep
|
||||
;/*
|
||||
; * rt_base_t rt_hw_interrupt_disable();
|
||||
; */
|
||||
EXPORT rt_hw_interrupt_disable
|
||||
PUBWEAK rt_hw_interrupt_disable
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
rt_hw_interrupt_disable:
|
||||
MRS r0, PRIMASK
|
||||
CPSID I
|
||||
@ -45,7 +47,8 @@ rt_hw_interrupt_disable:
|
||||
;/*
|
||||
; * void rt_hw_interrupt_enable(rt_base_t level);
|
||||
; */
|
||||
EXPORT rt_hw_interrupt_enable
|
||||
PUBWEAK rt_hw_interrupt_enable
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
rt_hw_interrupt_enable:
|
||||
MSR PRIMASK, r0
|
||||
BX LR
|
||||
@ -208,6 +211,10 @@ rt_hw_context_switch_to:
|
||||
CPSIE F
|
||||
CPSIE I
|
||||
|
||||
; clear the BASEPRI register to disable masking priority
|
||||
MOV r0, #0x00
|
||||
MSR BASEPRI, r0
|
||||
|
||||
; ensure PendSV exception taken place before subsequent operation
|
||||
DSB
|
||||
ISB
|
||||
|
@ -10,6 +10,7 @@
|
||||
; * 2013-06-18 aozima add restore MSP feature.
|
||||
; * 2013-06-23 aozima support lazy stack optimized.
|
||||
; * 2018-07-24 aozima enhancement hard fault exception handler.
|
||||
; * 2024-08-13 Evlers allows rewrite to interrupt enable/disable api to support independent interrupts management
|
||||
; */
|
||||
|
||||
;/**
|
||||
@ -36,7 +37,7 @@ NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV excep
|
||||
; * rt_base_t rt_hw_interrupt_disable();
|
||||
; */
|
||||
rt_hw_interrupt_disable PROC
|
||||
EXPORT rt_hw_interrupt_disable
|
||||
EXPORT rt_hw_interrupt_disable [WEAK]
|
||||
MRS r0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
@ -46,7 +47,7 @@ rt_hw_interrupt_disable PROC
|
||||
; * void rt_hw_interrupt_enable(rt_base_t level);
|
||||
; */
|
||||
rt_hw_interrupt_enable PROC
|
||||
EXPORT rt_hw_interrupt_enable
|
||||
EXPORT rt_hw_interrupt_enable [WEAK]
|
||||
MSR PRIMASK, r0
|
||||
BX LR
|
||||
ENDP
|
||||
@ -208,6 +209,10 @@ rt_hw_context_switch_to PROC
|
||||
CPSIE F
|
||||
CPSIE I
|
||||
|
||||
; clear the BASEPRI register to disable masking priority
|
||||
MOV r0, #0x00
|
||||
MSR BASEPRI, r0
|
||||
|
||||
; ensure PendSV exception taken place before subsequent operation
|
||||
DSB
|
||||
ISB
|
||||
|
Reference in New Issue
Block a user