Приоритет задачи FreeRTOS и размер стека
У меня есть плата STM32F746ZG Nucleo-144pin и я сгенерировал коды, используя STMCubeMx. Я выбрал FreeRTOS версии 10.0.0, предлагаемой CubeMx, и набор инструментов - 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 КБ, было подтверждено, что задача работает неправильно. Код ниже работает правильно.
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.
Попытка изменить _Min_Stack_Size с 0x400 на 0x4000 в STM32F746ZGTx_FLASH.ld имеет ту же проблему.
/* 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 */
Кто-нибудь может объяснить причину этого?
3 ответа
Ваш ответ подтвердил, что все работает правильно.
- Если я использую vTaskDelay() вместо HAL_Delay(), все задачи работают нормально.
- Я сделал размер стека в качестве тестового процесса и не буду использовать такой большой размер стека. Если я увеличу размер "configTOTAL_HEAP_SIZE" в коде FreeRTOS, то он будет работать нормально. Но я не изменяю этот размер. Я буду использовать правильный размер стека.
Спасибо вам большое за ваш ответ.
Чтобы ответить на ваши вопросы:
- Приоритет задачи
Ваша задача с более низким приоритетом не работает, потому что вы используете HAL_Delay
, Эта функция выполняет "активную" блокировку, то есть задача, которая вызывает эту функцию, будет продолжать проверять внутренний счетчик тиков, пока не будет выполнено условие. Другими словами - это не блокирует эту задачу в смысле RTOS. Вы должны использовать vTaskDelay
вместо HAL_Delay
,
- Размер стека задач
Здесь следует отметить несколько моментов.
а. Глубина стека, заданная для xTaskCreate
дается словами, а не байтами. В вашем примере объединенный размер стеков задач составляет (2048 + 1024) * sizeof(uint32_t)'байтов. Это много в вашем случае, слишком много для того, что вы делаете там в настоящее время.
б. Без отладки трудно с уверенностью сказать, почему ваша вторая задача не работает, но весьма вероятно, что вторая задача вообще не будет создана, потому что вы достигли некоторого предела, например, превышения размера кучи RTOS. Это зависит от того, какую реализацию управления памятью FreeRTOS вы используете (heap_1, heap_2 и т. Д.). Вы, вероятно, используете тот, который зависит от configTOTAL_HEAP_SIZE
- это определение, которое вы должны проверить и увеличить соответственно.
с. _Min_Heap_Size
а также _Min_Stack_Size
не имеет ничего общего с FreeRTOS (если вы не используете heap_3, который использует malloc
внутри). Они соответствуют куче и стеку вне RTOS.
На ваш второй вопрос:
Обратите внимание, что используется куча FreeRTOS, поэтому увеличьте
FreeRTOS.h
файл.
Важная заметка:
configTOTAL_HEAP_SIZE
в БАЙТАХ, а
xTaskCreate
получает размер стека в СЛОВАХ (1 слово равно 4 байтам).