Skip to content

Commit d6f326a

Browse files
committed
feat(core): Add Cortex-M4 interrupt context helpers
1 parent 4a74224 commit d6f326a

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

libcpu/arm/cortex-m4/cpuport.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
#include <rtthread.h>
2222

23+
#define DBG_TAG "cortex.m4"
24+
#define DBG_LVL DBG_INFO
25+
#include <rtdbg.h>
26+
2327
#if /* ARMCC */ ( (defined ( __CC_ARM ) && defined ( __TARGET_FPU_VFP )) \
2428
/* Clang */ || (defined ( __clang__ ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__)) \
2529
/* IAR */ || (defined ( __ICCARM__ ) && defined ( __ARMVFP__ )) \
@@ -436,6 +440,107 @@ void rt_hw_cpu_reset(void)
436440
SCB_AIRCR = SCB_RESET_VALUE;
437441
}
438442

443+
/**
444+
\brief Get IPSR Register
445+
\details Returns the content of the IPSR Register.
446+
\return IPSR Register value
447+
*/
448+
rt_inline rt_uint32_t __get_IPSR(void)
449+
{
450+
#if defined(__CC_ARM)
451+
register uint32_t __regIPSR __asm("ipsr");
452+
return(__regIPSR);
453+
#elif defined(__clang__)
454+
uint32_t result;
455+
__asm volatile ("MRS %0, ipsr" : "=r" (result) );
456+
return(result);
457+
#elif defined(__IAR_SYSTEMS_ICC__)
458+
return __iar_builtin_rsr("IPSR");
459+
#elif defined ( __GNUC__ )
460+
uint32_t result;
461+
__asm volatile ("MRS %0, ipsr" : "=r" (result) );
462+
return(result);
463+
#endif
464+
}
465+
466+
/**
467+
* @brief This function will be invoked by BSP, when enter interrupt service routine
468+
*
469+
* @note Please don't invoke this routine in application
470+
*
471+
* @see rt_interrupt_leave
472+
*/
473+
void rt_interrupt_enter(void)
474+
{
475+
extern void (*rt_interrupt_enter_hook)(void);
476+
RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,());
477+
LOG_D("irq has come...");
478+
}
479+
480+
/**
481+
* @brief This function will be invoked by BSP, when leave interrupt service routine
482+
*
483+
* @note Please don't invoke this routine in application
484+
*
485+
* @see rt_interrupt_enter
486+
*/
487+
void rt_interrupt_leave(void)
488+
{
489+
extern void (*rt_interrupt_leave_hook)(void);
490+
LOG_D("irq is going to leave");
491+
RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());
492+
}
493+
494+
/**
495+
* @brief This function will return the nest of interrupt.
496+
*
497+
* User application can invoke this function to get whether current
498+
* context is interrupt context.
499+
*
500+
* @return the number of nested interrupts.
501+
*/
502+
rt_uint8_t rt_interrupt_get_nest(void)
503+
{
504+
return (__get_IPSR() != 0);
505+
}
506+
507+
/**
508+
\brief Get PRIMASK Register
509+
\details Returns the content of the PRIMASK Register.
510+
\return PRIMASK Register value
511+
*/
512+
rt_inline rt_uint32_t rt_hw_get_primask_value(void)
513+
{
514+
#if defined(__CC_ARM)
515+
register uint32_t __regPRIMASK __asm("primask");
516+
return (__regPRIMASK);
517+
#elif defined(__clang__)
518+
uint32_t result;
519+
__asm volatile ("MRS %0, primask" : "=r" (result));
520+
return result;
521+
#elif defined(__IAR_SYSTEMS_ICC__)
522+
return __iar_builtin_rsr("PRIMASK");
523+
#elif defined(__GNUC__)
524+
uint32_t result;
525+
__asm volatile ("MRS %0, primask" : "=r" (result));
526+
return result;
527+
#endif
528+
}
529+
530+
/**
531+
* @brief Check whether maskable interrupts are currently disabled.
532+
*
533+
* @details
534+
* For Cortex-M4, interrupts are considered disabled when either:
535+
* - PRIMASK masks all configurable interrupts.
536+
*
537+
* @return RT_TRUE if interrupts are masked; otherwise RT_FALSE.
538+
*/
539+
rt_bool_t rt_hw_interrupt_is_disabled(void)
540+
{
541+
return ((rt_hw_get_primask_value() & 0x1UL) != 0UL);
542+
}
543+
439544
#ifdef RT_USING_CPU_FFS
440545
/**
441546
* This function finds the first bit set (beginning with the least significant bit)

0 commit comments

Comments
 (0)