Zazwyczaj programuję PIC w C, zwykle dla konwerterów przełączanych. Słyszałem o różnych narzędziach i standardach analizy statycznej, takich jak MISRA C , których można użyć do poprawy niezawodności kodu. Chciałbym wiedzieć więcej. Jakie standardy lub narzędzia mogą być odpowiednie dla mojego kontekstu?
9
Odpowiedzi:
Sprawdzanie poprawności kodu osadzonego jest trudne, szczególnie w przypadku części o ograniczonych zasobach, takich jak PIC. Często nie masz luksusu kodowania w przypadkach testowych z powodu ograniczeń pamięciowych części i często programowania w czasie rzeczywistym wykonywanego na tego rodzaju urządzeniach.
Oto niektóre z moich wskazówek:
Napisz specyfikację, jeśli nie istnieje: Jeśli nie kodujesz w oparciu o specyfikację, udokumentuj, do czego powinien służyć Twój kod, jakie są prawidłowe dane wejściowe, jakie są oczekiwane wyniki, jak długo powinna trwać każda procedura, co może, a czego nie może uzyskać clobbered itp. - teoria działania, schematy blokowe, wszystko jest lepsze niż nic.
Skomentuj swój kod: To, że coś jest dla ciebie oczywiste, nie oznacza, że jest oczywiste (lub poprawne) dla kogoś innego. Komentarze w prostym języku są niezbędne zarówno do przeglądu, jak i utrzymania kodu.
Kod defensywnie: Nie dołączaj tylko kodu do normalnych danych wejściowych. Obsługuj brakujące dane wejściowe, dane wejściowe poza zakresem, przepełnienia matematyczne itp. - im więcej zakrętów obejmie Twój projekt kodu, tym mniej stopni swobody będzie miał kod po wdrożeniu.
Użyj narzędzi do analizy statycznej: może być upokarzające, ile narzędzi błędów, takich jak PC-lint, można znaleźć w kodzie. Rozważ czystą analizę statyczną jako dobry punkt wyjścia do poważnych testów.
Niezbędne są wzajemne oceny: Twój kod powinien być czysty i wystarczająco udokumentowany, aby mógł być skutecznie sprawdzony przez niezależną stronę. Sprawdź swoje ego przy drzwiach i poważnie rozważ wszelkie uwagi i sugestie.
Testowanie jest niezbędne: powinieneś przeprowadzić własną weryfikację, a także niezależną weryfikację kodu. Inni mogą złamać kod w sposób, którego nie możesz sobie wyobrazić. Przetestuj każdy prawidłowy warunek i każdy nieprawidłowy warunek, jaki możesz wymyślić. Używaj PRNG i wprowadzaj śmieciowe dane. Rób wszystko, co możesz, aby coś zepsuć, a następnie napraw i spróbuj ponownie. Jeśli masz szczęście, będziesz mógł uruchomić swój kod w trybie debugowania i zerknąć na rejestry i zmienne - jeśli nie, musisz być sprytny i przełączać diody LED / sygnały cyfrowe, aby zorientować się w stanie swojego urządzenie. Zrób wszystko, co konieczne, aby uzyskać potrzebne informacje zwrotne.
Spójrz pod maską: nie bój się spojrzeć na kod maszynowy generowany przez kompilator C. Możesz (będzie?) Znajdować miejsca, w których twój piękny kod C wysadził się w dziesiątki, jeśli nie setki operacji, w których coś, co powinno być bezpieczne (ponieważ jest to tylko jedna linia kodu, prawda?), Zajmuje tyle czasu, że wykonanie wielu przerwań zwolnili i unieważnili warunki. Jeśli coś stanie się okropnie nieefektywne, przerób to i spróbuj ponownie.
źródło
Większość tych samych technik tworzenia niezawodnego oprogramowania na PC ma również zastosowanie do programowania wbudowanego. Pomocne jest oddzielenie algorytmów od kodu specyficznego dla sprzętu i przetestowanie ich osobno za pomocą testów jednostkowych, symulacji, analizy statycznej i narzędzi takich jak Valgrind. W ten sposób jest o wiele mniej kodu, który jest testowany tylko na sprzęcie.
Nie zrezygnowałbym z C. Chociaż języki takie jak Ada dają pewne drobne gwarancje, łatwo wpaść w pułapkę myślenia, że język obiecuje więcej niż w rzeczywistości.
źródło
MISRA-C jest rzeczywiście bardzo przydatny do poprawy ogólnej jakości kodu i minimalizacji błędów. Upewnij się tylko, że przeczytałeś i zrozumiałeś każdą zasadę, większość z nich jest dobra, ale kilka z nich nie ma żadnego sensu.
Ostrzeżenie tutaj. Dokument MISRA zakłada, że czytelnikiem jest osoba z rozległą znajomością języka C. Jeśli nie masz takiego zahartowanego weterana C w swoim zespole, ale zdecydujesz się wziąć analizator statyczny, a następnie ślepo stosować się do każdego podanego ostrzeżenia, najprawdopodobniej spowoduje to obniżenie jakości kodu, ponieważ możesz zmniejszyć czytelność i wprowadzić błędy przez przypadek. Widziałem to wiele razy, konwersja kodu do zgodności z MISRA nie jest łatwym zadaniem.
Mogą obowiązywać dwie wersje dokumentu MISRA-C. Albo MISRA-C: 2004, która jest nadal aktualnym standardem branżowym. Lub nowy MISRA-C: 2012, który obsługuje standard C99. Jeśli nigdy wcześniej nie korzystałeś z MISRA-C, zaleciłbym wdrożenie tego drugiego.
Należy jednak pamiętać, że dostawcy narzędzi zwykle odnoszą się do MISRA-C: 2004, kiedy twierdzą, że mają sprawdzanie MISRA (czasami nawet odnoszą się do przestarzałej wersji MISRA-C: 1998). O ile mi wiadomo, wsparcie narzędziowe dla MISRA-C: 2012 jest nadal ograniczone. Myślę, że jak dotąd zaimplementowały go tylko niektóre analizatory statyczne: Klocwork, LDRA, PRQA i Polyspace. Może być więcej, ale zdecydowanie musisz sprawdzić, którą wersję MISRA obsługuje.
Przed podjęciem decyzji możesz oczywiście zacząć od przeczytania dokumentu MISRA i zobacz, co się z tym wiąże. Można go kupić za 10 funtów na stronie misra.org , co jest dość przystępne w porównaniu do cen norm ISO.
źródło
Mathworks (ludzie MATLAB) mają narzędzie do analizy kodu statycznego o nazwie Polyspace .
Oprócz statycznej analizy kodu, kłaczków itp. Sugerowałbym staranne zdefiniowanie i zaprojektowanie interfejsów (z formalnym procesem przeglądu) oraz analizę pokrycia kodu.
Warto również zapoznać się ze wskazówkami dotyczącymi projektowania kodu krytycznego dla bezpieczeństwa, w tym MISRA, ale także normami UL1998 i IEC 61508.
źródło
Aby uzyskać pełną odpowiedź na to pytanie, odrzuciłbym myśl o „niezawodności kodu”, a zamiast tego pomyślałem o „niezawodności projektu”, ponieważ kod jest tylko ostatnim wyrazem projektu.
Zacznij więc od wymagań, napisz je i sprawdź. Jeśli nie masz dokumentu wymagań, wskaż losowy wiersz kodu i zadaj sobie pytanie „dlaczego ten wiersz jest potrzebny?” Potrzeba dowolnego wiersza kodu powinna być ostatecznie zgodna z wymaganiami, nawet jeśli jest to tak proste / oczywiste, jak „zasilacz powinien wytwarzać napięcie 5 V DC, jeśli napięcie wejściowe wynosi 12–36 V DC”. Jednym ze sposobów myślenia na ten temat jest to, że jeśli tego wiersza kodu nie można prześledzić do wymogu, to skąd wiesz, że jest to właściwy kod lub że w ogóle jest potrzebny?
Następnie sprawdź swój projekt. Jest OK, jeśli jest całkowicie w kodzie (np. W komentarzach), ale to sprawia, że trudniej jest wiedzieć, czy kod robi to, co naprawdę ma na myśli. Na przykład w kodzie może znajdować się wiersz o treści
output = 3 * setpoint / (4 - (current * 5));
Czycurrent == 4/5
prawidłowe dane wejściowe mogą spowodować awarię? Co należy zrobić w tym przypadku, aby zapobiec podziałowi przez zero? Czy unikasz operacji całkowicie, czy zamiast tego degradujesz wyjście? Dzięki ogólnej notatce w dokumencie projektowym dotyczącym obsługi takich przypadków krawędzi znacznie łatwiej jest zweryfikować projekt na wyższym poziomie. Tak więc teraz kontrola kodu jest łatwiejsza, ponieważ chodzi o sprawdzenie, czy kod poprawnie implementuje ten projekt.Oprócz tego inspekcja kodu powinna sprawdzić typowe błędy, których nie może wykryć IDE (używasz IDE, prawda?), Takie jak „=”, gdy miałeś na myśli „==”, brak nawiasów klamrowych, które zmieniają znaczenie „jeśli „oświadczenia, średniki tam, gdzie nie powinny być itp.
Kiedy to piszę, przychodzi mi do głowy, że naprawdę trudno jest podsumować lata szkolenia / doświadczenia w zakresie jakości oprogramowania w jednym poście. Piszę kod dla urządzeń medycznych, a powyższe jest niezwykle uproszczonym podsumowaniem tego, jak do tego podchodzimy.
źródło