
举报
从你描述的现象来看,当加入 rt_thread_delay() 时系统卡在空闲线程,而移除后工作正常,这表明 系统时钟中断或调度机制未正常工作。以下是可能原因和解决方案:
时钟中断未触发
rt_thread_delay(1) 依赖系统时钟中断推进时间节拍(tick),若时钟中断未触发:idle_entry)SysTick_Handler() 中断服务函数中放一个断点/打印,检查是否被触发。SysTick 中断配置错误
board.c 中 rt_hw_board_init() 函数未正确初始化 SysTick 定时器void rt_hw_board_init()
{
// 确保调用以下关键初始化:
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); // 配置SysTick频率
// ...其他硬件初始化
}未调用 rt_tick_increase()
即使 SysTick 中断触发,但若中断服务函数 未更新系统滴答,延时依然无效:
void SysTick_Handler(void)
{
rt_interrupt_enter(); // 通知内核进入中断
rt_tick_increase(); // <-- 必须调用此函数更新系统节拍!
rt_interrupt_leave(); // 通知内核退出中断
}线程优先级问题
RT_THREAD_PRIORITY_MAX-1)delay() 挂起线程,系统无更高优先级线程可运行,只剩空闲线程。堆栈溢出导致异常
rt_thread_delay 时函数调用链导致溢出RT_USING_OVERFLOW_CHECK 并在运行时观察日志输出在板级初始化文件 board.c 中检查以下代码:
// 确保 SysTick 以正确频率初始化
void rt_hw_board_init()
{
// 关键配置 ↓
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
// 启用RT-Thread的定时器框架
rt_system_timer_init();
}在 drv_common.c 或中断向量表中定位中断服务函数:
void SysTick_Handler(void)
{
rt_tick_increase(); // 必须调用此函数!
}
⚠️ 注意:若使用标准库(如STM32 HAL),中断函数名可能为
SysTick_Handler(void);若为自定义名称,需在中断向量表中正确注册。
确保你的线程优先级 高于空闲线程:
// 创建线程示例:优先级建议设为5~10 (数字越小优先级越高)
rt_thread_t thread = rt_thread_create(
"test",
thread_entry,
RT_NULL,
512,
8, // <-- 优先级设为8(必须 < RT_THREAD_PRIORITY_MAX-1)
5
);增大线程堆栈排除溢出问题:
rt_thread_create(..., 1024, ...); // 测试时堆栈从512增大到1024确认在 main() 中正确启动了 RT-Thread 内核:
int main(void)
{
rt_thread_startup(rt_thread_create( ... )); // 启动主线程
rt_system_scheduler_start(); // 开始调度器 -> 某些BSP会封装在底层
}中断触发测试
在 SysTick_Handler 中加入调试代码:
void SysTick_Handler(void) {
static int count = 0;
rt_kprintf("[Tick] %dn", count++); // 查看是否周期性打印
rt_tick_increase();
}若无输出,说明中断未触发或函数未正确注册。
查看线程状态
使用 list_thread 命令(在 Finsh 控制台)观察线程状态:
thread pri status sp stack size max used
------ --- ------- --- ---------- --------
tidle 31 ready ... 0x200 12%
your_thr 10 suspend ... 0x400 35% <-- 查看是否处于suspend态检查系统时钟频率
确认 RT_TICK_PER_SECOND 配置与硬件匹配:
// rtconfig.h 中检查定义
#define RT_TICK_PER_SECOND 1000 // 1 tick = 1ms| 问题现象 | **可能原因」 | 修复方法 |
|---|---|---|
| 卡在空闲线程 | SysTick中断未触发 | 初始化SysTick并注册中断服务函数 |
| 移除delay()后恢复正常 | 时间节拍未更新 | 在SysTick中断中调用 rt_tick_increase |
| 线程无法唤醒 | 线程优先级 ≤ 空闲线程优先级 | 提高业务线程优先级 |
| 随机崩溃 | 线程堆栈溢出 | 增大堆栈并使用溢出检测工具 |
按照上述步骤逐一排查,重点检查 SysTick中断服务函数 和 rt_tick_increase()调用,问题通常可快速解决。
举报
更多回帖