Ce que je faisais
J'utilise un microcontrôleur STM32 et pour mon projet, je dois pouvoir envoyer des données à des moments précis de la journée (par exemple, à 11 h et 14 h). Le microcontrôleur doit savoir quelle heure il est avant que je puisse y arriver. Malheureusement, je n'ai qu'une communication à sens unique et je ne peux donc pas demander l'heure actuelle au réseau.
Par conséquent, je veux régler l'heure actuelle, directement après avoir terminé la programmation. Je savais que je pouvais écrire des données sur la mémoire flash à l'aide de l'interface de ligne de commande de l'utilitaire ST-LINK (ST-LINK_CLI) à l'aide de la commande suivante:
ST-LINK_CLI.exe -w32 <Address> <data> -Rst
J'ai écrit un script de test simple qui écrit l'horodatage Unix à une adresse non utilisée actuellement par le code.
J'étais sur le point d'écrire une fonction pour lire l'horodatage et l'utiliser pour régler l'heure RTC. Jusqu'à ce que je lise ce qui suit dans le manuel de l'utilisateur de l'utilitaire ST-LINK :
-w32 prend en charge l'écriture dans les registres de mémoire Flash, OTP, SRAM et R / W.
Lorsque le manuel dit qu'il prend en charge l'écriture dans les registres R / W, cela signifie-t-il que je peux accéder directement aux registres RTC et les définir? J'ai essayé, mais je n'arrive pas à écrire dans ces registres.
Je préférerais utiliser cette méthode si c'est le cas, car je n'aurais plus besoin d'écrire une fonction spécifique pour la gérer sur le microcontrôleur. Cela signifie que je peux définir l'heure RTC de tout microcontrôleur que nous utilisons actuellement, au lieu de devoir mettre à jour leur code.
Ce que j'avais l'intention de faire
Pour définir les registres RTC, j'ai essayé de faire les étapes suivantes, comme décrit dans le manuel de référence STM :
- définir le bit DPB dans le registre PWR_CR
- écrire 0xCA dans le registre RTC_WPR
- écrire 0x53 dans le registre RTC_WPR
- arrêter le RTC en définissant le bit INIT dans le registre RTC_ISR
- sélectionner l'horloge 1Hz en écrivant dans le registre RTC_PRER
- charger l'heure actuelle en écrivant dans le registre RTC_TR
- charger la date actuelle en écrivant dans le registre RTC_DR
- démarrer le RTC en réinitialisant le bit INIT dans le registre RTC_ISR
Pour accéder aux registres, j'ai utilisé les adresses suivantes:
- PWR_CR: 0x4000 7000
- RTC_WPR: 0x4000 2824
- RTC_ISR: 0x4000 280C
- RTC_PRER: 0x4000 2810
- RTC_TR: 0x4000 2800
- RTC_DR: 0x4000 2804
Qu'est ce qui ne s'est pas bien passé
Je ne peux écrire sur aucun de ces registres. Avec l'utilitaire ST-LINK, j'obtiens le message suivant:
Une erreur s'est produite lors de l'écriture de la mémoire!
Utilisation de ST-LINK_CLI:
Écriture de 0x00000100 à 0x40007000 ... Erreur!
La lecture de ces registres n'est pas un problème, mais je ne peux pas y écrire en utilisant l'utilitaire ST-LINK ou son interface de ligne de commande.
La question
Comment puis-je écrire dans les registres R / W à l'aide de l'utilitaire ST-LINK?
Existe-t-il une sorte de protection en écriture pour permettre l'écriture dans les registres RTC que j'ai ignorés?
Réponses:
Certains registres ne sont légaux que pour une largeur d'accès spécifique (c'est-à-dire que -w32 peut ne pas être correct) ou peuvent ne pas relire les valeurs écrites, ce qui pourrait entraîner un problème de vérification.
Il peut également y avoir des restrictions de séquence ou d'état sur l'accès aux choses.
Une option qui devrait contourner la plupart des problèmes imaginables serait de créer un petit programme pour faire le travail qui serait lié à l'exécution en RAM. Vous pouvez remplacer les données dans son binaire après avoir déterminé l'offset, télécharger la version modifiée et l'exécuter. Ou vous pourriez demander au programme d'obtenir des valeurs d'une région de RAM en dehors des étendues du fichier, que vous définiriez avant de l'exécuter. Avec un contrôle plus fin du stlink, vous pouvez également transmettre des valeurs dans les registres du processeur, bien que vous puissiez (?) Avoir besoin du programme de ligne de commande open source alternatif plutôt que des ST pour le faire (cette petite routine dans la méthode RAM est d'ailleurs la façon dont ce programme accomplit l'écriture à clignoter)
la source
Ainsi, l'un des problèmes était, comme l'a souligné Chris Stratton:
Cela signifiait que la vérification avait échoué, provoquant l'affichage de l'erreur, même si l'opération d'écriture avait réussi.
Vous trouverez ci-dessous la réponse que j'obtiens en lisant le registre PWR_ISR, en définissant le bit INIT, puis en relisant le registre:
La vérification de l'utilitaire ST-LINK vérifie si la valeur écrite à l'adresse et lue à partir de l'adresse correspond. Dans ce cas, l'opération d'écriture a réussi, même si les deux valeurs ne correspondent pas, car le bit INIT est maintenant défini.
L'autre problème était que je ne pouvais pas remarquer l'effet de l'opération d'écriture. Lorsqu'il est connecté au microcontrôleur, il est maintenu dans l'état de réinitialisation par le ST-LINK (connu sous le nom de "connexion sous réinitialisation"). J'avais besoin d'utiliser l'option de connexion HOTPLUG, qui se connecte au microcontrôleur sans arrêt ni réinitialisation.
Le fichier batch fonctionne parfaitement comme je le voulais! La commande ressemble maintenant à ceci:
la source
Je pense que ce qui se passe, c'est qu'après l'écriture, une lecture de vérification est effectuée. Si le même registre renvoie l'heure actuelle dans une lecture, bien que vous réussissiez à mettre à jour le RTC, le débogueur ne s'en rendra pas compte. Cela est moins susceptible d'expliquer un problème avec le registre d'alimentation (sauf si le débogueur accède également à ce registre sous le capot). Vérifiez la valeur lue manuellement. S'il y avait un problème plus important, cette lecture pourrait également échouer. Essayez également les autres registres de votre liste.
la source