You are here

Использование стека и обнаружение переполнения стека

Перевод может содержать ошибки. Читайте первоисточник: Stack Usage and Stack Overflow Checking

Назад: [Более подробно...] Вверх: [Более подробно...] Вперёд: [Более подробно...]

 

Использование стека

[Дополнительно смотрите описание функции API uxTaskGetStackHighWaterMark()]

Каждая задача поддерживает свой собственный стек. Если задача создана вызовом функции API xTaskCreate(), то память под стек резервируется автоматически из кучи FreeRTOS, и размер стека определяется параметром, передаваемым в функцию API xTaskCreate(). Если задача создаётся  с помощью xTaskCreateStatic(), то память, используемая для стека задачи, должна быть предварительно выделена разработчиком приложения. Переполнение стека - очень частая причина нестабильности приложения. Поэтому FreeRTOS предоставляет два дополнительных механизма, которые могут помощь обнаружить и исправить именно такую ситуацию. Эта возможность настраивается с помощью константы configCHECK_FOR_STACK_OVERFLOW в файле FreeRTOSConfig.h.

Обратите внимание, что эти механизмы доступны только на архитектурах, где карта памяти не сегментирована. Таже некоторые процессоры могут вырабатывать ошибку или исключение в ответ на повреждение стека ещё до того, как ядро ОС выполнит свою проверку переполнения стека. Приложение должно предоставить функцию-ловушку переполнения стека, если константа configCHECK_FOR_STACK_OVERFLOW установлена в значение, отличное от 0. Функция-ловушка должна называться vApplicationStackOverflowHook() и имеет прототип, как приведено ниже:

void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName );

Параметры xTask и pcTaskName передают в функцию-ловушку хэндл и имя вызывающей задачи соответственно. Однако будьте внимательны: в зависимости от степени переполнения стека, эти параметры также могут быть повреждены. В этом случае переменная pxCurrentTCB может быть проверена напрямую.

Проверка переполнения стека добавляет издержки при переключении контекста, поэтому её рекомендуется использовать только во время разработки и тестирования приложения.

 

Обнаружение переполнения стека - метод 1

Существует вероятность того, что размер стека достигнет своего наибольшего значения (или своей максимальной глубины) после того, как ядро ОС выведет задачу из состояние "запущено", потому что в этот момент стек содержит контекст задачи. На этом этапе ядро ОС может проверить, что указатель стека процессора находится в допустимом пространстве стека. Функция-ловушка переполнения стека будет вызвана, если значение указателя стека окажется за пределами допустимого диапазона.

Этот метод быстрый, но не гарантирует перехвата всех переполнений стека. Для использования этого метода установите значение константы configCHECK_FOR_STACK_OVERFLOW в 1.

 

Обнаружение переполнения стека - метод 2

Когда задача впервые создаётся, её стек заполняется некоторым определённым значением. При выводе задачи из запущенного состояния ядро ОС может проверить последние 16 байт в допустимом диапазона стека, чтобы убедиться, что эти известные значения не были перезаписаны задачей или обработчиком прерывания. Функция-ловушка переполнения стека будет вызвана, если любой из этих 16 байт не сохранил значение, присвоенное при инициализации.

Этот метод менее эффективен, чем первый, но всё же довольно быстрый. Весьма вероятно, что он обнаружит переполнения стека, но по-прежнему нет гарантии, что он отследит все переполнения стека.

Для использования этого метода в комбинации с методом 1 установите значение константы configCHECK_FOR_STACK_OVERFLOW в 2. Возможности использовать только этот метод не существует.

Hobby's category: