J'ai rencontré de nombreux projets dans lesquels un microcontrôleur AVR utilise un chargeur de démarrage (tel que l'Arduino), mais je ne comprends pas très bien le concept.
Comment puis-je créer un chargeur de démarrage (pour n'importe quel microcontrôleur)?
Après avoir écrit mon chargeur de démarrage, comment est-il programmé sur le microcontrôleur (comme tout programme .hex gravé sur la mémoire flash de l’AVR, ou une autre méthode)?
microcontroller
avr
bootloader
mina_g
la source
la source
Réponses:
Un chargeur de démarrage est un programme qui s'exécute dans le microcontrôleur à programmer. Il reçoit les nouvelles informations de programme de manière externe via certains moyens de communication et les écrit dans la mémoire de programme du processeur.
Ceci est en contraste avec la manière habituelle de faire entrer le programme dans le microcontrôleur, via un matériel spécial intégré au micro à cette fin. Sur les PIC, il s'agit d'une interface de type SPI. Si je me souviens bien, les AVR utilisent Jtag, ou du moins certains d'entre eux. Quoi qu'il en soit, cela nécessite un matériel externe qui remue les broches de programmation juste pour écrire les informations dans la mémoire du programme. Le fichier HEX décrivant le contenu de la mémoire du programme provient d'un ordinateur à usage général. Ce matériel se connecte donc à l'ordinateur d'un côté et aux broches de programmation spéciales du micro de l'autre. Ma société fabrique des programmeurs PIC entre autres comme activité secondaire. Je connais donc assez bien ce processus pour les PIC.
Le point important de la programmation externe via un matériel spécialisé est qu’il fonctionne indépendamment du contenu existant de la mémoire programme. Les microcontrôleurs démarrent avec la mémoire de programme effacée ou dans un état inconnu. La programmation externe est donc le seul moyen de transférer le premier programme dans un micro.
Si vous êtes sûr du programme que vous souhaitez charger dans votre produit et que vos volumes sont suffisamment élevés, vous pouvez demander au fabricant ou à un distributeur de programmer des puces. La puce est soudée à la carte comme n'importe quelle autre puce et l'unité est prête à fonctionner. Cela peut être approprié pour quelque chose comme un jouet, par exemple. Une fois le micrologiciel terminé, c'est à peu près terminé et il sera produit en gros volumes.
Si vos volumes sont inférieurs ou, plus important encore, si vous attendez du développement de microprogrammes et des corrections de bogues en cours, vous ne souhaitez pas acheter de puces préprogrammées. Dans ce cas, des puces vierges sont montées sur la carte et le micrologiciel doit être chargé sur la puce dans le cadre du processus de production. Dans ce cas, les lignes de programmation matérielles doivent être mises à disposition. Cela peut être via un connecteur explicite, ou des pin pads pogo si vous êtes prêt à créer un montage de test de production. De tels produits doivent souvent être testés et éventuellement calibrés. Le coût supplémentaire de l’écriture du programme sur le processeur est généralement minime. Parfois, lorsque de petits processeurs sont utilisés, un microprogramme de test de production spécial est d'abord chargé dans le processeur. Ceci est utilisé pour faciliter les tests et le calibrage de l'unité, alors le vrai firmware est chargé après que le matériel soit connu pour être bon. Dans ce cas, certaines considérations relatives à la conception du circuit permettent un accès suffisant aux lignes de programmation pour que le processus de programmation fonctionne, mais également pour ne pas trop gêner le circuit. Pour plus de détails à ce sujet, voir monrédaction de la programmation en circuit .
Jusqu'ici tout va bien, et aucun chargeur de démarrage n'est nécessaire. Toutefois, envisagez un produit avec un micrologiciel relativement complexe que vous souhaitez mettre à niveau sur site ou même autorisez le client final à effectuer la mise à niveau. Vous ne pouvez pas vous attendre à ce que le client final ait un gadget de programmation ou sache l’utiliser correctement, même si vous en avez fourni un. En fait, un de mes clients le fait. Si vous achetez leur option spéciale de personnalisation sur le terrain, vous obtenez l'un de mes programmeurs avec le produit.
Cependant, dans la plupart des cas, vous voulez simplement que le client exécute un programme sur un PC et que le firmware soit mis à jour comme par magie. C’est là qu’un chargeur de démarrage entre en jeu, en particulier si votre produit dispose déjà d’un port de communication permettant une interface simple avec un PC, tel que USB, RS-232 ou Ethernet. Le client exécute un programme PC qui communique avec le chargeur de démarrage déjà présent dans le micro. Cela envoie le nouveau fichier binaire au chargeur de démarrage, qui l'écrit dans la mémoire programme et entraîne l'exécution du nouveau code.
Cela semble simple, mais ce n'est pas le cas, du moins si vous voulez que ce processus soit robuste. Que se passe-t-il si une erreur de communication se produit et que le nouveau micrologiciel est corrompu au moment où il arrive au chargeur de démarrage? Que se passe-t-il si le courant est interrompu pendant le processus de démarrage? Et si le chargeur de démarrage a un bug et craps sur lui-même?
Un scénario simpliste est que le chargeur de démarrage est toujours exécuté à partir de la réinitialisation. Il essaie de communiquer avec l'hôte. Si l'hôte répond, il indique alors au chargeur de démarrage qu'il n'a rien de nouveau ou lui envoie un nouveau code. Lorsque le nouveau code arrive, l'ancien code est écrasé. Vous incluez toujours une somme de contrôle avec le code téléchargé afin que le chargeur de démarrage puisse dire si la nouvelle application est intacte. Sinon, il reste dans le chargeur de démarrage en demandant constamment un téléchargement jusqu'à ce que quelque chose avec une somme de contrôle valide soit chargé en mémoire. Cela peut être acceptable pour un périphérique toujours connecté et éventuellement lorsqu'une tâche en arrière-plan est exécutée sur l'hôte et qui répond aux demandes du chargeur de démarrage. Ce système ne convient pas aux unités largement autonomes qui ne se connectent qu'occasionnellement à un ordinateur hôte.
Habituellement, le chargeur de démarrage simple décrit ci-dessus n'est pas acceptable, car il n'y a pas de sécurité intégrée. Si une nouvelle image d'application n'est pas reçue intacte, vous voulez que l'appareil continue d'exécuter l'ancienne image et ne soit pas mort tant qu'un téléchargement réussi n'a pas été effectué. Pour cette raison, il existe généralement deux modules spéciaux dans le micrologiciel, un téléchargeur et un chargeur de démarrage. Le téléchargeur fait partie de l'application principale. Dans le cadre des communications régulières avec l'hôte, une nouvelle image d'application peut être téléchargée. Cela nécessite une mémoire séparée de l'image principale de l'application, comme une EEPROM externe ou un processeur plus important, de sorte que la moitié de la mémoire programme puisse être allouée au stockage de la nouvelle image d'application. Le téléchargeur écrit simplement la nouvelle image d'application reçue quelque part, mais ne l'exécute pas. Lorsque le processeur est réinitialisé, ce qui peut arriver sur commande de l'hôte après un téléchargement, le chargeur de démarrage s'exécute. Il s’agit maintenant d’un programme totalement autonome qui n’a pas besoin de capacités de communication externes. Il compare les versions actuelle et téléchargée des applications, vérifie leurs sommes de contrôle et copie la nouvelle image dans la zone d'application si les versions diffèrent et les nouvelles vérifications de contrôle de l'image. Si la nouvelle image est corrompue, il exécute simplement l'ancienne application comme auparavant.
J'ai fait beaucoup de chargeurs de démarrage, et il n'y en a pas deux pareils. Il n'y a pas de chargeur de démarrage à usage général, malgré ce que certaines sociétés de microcontrôleurs veulent que vous croyiez. Chaque appareil a ses propres exigences et circonstances spéciales pour traiter avec l'hôte. Voici quelques-unes des configurations de chargeur de démarrage et parfois de téléchargement que j'ai utilisées:
Comme le chargeur de démarrage était lui-même un morceau de code complexe contenant une pile réseau TCP complète, il devait également être mis à niveau sur site. Nous avions pour objectif que le serveur de téléchargement alimente une application spéciale dont le seul but était d’écraser le chargeur de démarrage une fois celui-ci exécuté, puis de réinitialiser la machine afin que le nouveau chargeur de démarrage s’exécute, ce qui obligerait le serveur de téléchargement à envoyer le message. dernière image principale de l'application. Techniquement, un problème de puissance pendant les quelques millisecondes nécessaires à l'application spéciale pour copier une nouvelle image sur le chargeur de démarrage constituerait un échec irrémédiable. En pratique, cela n'est jamais arrivé. Cela nous convenait très peu, car ces périphériques faisaient partie de grandes installations où il y avait déjà des personnes chargées de la maintenance du système, ce qui impliquait parfois de remplacer les périphériques intégrés pour d'autres raisons.
Si tout va bien, vous constaterez qu'il existe un certain nombre d'autres possibilités, chacune avec ses propres compromis de risque, de rapidité, de coût, de facilité d'utilisation, de temps d'arrêt, etc.
la source
Imaginez ce scénario: votre microcontrôleur dispose d'une quantité de stockage suffisante, suffisante pour stocker plus de 2 ou 3 programmes ou applications indépendants les uns des autres. Supposons que lorsque vous démarrez votre appareil, vous souhaitiez pouvoir choisir lequel exécuter. Alors, de quoi auriez-vous besoin pour supporter cela? Vous auriez besoin d'un programme de démarrage qui vous permet ensuite de choisir entre les autres au démarrage.
Un programme d'amorçage est ce programme - c'est la première chose à exécuter. Il peut charger d'autres applications dans des emplacements spécifiques de la mémoire (soit persistant comme FLASH, soit volatile comme de la RAM), puis passe au programme souhaité où il prendra ensuite en charge l'exécution. .
Je n'ai jamais fabriqué de chargeur de démarrage, mais voici comment je pense que je m'y prendrais bien: commencez à écrire un programme de firmware comme vous le feriez normalement - mais assurez-vous qu'il est placé dans une zone telle que c'est toujours la première chose à faire fonctionner l'appareil démarre. D’emblée, certaines des fonctionnalités que je souhaiterais utiliser dans ce petit programme: possibilité de télécharger un nouveau programme vers un emplacement disponible en mémoire, d’effacer un programme précédemment chargé, de choisir le programme à exécuter (s’il existe plus de un), et avoir une sorte de structure de données de stockage (table de saut évolutive?) pour pouvoir se rappeler où sont les autres programmes et y accéder directement. L'interaction pourrait se faire sur UART, où il peut vous présenter un menu de terminal très simple et la possibilité de télécharger un micrologiciel sur ce même canal.
S'il s'agit d'une puce totalement vierge sans aucun chargeur de démarrage existant pouvant se mettre à jour, vous devrez alors graver en FLASH de la même manière que vous avez décrit à l'aide de la technique requise (ICSP dans le cas d'AVR).
Ceci n’est nullement exhaustif sur ce que sont les "chargeurs de démarrage". En fonction de ce que vous voulez sur l'un des systèmes ou sur le système pour lequel ils ont été conçus, vous pouvez en concevoir un pour télécharger des éléments à un emplacement spécifié dans la RAM au lieu de FLASH et commencer l'exécution à n'importe quel emplacement de mémoire arbitraire. Ou vous en voulez peut-être un qui soit capable de choisir le système d’exploitation à charger lors du démarrage de votre PC (voir grub par exemple). Les chargeurs de démarrage pour les microcontrôleurs 8 bits ont tendance à être très simples.
Remarque à propos d'Arduino: ce chargeur de démarrage ne gère qu'un seul programme, autant que je sache, mais il prend également en charge le port série pour gérer le téléchargement du micrologiciel et d'autres éléments .
la source
Le concept de chargeur "d'amorçage" est similaire au concept "d'amorçage" d'une pompe. En d'autres termes, vous avez besoin de "quelque chose" qui charge un programme à une adresse donnée, puis commence à exécuter le programme à cette adresse donnée. Ce quelque chose, c'est le chargeur de démarrage. Dans le cas le plus simple, le chargeur de démarrage "apparaît" à l'adresse de départ spécifiée par la CPU (zéro, très probablement), charge le programme dans le segment de mémoire requis, y transfère le contrôle et "disparaît". L'apparition et la disparition sont contrôlées par du matériel "externe". Une implémentation possible consisterait à utiliser une ROM activée par une réinitialisation "matérielle" et désactivée par une réinitialisation "logicielle". Le chargeur dans la ROM peut être aussi simple ou aussi complexe que nécessaire, et doit être écrit sous la forme binaire que le processeur particulier comprend. Si l'espace d'adressage utilisé par la ROM n'est pas nécessaire, la désactivation de la ROM n'est pas requise. Bien évidemment, EEPROM, ePROM, flash PROM, etc. pourraient être utilisés à la place de la ROM.
la source