FreeRTOS 任务优先级和堆栈大小

Han*_*ans 2 stm32 freertos stm32f7 cubemx stm32cubemx

我有 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);
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 任务优先。

我发现如果两个任务具有相同的任务优先级,则这两个任务可以正常工作,但是如果它们的任务优先级不同,则低任务不起作用。

  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.

Run Code Online (Sandbox Code Playgroud)
  1. 任务堆栈大小。

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

  xTaskCreate(led1_task, "led1_task", 2048, NULL, 2, NULL);  ==> Works fine.
  xTaskCreate(led2_task, "led2_task", 1024, NULL, 2, NULL);  ==> Works fine.
Run Code Online (Sandbox Code Playgroud)

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

  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.
Run Code Online (Sandbox Code Playgroud)

尝试将 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 */
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释原因吗?

Jac*_*mok 6

回答您的问题:

  1. 任务优先级

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

  1. 任务堆栈大小

这里有几点需要注意。

一种。给予堆深度xTaskCreate中给出的话,不字节。在您的示例中,任务堆栈的组合大小为“(2048 + 1024) * sizeof(uint32_t)”字节。你的情况很多,对于你目前在那里做的事情来说太多了。

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

C。_Min_Heap_Size并且_Min_Stack_Size与 FreeRTOS 无关(除非您使用malloc内部使用的 heap_3 )。这些对应于 RTOS 之外的堆和栈。