



举报
在 RT-Thread 的 main() 函数中使用 HAL_Delay() 失效的根本原因是:RT-Thread 在启动调度器后接管了 Systick 中断,导致 HAL 库的时钟计数器停止更新。而 rt_thread_mdelay() 使用 RT-Thread 自己的时钟系统,因此能正常工作。
HAL_GetTick()(推荐)这是最直接的解决方案,让 HAL 库直接使用 RT-Thread 的时钟源:
// 在 main.c 或其他文件中添加以下代码
uint32_t HAL_GetTick(void) {
// 将 RT-Thread 的 tick 转换为毫秒
return (rt_tick_get() * 1000) / RT_TICK_PER_SECOND;
}原理:
rt_tick_get() 获取 RT-Thread 的系统时钟节拍数。RT_TICK_PER_SECOND 是每秒的节拍数(默认为 1000)。HAL_Delay() 依赖正确的时钟。如果需要在 调度器启动前(如初始化阶段)使用 HAL_Delay():
rtthread_startup() 前调用 HAL_Init():int main(void) {
HAL_Init(); // 初始化 HAL 库时钟
rtthread_startup(); // 启动 RT-Thread 调度器
// ...后续代码
}rt_hw_board_init() 中初始化 HAL 时钟(在 board.c 文件):void rt_hw_board_init() {
HAL_Init(); // 初始化 HAL
SystemClock_Config(); // 配置系统时钟(由 STM32CubeMX 生成)
// ...其他硬件初始化
}强烈建议在 RT-Thread 线程中使用原生延时函数:
#include
int main(void) {
while (1) {
rt_kprintf("Hello RT-Thread!n");
rt_thread_mdelay(500); // 使用 RT-Thread 的毫秒延时
}
return 0;
}优势:
优先级冲突:
RT_TICK_PER_SECOND(在 rtconfig.h 中)是否合理(通常为 1000)。调试建议:
uwTick 变量(HAL 时钟计数器)是否在中断中更新:void SysTick_Handler(void) {
// RT-Thread 接管后此处变为 rt_tick_increase()
HAL_IncTick(); // 如果保留此行,HAL_Delay() 可能恢复工作
rt_tick_increase();
}注意:同时调用两者可能导致时钟混乱,通常二选一。
| 方案 | 适用场景 | 优点 |
|---|---|---|
重写 HAL_GetTick() | 需兼容 HAL 驱动代码 | 无需修改现有 HAL_Delay() 调用 |
| 确保 HAL 初始化 | 调度器启动前的初始化阶段 | 解决初始化阶段延时问题 |
改用 rt_thread_mdelay | 通用 RT-Thread 应用开发 | 符合 RTOS 规范,避免调度阻塞 |
推荐实践:
rt_thread_mdelay。HAL_Delay(),采用 方案一重写 HAL_GetTick()。
通过以上任一方案均可解决
HAL_Delay()失效问题。优先推荐使用 RT-Thread 原生延时函数以确保系统稳定性。
举报
更多回帖