Télécharger le firmware sur STM32 via USB

image

Dans mon projet, j'utilise le microcontrôleur STM32F103C8 et le framework stm32duino . Ce clone d'Arduino propose un chargeur de démarrage spécial qui vous permet de télécharger le firmware via USB, sans utiliser de composants externes tels que l'adaptateur ST-Link ou USB-UART.

Aujourd'hui, je devais travailler avec un contrôleur nu sous CooCox et sans stm32duino. Mais voici le problème. Même une simple ampoule clignotante versée à travers ce chargeur de démarrage ne fonctionne pas.

Faisons les choses correctement. Peut-être mes calculs semblent-ils banals. Mais je commence tout juste à étudier les contrôleurs STM32 et j'ai tué au moins une demi-journée pour trouver le problème. Soudain, cet article raccourcira le temps de développement pour quelqu'un.

Je n'ai rien contre ST-Link et d'autres débogueurs. Mais dans mon appareil fini, ce ne sera pas le cas, mais il y aura certainement une clé USB. Pourquoi ne pas prévoir immédiatement la possibilité de mettre à jour le firmware via USB? Personnellement, je trouve cette méthode pratique. D'autant plus que de toute façon, j'ai déjà un cordon connecté auquel il y a de l'alimentation et USB Serial.

Voyons comment fonctionne le chargeur de démarrage. Pour commencer avec l'exemple des contrôleurs AVR. Pourquoi je me souviens de lui? Je suis passé d'Arduino et je m'attendais inconsciemment au même comportement. Mais dans STM32, tout s'est passé différemment. Par conséquent, je veux parler de la différence entre ces deux microcontrôleurs.

Alors. Dans les microcontrôleurs AVeg ATMega, une certaine quantité de mémoire peut être réservée pour le chargeur de démarrage vers la fin du flash. À l'aide de bits de fusible, vous pouvez contrôler à partir de quelle adresse le programme démarrera. S'il n'y a pas de chargeur de démarrage, le programme démarre à l'adresse 0x0000. S'il y a un chargeur de démarrage, il démarre à partir d'une autre adresse (par exemple, dans ATMega32 avec 0x3C00, si la taille du chargeur de démarrage est de 2k).

image

Lorsque le chargeur de démarrage a terminé son travail, il transfère le contrôle au programme principal à partir de l'adresse 0x0000. C'est-à-dire le programme démarre toujours à 0x0000. Le compilateur et l'éditeur de liens fonctionnent avec le fait que le code sera situé au début de l'espace d'adressage.

Dans les microcontrôleurs STM32, ce n'est pas le cas. Tous les programmes commencent à l'adresse 0x0800000. Un chargeur de démarrage n'est pas si spécial. Il s'agit du même programme qui démarre à partir de la même adresse de départ. Dans le processus, le chargeur de démarrage peut recevoir le firmware (via USB ou UART, lire à partir d'un lecteur flash USB, recevoir à partir d'un satellite, l'obtenir à partir d'un sous-espace, peu importe ...) et l'écrire à des adresses plus élevées que le chargeur de démarrage lui-même. Et, bien sûr, à la fin de son travail, transférez le contrôle au programme principal.

image

Ainsi, lors de la compilation du firmware, vous devez savoir où le chargeur de démarrage va écrire le firmware et ajuster les adresses en conséquence.

C'est tout avec la théorie. Passons à la pratique. Vous trouverez ci-dessous une instruction étape par étape sur la façon de fixer le chargeur de démarrage USB aux microcontrôleurs de la série STM32F1xx, et peut-être à d'autres également.

Il existe cependant certaines limites aux circuits. Ici, malheureusement, je ne suis pas fort. ITP a besoin d'une résistance de rappel de 1,5 k pour le port PA12 (alias USB D +). Cela permet au chargeur de démarrage de se connecter et de se déconnecter de l'USB au bon moment.

Instruction:

  • Téléchargez github.com/rogerclarkmelbourne/STM32duino-bootloader . Dans le répertoire STM32F1 \ binaries, il y a déjà un paquet de chargeurs de démarrage compilés pour différentes cartes. L'index à la fin du nom de fichier indique où la LED est connectée. Dans le cas de ma carte où la LED est connectée à la broche C13, j'ai utilisé le fichier generic_boot20_pc13.bin.

  • Nous flasherons selon les instructions . Oui, ici, vous aurez besoin d'un adaptateur USB-UART, mais vous pouvez également utiliser un débogueur .

  • Le microcontrôleur est maintenant prêt à flasher via le chargeur de démarrage USB. Mais vous devez toujours réparer le firmware lui-même. Et vous devez faire 2 choses:

    • Donnez à l'éditeur de liens une adresse de début. Dans CooCox, cela se fait dans les paramètres du projet, onglet Lien, section Zones de mémoire, Adresse de démarrage IROM1. Le chargeur de démarrage prend les 8 premiers kilo-octets, ce qui signifie que l'adresse de démarrage du micrologiciel sera 0x0800000 + 0x2000 = 0x08002000. Le champ Taille devrait probablement également être réduit de 8 Ko.

    • Quelque part au début du programme, avant d'initialiser la périphérie, faites un appel

      NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000); 


      MISE À JOUR 17/05/2018: Il n'y a pas de fonction NVIC_SetVectorTable () dans la version moderne de STM32Cube. Au lieu de cela, vous pouvez corriger le défaut VECT_TAB_OFFSET dans le fichier system_stm32f1xx.c (ou similaire pour un autre microcontrôleur)

  • Le remplissage du firmware peut être extrait du projet stm32duino . Dans le répertoire tools, recherchez un script appelé maple_upload. J'ai utilisé uniquement la version Windows - maple_upload.bat.

  • Courez comme ceci:

     "maple_upload.bat" COM20 2 1EAF:0003 "Path\To\Firmware.bin" 

    Au lieu de COM20, vous devez remplacer votre port où le microcontrôleur est connecté.

    Le verseur est une chose très tendre, il n'aime pas les chemins relatifs. le chemin vers le firmware doit donc être spécifié complètement.

    1EAF: 0003 est le VID et le PID

    2 - il s'agit du paramètre AltID, qui indique que le firmware doit être téléchargé à 0x08002000 (lire ici ).

Encore un peu de nuances. Avant de télécharger le firmware, vous devez exécuter le chargeur de démarrage. Le moyen le plus simple consiste à appuyer sur le bouton de réinitialisation. Après cela, le chargeur de démarrage démarrera et attendra quelques secondes le micrologiciel. Si personne n'a démarré maple_upload à ce moment, le chargeur de démarrage transférera le contrôle au micrologiciel principal.

Afin de ne pas appuyer sur reset à chaque fois, les cartes basées sur libmaple / stm32duino utilisent une astuce. Ils écoutent le port série USB. Si un signal DTR s'y produit et qu'une séquence clé d'octets est transmise, le microcontrôleur est alors rechargé dans le chargeur de démarrage. Regardez dans la fonction rxHook () .

Cela peut entraîner des désagréments. Si le microcontrôleur s'arrête et se bloque, il n'écoute plus le port. Par conséquent, il ne peut pas entendre la séquence de touches et redémarrer dans le chargeur de démarrage. Ensuite, réinitialisez uniquement pour aider.

C’est tout. J'espère que mon article éclairera le fonctionnement du chargeur de démarrage dans STM32 et comment télécharger le firmware via un port USB. Malheureusement, le seuil d'entrée est toujours élevé, mais tout à coup mon article aidera quelqu'un à le surmonter.

Source: https://habr.com/ru/post/fr403007/


All Articles