Vraag:
Welke tools of standaarden kunnen worden gebruikt om de betrouwbaarheid van embedded C-code te verbeteren?
Stephen Collings
2014-01-21 21:10:18 UTC
view on stackexchange narkive permalink

Ik programmeer PIC's meestal in C, meestal voor omvormers met geschakelde modus. Ik heb gehoord van verschillende statische analyse tools en standaarden zoals MISRA C die kunnen worden gebruikt om de betrouwbaarheid van code te verbeteren. Ik zou graag meer willen weten. Welke standaarden of tools kunnen geschikt zijn voor mijn context?

Hoe goed ben je ingesteld op de C-taal?
Ik zou kunnen worden overgehaald om over te schakelen naar iets anders als daar een heel goede zaak voor te maken was. Maar het zou een heel goede zaak moeten zijn.
"Een zeer goede zaak" om over te stappen van C kan niet snel gemaakt worden, en voor de PIC wellicht nog niet. Voor AVR, ARM of MSP430 zou Ada een serieuze blik waard zijn (ondanks de negativiteit die het aantrekt, zoals je kunt zien!) En voor hoge rel is SPARK het bekijken waard.
Misschien vindt u deze interessant als achtergrondinformatie: SPARK vs MISRA-C http://www.spark-2014.org/entries/detail/misra-c-2012-vs-spark-2014-the-subset-matching-game en deze lopende casus: http://www.spark-2014.org/uploads/Nosegearpaper_1.pdf
Misschien is een betere tijd geïnvesteerd om een ​​pleidooi te houden voor het overschakelen van de PIC naar iets moderns ... Vooral als u het soort bedrijfskritische systemen ontwerpt waarvoor MISRA en SPARK oorspronkelijk bedoeld waren.
Vijf antwoorden:
Adam Lawrence
2014-01-22 00:06:29 UTC
view on stackexchange narkive permalink

Embedded codevalidatie is lastig, vooral als het gaat om onderdelen met beperkte bronnen, zoals PIC's. Je hebt vaak niet de luxe van coderen in testgevallen vanwege de geheugenbeperkingen van het onderdeel en de vaak "realtime" programmering op dit soort apparaten.

Hier zijn enkele van mijn richtlijnen :

  1. Schrijf een specificatie als die er niet is: Als u niet codeert tegen een specificatie, documenteer dan wat uw code zou moeten doen, wat zijn geldige inputs, wat zijn verwachte outputs, hoe lang zou elke routine moeten duren, wat kan en kan niet in de war raken, enz. - een theorie van de werking, stroomdiagrammen, alles is beter dan niets.

  2. Geef commentaar op uw code: het feit dat iets voor u duidelijk is, betekent niet dat het voor iemand anders duidelijk (of correct) is. Commentaar in gewone taal is nodig voor zowel controle als voor onderhoud van de code.

  3. Code defensief: Voeg niet alleen code toe voor normale invoer. Omgaan met ontbrekende invoer, invoer die buiten bereik is, wiskundige overlopen, enz. - hoe meer hoeken u afdekt met uw codeontwerp, hoe minder vrijheidsgraden de code zal hebben wanneer deze wordt geïmplementeerd.

  4. Gebruik statische analyse-instrumenten: het kan vernederend zijn hoeveel bug-tools zoals PC-lint in uw code kunnen vinden. Beschouw een zuivere statische analyse als een goed startpunt voor serieuze tests.

  5. Peerrecensies zijn essentieel: uw code moet schoon en goed gedocumenteerd zijn voldoende dat het efficiënt kan worden beoordeeld door een onafhankelijke partij. Controleer je ego bij de deur en overweeg serieus eventuele kritiek of suggesties.

  6. Testen is essentieel: u dient uw eigen validatie uit te voeren, evenals een onafhankelijke validatie van de code. Anderen kunnen uw code breken op manieren die u zich onmogelijk kunt voorstellen. Test elke geldige voorwaarde en elke ongeldige voorwaarde die u maar kunt bedenken. Gebruik PRNG's en voer afvalgegevens in. Doe wat je kunt om dingen kapot te maken, repareer ze en probeer het opnieuw. Als je geluk hebt, kun je je code in de foutopsporingsmodus uitvoeren en naar registers en variabelen kijken - zo niet, dan moet je slim zijn en LED's / digitale signalen omschakelen om een ​​idee te krijgen van de staat van je apparaat. Doe wat nodig is om de feedback te krijgen die u nodig heeft.

  7. Kijk onder de motorkap: wees niet bang om naar de machinecode te kijken die wordt gegenereerd door uw C-compiler. U kunt (zult?) Plaatsen vinden waar uw prachtige C-code is opgeblazen in tientallen, zo niet honderden bewerkingen, waar iets dat veilig zou moeten zijn (aangezien het maar één regel code is, toch?) Zo lang duurt om uit te voeren dat meerdere interrupts hebben ontslagen en de voorwaarden ongeldig gemaakt. Als iets vreselijk inefficiënt wordt, refactuur het dan en probeer het opnieuw.

+1 Alle goed advies. Ik zou van elke professionele firmware-ontwikkelaar verwachten dat hij alleen maar glimlacht en knikt als hij dit leest.
Een belangrijk aspect van peer reviews is dat de review over de code gaat, niet over de programmeur. Als je je code analyseert met termen als "eerst doe ik dit, dan doe ik dat", dan zit je waarschijnlijk in de problemen. "Eerst doet de code dit, dan doet hij dat" is de juiste manier om erover na te denken. En hetzelfde geldt voor recensenten: niet "waarom deed je dit?", Maar "waarom doet de code dit?".
U kunt ook overwegen om toe te voegen: 1. Cyclomatische complexiteitscontrole gebruiken 2. Versiebeheersoftware
Theran
2014-01-21 22:00:23 UTC
view on stackexchange narkive permalink

De meeste van dezelfde technieken voor het maken van betrouwbare software op een pc zijn ook van toepassing op embedded ontwikkeling. Het is handig om uw algoritmen te scheiden van de hardwarespecifieke code en deze afzonderlijk te testen met unit-tests, simulaties, statische analyse en tools zoals Valgrind. Op die manier is er veel minder code die alleen op de hardware wordt getest.

Ik zou C niet verlaten. Hoewel talen zoals Ada enkele kleine garanties kunnen bieden, is het gemakkelijk om in de val te trappen door de taal belooft meer dan het in werkelijkheid doet.

Valgrid is misschien een beetje relevanter voor pc dan voor een 8-bit MCU :)
Helaas zijn * sommige * technieken voor het maken van goede software op pc-niveau erg ongeschikt voor kleine micros, en sommige praktijken die als slecht en fout worden beschouwd in pc-land, zijn perfect acceptabel in een embedded omgeving.
Lundin
2014-01-29 21:25:53 UTC
view on stackexchange narkive permalink

MISRA-C is inderdaad erg handig om de algemene codekwaliteit te verbeteren en bugs te minimaliseren. Zorg ervoor dat u elke regel leest en begrijpt, de meeste zijn goed, maar een paar kloppen niet.

Een waarschuwing hier. Het MISRA-document gaat ervan uit dat de lezer iemand is met uitgebreide kennis van de C-taal. Als je niet zo'n doorgewinterde C-veteraan in je team hebt, maar besluit om een ​​statische analysator aan te schaffen en dan blindelings elke gegeven waarschuwing te volgen, zal dit hoogstwaarschijnlijk resulteren in code van mindere kwaliteit , aangezien je de leesbaarheid mogelijk vermindert en per ongeluk bugs introduceren. Ik heb dit vaak zien gebeuren, het omzetten van code naar MISRA-conformiteit is geen triviale taak.

Er zijn twee versies van het MISRA-C-document die van toepassing kunnen zijn. Ofwel MISRA-C: 2004, dat nog steeds de huidige de facto standaard voor de embedded industrie is. Of de nieuwe MISRA-C: 2012 die de C99-standaard ondersteunt. Als je nog nooit MISRA-C hebt gebruikt, raad ik je aan om het laatste te implementeren.

Houd er echter rekening mee dat leveranciers van tools meestal naar MISRA-C: 2004 verwijzen als ze zeggen dat ze MISRA-controle hebben (soms verwijzen ze zelfs naar de verouderde MISRA-C: 1998-versie). Voor zover ik weet, is de toolondersteuning voor MISRA-C: 2012 nog steeds beperkt. Ik denk dat tot nu toe slechts enkele statische analysers het hebben geïmplementeerd: Klocwork, LDRA, PRQA en Polyspace. Misschien meer, maar u moet zeker controleren welke versie van MISRA het ondersteunt.

Voordat u besluit, kunt u natuurlijk beginnen met het lezen van het MISRA-document en kijken wat het inhoudt. Het kan voor £ 10 worden gekocht bij misra.org, redelijk betaalbaar vergeleken met de prijzen voor ISO-normen.

Spehro Pefhany
2014-01-21 22:14:17 UTC
view on stackexchange narkive permalink

Mathworks (de MATLAB-mensen) hebben een statische code-analysetool genaamd Polyspace.

Naast statische code-analyse, lint en dergelijke, zou ik een zorgvuldige definitie en ontwerp van interfaces (met een formeel beoordelingsproces) en codedekkinganalyse willen voorstellen.

Misschien wilt u ook kijken naar richtlijnen voor het ontwerpen van veiligheidskritische codes, inclusief MISRA, maar ook de UL1998- en IEC 61508-normen.

Ik raad niet aan om in de buurt van IEC 61508 te gaan, tenzij het moet. Het vermeldt wel software, maar het mist moderne, wetenschappelijke bronnen voor zijn beweringen. Die standaard kwam 30 jaar te laat - als hij in de jaren '70 was uitgebracht, zoals de meeste van zijn zogenaamde "bronnen", zou hij nuttig kunnen zijn geweest.
lyndon
2014-01-21 23:43:30 UTC
view on stackexchange narkive permalink

Voor een volledig antwoord op deze vraag zou ik de gedachte aan "codebetrouwbaarheid" onderdrukken en in plaats daarvan denken aan "ontwerpbetrouwbaarheid", omdat de code slechts de laatste uitdrukking van het ontwerp is.

Begin dus met de vereisten en schrijf en inspecteer deze. Als je geen requirementsdocument hebt, wijs dan naar een willekeurige regel code en vraag jezelf af "waarom is die regel nodig?" De behoefte aan een regel code moet uiteindelijk herleidbaar zijn tot een vereiste, zelfs als het zo simpel / voor de hand liggend is als "de voeding zal 5 VDC leveren als de invoer tussen 12-36 VDC ligt". Een manier om hierover na te denken is dat als die regel code niet kan worden herleid tot een vereiste, hoe weet u dan dat het de juiste code is of dat deze überhaupt nodig is?

Verifieer vervolgens uw ontwerp. Het is oké als het volledig in de code staat (bijvoorbeeld in opmerkingen), maar dat maakt het moeilijker om te weten of de code doet wat echt bedoeld is. De code kan bijvoorbeeld een regel hebben die luidt: output = 3 * setpoint / (4 - (current * 5)); Is current == 4/5 een geldige invoer die een crash kan veroorzaken? Wat moet er in dit geval worden gedaan om de deling door nul te voorkomen? Vermijdt u de operatie helemaal of vermindert u in plaats daarvan de output? Als u een algemene opmerking in uw ontwerpdocument heeft over hoe u met dergelijke randgevallen moet omgaan, wordt het veel gemakkelijker om het ontwerp op een hoger niveau te verifiëren. Code-inspectie is nu dus gemakkelijker omdat het een kwestie is van controleren of de code dat ontwerp correct implementeert.

Daarnaast moet code-inspectie controleren op veelvoorkomende fouten die uw IDE niet opvangt (u gebruikt een IDE, toch?) zoals '=' toen je '==' bedoelde, ontbrekende accolades die de betekenis van 'als'-uitspraken veranderen, puntkomma's waar ze niet zouden moeten zijn, enz.

Zoals ik Als ik dit schrijf, bedenk ik me dat het erg moeilijk is om jarenlange training / ervaring op het gebied van softwarekwaliteit in één bericht samen te vatten. Ik schrijf code voor medische hulpmiddelen en het bovenstaande is een extreem vereenvoudigde samenvatting van hoe we het benaderen.

Ik heb begrepen dat het codegedeelte in een medisch apparaat bijna wordt getest alsof het een afzonderlijk apparaat is. Klopt dat?
@ScottSeidman Het is waarschijnlijker dat het wordt getest op basis van vereisten, zoals vermeld in dit antwoord. Voor elke vereiste zou u een codemodule moeten hebben en voor elke dergelijke codemodule zou u een test moeten hebben. Dus in wezen heeft elke vereiste een overeenkomstige test en de code is het middel om aan de vereiste te voldoen. Dit soort opsporing van vereisten is een gangbare praktijk in alle bedrijfskritische systemen, lang voordat het modewoord "TDD" opdook.
Ik verwees specifiek naar richtlijnen van de FDA, zoals http://www.fda.gov/downloads/RegulatoryInformation/Guidances/ucm126955.pdf Software vereist eigenlijk meer dan je zou denken als het deel uitmaakt van een medisch hulpmiddel, beginnend bij de planningsfase en ontwerpcontroles.
Scott, ik heb er nooit zo over nagedacht, maar je hebt gelijk. Onze Software Quality Assurance-mensen verifiëren de software (zoveel mogelijk) apart van de rest van het systeem voordat ze deze overdragen aan een andere groep die verantwoordelijk is voor systeemverificatie en validatie.


Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 3.0-licentie waaronder het wordt gedistribueerd.
Loading...