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

    文章

    3829

    浏览量

    83428
  • RTOS
    +关注

    关注

    24

    文章

    853

    浏览量

    121449
  • FreeRTOS
    +关注

    关注

    13

    文章

    495

    浏览量

    64730
  • 线程
    +关注

    关注

    0

    文章

    508

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    详解FreeRTOS与SAFERTOS的区别

    开源免费的FreeRTOS由Richard Barry在WHIS工作时创建,WHIS基于FreeRTOS的功能模型,通过完整的HAZOP分析,确定了功能模型和API的所有的弱点,减轻所有薄弱环节,并采用IEC 61508 SI
    的头像 发表于 06-04 16:58 ?415次阅读
    详解<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

    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

    HAL库在STM32开发的重要性

    HAL库(Hardware Abstraction Layer Library,硬件抽象层库)在STM32开发扮演着至关重要的角色。以下是HAL库在STM32开发的重要性分析: 一
    的头像 发表于 12-02 13:35 ?1487次阅读

    HAL库在嵌入式系统的应用

    HAL库(Hardware Abstraction Layer Library,硬件抽象层库)在嵌入式系统扮演着至关重要的角色。以下是HAL库在嵌入式系统的应用的分析: 一、
    的头像 发表于 12-02 11:32 ?2385次阅读

    ADS1259转换结果一直比输入真实值小5.525倍左右,是什么原因导致的呀?

    ADS1259_INIT(void) { HAL_Delay(20); ADS1259_RESET_H; ADS1259_START_H; ADS1259_CS_L; HAL_Delay(20
    发表于 11-20 08:25

    ADS1299内部产生信号测试,SPI接收到的数据不对,为什么?

    ;amp;amp;tmp,1,1000);//===fff===?????????????? HAL_Delay(1000);LED1_TOGGLE();HAL
    发表于 11-13 06:23

    在rtthread启动函数调用HAL_Dealy()导致卡死的原因?

    看到文章推荐将系统的左右初始化都放入rt_hw_board_init()内,于是将所有初始化都搬进去,结果由于内部调用了Hal_Delay(),导致卡死,HAL库的时钟源被设置成TIM6,但是
    发表于 09-27 06:42

    使用STM32CubeMX对红外波形进行GPIO输出,并LED显示

    _GPIO_WritePin(LED_R_GPIO_Port,LED_R_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET); HAL_Delay(1000
    发表于 09-04 14:19

    STM32CUBEMX生成freeRTOS代码的时候出现警告

    to use HAL timebase source other than the Systick. HAL函数如果是阻塞型呼叫,內部会用到HAL_Delay(),FreeRTOS
    发表于 09-04 14:13

    freertos和rtos区别是什么

    FreeRTOS 和 RTOS(实时操作系统)是两个不同的概念,但它们之间有紧密的联系。FreeRTOS 是一个特定的开源实时操作系统,而 RTOS 是实时操作系统的一般概念。 概念定义 RTOS
    的头像 发表于 09-02 14:18 ?3272次阅读

    freertos和裸机有什么区别

    FreeRTOS 和裸机编程是两种不同的嵌入式系统开发方法,它们在设计理念、资源使用、功能实现等方面有着显著的差异。 1. 基本概念 1.1 FreeRTOS FreeRTOS 是一个小型的、可裁剪
    的头像 发表于 09-02 14:13 ?3157次阅读