Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions libcpu/arm/cortex-m4/cpuport.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* 2018-07-24 aozima enhancement hard fault exception handler.
* 2019-07-03 yangjie add __rt_ffs() for armclang.
* 2022-06-12 jonas fixed __rt_ffs() for armclang.
* 2025-08-18 wdfk_prog add rt_interrupt_get_nest() and __get_IPSR() support.
*/

#include <rtthread.h>
Expand Down Expand Up @@ -436,6 +437,42 @@ 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");
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use rt_uint32_t instead of uint32_t to maintain consistency with RT-Thread's type naming conventions used elsewhere in the codebase.

Suggested change
register uint32_t __regIPSR __asm("ipsr");
register rt_uint32_t __regIPSR __asm("ipsr");

Copilot uses AI. Check for mistakes.

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;
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use rt_uint32_t instead of uint32_t to maintain consistency with RT-Thread's type naming conventions used elsewhere in the codebase.

Suggested change
uint32_t result;
rt_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__ )
rt_uint32_t result;

Copilot uses AI. Check for mistakes.

Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use rt_uint32_t instead of uint32_t to maintain consistency with RT-Thread's type naming conventions used elsewhere in the codebase.

Suggested change
uint32_t result;
rt_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__ )
rt_uint32_t result;

Copilot uses AI. Check for mistakes.

__asm volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
#endif
}

/**
* @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 (__get_IPSR() != 0);
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function return type is rt_uint8_t but this expression returns a boolean (0 or 1). While this works, it changes the semantic meaning from returning the actual nest count to returning a boolean. Consider either changing the return type to rt_bool_t or updating the function documentation to clarify that it returns 1 for interrupt context and 0 for thread context.

Copilot uses AI. Check for mistakes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wdfk-prog 这块应该返回__get_IPSR()的数值?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wdfk-prog 这块应该返回__get_IPSR()的数值?

  • 函数返回值类型我会进行修改
  • 根据手册来看IPSR寄存器的值仅能代表当前是否处于中断,处于哪个中断源.不能识别进入了嵌套中断的层数.

https://developer.arm.com/documentation/dui0646/c/The-Cortex-M7-Processor/Programmers-model/Core-registers

image
  • 我进行全局搜索rt_interrupt_get_nest的用法.并未发现有对嵌套层数的判断.这样修改不会造成影响.
  • 硬件方案没有办法识别到中断嵌套的层数
  • 或许rt_interrupt_get_nest可以改为``rt_is_interrupt_mode`?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rt_interrupt_get_nest 这种用法可能更好一些

我看到ut里面有类似使用 rt_interrupt_get_nest 的代码:

if(rt_interrupt_get_nest() > max_get_nest_count)

Copy link
Contributor Author

@wdfk-prog wdfk-prog Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rt_interrupt_get_nest 这种用法可能更好一些

我看到ut里面有类似使用 rt_interrupt_get_nest 的代码:

if(rt_interrupt_get_nest() > max_get_nest_count)

  • 是,我也有看到.但是这种是实实在在的优化.大部分场景下并没有要获取中断嵌套层数的必要.
  • 有必要的话,也应该是重新定义两个函数,一个用于获取嵌套层数,另一个专门用来获取是否进入中断既可
  • 另外对于只用内核不使用驱动的方式,之前的rt_interrupt_get_nest 大概率失效.

}

#ifdef RT_USING_CPU_FFS
/**
* This function finds the first bit set (beginning with the least significant bit)
Expand Down
Loading