Чтобы проверить любой примитив:
function isPrimitive(test) {
return (test !== Object(test));
};
Пример:
isPrimitive(100); // true
isPrimitive(new Number(100)); // false
В качестве другой точки зрения на изменение требований ... требования входят в создание кода . Так почему бы не применить к этому мета-подход:
Таким образом вы поддерживаете совместимое построение логики блоки в C ... а затем склеить эти совместимые части вместе в конце:
/* {conditions_for_airbag_placeholder} */
if( require_deployment)
trigger_gas_release()
Затем поддержать независимые условия:
/* VAG Condition */
if( poll_vag_collision_event() )
require_deployment=1
и еще один
/* Ford Conditions */
if( ford_interrupt( FRONT_NEARSIDE_COLLISION ))
require_deploymen=1
Ваш сценарий сборки может выглядеть так:
BUILD airbag_deployment_logic.c WITH vag_events
TEST airbag_deployment_blob WITH vag_event_emitter
На самом деле мыслить вслух. Таким образом, вы получите плотный двоичный двоичный объект без чтения в config. Это похоже на использование оверлеев http://en.wikipedia.org/wiki/Overlay_ (программирование) , но при этом во время компиляции.
Что именно вы пытаетесь сохранить? Усилия по переработке кода? Бюрократия, связанная с выпуском версии программного обеспечения?
Вполне возможно, что изменить код достаточно просто и, возможно, проще, чем изменять данные в таблицах. Перенос вашей часто меняющейся логики из кода в данные полезен только в том случае, если по какой-то причине требуется меньше усилий для изменения данных, чем кода. Это может быть правдой, если изменения лучше выразить в форме данных (например, числовые параметры, хранящиеся в EEPROM). Или это может быть правдой, если запросы клиента требуют выпуска новой версии программного обеспечения, а создание новой версии программного обеспечения - дорогостоящая процедура (много документов или, возможно, чипы OTP, сожженные производителем микросхем).
Модульность - очень хороший принцип для подобных вещей. Похоже, ты в какой-то степени уже этим занимаюсь. Целесообразно стремиться изолировать часто изменяющийся код до как можно меньшей области и стараться сохранить остальную часть кода («вспомогательные» функции) отдельно (модульной) и максимально стабильной.
Наша система разделена на множество компонентов с открытой конфигурацией и контрольными точками. Существует файл конфигурации, который читается при запуске, который на самом деле помогает нам создавать экземпляры компонентов, присоединять их друг к другу и настраивать их поведение.
Он очень похож на объектно-ориентированный язык в C, с редкими взломами для реализации чего-то вроде наследование.
В мире защиты / авионики обновления программного обеспечения очень строго контролируются, и вы не можете просто обновить ПО, чтобы исправить проблемы ... однако по какой-то странной причине вы можете обновить файл конфигурации без серьезной борьбы. Так что для нас было чертовски полезно иметь возможность указать большую часть нашей реализации в этих файлах конфигурации.
Нет никакого волшебства, просто хорошее разделение проблем при проектировании системы и немного предвидения со стороны разработчиков. .
Я полагаю, что вы могли бы указать несколько допустимого поведения на основе байта или слова данных, которые вы могли бы получить EEPROM или порт ввода-вывода, если необходимо, а затем создайте общий код для обработки всех возможных событий, описываемых этими байтами.
Например, если у вас есть байт, в котором указаны требования для снятия подушки безопасности, это может быть что-то вроде:
Бит 0: Столкновение сзади
Бит 1: Скорость выше 55 миль в час (бонусные баллы за обобщение значения скорости !)
Бит 2: пассажир в машине
...
И т. Д.
Затем вы берете другой байт, который сообщает, какие события произошли, и сравнивает их. Если они одинаковые, выполняйте свою команду, если нет - не делайте этого.
Для адаптации к меняющимся требованиям я бы сконцентрировался на создании модульного кода и легкости изменения, например, с помощью макросов или встроенных функций для параметров, которые могут измениться.
Для конфигурации, которая может измениться. могут быть изменены независимо от кода, я надеюсь, что параметры, которые можно изменить, также указаны в требованиях. Специально для таких важных вещей, как контроллеры подушек безопасности.
Перехват в динамическом языке может быть спасением, если у вас есть для этого память и мощность процессора.
Пусть C поговорит с оборудованием, а затем откажется от известного набор событий для такого языка, как Lua. Пусть сценарий Lua проанализирует событие и обратный вызов соответствующей функции (-м) C.
После того, как ваш код C работает нормально, вам не придется снова его трогать, если не изменится оборудование. Вся бизнес-логика становится частью сценария, который, на мой взгляд, намного проще создавать, изменять и поддерживать.
Я не делаю код невосприимчивым к изменениям требований как таковых, но я всегда помечаю часть кода, которая реализует требование, помещая уникальную строку в комментарий. Имея теги требований, я могу легко найти этот код, когда требование требует изменения. Эта практика также соответствует процессу CMMI.
Например, в документе с требованиями:
Ниже приводится список требования, относящиеся к RST:
- [RST001] ДжульетТА ДОЛЖНА начинать RST с 5-минутной задержкой при включении зажигания. выключен.
И в коде:
/* Delay for RST when ignition is turned off [RST001] */
#define IGN_OFF_RST_DELAY 5
...snip...
/* Start RST with designated delay [RST001] */
if (IS_ROMEO_ON())
{
rst_set_timer(IGN_OFF_RST_DELAY);
}