-
Notifications
You must be signed in to change notification settings - Fork 5.4k
feat[libcpu][cortex-m4]: Detect interrupt context from IPSR on Cortex-M4` #11316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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 __get_IPSR(void) | ||||||||||||||||
| { | ||||||||||||||||
| #if defined(__CC_ARM) | ||||||||||||||||
| register uint32_t __regIPSR __asm("ipsr"); | ||||||||||||||||
| return(__regIPSR); | ||||||||||||||||
| #elif defined(__clang__) | ||||||||||||||||
| uint32_t result; | ||||||||||||||||
|
Comment on lines
+450
to
+454
|
||||||||||||||||
| __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..."); | ||||||||||||||||
|
Comment on lines
+473
to
+477
|
||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| /** | ||||||||||||||||
| * @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); | ||||||||||||||||
|
Comment on lines
+488
to
+489
|
||||||||||||||||
| { | |
| extern void (*rt_interrupt_leave_hook)(void); | |
| { | |
| extern rt_uint8_t rt_interrupt_nest; | |
| extern void (*rt_interrupt_leave_hook)(void); | |
| rt_interrupt_nest--; |
Copilot
AI
Apr 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[bug/类别]: rt_interrupt_get_nest() changed from “nesting depth” to boolean / rt_interrupt_get_nest() 从“嵌套深度”变为布尔语义
English: The API contract is “the number of nested interrupts”, but this implementation returns only 0/1 based on IPSR. This can break callers that expect depth > 1 (e.g., IRQ nesting tests or logic distinguishing nested vs first-level ISR). Please keep rt_interrupt_get_nest() returning the real nesting count; add a separate fast helper for “in ISR context” if needed.
中文:该 API 约定是“中断嵌套次数”,但当前实现仅基于 IPSR 返回 0/1。这样会破坏依赖嵌套深度 > 1 的调用方(例如中断嵌套测试或需要区分是否发生嵌套的逻辑)。建议保持 rt_interrupt_get_nest() 返回真实嵌套计数;若需要快速判断 ISR 上下文,可新增独立接口。
Copilot
AI
Apr 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[bug/类别]: rt_hw_get_primask_value() lacks a final #else/#error or return path / rt_hw_get_primask_value() 缺少最终 #else/#error 或返回路径
English: Like __get_IPSR(), this helper has no final #else branch. Please add a final #else with #error (preferred) or a safe fallback return to avoid undefined behavior / build failures on unexpected toolchains.
中文:与 __get_IPSR() 类似,该辅助函数也缺少最终 #else 分支。建议补充最终 #else:使用 #error(推荐)或安全兜底返回值,以避免在非预期工具链下出现未定义行为/编译失败。
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,8 +26,8 @@ | |||||||||
|
|
||||||||||
| #if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR) | ||||||||||
|
|
||||||||||
| static void (*rt_interrupt_enter_hook)(void); | ||||||||||
| static void (*rt_interrupt_leave_hook)(void); | ||||||||||
| void (*rt_interrupt_enter_hook)(void); | ||||||||||
| void (*rt_interrupt_leave_hook)(void); | ||||||||||
|
Comment on lines
+29
to
+30
|
||||||||||
| void (*rt_interrupt_enter_hook)(void); | |
| void (*rt_interrupt_leave_hook)(void); | |
| static void (*rt_interrupt_enter_hook)(void); | |
| static void (*rt_interrupt_leave_hook)(void); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,7 +50,6 @@ rt_uint32_t rt_thread_ready_priority_group; | |
| rt_uint8_t rt_thread_ready_table[32]; | ||
| #endif /* RT_THREAD_PRIORITY_MAX > 32 */ | ||
|
|
||
| extern volatile rt_atomic_t rt_interrupt_nest; | ||
| static rt_atomic_t rt_scheduler_lock_nest; | ||
| rt_uint8_t rt_current_priority; | ||
|
|
||
|
|
@@ -347,13 +346,13 @@ void rt_schedule(void) | |
| LOG_D("[%d]switch to priority#%d " | ||
| "thread:%.*s(sp:0x%08x), " | ||
| "from thread:%.*s(sp: 0x%08x)", | ||
| rt_interrupt_nest, highest_ready_priority, | ||
| rt_interrupt_get_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); | ||
|
Comment on lines
+349
to
353
|
||
|
|
||
| if (rt_interrupt_nest == 0) | ||
| if (rt_interrupt_get_nest() == 0) | ||
| { | ||
| extern void rt_thread_handle_sig(rt_bool_t clean_state); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[best_practices/类别]: Avoid defining
__get_IPSR(reserved/CMSIS name) in RT-Thread code / 避免在 RT-Thread 代码中定义__get_IPSR(保留标识符/CMSIS 重名)English:
__get_IPSRis commonly provided by CMSIS and the leading__identifier is reserved by the C standard. Defining it here risks redefinition conflicts depending on BSP/CMSIS include order. Prefer using the CMSIS intrinsic (include the proper CMSIS header) or rename this helper to an RT-Thread-specific name.中文:
__get_IPSR通常由 CMSIS 提供,且以__开头的标识符属于 C 标准保留名称。在此处定义可能因 BSP/CMSIS 头文件包含顺序导致重定义冲突。建议直接使用 CMSIS 的实现(包含对应头文件),或将本地辅助函数改为 RT-Thread 风格命名。