tonyk писал(а):Промышленные стандарты на функциональную безопасность ПО запрещают использовать динамическое распределение памяти
Интересно, не знал об этом.
tonyk писал(а):Потому, что не все умеют писать сразу правильно. Вы часто едите в автосервис для очередного апгрейда ПО в ЭБУ двигателя вашего авто?
Подискутировал бы, но не знаком глубоко с устройством ЭБУ. Может там отдельный МК для критических задач, которых в целом, не так и много, да и сложности я не вижу в них большой. А может и в чем другом дело...
Базилюк писал(а):Гипотетический пример - есть три датчика температуры воды в нагревателе
Вот это как раз случай, когда исключения лучше не использовать. Эта ошибка может быть обработана просто возвратом сообщения о невалидных данных.
Я имел в виду более сложные в обработке ситуации типа обращения к указателю с несуществующим блоком памяти, либо когда память была затерта и т.п.
Кстати, я тут поразмышлял и придумал интересную схему (а может и изобрел велосипед).
Как я говорил, мне исключения интересны больше тем, что позволяют размотать стек и посмотреть из каого класса и метода оно было выброшено.
Схема такая:
- создаем в каждом классе статическое константное поле с именем класса и в каждом методе такое же, но с именем метода
- делаем два глобальных статических указателя
- при каждом заходе в какую-либо функцию или метод назначаем этим указателям адреса наименований класса и фонкции\метода соответственно
- в обработчике HardFault берем значения из этих переменных, копируем в выделенную область энергонезависимой памяти, в которой также ставим флаг о наличии ошибки. Можно еще добавить инфу об инструкции из регистров.
- при перезапуске МК после инициализации добавляем проверку этого флага и если он выставлен, то что-то делаем (например передаем на сервер сохраненные строки с методом и классом), очищаем флаг и строки в энергонезависимой памяти.
Вместо наименования класса можно использовать namespace, имя файла или т.п. Пока не пришел к решению, что более эффективно.
Из недостатков:
- дополнительная память под строки, хотя этим полагаю, можно пренебречь.
- лишние такты в каждой функции на копирование адреса в статические переменные. Операции насколько я помню атомарные и потребуется два такта, что в целом терпимо. В обработчиках прерываний только вот нужно будет 6, так как сначала текущие адреса нужно сохранить во временную переменную, изменить указатели на имя обработчика, а потом при выходе вернуть прежние значения.
- необходимость вручную указывать наименование методов, классов и функций. Возможно есть средства языка, которые помогают получить их автоматом на этапе компиляции, но я не в курсе. Если кто знает - подскажите, буду признателен.
В качестве расширения можно реализовать операции изменения статических переменных в виде define, что позволит иметь возможность изменять логику работы из одной точки кода + включать и отключать их когда нужно (например, отключить в продакшене, по каким-то причинам).