0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FreeRTOS中osDelay和HAL_Delay的区别

撞上电子 2023-10-29 08:00 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

问题场景

FreeRTOS中创建了线程A、线程B,其中线程A优先级大于线程B。线程A、B任务代码如下:

void A(void *argument)
{
while (1)
{
printf("A\r\n");
HAL_Delay(1000);
}
}

void B(void *argument)
{
while (1)
{
printf("B\r\n");
HAL_Delay(1000);
}
}

烧录程序后查看串口数据发现只打印了A而不打印B,说明只执行了A线程没有执行B线程。

问题原因

HAL_Delay是由ST提供的STM32 Cube HAL库中的一个函数,通常用于在STM32微控制器上实现简单的延时。HAL_Delay函数使用系统时钟来进行延时,并且在延时期间会阻塞整个处理器,也就是说,它会使处理器暂时停止执行其他任务和代码。

在开始运行线程之前,线程A、B处于就绪态,由于线程A优先级比线程B高,FreeRTOS任务控制器优先选择线程A运行,此时线程A进入运行态。随后线程A打印A,然后被HAL_Delay函数"阻塞",注意此时的"阻塞"并不意味着程序进入了阻塞态,由于HAL_Delay阻塞的是整个处理器,因此FreeRTOS无法进行其他线程的调度,也就是说,HAL_Delay同时阻塞了线程B。当HAL_Delay函数运行结束后,线程A重回就绪态,由于线程A优先级比线程B高,FreeRTOS任务控制器优先选择线程A运行,循环往复,线程B不被执行。

解决办法

osDelay是FreeRTOS(Real-Time Operating System)中的一个函数,用于实现任务的延时。FreeRTOS是一个开源的实时操作系统,专门用于嵌入式系统。osDelay函数允许任务挂起一段时间,然后由操作系统调度器在指定的时间后重新运行该任务。在等待期间,任务会被放入挂起状态,让其他任务有机会运行。

也就是说,当调用osDelay时,线程A进入阻塞态,此时任务控制器选择进入就绪态的线程B执行,循环往复,线程A、B同时被执行。我们可以将任务A和B进行如下改动,即可看到既打印A又打印B。

void A(void *argument)
{
while (1)
{
printf("A\r\n");
osDelay(1000);
}
}

void B(void *argument)
{
while (1)
{
printf("B\r\n");
osDelay(1000);
}
}

使用osDelay可能带来的问题

观察一下HAL_Delay和osDelay的函数原型:

/**
* @brief This function provides minimum delay (in milliseconds) based
*/
__weak void HAL_Delay(uint32_t Delay);

/*
Wait for Timeout (Time Delay).
*/
osStatus_t osDelay (uint32_t ticks);

可以看到HAL_Delay函数的目的是提供毫秒级别的延时,意味着当你输入HAL_Delay(500),硬件会尽量延时精确到500ms的时间。

与之不同的是,osDelay函数的输入是ticks。ticks是一个计时单位,表示任务将被挂起的时间长度。每个tick的时间取决于FreeRTOS配置的时钟节拍(tick)周期。例如,如果tick周期为1毫秒,那么传递参数ticks为10就会使任务挂起10毫秒。由此可见,osDelay函数延时的时间和一个ticks记时时间长度有很大关系。

那么如何确定ticks具体代表多长时间呢?首先我们应该找到用于配置的头文件,通常这个头文件名字叫做FreeRTOSConfig.h。其中,configTICK_RATE_HZ配置选项的值表示每秒钟系统时钟节拍(tick)的数量。configTICK_RATE_HZ的值一般默认被设置为1000,表示系统时钟每秒产生1000个tick,即每个tick的时间间隔为1毫秒,此时osDelay对单个任务延时的时间长度和HAL_Delay近似。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    117

    文章

    3836

    浏览量

    84767
  • RTOS
    +关注

    关注

    25

    文章

    863

    浏览量

    122619
  • FreeRTOS
    +关注

    关注

    14

    文章

    497

    浏览量

    66368
  • 线程
    +关注

    关注

    0

    文章

    508

    浏览量

    20761
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【道生物联TKB-623评估板试用】——3.TKB-623评估板连接STM32发送数据

    ;); HAL_Delay(3000); printf(\"复位芯片 \\\\r\\\\n\"); while(TK8620_SendCmd(\"AT\\\\r\\\\n\"
    发表于 11-17 14:44

    【CPKCOR-RA8D1】+ 2.串口输出测试

    ;); HAL_Delay(200); } #if BSP_TZ_SECURE_BUILD /* Enter non-secure code */ R_BSP_NonSecureEnter(); #endif } 6.编译代码 7.烧录代码 8.打开串口助手 可以看到串口打印正常 测试完毕!!!!!!
    发表于 09-24 19:39

    在rtthread的main函数里用HAL_Delay函数不起作用是哪里的问题?

    在rtthread的main函数里用HAL_Delay函数无效,我设置延时500ms打印一次,但是实际上,一秒打印了几百次,很显然是HAL_Delay出现了问题。用RT_thread_mdelay
    发表于 09-15 07:53

    制作STM32H743VIT6的BSP包烧录后板子没反应,进行debug时会卡死的原因?怎么解决?

    , PIN_HIGH); HAL_Delay(50); rt_pin_write(18, PIN_LOW); rt_pin_write(45, PIN_LOW); HAL_Delay(50); } return RT_EOK; }
    发表于 09-15 06:43

    【RA4M2-SENSOR】开箱 + 开发环境配置 + 点灯

    ,BSP_IO_LEVEL_LOW); HAL_Delay(500); g_ioport.p_api->pinWrite(&g_ioport_ctrl
    发表于 09-01 17:47

    【RA4M2-SENSOR】—— 16.完结篇《使用AT指令通过MQTT远程控制RA4M2-SENSOR》

    \\\\n\",U2_RxBuff);//debug--- user_uart0_clear(); return 0; } } HAL_Delay(10); } return 1
    发表于 09-01 14:31

    【RA4E2开发板评测】4.RA4E2 移植coremark跑分性能测试

    ) { SerialDecode(); /* switch(key_count) { case 1: led2_off(); led1_on();HAL_Delay(200); led1_off
    发表于 08-25 13:10

    详解hal_entry入口函数

    当使用RTOS时,程序从main函数开始进行线程调度;当没有使用RTOS时,C语言程序的入口函数main函数调用了hal_entry函数。由于我们新建的工程是没有选用RTOS的,因此,用户程序从
    的头像 发表于 07-25 15:34 1671次阅读

    详解FreeRTOS与SAFERTOS的区别

    开源免费的FreeRTOS由Richard Barry在WHIS工作时创建,WHIS基于FreeRTOS的功能模型,通过完整的HAZOP分析,确定了功能模型和API的所有的弱点,减轻所有薄弱环节,并采用IEC 61508 SI
    的头像 发表于 06-04 16:58 697次阅读
    详解<b class='flag-5'>FreeRTOS</b>与SAFERTOS的<b class='flag-5'>区别</b>

    HAL15xy_SOT23

    HAL1501SU-A,HAL1502SU-A,HAL1503SU-A,HAL1504SU-A,HAL1505SU-A,
    发表于 05-14 15:03 0次下载

    cubemx生成HAL库+FreeRTOS,当编写程序时却代码无法自动提示怎么解决?

    各位佬,请问一下,我用的是cubemx生成HAL库+FreeRTOS,编译时并没有错误,但当我编写程序时却代码无法自动提示(我设置好了),并且连uint8_t这种变量也不会变成蓝色,当我查看工程文件
    发表于 03-12 08:21

    cubemx生成的freertos代码在keil ac6下不能编译,怎么解决?

    ../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM3portmacro.h(167): error: unknown
    发表于 03-12 08:19

    STM32C031C6在按键中断处理程序中使用HAL_Delay()延时函数,程序则无法运行怎么解决?

    测试STM32C031C6开发板的长短按键,在按键中断处理程序中使用HAL_Delay()延时函数,程序则无法运行,类似进入了死循环,于是则添加了延时函数如下: /[i
    发表于 03-07 06:50

    关于freertos任务usb文件系统写入数据的问题

    请问一下,我用freertos系统的定时器,sendtime++满500的时候执行usb文件系统写入数据的函数Flash_Write();这个函数需要300多ms跑完,按理来说他就算300多ms
    发表于 02-20 20:55

    【正点原子STM32H7R3开发套件试用体验】流水灯

    , GPIO_Pin_0); HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0); HAL_Delay(200); HAL_GPIO_TogglePin(GPIOD
    发表于 12-28 18:51