Autor: Maciej Gajdzica (Senior Software Developer)
V-model, normy branżowe, dyscyplina, skupienie… i co jeszcze?
Oto garść porad dot. rozwoju oprogramowania do systemów krytycznych.
Rozwój oprogramowania krytycznego w oparciu o V-model:
V-model określa trzy części projektu:
Konkretne normy takie jak np. EN50128 dla kolejnictwa określają zalecane praktyki dla każdej z tych części przekładające się na zwiększone bezpieczeństwo docelowego systemu. W EN50128 praktyki te zostały zebrane w formie tabel z rekomendacjami dla poszczególnych poziomów SIL (Safety Integrity Level). Dodatkowo każda z technik została opisana w normie.
Oprogramowanie typu safety-critical powinno być projektowane w sposób ustrukturyzowany (Structured methodology). Powinniśmy określić granice systemu, zidentyfikować wymagania i stopniowo uszczegóławiać projekt rozbijając duże problemy na mniejsze. Pomóc nam w tym mogą checklisty, diagramy, maszyny stanów i narzędzia komputerowe. W trakcie projektowania możemy stosować metody nieformalne pomagające nam w zrozumieniu zagadnienia. Część z powstałych w ten sposób schematów trafi później do oficjalnej dokumentacji. Decyzje projektowe powinny być konsultowane w większym gronie podczas Design Review.
Norma wyszczególnia również bardziej techniczne aspekty, które powinny być uwzględnione m.in.:
Są również praktyki wyraźnie odradzane przez normę takie jak dynamiczna zmiana konfiguracji podczas działania programu. Zamiast tego konfiguracja powinna być wykonywana podczas inicjalizacji, a potem system ma działać według niej. Tak samo nie zaleca się przywracania systemu po błędzie do wcześniejszej działającej konfiguracji. Jeśli wystąpił poważny błąd, powinniśmy ograniczyć jego skutki poprzez wejście do procedury safe-state i czekać na interwencję operatora.
Kolejna grupa porad z normy EN50128 dotyczy implementacji. Przede wszystkim powinniśmy używać języków kompilowanych i silnie typowanych, aby jak najwięcej niebezpiecznych konstrukcji po prostu nie mogło się skompilować. Niebezpieczne konstrukcje dające się skompilować powinny być opisane w dokumencie Coding Standard i wyłapywane za pomocą analizy statycznej. Jest to szczególnie ważne w przypadku C i C++ dopuszczających wiele podejrzanych konstrukcji. Szeroko przyjętym standardem jest tutaj MISRA C.
Inne rekomendacje mówią, żeby nie używać zmiennych globalnych, pisać funkcje o ograniczonej długości, złożoności i ilości parametrów wejściowych. Moduły powinny mieć ograniczony rozmiar i skupiać się na pojedynczym zadaniu. System powinien być podzielony na warstwy abstrakcji i mieć ograniczone zależności pomiędzy modułami i warstwami. To wszystko są dobrze znane zasady tworzenia wysokiej jakości kodu wykorzystywane również poza systemami safety-critical. Istnieją jednak także bardziej restrykcyjne rekomendacje, których nie znajdziemy w konwencjonalnych systemach takie jak:
Trzecia grupa porad odnosi się do weryfikacji i testowania oprogramowania. Powinniśmy robić testy na różnych poziomach – jednostkowe, integracyjne, systemowe. Do tego testy niefunkcjonalne np. wydajnościowe. Testy powinny być zarówno white-boxowe jak i black-boxowe. Norma zaleca monitorowanie code coverage, najlepiej Modified Condition/Decision Coverage (MCDC). Do tego powinniśmy posiłkować się metrykami, analizą statyczną i dynamiczną. Zalecane jest również robienie Code Review.
Jak widać, w normach zebrano wiele dobrych praktyk znanych również z innych dziedzin programowania. Nic dziwnego – zostały one dobrze opisane i przeanalizowane oraz udowodniły swoją skuteczność. Jednocześnie systemy safety-critical muszą być wykonywane pod większym rygorem przez co istnieje też trochę technik specyficznych tylko dla systemów tego typu.