Какие инструменты или стандарты можно использовать для повышения надежности встроенного кода C?


9

Я обычно программирую PIC на C, обычно для преобразователей с переключением режимов. Я слышал о различных инструментах и ​​стандартах статического анализа , таких как MISRA C, которые можно использовать для повышения надежности кода. Я хотел бы знать больше. Какие стандарты или инструменты могут быть подходящими для моего контекста?


1
Насколько ты настроен на язык Си?
Брайан Драммонд

1
Меня можно было бы убедить переключиться на что-то другое, если бы было очень хорошее основание для этого. Но это должен быть очень хороший случай.
Стивен Коллингз

«Очень хороший случай» для переключения с C не может быть сделан быстро, а для PIC, возможно, еще нет. Для AVR, ARM или MSP430 Ада стоила бы серьезного взгляда (несмотря на негатив, который она привлекает, как вы можете видеть!), А для высокой относительности, SPARK стоит посмотреть.
Брайан Драммонд

Вы можете найти их интересными в качестве справочной информации: SPARK vs MISRA-C spark-2014.org/entries/detail/… и это продолжающееся тематическое исследование: spark-2014.org/uploads/Nosegearpaper_1.pdf
Брайан Драммонд

Может быть, лучше потратить время, чтобы обосновать необходимость перехода от PIC к чему-то современному ... Особенно, если вы разрабатываете критически важные системы, для которых MISRA и SPARK были изначально предназначены.
Лундин

Ответы:


11

Проверка встроенного кода является сложной задачей, особенно при работе с частями с ограниченными ресурсами, такими как PIC. Зачастую вы не можете позволить себе роскошь кодирования в тестовых примерах из-за ограничений memnry детали и частого программирования в реальном времени, выполняемого на таких устройствах.

Вот некоторые из моих рекомендаций:

  1. Напишите спецификацию, если ее нет: если вы не кодируете спецификацию, запишите, что должен делать ваш код, какие допустимые входные данные, какие ожидаемые выходные данные, сколько времени должна занять каждая подпрограмма, что может и не может получить забил и т. д. - теория работы, блок-схемы, все лучше, чем ничего.

  2. Прокомментируйте свой код: просто потому, что что-то очевидно для вас, не означает, что это очевидно (или правильно) для кого-то другого. Комментарии на простом языке необходимы как для проверки, так и для сопровождения кода.

  3. Защитите код: не просто включайте код для нормальных входных данных. Обработка пропущенных входных данных, входных данных, выходящих за пределы допустимого диапазона, математических переполнений и т. Д. - чем больше углов вы охватите при разработке кода, тем меньше степеней свободы будет иметь код при развертывании.

  4. Используйте инструменты статического анализа: может быть просто унизительно, сколько инструментов ошибок, таких как PC-lint, могут найти в вашем коде. Рассматривайте чистый статический анализ как хорошую отправную точку для серьезного тестирования.

  5. Экспертные обзоры очень важны: ваш код должен быть достаточно чистым и хорошо документированным, чтобы он мог быть эффективно рассмотрен независимой стороной. Проверьте свое эго у двери и серьезно обдумайте любую критику или высказанные предложения.

  6. Тестирование имеет важное значение: вы должны сделать свою собственную проверку, а также иметь независимую проверку кода. Другие могут нарушить ваш код способами, которые вы не можете себе представить. Проверьте все действительные условия и все недопустимые условия, которые вы можете придумать. Используйте PRNG и вводите данные мусора. Делайте все возможное, чтобы сломать вещи, затем восстановите и попробуйте снова. Если вам повезет, вы сможете запустить свой код в режиме отладки и посмотреть регистры и переменные - если нет, вам нужно быть хитрым и переключать светодиоды / цифровые сигналы, чтобы получить представление о состоянии вашего устройство. Делайте все необходимое, чтобы получить обратную связь, которая вам нужна.

  7. Загляните внутрь: не бойтесь взглянуть на машинный код, сгенерированный вашим C-компилятором. Вы можете (будете?) Находить места, где ваш красивый код на C взорвался за десятки, если не за сотни операций, где что-то, что должно быть безопасным (так как это всего лишь одна строка кода, верно?) Занимает так много времени, чтобы выполнить несколько прерываний уволили и аннулировали условия. Если что-то становится ужасно неэффективным, проведите рефакторинг и попробуйте снова.


+1 Всем звук советую. Я ожидаю, что любой профессиональный разработчик прошивок просто улыбнется и кивнет, читая это.
Лундин

2
Важным аспектом рецензирования является то, что рецензия касается кода, а не программиста. Если вы анализируете свой код с такими терминами, как «сначала я делаю это, затем я делаю это», вы, вероятно, попали в беду. «Сначала код делает это, затем он делает это» - это правильный способ думать об этом. То же самое относится и к рецензентам: не «почему вы это сделали?», А «почему код делает это?».
Пит Беккер

Вы можете также рассмотреть возможность добавления: 1. Использование проверки
Cyclomatic

4

Большинство тех же методов создания надежного программного обеспечения на ПК также применимы к разработке встраиваемых систем. Полезно отделять ваши алгоритмы от аппаратного кода и тестировать их отдельно с помощью модульных тестов, симуляций, статического анализа и таких инструментов, как Valgrind. Таким образом, гораздо меньше кода проверяется только на оборудовании.

Я бы не отказался от C. Хотя такие языки, как Ada, могут дать некоторые незначительные гарантии, легко оказаться в ловушке, думая, что язык обещает больше, чем на самом деле.


Однако Valgrid может быть немного более актуальным для ПК, чем для 8-битного MCU :)
Лундин

К сожалению, некоторые методы для создания хорошего программного обеспечения на уровне ПК совершенно не подходят для небольших микроуровней, а некоторые методы, которые считаются плохими и неправильными в мире ПК, вполне приемлемы во встроенной среде.
Джон У

3

MISRA-C действительно очень полезен для улучшения общего качества кода и минимизации ошибок. Просто убедитесь, что вы прочитали и поняли каждое правило, большинство из них хороши, но некоторые из них не имеют никакого смысла.

Предупреждение здесь. Документ MISRA предполагает, что читатель - это человек с обширными знаниями языка Си. Если в вашей команде нет такого закаленного ветерана C, но вы решили получить статический анализатор, а затем вслепую следовать каждому предупреждению, это, скорее всего, приведет к снижению качества кода, поскольку вы можете снизить читабельность и случайно внести ошибки. Я видел это много раз, преобразование кода в соответствие требованиям MISRA не является тривиальной задачей.

Существует две версии документа MISRA-C, которые могут применяться. Либо MISRA-C: 2004, который до сих пор является фактическим стандартом встраиваемой промышленности. Или новый MISRA-C: 2012, который поддерживает стандарт C99. Если вы никогда не использовали MISRA-C раньше, я бы порекомендовал вам реализовать последнее.

Однако следует помнить, что поставщики инструментов обычно ссылаются на MISRA-C: 2004, когда говорят, что у них есть проверка MISRA (иногда они даже ссылаются на устаревшую версию MISRA-C: 1998). Насколько я знаю, инструментальная поддержка MISRA-C: 2012 все еще ограничена. Я думаю, что только некоторые статические анализаторы реализовали это до сих пор: Klocwork, LDRA, PRQA и Polyspace. Может быть и больше, но вам обязательно нужно проверить, какую версию MISRA он поддерживает.

Прежде чем принять решение, вы, конечно, можете начать с чтения документа MISRA и посмотреть, что с ним связано. Его можно купить за 10 фунтов стерлингов с сайта misra.org , вполне доступного по сравнению с ценами на стандарты ISO.


1

Mathworks (ребята из MATLAB) имеют инструмент статического анализа кода, который называется Polyspace .

Помимо статического анализа кода, ворса и тому подобного, я бы предложил тщательное определение и проектирование интерфейсов (с формальным процессом проверки) и анализ покрытия кода.

Возможно, вы также захотите ознакомиться с рекомендациями по разработке кода, критически важного для безопасности, включая MISRA, а также стандарты UL1998 и IEC 61508.


Я не рекомендую приближаться к IEC 61508, если вам не нужно. В нем упоминается программное обеспечение, но не хватает современных научных источников для своих требований. Этот стандарт появился на 30 лет позже - если бы он был выпущен в 70-х годах, как и большинство его так называемых «источников», он мог бы быть полезным.
Лундин

1

Чтобы получить полный ответ на этот вопрос, я бы подавил мысль о «надежности кода» и вместо этого подумал бы о «надежности дизайна», потому что код - это только окончательное выражение дизайна.

Итак, начните с требований и напишите и осмотрите их. Если у вас нет документа с требованиями, укажите случайную строку кода и спросите себя: «Зачем нужна эта строка?» Потребность в любой строке кода должна в конечном итоге быть прослеживаемой до требований, даже если это так просто / очевидно, как «источник питания должен выдавать 5 В постоянного тока, если входное напряжение находится в пределах 12-36 В постоянного тока». Один из способов думать об этом заключается в том, что если эту строку кода нельзя отследить до требования, то как вы узнаете, что это правильный код или он вообще нужен?

Далее проверьте свой дизайн. Это нормально, если он полностью находится в коде (например, в комментариях), но это затрудняет понимание того, выполняет ли код то, что на самом деле имеет в виду. Например, код может иметь строку, которая гласит: output = 3 * setpoint / (4 - (current * 5)); Является current == 4/5ли допустимый ввод, который может вызвать сбой? Что нужно сделать в этом случае, чтобы предотвратить деление на ноль? Вы вообще избегаете операции или ухудшаете выход? Наличие общего примечания в вашем проектном документе о том, как обрабатывать такие крайние случаи, значительно упрощает проверку проекта на более высоком уровне. Итак, теперь проверка кода стала проще, потому что нужно проверить, правильно ли код реализует этот дизайн.

Наряду с этим, проверка кода должна проверять распространенные ошибки, которые ваша IDE не улавливает (вы используете IDE, верно?), Такие как '=', когда вы имели в виду '==', пропущенные фигурные скобки меняют значение 'if заявления, точки с запятой там, где их не должно быть, и т. д.

Когда я пишу это, мне приходит в голову, что действительно сложно обобщить годы обучения / опыта в области качества программного обеспечения в одном посте. Я пишу код для медицинских устройств, и вышеизложенное представляет собой чрезвычайно упрощенное изложение того, как мы к нему подходим.


Насколько я понимаю, часть кода в медицинском устройстве проверяется почти так, как будто это отдельное устройство. Это точно?
Скотт Сейдман

@ScottSeidman Скорее всего, это тестируется на основе требований, как указано в этом ответе. Для каждого требования у вас должен быть модуль кода, а для каждого такого модуля кода - тест. По сути, каждое требование имеет соответствующий тест, а код является средством его выполнения. Такого рода отслеживание требований является обычной практикой в ​​любых критически важных системах задолго до появления модного слова «TDD».
Лундин

Я имел в виду конкретно руководство FDA, например, fda.gov/downloads/RegulatoryInformation/Guidances/ucm126955.pdf Программное обеспечение на самом деле требует больше, чем вы думаете, если оно является частью медицинского устройства, начиная со стадии планирования и контроля конструкции.
Скотт Сейдман

Скотт, я никогда не думал об этом таким образом, но ты прав. Наши специалисты по обеспечению качества программного обеспечения проверяют программное обеспечение отдельно от остальной части системы (насколько это возможно), прежде чем передать его другой группе, отвечающей за проверку и подтверждение системы.
Линдон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.