Actuellement, j'ai un numéro de série codé en dur dans mon firmware pour une conception avec laquelle je travaille. Le micrologiciel peut lire et signaler le numéro de série. Cela fonctionne bien pour ce dont j'ai besoin. Le problème est que chaque nouveau numéro de série me demande de changer mon code et de recompiler. C'est lourd quand il y a beaucoup d'unités à construire, peut éventuellement introduire des erreurs et c'est une mauvaise pratique générale. Les numéros de série m'ont été donnés et la conception matérielle est gravée dans le marbre, donc je ne peux pas ajouter de fonctionnalités matérielles pour sérialiser les unités (EEPROM / puce ID silicone / Pull-Ups). Ce que je voudrais faire, c'est localiser le numéro de série à une adresse fixe, compiler le code une fois, puis modifier cette adresse dans le fichier HEX compilé pour chaque nouveau numéro de série. Le numéro est référencé à plusieurs endroits, donc idéalement, je veux le définir et le localiser une fois, puis référencez cette "variable" partout ailleurs dans mon code. Quelqu'un sait-il comment localiser des données constantes à un emplacement de mémoire adressable spécifique de mon choix, à l'aide du compilateur C18? Y a-t-il une meilleure façon de suggérer?
la source
Réponses:
Spécifiquement pour résoudre la question de la liaison des variables à des adresses spécifiques dans la mémoire flash sur le PIC18 avec le compilateur C18, veuillez référencer la section "Pragmas" dans hlpC18ug.chm dans le répertoire doc où le compilateur est installé.
Pour ce faire, vous devez définir une nouvelle "section" en mémoire et la lier à une adresse de début afin
#pragma romdata serial_no_section=0x1700
Cela crée une nouvelle section appelée "serial_no_section" qui commence à l'adresse 0x1700 dans la mémoire flash (programme) (car nous avons défini "romdata" dans le #pragma).
Directement après la ligne #pragma, définissez vos variables de la manière suivante:
Vous avez maintenant 0x12 à l'adresse 0x1700 et 0x34 à l'adresse 0x1701 en mémoire (car PIC18 utilise le modèle little-endian). Le "const rom" garantit que le compilateur sait qu'il s'agit d'un type de variable const, et que la variable se trouve dans la mémoire "rom" et doit donc être accessible via des instructions de lecture de table.
L'
#pragma romdata
instruction finale garantit que toutes les déclarations de variables suivantes sont liées aux sections de mémoire par défaut comme l'éditeur de liens voit les ajustements plutôt que de suivre dans la section "serial_no_section".Désormais, tout le code peut simplement référencer la variable "mySerialNumber", et vous savez exactement à quelle adresse le numéro de série se trouve en mémoire.
La modification du code HEX peut être un peu difficile car vous devez calculer la somme de contrôle pour chaque ligne que vous modifiez. Je travaille sur une classe C ++ pour décoder et encoder les fichiers Intel HEX, ce qui devrait faciliter les choses, mais ce n'est pas encore terminé. Le décodage des fichiers fonctionne, le codage n'est pas encore implémenté. Le projet (si vous êtes intéressé) est ici https://github.com/codinghead/Intel-HEX-Class
J'espère que cela t'aides
la source
J'ai fait le numéro de série (s / n pour faire court) d'une manière similaire à ce que Joel décrit. J'utilisais PIC18F4620 et le compilateur CCS. L'emplacement de s / n dans la mémoire Flash a été forcé sur les 4 derniers octets. Étant donné que j'utilisais seulement 80% de Flash, mon compilateur et l'éditeur de liens n'écriraient pas de code exécutable dans les 4 derniers octets.
Ensuite, j'ai eu 2 façons alternatives d'écrire réellement s / n dans des unités individuelles:
Répondre au commentaire de Joel
Je ne sais pas pour C18, mais le compilateur CCS est livré avec les fonctions de bibliothèque
write_program_eeprom(...)
etread_program_eeprom(...)
. Voici à quoi ils ressemblent en assemblage.la source
write_program_eeprom(...)
etread_program_eeprom(...)
. L'EEPROM et le Flash sont deux choses différentes!Je l'ai fait plusieurs fois. Habituellement, je définis une zone d'informations sur le firmware dans un emplacement fixe dans la mémoire du programme, puis j'écris un programme qui crée un fichier HEX sérialisé à partir du fichier HEX modèle. Ce sont toutes des choses faciles à faire.
En production, vous exécutez le programme de sérialisation une fois que tous les tests ont réussi. Il crée le fichier HEX temporaire avec le numéro de série unique, qui est programmé dans le PIC, puis le fichier HEX temporaire est supprimé.
Je ne laisserais pas l'emplacement être déplaçable, alors je devrais le trouver. Cela peut changer chaque version à mesure que l'éditeur de liens déplace les choses. Je l'ai fait pour de très petits PIC comme la série 10F où ces constantes font partie des instructions MOVLW. Dans ces cas, je le fais lire le fichier MAP à la volée pour déterminer où se trouvent ces emplacements. J'ai du code d'analyse de fichier MPLINK MAP dans une bibliothèque juste à cet effet.
Pour placer quelque chose dans un emplacement fixe, définissez un segment à une adresse fixe. L'éditeur de liens place d'abord ces segments absolus, puis ceux qui peuvent être déplacés autour de lui. N'oubliez pas d'utiliser CODE_PACK au lieu de simplement CODE sur un PIC 18, sinon vous aurez affaire à des mots d'instuction entiers au lieu d'octets individuels. Par exemple (juste tapé, pas passé devant l'assembleur):
la source
Je suggère de stocker le numéro de série dans une adresse fixe. Selon votre compilateur / éditeur de liens et la partie en question, vous pouvez adopter quelques approches:
la source
retlw
approche est souvent beaucoup plus rapide (sur les PIC de 18 bits, acall
à aretlw
prendra quatre cycles au total; l'utilisation enclrf TBLPTRU/movlw xx/movwf TBLPTRH/movlw xx/movwf TBLPTRL/tblrd *+/movf TABLAT,w
prendrait huit).Je ferais le contraire: compiler et lier le code, puis savoir où la valeur est stockée à partir du fichier de l'éditeur de liens. Vous devrez peut-être localiser la variable explicitement dans un segment mappé sur flash.
Je n'ai pas demandé cela, mais le logiciel PC que je fournis pour mon programmeur Wisp648 a la capacité de lire un fichier .hex, de modifier un emplacement spécifique et de réécrire le fichier .hex (dans le même fichier ou dans un autre fichier). Pas besoin d'avoir mon programmeur présent. La source est disponible (en Python), la licence permet toute utilisation: www.voti.nl/xwisp Peut être utile une fois que vous avez résolu votre problème principal.
la source