VX_FP_TASK заставляет переключение контекста задачи включать регистры FP. Это увеличивает время переключения контекста. Если во время вашего приложения сроки и целевые показатели производительности могут быть достигнуты даже с учетом этих накладных расходов, то есть небольшая проблема, которую я предлагаю сделать. Отсутствие VX_FP_TASK может рассматриваться как оптимизация , которую следует применять с осторожностью, только если и когда это необходимо. Так что, если по умолчанию используется VX_FP_TASK, вам, вероятно, придется меньше проверять в тех случаях, когда вам может потребоваться оптимизировать производительность; так как часто оптимизация не нужна для достижения требуемых результатов. Если это приводит к снижению производительности при переключении контекста, это создает или разрушает ваш проект, в любом случае оно может быть незначительным.
С другой стороны, хотя во встроенных системах FPU становятся все более распространенными, разработчики встроенных систем также часто используют FP в качестве исключения, а не правила из-за традиционного отсутствия аппаратной поддержки FP. Поэтому одно решение состоит в том, чтобы иметь внутреннее правило проектирования, согласно которому плавающая точка не должна использоваться без формального обоснования и подписания: т.е. использование плавающей запятой должно быть в проекте, а не в решении программиста. Проверка обычно представляет собой простой случай сканирования источника для float
, double
и math.h
. (поскольку, вероятно, трудно использовать плавающую точку без того, чтобы ни один из них не встречался в коде). Например, вы можете добавить проверку статического анализа перед сборкой, которая ищет их и отмечает предупреждение.
Во многих приложениях можно спроектировать так, чтобы математические операции FP естественно ограничивались конкретными задачами. Однако возникает проблема, когда кто-то решает использовать существующую функцию, предназначенную для использования в одной из этих задач, в другой, которая не является безопасной для FP. Это может быть трудно обнаружить; Решение этой проблемы состоит в том, чтобы иметь функции, которые используют с плавающей запятой и которые могут использоваться в других задачах, чтобы включить отладочный ASSERT, который проверяет параметры задачи с помощью taskOptionsGet ().
Таким образом, комбинация сканирования для использования float
, double
и math.h
и добавления проверки ASSERT к функциям, которые их используют, вероятно, защитят вас от ошибок при обслуживании кода.
[добавлено 2010 Фев14]
Поскольку сложные макросы, как правило, являются плохой вещью, я полагаю, что может быть полезно следующее (как упоминалось выше):
#if NDEBUG
#define ASSERT_FP_SAFE() ((void) 0)
#else
#define ASSERT_FP_SAFE() do{ int opt; \
STATUS st = taskGetOptions( taskIdSelf(), &opt ); \
assert( st == OK && (opt & VX_FP_TASK) != 0 ) ; \
}while(0) ;
#endif
Этот макрос должен быть вставлен в любую функцию, которая использует float или double, или которая включает или любую другую зависимую от FP библиотеку, которую вы можете использовать (чего вы можете достичь с помощью текстового поиска). В этом случае утверждение не будет выполнено, когда такая функция вызывается из задачи, не связанной с FP.
Обратите внимание, что проверка возврата из taskGetOptions () перехватит использование плавающей запятой в контекстах прерывания. Хотя, если утверждение происходит в прерывании, вы можете не получить никакого вывода. Вызов logMsg () может быть безопаснее, возможно; Вы можете использовать это, если st! = OK и assert () в противном случае.
К сожалению, это утверждение во время выполнения, поэтому для его проверки необходимо выполнить код. Было бы лучше, если бы это можно было обнаружить с помощью статического анализа, но я не могу придумать простой метод. Однако, если вы также используете анализ покрытия кода, этого может быть достаточно. Это может быть хорошей привычкой, даже если вы решите сделать все задачи VX_FP_TASK; таким образом, если кто-то забудет сделать одно или другое, у вас есть шанс его поймать.