RT-Thread论坛
直播中

张鑫

8年用户 1131经验值
私信 关注
[问答]

调用rt_timer_check函数就报错怎么解决?

调用rt_timer_check函数就报错

  • (rt_interrupt_get_nest() > 0) assertion failed at function:rt_timer_check, line number:677
  • [W/kernel.service] rt_hw_backtrace_frame_unwind is not implemented
  • please use: addr2line -e rtthread.elf -a -f 0x800320e[W/kernel.service] rt_hw_backtrace_frame_unwind is not implemented

回帖(1)

美信电子

2025-9-23 16:59:05

根据错误信息分析,问题在于调用 rt_timer_check() 时中断嵌套计数(rt_interrupt_get_nest())不符合要求(必须 > 0),导致断言失败。以下是逐步解决方案:




根本原因分析




  1. 上下文错误

    rt_timer_check() 是RT-Thread内核的内部函数,只能在中断上下文(尤其是时钟中断)中调用。用户代码在非中断环境(如线程上下文)调用它时,会触发断言 (rt_interrupt_get_nest() > 0)




  2. 栈回溯未实现

    错误信息中的 rt_hw_backtrace_frame_unwind is not implemented 表明系统未实现硬件栈回溯功能,需通过 addr2line 定位调用点。






解决方案


1. 定位违规调用点


使用 addr2line 分析调用栈地址:


addr2line -e rtthread.elf -a -f 0x800320e


  • -e rtthread.elf: 指定你的RT-Thread可执行文件

  • -a: 显示地址

  • -f: 显示函数名
    输出将显示调用 rt_timer_check() 的代码位置(文件名和行号)。


2. 修改代码移除违规调用




  • 禁止在用户线程调用 rt_timer_check()

    删除或注释掉用户代码中直接调用 rt_timer_check() 的地方。该函数仅供内核在时钟中断(如 SysTick_Handler)中使用。




  • 替代方案

    如果需要检查定时器状态,使用RT-Thread提供的标准API:


    rt_tick_t rt_tick_get(void);           // 获取当前系统滴答数
    rt_err_t rt_thread_delay(rt_tick_t);   // 线程延时



3. 检查中断处理函数


确保 rt_timer_check() 仅在中断中被调用(如系统时钟中断):


// 正确的时钟中断处理函数示例
void SysTick_Handler(void)
{
    rt_interrupt_enter();    // 标记进入中断
    rt_tick_increase();      // 内部会调用 rt_timer_check()
    rt_interrupt_leave();    // 标记离开中断
}

4. 实现栈回溯功能(可选但推荐)


board.c 中实现缺失的硬件栈回溯函数:


void rt_hw_backtrace_frame_unwind(rt_ubase_t fp, rt_ubase_t pc)
{
    /* 根据你的MCU架构实现栈帧解析 */
    // 示例(Cortex-M):
    struct stack_frame {
        rt_ubase_t r0, r1, r2, r3, r12, lr, pc, xpsr;
    };
    struct stack_frame *frame = (struct stack_frame *)fp;
    rt_kprintf("PC: 0x%08xn", frame->pc);
}



关键总结



  • 严禁在用户线程调用 rt_timer_check(),这是内核内部函数。

  • 通过 addr2line 定位调用源码位置并删除相关代码。

  • 确保系统时钟中断函数正确调用 rt_tick_increase()

  • 实现 rt_hw_backtrace_frame_unwind 以增强调试能力。



提示:若问题仍存在,检查是否有其他内核API被误用(如自定义中断未正确使用 rt_interrupt_enter/leave()),或使用调试器单步跟踪调用来源。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分