From e74547bbb36c38bbebf8baca4d728b3db14885df Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Wed, 8 Apr 2026 13:45:46 +0800 Subject: feat(core): Add Cortex-M4 interrupt context helpers --- libcpu/arm/cortex-m4/cpuport.c | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) (limited to 'libcpu') diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c index 9504008e36..69bcc4c6d9 100644 --- a/libcpu/arm/cortex-m4/cpuport.c +++ b/libcpu/arm/cortex-m4/cpuport.c @@ -20,6 +20,10 @@ #include +#define DBG_TAG "cortex.m4" +#define DBG_LVL DBG_INFO +#include + #if /* ARMCC */ ( (defined ( __CC_ARM ) && defined ( __TARGET_FPU_VFP )) \ /* Clang */ || (defined ( __clang__ ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__)) \ /* IAR */ || (defined ( __ICCARM__ ) && defined ( __ARMVFP__ )) \ @@ -436,6 +440,107 @@ void rt_hw_cpu_reset(void) SCB_AIRCR = SCB_RESET_VALUE; } +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +rt_inline rt_uint32_t rt_hw_get_ipsr(void) +{ +#if defined(__CC_ARM) + register uint32_t __regIPSR __asm("ipsr"); + return(__regIPSR); +#elif defined(__clang__) + uint32_t result; + __asm volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +#elif defined(__IAR_SYSTEMS_ICC__) + return __iar_builtin_rsr("IPSR"); +#elif defined ( __GNUC__ ) + uint32_t result; + __asm volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +#endif +} + +/** + * @brief This function will be invoked by BSP, when enter interrupt service routine + * + * @note Please don't invoke this routine in application + * + * @see rt_interrupt_leave + */ +void rt_interrupt_enter(void) +{ + extern void (*rt_interrupt_enter_hook)(void); + RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,()); + LOG_D("irq has come..."); +} + +/** + * @brief This function will be invoked by BSP, when leave interrupt service routine + * + * @note Please don't invoke this routine in application + * + * @see rt_interrupt_enter + */ +void rt_interrupt_leave(void) +{ + extern void (*rt_interrupt_leave_hook)(void); + LOG_D("irq is going to leave"); + RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,()); +} + +/** + * @brief This function will return the nest of interrupt. + * + * User application can invoke this function to get whether current + * context is interrupt context. + * + * @return the number of nested interrupts. + */ +rt_uint8_t rt_interrupt_get_nest(void) +{ + return (rt_hw_get_ipsr() != 0); +} + +/** + \brief Get PRIMASK Register + \details Returns the content of the PRIMASK Register. + \return PRIMASK Register value + */ +rt_inline rt_uint32_t rt_hw_get_primask_value(void) +{ +#if defined(__CC_ARM) + register uint32_t __regPRIMASK __asm("primask"); + return (__regPRIMASK); +#elif defined(__clang__) + uint32_t result; + __asm volatile ("MRS %0, primask" : "=r" (result)); + return result; +#elif defined(__IAR_SYSTEMS_ICC__) + return __iar_builtin_rsr("PRIMASK"); +#elif defined(__GNUC__) + uint32_t result; + __asm volatile ("MRS %0, primask" : "=r" (result)); + return result; +#endif +} + +/** + * @brief Check whether maskable interrupts are currently disabled. + * + * @details + * For Cortex-M4, interrupts are considered disabled when either: + * - PRIMASK masks all configurable interrupts. + * + * @return RT_TRUE if interrupts are masked; otherwise RT_FALSE. + */ +rt_bool_t rt_hw_interrupt_is_disabled(void) +{ + return ((rt_hw_get_primask_value() & 0x1UL) != 0UL); +} + #ifdef RT_USING_CPU_FFS /** * This function finds the first bit set (beginning with the least significant bit) -- cgit v1.3.1