FreeRTOS 任务优先级和堆栈大小

Posted

技术标签:

【中文标题】FreeRTOS 任务优先级和堆栈大小【英文标题】:FreeRTOS task priority and stack size 【发布时间】:2019-09-23 16:03:26 【问题描述】:

我有 STM32F746ZG Nucleo-144pin 板并使用 STMCubeMx 生成代码。 我选择了CubeMx提供的10.0.0版本的FreeRTOS,工具链是SW4STM32。

我做了两个任务,以下是我的功能。 我的代码在这里:

void led1_task(void)

    while(1)
    
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
        HAL_Delay(1000);
    


void led2_task(void)

    while(1)
    
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
        HAL_Delay(4100);
    

    任务优先级。

我发现如果两个任务具有相同的任务优先级,这两个任务可以正常工作,但如果它们具有不同的任务优先级,那么低任务就不能工作。

  xTaskCreate(led1_task, "led1_task", 1024, NULL, 2, NULL);  ==> Works fine.
  xTaskCreate(led2_task, "led2_task", 1024, NULL, 2, NULL);  ==> Works fine.

----------------------------------------------------------------------------

  xTaskCreate(led1_task, "led1_task", 1024, NULL, 2, NULL);  ==> This task is not working.
  xTaskCreate(led2_task, "led2_task", 1024, NULL, 3, NULL);  ==> Works fine.

    任务堆栈大小。

如果两个任务的堆栈大小加起来大于 3 KB,则确认该任务没有正常工作。 下面的代码可以正常工作。

  xTaskCreate(led1_task, "led1_task", 2048, NULL, 2, NULL);  ==> Works fine.
  xTaskCreate(led2_task, "led2_task", 1024, NULL, 2, NULL);  ==> Works fine.

但是,如果堆栈大小如下更改,第二个任务将不起作用。

  xTaskCreate(led1_task, "led1_task", 2048, NULL, 2, NULL);  ==> Works fine.
  xTaskCreate(led2_task, "led2_task", 2048, NULL, 2, NULL);  ==> This task is not working.

尝试将 STM32F746ZGTx_FLASH.ld 中的 _Min_Stack_Size 从 0x400 更改为 0x4000 也有同样的问题。

/* Generate a link error if heap and stack don't fit into RAM */

_Min_Heap_Size = 0x200; /* required account of heap */

_Min_Stack_Size = 0x4000;  /* required account of stack */

谁能解释一下这个原因?

【问题讨论】:

【参考方案1】:

第二个问题:

注意xTaskCreate 使用FreeRTOS 堆,所以在FreeRTOS.h 文件中增加configTOTAL_HEAP_SIZE

重要提示:configTOTAL_HEAP_SIZE 以字节为单位,而xTaskCreate 以字为单位获取堆栈大小(1 个字等于 4 个字节)。

【讨论】:

【参考方案2】:

回答您的问题:

    任务优先级

由于您使用了HAL_Delay,因此您的较低优先级任务不起作用。此函数执行“主动”阻塞,即调用此函数的任务将继续检查内部滴答计数器,直到满足条件。换句话说 - 它不会在 RTOS 意义上阻止此任务。您应该使用vTaskDelay 而不是HAL_Delay

    任务堆栈大小

这里有几点需要注意。

一个。给xTaskCreate 的堆栈深度以words 给出,而不是bytes。在您的示例中,任务堆栈的组合大小为 `(2048 + 1024) * sizeof(uint32_t)' 字节。你的情况很多,对于你目前在那里做的事情来说太多了。

b.如果不进行调试,很难确定为什么您的第二个任务不起作用,但很有可能因为您达到了某个限制而根本没有创建第二个任务,例如超过 RTOS 堆大小。这取决于您使用的 FreeRTOS 内存管理实现(heap_1、heap_2 等)。您可能会使用依赖于 configTOTAL_HEAP_SIZE 的定义 - 这是您应该分别检查和增加的定义。

c。 _Min_Heap_Size_Min_Stack_Size 与 FreeRTOS 无关(除非您使用 heap_3,它在内部使用 malloc)。这些对应于 RTOS 之外的堆和栈。

【讨论】:

以上是关于FreeRTOS 任务优先级和堆栈大小的主要内容,如果未能解决你的问题,请参考以下文章

006_FreeRTOS其他API函数

FreeRTOS功能和特点都有哪些

FreeRTOS创建任务

FreeRTOS和Ucos在任务优先级的区别

freertos 任务优先级timer和一般任务的不同

FreeRTOS任务创建启动调度器任务切换的过程分析——基于ARM-CotexM3