From 47677d9e7fc1a270595e4bafef26916cf363cb64 Mon Sep 17 00:00:00 2001 From: jonas Date: Mon, 30 Sep 2024 10:51:44 +0800 Subject: [PATCH] allows rewrite to interrupt enable/disable api to support independent interrupts management --- libcpu/arm/cortex-m4/README.md | 53 +++++++++++++++++++++++++++++ libcpu/arm/cortex-m4/context_gcc.S | 7 ++++ libcpu/arm/cortex-m4/context_iar.S | 11 ++++-- libcpu/arm/cortex-m4/context_rvds.S | 9 +++-- 4 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 libcpu/arm/cortex-m4/README.md diff --git a/libcpu/arm/cortex-m4/README.md b/libcpu/arm/cortex-m4/README.md new file mode 100644 index 0000000..05e4b14 --- /dev/null +++ b/libcpu/arm/cortex-m4/README.md @@ -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`. diff --git a/libcpu/arm/cortex-m4/context_gcc.S b/libcpu/arm/cortex-m4/context_gcc.S index 5088e40..908c957 100644 --- a/libcpu/arm/cortex-m4/context_gcc.S +++ b/libcpu/arm/cortex-m4/context_gcc.S @@ -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 diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S index 30be2b7..fc87c82 100644 --- a/libcpu/arm/cortex-m4/context_iar.S +++ b/libcpu/arm/cortex-m4/context_iar.S @@ -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 diff --git a/libcpu/arm/cortex-m4/context_rvds.S b/libcpu/arm/cortex-m4/context_rvds.S index 018e425..3f6e2e8 100644 --- a/libcpu/arm/cortex-m4/context_rvds.S +++ b/libcpu/arm/cortex-m4/context_rvds.S @@ -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