Quels outils ou normes peuvent être utilisés pour améliorer la fiabilité du code C intégré?


9

Je programme généralement les PIC en C, généralement pour les convertisseurs en mode commuté. J'ai entendu parler de divers outils et normes d' analyse statique comme MISRA C qui peuvent être utilisés pour améliorer la fiabilité du code. J'aimerais en savoir plus. Quelles normes ou quels outils pourraient convenir à mon contexte?


1
Comment êtes-vous réglé sur le langage C?
Brian Drummond

1
Je pourrais être persuadé de passer à autre chose s'il y avait de très bonnes raisons de le faire. Mais il faudrait que ce soit un très bon cas.
Stephen Collings

"Un très bon cas" pour passer de C ne peut pas être fait rapidement, et pour le PIC, peut-être pas encore du tout. Pour AVR, ARM ou MSP430, Ada vaudrait un coup d'oeil sérieux (malgré la négativité qu'il attire, comme vous pouvez le voir!) Et pour des rel élevés, SPARK vaut le coup d'oeil.
Brian Drummond

Vous pouvez trouver ces informations de base intéressantes: SPARK vs MISRA-C spark-2014.org/entries/detail/… et cette étude de cas en cours: spark-2014.org/uploads/Nosegearpaper_1.pdf
Brian Drummond

Il serait peut-être préférable d'investir plus de temps pour justifier le passage du PIC à quelque chose de moderne ... Surtout si vous concevez le type de systèmes critiques pour lesquels MISRA et SPARK étaient initialement destinés.
Lundin

Réponses:


11

La validation de code intégré est délicate, en particulier lorsqu'il s'agit de parties à ressources limitées comme les PIC. Souvent, vous n'avez pas le luxe de coder dans des cas de test en raison des contraintes de mémoire de la pièce et de la programmation souvent "en temps réel" effectuée sur ce type d'appareils.

Voici quelques-unes de mes directives:

  1. Écrivez une spécification s'il n'y en a pas: si vous ne codez pas contre une spécification, documentez ce que votre code est censé faire, quelles sont les entrées valides, quelles sont les sorties attendues, combien de temps chaque routine devrait-elle prendre, ce qui peut et ne peut pas être obtenu clobbered, etc. - une théorie du fonctionnement, des organigrammes, tout vaut mieux que rien.

  2. Commentez votre code: ce n'est pas parce que quelque chose est évident pour vous qu'il est évident (ou correct) pour quelqu'un d'autre. Des commentaires en langage clair sont nécessaires à la fois pour la révision et la maintenabilité du code.

  3. Code défensivement: n'incluez pas seulement le code pour les entrées normales. Gérez les entrées manquantes, les entrées hors de portée, les débordements mathématiques, etc. - plus vous recouvrirez de coins par la conception de votre code, moins il aura de degrés de liberté lors de son déploiement.

  4. Utilisez des outils d'analyse statique: il peut être humiliant de voir combien d'outils de bogues comme PC-lint peuvent trouver dans votre code. Considérez une analyse statique propre comme un bon point de départ pour des tests sérieux.

  5. Les évaluations par les pairs sont essentielles: votre code doit être suffisamment propre et bien documenté pour pouvoir être examiné efficacement par une partie indépendante. Vérifiez votre ego à la porte et considérez sérieusement toute critique ou suggestion faite.

  6. Les tests sont essentiels: vous devez faire votre propre validation, ainsi qu'une validation indépendante du code. D'autres peuvent casser votre code d'une manière que vous ne pouvez pas imaginer. Testez toutes les conditions valides et toutes les conditions invalides auxquelles vous pouvez penser. Utilisez des PRNG et introduisez des données d'ordures. Faites tout ce que vous pouvez pour casser les choses, puis réparez et réessayez. Si vous êtes chanceux, vous pourrez exécuter votre code en mode débogage et jeter un œil aux registres et aux variables - sinon, vous devrez être astucieux et basculer les LED / signaux numériques pour avoir une idée de l'état de votre dispositif. Faites tout ce qui est nécessaire pour obtenir les commentaires dont vous avez besoin.

  7. Regardez sous le capot: N'ayez pas peur de regarder le code machine généré par votre compilateur C. Vous pouvez (trouverez?) Trouver des endroits où votre beau code C a explosé en dizaines sinon en centaines d'opérations, où quelque chose qui devrait être sûr (car il ne s'agit que d'une seule ligne de code, n'est-ce pas?) Prend tellement de temps pour exécuter plusieurs interruptions ont tiré et invalidé les conditions. Si quelque chose devient horriblement inefficace, refactorisez-le et réessayez.


+1 Tous les conseils sonores. Je m'attendrais à ce que tout développeur de firmware professionnel sourie et acquiesce en lisant ceci.
Lundin

2
Un aspect important des revues par les pairs est que la revue concerne le code, pas le programmeur. Si vous analysez votre code avec des termes comme «d'abord je fais ceci, puis je fais ça», vous êtes probablement en difficulté. "D'abord, le code fait ceci, puis il fait cela" est la bonne façon d'y penser. Et la même chose s'applique aux réviseurs: pas "pourquoi avez-vous fait cela?", Mais "pourquoi le code fait-il cela?".
Pete Becker

Vous pouvez également envisager d'ajouter: 1. Utilisation de la vérification de la complexité cyclomatique 2. Logiciel de contrôle de version
AlphaGoku

4

La plupart des mêmes techniques de création de logiciels fiables sur PC sont également applicables au développement embarqué. Il est utile de séparer vos algorithmes du code spécifique au matériel et de les tester séparément avec des tests unitaires, des simulations, des analyses statiques et des outils comme Valgrind. De cette façon, il y a beaucoup moins de code qui n'est testé que sur le matériel.

Je n'abandonnerais pas C. Bien que des langues comme Ada puissent offrir des garanties mineures, il est facile de tomber dans le piège de penser que la langue promet plus qu'elle ne le fait vraiment.


Valgrid pourrait être un peu plus pertinent pour PC que pour un MCU 8 bits, cependant :)
Lundin

Malheureusement, certaines techniques pour créer de bons logiciels de niveau PC sont très inadaptées aux petits micros, et certaines pratiques considérées comme mauvaises et erronées dans les terrains PC sont parfaitement acceptables dans un environnement embarqué.
John U

3

MISRA-C est en effet très utile pour améliorer la qualité générale du code et minimiser les bugs. Assurez-vous simplement de lire et de comprendre chaque règle, la plupart d'entre elles sont bonnes, mais quelques-unes n'ont aucun sens.

Un avertissement ici. Le document MISRA suppose que le lecteur est une personne ayant une connaissance approfondie du langage C. Si vous n'avez pas un tel vétéran C endurci dans votre équipe, mais décidez d'obtenir un analyseur statique et de suivre aveuglément chaque avertissement donné, cela entraînera très probablement un code de qualité inférieure , car vous pourriez réduire la lisibilité et introduire des bogues par accident. J'ai vu cela se produire de nombreuses fois, la conversion de code en conformité avec MISRA n'est pas une tâche triviale.

Il existe deux versions du document MISRA-C qui peuvent s'appliquer. Soit MISRA-C: 2004, qui est toujours la norme de facto intégrée de l'industrie actuelle. Ou le nouveau MISRA-C: 2012 qui prend en charge la norme C99. Si vous n'avez jamais utilisé MISRA-C auparavant, je vous recommande de l'implémenter.

Sachez cependant que les fournisseurs d'outils se réfèrent généralement à MISRA-C: 2004 lorsqu'ils disent qu'ils ont une vérification MISRA (parfois ils se réfèrent même à la version obsolète de MISRA-C: 1998). Pour autant que je sache, la prise en charge des outils pour MISRA-C: 2012 est encore limitée. Je pense que seuls certains analyseurs statiques l'ont mis en œuvre jusqu'à présent: Klocwork, LDRA, PRQA et Polyspace. Peut-être plus, mais vous devez absolument vérifier quelle version de MISRA il prend en charge.

Avant de vous décider, vous pouvez bien sûr commencer par lire le document MISRA et voir ce qu'il implique. Il peut être acheté pour 10 £ sur misra.org , assez abordable par rapport aux prix des normes ISO.


1

Mathworks (les gens de MATLAB) ont un outil d'analyse de code statique appelé Polyspace .

En plus de l'analyse de code statique, des peluches et autres, je suggérerais une définition et une conception soigneuses des interfaces (avec un processus d'examen formel) et une analyse de la couverture du code.

Vous voudrez peut-être également consulter les directives pour la conception de codes critiques pour la sécurité, y compris MISRA, mais aussi les normes UL1998 et CEI 61508.


Je ne recommande pas d'aller près de la CEI 61508, sauf si vous y êtes obligé. Il mentionne des logiciels, mais manque de sources scientifiques modernes pour ses affirmations. Cette norme est arrivée 30 ans trop tard - si elle avait été publiée dans les années 70 comme la plupart de ses soi-disant "sources", elle aurait pu être utile.
Lundin

1

Pour une réponse complète à cette question, je supprimerais la réflexion sur la «fiabilité du code» et je penserais plutôt à la «fiabilité de la conception», car le code n'est que l'expression finale de la conception.

Alors, commencez par les exigences et écrivez-les et inspectez-les. Si vous n'avez pas de document d'exigences, pointez sur une ligne de code aléatoire et demandez-vous "pourquoi cette ligne est-elle nécessaire?" Le besoin de n'importe quelle ligne de code devrait éventuellement être lié à une exigence, même si elle est aussi simple / évidente que "l'alimentation doit produire 5VDC si l'entrée est entre 12-36VDC". Une façon de penser à ce sujet est que si cette ligne de code ne peut pas être attribuée à une exigence, alors comment savez-vous que c'est le bon code, ou qu'il est nécessaire du tout?

Ensuite, vérifiez votre conception. C'est OK si c'est complètement dans le code (par exemple, dans les commentaires), mais cela rend plus difficile de savoir si le code fait ce que l'on veut vraiment dire. Par exemple, le code peut avoir une ligne qui lit output = 3 * setpoint / (4 - (current * 5)); Est-ce current == 4/5qu'une entrée valide pourrait provoquer un crash? Que faire dans ce cas pour éviter la division par zéro? Évitez-vous complètement l'opération ou dégrade-t-il la sortie à la place? Avoir une note générale dans votre document de conception sur la façon de gérer de tels cas de bord facilite la vérification de la conception à un niveau supérieur. Ainsi, maintenant l'inspection du code est plus facile car il s'agit de vérifier si le code implémente correctement cette conception.

Parallèlement à cela, l'inspection du code devrait vérifier les erreurs courantes que votre IDE ne détecte pas (vous utilisez un IDE, n'est-ce pas?) Tels que '=' lorsque vous vouliez dire '==', des accolades manquantes qui changent la signification de 'si 'déclarations, points-virgules où ils ne devraient pas être, etc.

Au moment où j'écris ceci, il me semble qu'il est vraiment difficile de résumer des années de formation / expérience de qualité logicielle dans un seul poste. J'écris du code pour les dispositifs médicaux et ce qui précède est un résumé extrêmement simplifié de notre approche.


Ma compréhension est que la portion de code d'un appareil médical est testée presque comme s'il s'agissait d'un appareil séparé. Est-ce exact?
Scott Seidman

@ScottSeidman Plus probablement, il est testé sur la base des exigences, comme mentionné dans cette réponse. Pour chaque exigence, vous devriez avoir un module de code et pour chacun de ces modules de code, vous devriez avoir un test. Donc, essentiellement, chaque exigence a un test correspondant et le code est le moyen de répondre à l'exigence. Ce type de suivi des exigences est une pratique courante dans tous les systèmes critiques, bien avant que le mot à la mode «TDD» n'apparaisse.
Lundin

Je faisais référence spécifiquement aux directives de la FDA, telles que fda.gov/downloads/RegulatoryInformation/Guidances/ucm126955.pdf Le logiciel nécessite en fait plus que vous ne le pensez si sa partie d'un dispositif médical, à partir de la planification et des contrôles de conception.
Scott Seidman

Scott, je n'y ai jamais pensé de cette façon, mais tu as raison. Nos employés chargés de l'assurance qualité des logiciels vérifient le logiciel séparément du reste du système (dans la mesure du possible) avant de le confier à un autre groupe responsable de la vérification et de la validation du système.
lyndon
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.