Brevet FR2819603A1 — publié le 20020719

PROCÉDÉ D'INJECTION D'ERREURS PAR INTERRUPTIONS La présente invention concerne de façon générale le test de l'aptitude de systèmes électroniques et logiques à base de circuits intégrés, par exemple de systèmes destinés à des applications spatiales, à fonctionner correctement sous irradiation. Toutefois, étant donné la miniaturisation des circuits intégrés, ceux-ci deviennent de plus en plus sensibles aux effets des radiations et l'invention trouve également des applications dans le test de circuits intégrés utilisés sur terre. La présente invention vise plus particulièrement la vérification de systèmes capables d'exécuter un jeu d'instructions ou de commandes (microprocesseur, microcontrôleur, processeur de traitement de signal, etc.). Une façon classique de tester de tels systèmes est de les placer dans un environnement irradié, provoqué par exemple par un accélérateur de particules, et de vérifier leur fonctionnement en tenant compte du nombre d'impacts qu'ils reçoivent. On conçoit que de telles vérifications sont très lourdes, surtout si on tient compte du fait qu'elles doivent être réalisées"en ligne", c'est-à-dire que le circuit testé doit accomplir les fonctions pour lesquelles il a été conçu pour l'application considérée pendant l'exposition aux particules. En outre, quand elles sont réalisées sur des processeurs à l'aide de stratégies dites statiques, ces méthodes donnent des résultats parfois très éloignés de la réalité. En effet, un impact sur un circuit intégré, même s'il provoque un changement d'état du contenu d'une case mémoire peut n'avoir en pratique aucune influence sur le fonctionnement d'un programme tournant sur ce circuit. Ainsi, la présente invention vise un procédé d'injection d'erreur de bit (s) en des emplacements quelconques d'un circuit intégré tandis qu'un programme principal est exécuté sur ce circuit. Plus particulièrement encore, la présente invention vise un procédé dans lequel l'injection d'erreur fictive est réalisée par l'intermédiaire d'un programme d'interruption. Un tel procédé a par exemple été proposé dans l'article de R. Velazco et S. Rezgui"Transient Bitflip Injection in Microprocessor Embedded Applications"paru dans Proceedings of 6th IEEE International on-line testing workshop, 3-5 juillet 2000, Palma de Majorque, PP 80-84. En d'autres termes, la présente invention concerne une architecture numérique organisée autour d'un processeur capable d'exécuter une séquence d'instructions ou de commandes stockée dans une mémoire (externe ou interne) et de prendre en compte l'effet de signaux d'entrée asynchrones tels que des interruptions. Le processeur peut être programmé pour réaliser de façon directe ou indirecte des opérations de lecture et d'écriture dans chacun des emplacements de la mémoire externe, ainsi que des registres et zones de mémoire interne. Des basculements de bits uniques ou basculements, ou événements, couramment désignés par le sigle SEU d'après l'expression anglo-saxonne Single Event Upset peuvent être provoqués dans des processeurs comme conséquence de l'exécution d'un code adéquat qui dépendra essentiellement de certaines caractéristiques de la cible. Ce code sera appelé ici CEU (Code Emulating an Upset). De même l'emplacement mémoire perturbé par suite de l'exécution du code CEU sera appelé la cible du CEU. Les basculements qui résultent de l'exécution du code CEU seront appelés également CEU (Code Emulated Upset). En réponse à l'activation d'une interruption, un processeur déroulera typiquement les étapes suivantes : - arrêt de l'exécution du programme en cours après avoir complété l'exécution de l'instruction courante, - sauvegarde du contexte (au moins la valeur de retour du compteur de programme PC dans une pile), - branchement vers le programme de traitement de l'interruption provoquant l'inversion du ou des bits cibles choisis, - restauration du contexte depuis la pile pour continuer l'exécu- tion du programme interrompu. Il suffit donc d'activer l'interruption à différents moments de l'exécution d'un programme pour provoquer l'injection de basculement de bits par des moyens logiciels. En pratique, cette injection d'erreurs au moyen d'un programme d'interruption se fait relativement facilement dans le cas où la cible est un registre ou mot mémoire accessible directement par le programme d'interruption. Toutefois, il se pose des difficultés pratiques à mettre en oeuvre le procédé quand la cible est ou bien un registre ou un mot mémoire non accessible directement, ou bien le registre stockant le compteur de programme, ou bien encore le registre stockant le pointeur de la pile dans laquelle est stocké le contexte du programme principal au moment de l'interruption. Ainsi, la présente invention vise à accéder à toutes les zones mémoire d'un processeur qui sont accessibles par l'intermédiaire du jeu d'instruction de tout programme associé à ce processeur. Par exemple, dans le cas du processeur 8051 d'Intel, ces zones mémoire accessibles comprennent notamment les accès d'entrée/sortie, les accumulateurs, les registres spéciaux, le registre compteur de programme et la mémoire RAM interne. Seule un très petit nombre des zones mémoire d'un processeur reste inaccessible à l'introduction de CEU. Ces zones comprennent notamment les registres d'entrée de l'unité arithmétique et logique, des bascules à mémoire (latch), des registres d'adresse, et la mémoire cache. Un calcul effectué dans le cas du micropro- cesseur 8051 et qui peut s'étendre à de nombreux types de microprocesseurs montre que ces zones non accessibles représentent moins de 7 % de l'ensemble des zones mémoire du processeur. Grâce à l'efficacité de l'injection d'erreur selon la présente invention, il devient possible d'évaluer un taux d'erreurs réel pour un processeur donné associé à un programme donné. Ce taux d'erreurs réel ou sensibilité du système peut être évalué par le calcul. Tout d'abord, pour un processeur donné soumis à un bombardement de particules, on peut déterminer un nombre P tel qu'une seule particule parmi P est susceptible de provoquer une erreur de bits (un CEU). La présente invention permet de montrer que sur N SEU, n seulement sont susceptibles de perturber un programme donné tournant sur processeur donné. Alors, la sensibilité du système peut être estimée comme égale à n/NP. Une fois que l'on a validé l'exactitude du mode de détermination du taux d'erreurs réel obtenu en soumettant un dispositif auquel on a appliqué le procédé de détermination d'erreur selon la présente invention à des conditions réelles, par exemple de travail dans l'espace, on peut appliquer la méthode à un système constitué du même élément matériel sur lequel tourne un autre logiciel. On pourra être certain que le procédé selon la présente invention fournit un résultat correct et il ne sera pas nécessaire de refaire une validation dans des conditions de perturbations réelles ou simulées puisque P est constant pour un matériel donné et un type de particules donné. On notera également que le procédé d'analyse de sensibilité d'un système à des perturbations de type CEU peut être réalisé de manière totalement aléatoire ou de façon systématique. Une analyse systématique pourra notamment être effectuée pour un programme donné sur les étapes successives de déroulement de ce programme. On s'aperçoit alors généralement que certaines phases du programme sont peu sensibles aux CEU alors que d'autres le sont nettement plus. On peut ainsi définir pour chaque programme des fenêtres de sensibilité. Ceci peut être utile dans des systèmes prévoyant des redondances pour ne réaliser des opéra- tions redondantes que sur des parties particulièrement sensibles d'un programme donné. Pour atteindre cet objet, la présente invention prévoit un procédé d'injection d'erreurs de bits dans un matériel opérant sous la commande d'un programme principal donné, consistant à procéder à une interruption et à introduire l'erreur de bit pendant le déroulement du programme d'interruption, dans lequel, au moment de l'interruption, la valeur de retour du registre de compteur de programme et éventuellement le contenu d'autres registres tels que des registres d'indicateurs d'état sont mémorisés dans une pile sous le contrôle d'un pointeur de pile. Quand l'erreur doit être injectée dans un mot mémoire cible stocké à un emplacement non accessible directement, le programme d'interruption comprend les étapes suivantes : mettre dans la pile le contenu d'un registre, transférer dans le registre le contenu du mot mémoire cible, modifier dans le registre le contenu recopié du mot mémoire cible pour y injecter l'erreur choisie, transférer le mot mémoire cible modifié à son emplacement d'origine, désempiler le registre, et terminer le programme d'interruption et revenir à l'adresse du programme principal indiquée par le compteur de programme. Quand l'erreur doit être injectée dans le registre de compteur de programme, le programme d'interruption comprend les étapes suivantes : mettre dans la pile le contenu d'un premier registre, mettre dans la pile le contenu d'un accumulateur, transférer la valeur du registre de pointeur de pile (correspondant à l'adresse dans la pile de l'adresse de retour du compteur de programme) dans le premier registre, transférer le contenu du registre de compteur de programme tel qu'indiqué par le premier registre dans l'accumu- lateur, modifier la valeur du compteur de programme dans l'accumulateur pour y injecter l'erreur choisie, recharger la valeur du compteur de programme modifiée dans la pile à l'adresse contenue dans le premier registre, désempiler l'accumulateur, et désempiler le premier registre. Quand l'erreur doit être injectée dans un registre de pointeur de pile, le programme d'interruption comprend les étapes suivantes : écrire à une adresse déterminée un code de saut inconditionnel vers une case mémoire déterminée, pointer au moyen du pointeur de pile vers la valeur de retour du compteur de programme, transférer le contenu du pointeur de pile dans un premier registre, transférer l'adresse de retour du compteur de programme stockée dans la pile dans un deuxième registre, transférer le contenu du deuxième registre à la suite dudit code de saut inconditionnel, modifier le premier registre pour injecter l'erreur choisie dans le registre pointeur de pile un saut inconditionnel vers ladite adresse déterminée du saut inconditionnel mentionné en premier pour obtenir la valeur de retour du programme principal. Ces objets, caractéristiques et avantages, ainsi que d'autres de la présente invention seront exposés en détail dans la description suivante de modes de réalisation particuliers faite à titre non-limitatif en relation avec les figures jointes parmi lesquelles : la figure 1 est une représentation symbolique d'éléments d'un système matériel/logiciel auquel s'applique la présente invention ; et les figures 2 à 5 représentent des exemples de séquences de programme d'interruption respectivement applicables à un registre accessible directement, à un registre à accès indirect, au compteur de programme, et au pointeur de pile. La figure 1 représente sous forme symbolique des éléments d'un système matériel/logiciel. On a représenté un programme principal 10 que l'on pourra considérer ou bien d'un point de vue logique comme une succession d'instructions ou bien d'un point de vue matériel comme une mémoire contenant les instructions. Le système comprend également un ou plusieurs programmes d'interruption 20 et une pile 30 ainsi qu'un pointeur de pile 40. Dans une architecture d'ordinateur classique, lorsqu'un ordre d'interruption est lancé à une étape 10 (i) d'un programme principal 10, plusieurs opérations sont effectuées : - on termine l'exécution de l'instruction 10 (i) en cours ; - on sauvegarde le contexte du programme, c'est-à-dire essentiellement la valeur du compteur du programme PC correspondant à l'adresse de retour (10 (i+1)) du programme principal, et éventuellement le contenu de divers registres indicateurs d'état (flag) et d'autres paramètres clés du système ; cette sauvegarde du contexte est classiquement effectuée dans une pile 30 du type premier-entré/dernier-sorti sous le contrôle d'un registre pointeur de pile (SP) 40 ; - on passe à la première étape (START) du programme d'interruption 20. Ceci a été représenté symboliquement en figure 1 en indiquant qu'une interruption IT est susceptible de survenir à l'étape 10 (i), que l'on passe alors à la phase START du programme d'interruption 20, que cette phase START contrôle le pointeur de pile 40 qui pointe vers la pile 30 (classiquement, on considère que le pointeur de pile SP pointe vers la dernière case libre de la pile). Une fois ces opérations initiales effectuées, le programme d'interruption se déroule jusqu'à arriver à sa phase finale END. A ce moment, il fournit un ordre au pointeur de pile pour réaliser le désempilement du contenu de la pile, c'est-àdire que toutes les informations relatives au contexte qui ont été mémorisées au moment de l'interruption sont remises à jour dans leurs emplacements d'origine. A la dernière étape de ce désempilement, on arrive au contenu du compteur de programme qui correspond à l'adresse i+1 du programme principal et on reprend le programme à l'étape 10 (i+1) comme cela est symbolisé par la liaison 31. Comme on l'a rappelé précédemment, l'objet de l'invention est d'introduire des erreurs de bits simples ou multiples (SEU) à partir de codes CEU génériques à tout emplacement choisi du système lors d'une étape choisie du déroulement du programme principal. 1. Injection d'erreur dans un registre à accès direct Un exemple de programme d'interruption destiné à permettre une injection d'erreur dans un registre ou mot mémoire accessible directement est illustré de façon très symbolique en figure 2. Lors d'une première étape 201 d'initialisation (START), on transfère dans la pile 30 l'adresse contenue dans le compteur de programme ou plus exactement l'adresse de retour [10 (i+1)] du compteur de programme. Lors d'une étape optionnelle 202, on transfère (push) dans la pile 30, si cela n'est pas déjà prévu par le programme normal d'interruption du système concerné, des indicateurs d'état (flag ou F) et éventuellement d'autres registres clé. A l'étape 203, on réalise le changement (chg) d'une ou plusieurs positions de bits (pos. bit) dans un mot mémoire accessible directement. L'étape 204 est une étape optionnelle qui est réalisée si l'étape 202 a été réalisée à savoir que l'on désempile (pop) les éléments du contexte de l'ordinateur qui ont été empilés à l'étape 202 au moment de l'interruption. Un programme d'interruption se termine classiquement par une étape finale 205 qui renvoie à la continuation de l'exécution du programme interrompu. On notera que le programme de la figure 2 est particulièrement simple à mettre en oeuvre et que, classiquement, il ne nécessite qu'une instruction pour le changement de position d'un bit dans la cible. Ce changement se fait en pratique au niveau du registre concerné par une opération de OU-Exclusif (XOR) entre le contenu du registre concerné et un masque contenu dans le code CEU. 2. Injection d'erreur dans un registre à accès indirect Un exemple de programme d'interruption destiné à permettre une injection d'erreur dans un registre ou mot mémoire non accessible directement est illustré en figure 3. Les étapes initiales 301 et 302 sont identiques aux étapes 201 et 202 décrites en relation avec la figure 2. A l'étape 303, le programme met dans la pile (push) le contenu d'un registre ou accumulateur ACC. A l'étape 304, on transfère (Ld) dans le registre ACC le contenu de la zone de mémoire interne (ZMI) cible. A l'étape 305, on effectue la modification recherchée au mot mémoire cible. Cette modification est maintenant effectuée dans le registre ACC qui est accessible, de façon similaire à la modification décrite en relation avec l'étape 203 de la figure 2. A l'étape 306, le contenu modifié du registre ACC est renvoyé vers la zone mémoire dans laquelle se trouvait le mot cible. Ensuite, on procède à une étape de désempilement 307 complémentaire de l'étape d'empilement 302 pour remettre dans l'accumulateur ACC sa valeur d'origine avant l'exécution des opérations susmentionnées. Le programme se termine par des étapes 308 et 309 respectivement similaires aux étapes 204 et 205 décrites en relation avec la figure 2. 3. Injection d'erreur dans le compteur de programme (PC) Un programme d'interruption permettant l'injection d'erreur dans le compteur de programme est illustré en figure 4. Dans ce cas, une difficulté particulière se pose du fait que le compteur de programme contrôle le séquencement des étapes d'exécution d'un programme et que, quand il est perturbé, il devient difficile d'exécuter correctement le programme. Un programme d'injection d'erreur dans le contenu du compteur programme selon un mode de réalisation de la présente invention, commence par des étapes 401 et 402 similaires aux étapes 201 et 202 décrites en relation avec la figure 2. A l'étape 403, on met dans la pile le contenu d'un premier registre RO. A l'étape 404, on incorpore également dans la pile le contenu d'un deuxième registre ACC, couramment appelé accumulateur. A l'étape 405, on transfère dans le registre RO, le contenu du pointeur de pile SP qui correspond à l'adresse dans la pile de l'adresse de retour du compteur de programme. A l'étape 406, on transfère dans l'accumulateur ACC le contenu (CP) du registre de compteur de programme tel qu'indiqué par le premier registre RO. C'est alors seulement qu'à l'étape 407, on effectue l'injection d'erreur choisie sur le contenu du registre ACC, c'est-à-dire la valeur du compteur de programme. A l'étape 408, on retransfère le contenu du registre ACC dans la pile à l'adresse indiquée par le registre RO. Les opérations sont alors terminées et l'on procède ensuite successivement à l'étape 409 au désempilage de l'accumulateur, à l'étape 410 au désempilage du registre RO, et aux étapes 411 et 412 aux étapes finales similaires aux étapes 204 et 205. 4. Injection d'une erreur dans le pointeur de pile (SP) Un programme d'interruption permettant l'injection d'erreur dans le pointeur de pile est illustré en figure 5. L'injection d'une erreur dans le pointeur de pile pose un problème particulier car si le pointeur de pile est perturbé lors du programme d'interruption, on ne peut a priori pas reprendre le déroulement du programme interrompu après l'exécution du programme d'interruption puisque le désempilement ne peut plus se dérouler normalement. En conséquence, la présente invention propose un procédé très spécifique incorporant des étapes de saut inconditionnel pour l'injection d'une erreur dans le pointeur de pile et le retour au programme interrompu. Un programme d'injection d'erreur dans le contenu du pointeur de pile selon un mode de réalisation de la présente invention, commence par des étapes 501 et 502 similaires aux étapes 201 et 202 décrites en relation avec la figure 2. A l'étape 503-504, on écrit à une adresse déterminée (adbranch) un code (JMP) de saut inconditionnel vers une case mémoire déterminée. Cette opération se fait généralement en passant par un registre R. A l'étape 505, on pointe (DEC) au moyen du pointeur de pile vers la valeur de retour du compteur de programme, A l'étape 506, on transfère le contenu du pointeur de pile (l'adresse dans la pile de l'adresse de retour du compteur de programme) dans un premier registre RI, A l'étape 507, on transfère l'adresse de retour du compteur de programme stockée dans la pile dans un deuxième registre R2. A l'étape 508, on transfère le contenu du deuxième registre à l'adresse (adbranch+1) qui suit l'adresse (adbranch) à laquelle on a écrit ledit code de saut inconditionnel, de façon à fixer l'adresse (celle qui contient la valeur de retour du compteur de programme) vers laquelle renverra le saut inconditionnel. A l'étape 509, on modifie le premier registre R1 pour injecter l'erreur choisie dans le registre pointeur de pile. A l'étape 510, on exécute un premier saut inconditionnel vers l'adresse (adbranch) à laquelle on a écrit ledit code de saut inconditionnel et on exécute ce saut inconditionnel pour arriver à la valeur de retour du programme principal. On notera que le programme ne se termine pas par des étapes de désempilement qui ne sont plus réalisables puisque le pointeur de pile a été perturbé. De façon générale, quelle que soit la cible du CEU, on notera que, pour la plupart des processeurs, les jeux d'instructions nécessaires à l'injection d'erreur selon l'invention permettent la réalisation de ces tâches en seulement quelques instructions en langage assembleur. Ces instructions, une fois compilées, donneront lieu à des codes d'au plus quelques dizaines de mots. L'aspect crucial pour simuler un SEU réside dans l'insertion de ces codes dans le programme en cours d'exécution pour qu'ils soient exécutés à l'instant souhaité pendant l'exécution d'un programme quelconque. Pour que l'erreur injectée reproduise fidèlement les SEU survenant comme conséquence de l'effet des radiations, l'exécution de ce code doit avoir pour seul effet la corruption de la valeur de la cible du SEU, laissant inchangés les autres éléments de mémorisation du processeur. La présente invention pourra être adaptée sans difficulté par l'homme de l'art du domaine de la programmation à des dispositions spécifiques matérielles ou logicielles. Notamment si la dimension des registres et autres mots mémoires destinés à être transférés d'une position à une autre est plus grande que la dimension de la case, registre ou pile vers lequel le transfert doit être effectué, le transfert pourra être décomposé en plusieurs transferts élémentaires, par exemple en séparant les bits les plus significatifs des bits les moins significatifs. REVENDICATIONS 1. Procédé d'injection d'erreurs de bits dans un matériel opérant sous la commande d'un programme principal donné, consistant à procéder à une interruption et à introduire l'erreur de bit pendant le déroulement du programme d'interruption, dans lequel, au moment de l'interruption, la valeur de retour du registre de compteur de programme (PC) et éventuellement le contenu d'autres registres tels que des registres d'indicateurs d'état sont mémorisés dans une pile sous le contrôle d'un pointeur de pile (SP), caractérisé en ce que, quand l'erreur doit être injectée dans un mot mémoire cible stocké à un emplacement non accessible directement, le programme d'interruption comprend les étapes suivantes : mettre dans la pile (303) le contenu d'un registre (ACC), transférer (304) dans le registre (ACC) le contenu du mot mémoire cible, modifier (305) dans le registre (ACC) le contenu recopié du mot mémoire cible pour y injecter l'erreur choisie, transférer (306) le mot mémoire cible modifié à son emplacement d'origine, désempiler (307) le registre (ACC), et terminer (308, 309) le programme d'interruption et revenir à l'adresse du programme principal indiquée par le compteur de programme (PC). 2. Procédé selon la revendication 1, caractérisé en ce que, quand l'erreur doit être injectée dans le registre de compteur de programme (PC), le programme d'interruption comprend les étapes suivantes : mettre dans la pile (403) le contenu d'un premier registre (R0), mettre dans la pile (404) le contenu d'un accumulateur (ACC), transférer (405) la valeur du registre de pointeur de pile (SP) (correspondant à l'adresse dans la pile de l'adresse de retour du compteur de programme) dans le premier registre (RO), transférer (406) le contenu du registre de compteur de programme (PC) tel qu'indiqué par le premier registre (RO) dans l'accumulateur, modifier (407) la valeur du compteur de programme dans l'accumulateur (A) pour y injecter l'erreur choisie, recharger (408) la valeur du compteur de programme (PC) modifiée dans la pile à l'adresse contenue dans le premier registre (RO), désempiler (409) l'accumulateur, et désempiler (410) le premier registre. 3. Procédé selon la revendication 1, caractérisé en ce que, quand l'erreur doit être injectée dans un registre de pointeur de pile (SP), le programme d'interruption comprend les étapes suivantes : écrire (503-504) à une adresse déterminée (adbranch) un code de saut inconditionnel (JMP) vers une case mémoire déterminée, pointer (505) au moyen du pointeur de pile vers la valeur de retour du compteur de programme (PC), transférer (506) le contenu du pointeur de pile (SP) dans un premier registre (RI), transférer (507) l'adresse de retour du compteur de programme (PC) stockée dans la pile dans un deuxième registre (R2), transférer (508) le contenu du deuxième registre (R2) à la suite dudit code de saut inconditionnel, modifier (509) le premier registre (RI) pour injecter l'erreur choisie dans le registre pointeur de pile (SP) exécuter (510) un saut inconditionnel vers ladite adresse déterminée du saut inconditionnel mentionné en premier pour obtenir la valeur de retour du programme principal.