Exécuter du code une fois dans la vie d'un programme C intégré

8

Comment puis-je exécuter un extrait de code une seule fois dans la durée de vie d'un programme? Il peut être désactivé et réactivé plusieurs fois. La seule option pour exécuter à nouveau l'extrait de code doit être de flasher à nouveau la carte.

Le code est une section d'étalonnage que je ne veux pas réexécuter. Si j'utilise EEPROM ou Flash, nous définirons un indicateur sur vrai ou faux. Ainsi, lorsque nous lisons pour la première fois cet emplacement de mémoire, quelle serait la valeur aléatoire dans cette zone de mémoire?

Quelle est la meilleure méthode pour implémenter cela en C embarqué?

ganeshredcobra
la source
5
Utilisez un drapeau et enregistrez ce drapeau sur eeprom (ou le flash). À chaque instant, lisez le drapeau de eeprom. La toute première fois de l'instant, la valeur du drapeau forcera la fonction à s'exécuter. Après cela, vous pouvez modifier la valeur du drapeau et l'enregistrer à nouveau dans eeprom. Toutes les autres fois, la valeur de l'indicateur ne forcera pas l'exécution de la fonction.
hoo2
2
pas clair ce que vous demandez.
old_timer
2
Quelle est votre motivation pour empêcher le code de s'exécuter une deuxième fois? Est-il important que le code ne puisse pas être rétroconçu, auquel cas la définition d'un indicateur pour le contourner peut ne pas être suffisamment sécurisée? Est-ce que l'exécution du code une deuxième fois endommagerait le matériel? Est-ce une chose UX, comme afficher un message de didacticiel la première fois que le système est utilisé, auquel cas il peut être souhaitable que la fonction "réinitialisation d'usine" (si présente) déclenche à nouveau le code?
Micheal Johnson
5
En général, c'est une bonne idée de permettre un recalibrage au cas où quelque chose se gâterait la première fois, ou si le système doit être recalibré pour une configuration différente ou pour compenser le vieillissement du matériel, etc. Par exemple, j'ai tendance à gâcher l'étalonnage du première fois parce que je ne sais pas ce que je suis censé faire.
Micheal Johnson
3
Que diriez-vous de configurer le code afin qu'il existe un moyen de le commander pour s'exécuter (c'est-à-dire envoyer quelque chose via un port série). De cette façon, il n'est pas nécessaire de s'occuper de la mémoire non volatile et vous pouvez déclencher l'étalonnage pendant la production de manière contrôlée.
alex.forencich

Réponses:

18

Votre microcontrôleur peut avoir de l'EEPROM, de la mémoire OTP, des bits de fusible utilisateur, où vous pouvez définir un indicateur.

Il n'y a pas de "meilleure méthode en C embarqué", l'écriture de mémoire non volatile est différente dans chaque microcontrôleur.

Éditer:

ÉCLAT

Le contenu de la mémoire flash est effacé lors de la programmation de l'appareil. Après la programmation, tous les octets non écrits contiennent 0xFF. Consultez la fiche technique pour trouver une zone qui peut être programmée en toute sécurité à partir du firmware en cours d'exécution.

EEPROM

Bien que cela ne soit pas garanti dans les fiches techniques, toutes les EEPROM que j'ai vues jusqu'à présent contenaient 0xFF: s lorsqu'elles sont expédiées de l'usine (sauf celles préprogrammées avec une adresse MAC unique, mais cela est explicitement documenté). Certains appareils / logiciels de programmation peuvent également effacer ou programmer le contenu de l'EEPROM. Certains peuvent être protégés en écriture, de façon permanente ou réversible.

OTP

La mémoire programmable unique contient toujours des valeurs initiales bien définies, documentées dans la fiche technique.

C'est toujours une bonne idée d'inclure une bonne somme de contrôle comme CRC32 avec les données écrites, pour se protéger contre la corruption de données causée par des pièces défectueuses, des erreurs de transmission, des rayons cosmiques, peu importe.

berendi - pour protester
la source
Si j'utilise EEPROM ou Flash, nous définirons un indicateur sur vrai ou faux. Ainsi, lorsque nous lirons pour la première fois cet emplacement de mémoire, quelle serait la valeur aléatoire dans cette zone de mémoire.
ganeshredcobra
2
Pendant la fabrication, réinitialisez l'EEPROM (avec un programmeur, si possible, ou en créant un petit programme d'essuyage stupide, flashez-le, allumez-le normalement pendant quelques secondes, puis chargez votre programme de production).
Nick T
13

Tu as dit:

La seule option pour exécuter ce code doit flasher à nouveau la carte.

D'autres ont dit d'utiliser EEPROM pour stocker un indicateur pour indiquer quand la fonction run_once () a été exécutée. Cependant, cela a un inconvénient qui est que si vous reflasher le microcontrôleur, le drapeau ran_it_once dans EEPROM a déjà été défini et la fonction run_once () ne sera pas exécutée. Si votre microcontrôleur a intégré l'EEPROM, il peut être possible d'effacer l'indicateur ran_it_once lorsque vous reflasher le microcontrôleur, si le programmeur le prend en charge.

Une meilleure façon consiste à avoir des numéros de version dans l'EEPROM et le code. Lorsque le code s'exécute à la mise sous tension, il doit lire le numéro de version de l'EEPROM et le comparer au numéro de version stocké dans le code. S'ils ne correspondent pas, la fonction run_once () est appelée et le dernier acte du code run_once () consiste à écrire le numéro de version du firmware dans l'EEPROM. Chaque fois que vous modifiez le code source du firmware, vous devez incrémenter le numéro de version intégré.

Steve G
la source
1
Cela aurait en fait le même problème qu'un indicateur booléen si tout ce que l'utilisateur faisait était de reflasher le microcontrôleur et qu'il devait être réexécuté (dans ce scénario). Cela résoudrait définitivement le problème si le micrologiciel était mis à jour et devait être réexécuté.
Taegost
8

Choisissez un microcontrôleur qui peut écrire / effacer sa propre mémoire de programme. Après avoir exécuté le code en question, demandez à la dernière partie dudit code de remplacer la première instruction par un saut qui la contourne. En option, vous pouvez également effacer le reste (peut-être le remplacer par nop), de sorte qu'il n'y a absolument aucune chance qu'il soit à nouveau exécuté.

Ce message s'autodétruit dans 5..4 ...

apalopohapa
la source
1
Aussi intelligente que puisse être cette réponse, je pense qu'elle est inutilement complexe. Peut-être pourrait-il utiliser une note spécifiant qu'il ne devrait probablement être utilisé que si la mémoire persistante en dehors de la mémoire de code n'est pas disponible?
skrrgwasme
Même si d'autres solutions sont possibles, je pense que c'est plus facile à comprendre que les autres.
Joshua
1
Même si d'autres solutions étaient possibles, je pense que cela serait très difficile à comprendre au niveau du code source.
un CVn du
La plupart des PIC n'ont que 35 instructions ... qu'est-ce qui pourrait mal tourner? ;)
rdtsc
5

Comme vous utilisez ce code pour l'étalonnage, ma suggestion serait de créer un processus de souffle qui exécute le code d'étalonnage comme première étape et ne pas même l'avoir sur la version de production finie de la carte. Ceci est similaire à la réponse de apalopohapa, sauf différent dans le sens où vous auriez deux charges de programme distinctes: avoir un processus de souffle qui flashe la première charge de programme qui exécute tous les étalonnages et crache les données de cela. Prenez ensuite ces données et incorporez-les aux données de la deuxième charge de programme.

L'un des avantages de cette approche est que vous minimisez absolument la quantité d'espace de stockage dont vous avez besoin - vous n'avez pas besoin de stocker votre code unique, uniquement les données qu'il génère. En ayant un processus de souffle qui charge deux programmes distincts, vous vous isolez également un peu des bogues dans le code d'initialisation qui pourraient persister autrement. Vous avez également une certaine flexibilité supplémentaire si vous souhaitez réexécuter votre code d'étalonnage: au lieu d'avoir à écrire du code supplémentaire pour effacer tout bit indiquant que votre code a été exécuté (ce qui pourrait déjà être effacé accidentellement), vous réexécutez simplement votre processus de souffle.

Michael
la source