mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-05-07 20:37:49 +08:00
feat(core): Add Cortex-M4 interrupt context helpers
RT-Thread BSP Static Build Check / 🔍 Summary of Git Diff Changes (push) Has been cancelled
RT-Thread BSP Static Build Check / ${{ matrix.legs.RTT_BSP }} (push) Has been cancelled
RT-Thread BSP Static Build Check / collect-artifacts (push) Has been cancelled
doc_doxygen / doxygen_doc generate (push) Has been cancelled
doc_doxygen / deploy (push) Has been cancelled
pkgs_test / change (push) Has been cancelled
utest_auto_run / A9 :components/dfs.cfg (push) Has been cancelled
utest_auto_run / A9 :components/lwip.cfg (push) Has been cancelled
utest_auto_run / A9 :components/netdev.cfg (push) Has been cancelled
utest_auto_run / A9 :components/sal.cfg (push) Has been cancelled
utest_auto_run / A9 :cpp11/cpp11.cfg (push) Has been cancelled
utest_auto_run / AARCH64-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / A9-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / XUANTIE-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64 :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64-smp :default.cfg (push) Has been cancelled
utest_auto_run / A9 :default.cfg (push) Has been cancelled
utest_auto_run / A9-smp :default.cfg (push) Has been cancelled
utest_auto_run / RISCV :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-smp :default.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / RISCV :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/ipc.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/kernel_basic.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/mem.cfg (push) Has been cancelled
Weekly CI Scheduler / Trigger and Monitor CIs (push) Has been cancelled
Weekly CI Scheduler / Create Discussion Report (push) Has been cancelled
RT-Thread BSP Static Build Check / 🔍 Summary of Git Diff Changes (push) Has been cancelled
RT-Thread BSP Static Build Check / ${{ matrix.legs.RTT_BSP }} (push) Has been cancelled
RT-Thread BSP Static Build Check / collect-artifacts (push) Has been cancelled
doc_doxygen / doxygen_doc generate (push) Has been cancelled
doc_doxygen / deploy (push) Has been cancelled
pkgs_test / change (push) Has been cancelled
utest_auto_run / A9 :components/dfs.cfg (push) Has been cancelled
utest_auto_run / A9 :components/lwip.cfg (push) Has been cancelled
utest_auto_run / A9 :components/netdev.cfg (push) Has been cancelled
utest_auto_run / A9 :components/sal.cfg (push) Has been cancelled
utest_auto_run / A9 :cpp11/cpp11.cfg (push) Has been cancelled
utest_auto_run / AARCH64-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / A9-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / XUANTIE-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64 :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64-smp :default.cfg (push) Has been cancelled
utest_auto_run / A9 :default.cfg (push) Has been cancelled
utest_auto_run / A9-smp :default.cfg (push) Has been cancelled
utest_auto_run / RISCV :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-smp :default.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / RISCV :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/ipc.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/kernel_basic.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/mem.cfg (push) Has been cancelled
Weekly CI Scheduler / Trigger and Monitor CIs (push) Has been cancelled
Weekly CI Scheduler / Create Discussion Report (push) Has been cancelled
This commit is contained in:
@@ -20,6 +20,10 @@
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#define DBG_TAG "cortex.m4"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#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)
|
||||
|
||||
+4
-2
@@ -284,6 +284,7 @@ void rt_schedule(void)
|
||||
struct rt_thread *to_thread;
|
||||
struct rt_thread *from_thread;
|
||||
struct rt_thread *curr_thread;
|
||||
rt_base_t interrupt_nest;
|
||||
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
@@ -343,16 +344,17 @@ void rt_schedule(void)
|
||||
RT_SCHED_CTX(to_thread).stat = RT_THREAD_RUNNING | (RT_SCHED_CTX(to_thread).stat & ~RT_THREAD_STAT_MASK);
|
||||
|
||||
/* switch to new thread */
|
||||
interrupt_nest = rt_interrupt_get_nest();
|
||||
LOG_D("[%d]switch to priority#%d "
|
||||
"thread:%.*s(sp:0x%08x), "
|
||||
"from thread:%.*s(sp: 0x%08x)",
|
||||
rt_interrupt_get_nest(), highest_ready_priority,
|
||||
interrupt_nest, highest_ready_priority,
|
||||
RT_NAME_MAX, to_thread->parent.name, to_thread->sp,
|
||||
RT_NAME_MAX, from_thread->parent.name, from_thread->sp);
|
||||
|
||||
RT_SCHEDULER_STACK_CHECK(to_thread);
|
||||
|
||||
if (rt_interrupt_get_nest() == 0)
|
||||
if (interrupt_nest == 0)
|
||||
{
|
||||
extern void rt_thread_handle_sig(rt_bool_t clean_state);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user