J'essaie de comprendre comment utiliser la fonction printf pour imprimer sur le port série.
Ma configuration actuelle est le code généré par STM32CubeMX et SystemWorkbench32 avec la carte de découverte STM32F407 .
Je vois dans stdio.h que le prototype printf est défini comme:
int _EXFUN(printf, (const char *__restrict, ...)
_ATTRIBUTE ((__format__ (__printf__, 1, 2))));
Qu'est-ce que ça veut dire? Où est l'emplacement exact de cette définition de fonction? Quel serait l'intérêt général de savoir comment utiliser ce type de fonction pour sortir?
microcontroller
c
stm32
stm32f4
stm32cubemx
user505160
la source
la source
_write()
fonction est ce que j'ai fait. Détails dans ma réponse ci-dessous.Réponses:
J'ai obtenu la première méthode de cette page sur mon STM32F072.
http://www.openstm32.org/forumthread1055
Comme indiqué ici,
J'ai utilisé STM32CubeMX pour configurer USART1 (
huart1
) comme port série. Comme je voulais seulementprintf()
, je n'avais qu'à remplir la_write()
fonction, ce que j'ai fait comme suit. Ceci est classiquement contenu danssyscalls.c
.la source
_EXFUN est une macro, contenant probablement des directives intéressantes qui indiquent au compilateur qu'il doit vérifier que la chaîne de format est compatible avec printf et s'assurer que les arguments de printf correspondent à la chaîne de format.
Pour apprendre à utiliser printf, je suggère la page de manuel et un peu plus de recherche sur Google. Écrivez quelques programmes C simples qui utilisent printf et exécutez-les sur votre ordinateur avant d'essayer de passer à l'utilisation sur le micro.
La question intéressante sera "où va le texte imprimé?". Sur un système de type Unix, il passe en "sortie standard", mais un microcontrôleur n'a rien de tel. Les bibliothèques de débogage CMSIS peuvent envoyer du texte printf au port de débogage de semihosting arm, c'est-à-dire dans votre session gdb ou openocd mais je n'ai aucune idée de ce que SystemWorkbench32 fera.
Si vous ne travaillez pas dans un débogueur, il peut être plus judicieux d'utiliser sprintf pour formater les chaînes que vous souhaitez imprimer, puis envoyer ces chaînes sur un port série ou sur tout affichage que vous pourriez avoir connecté.
Attention: printf et son code associé sont très volumineux. Cela n'a probablement pas beaucoup d'importance sur un 32F407, mais c'est un vrai problème sur les appareils avec peu de flash.
la source
__cdecl
pour éviter les erreurs. Au moins sur newlib / cygwin, _EXFUN n'est utilisé que pour définir__cdecl
.@ La réponse d'AdamHaun est tout ce dont vous avez besoin,
sprintf()
il est facile de créer une chaîne puis de l'envoyer. Mais si vous voulez vraiment uneprintf()
fonction de votre choix, alors les fonctions d'argument variable (va_list) sont la solution.Avec
va_list
une fonction d'impression personnalisée ressemble à ceci:Exemple d'utilisation:
Notez que bien que cette solution vous offre une fonction pratique à utiliser, elle est plus lente que l'envoi de données brutes ou l'utilisation de even
sprintf()
. Avec des taux de données élevés, je pense que ce ne sera pas suffisant.Une autre option, et probablement meilleure, consiste à utiliser ST-Link, le débogueur SWD avec l'utilitaire ST-Link. Et utilisez Printf via la visionneuse SWO , voici le manuel de l' utilitaire ST-Link , la partie pertinente commence à la page 31.
la source
printf () fait (généralement) partie de la bibliothèque standard C. Si votre version de la bibliothèque est livrée avec du code source, vous pouvez y trouver une implémentation.
Il serait probablement plus facile d'utiliser sprintf () pour générer une chaîne, puis d'utiliser une autre fonction pour envoyer la chaîne via le port série. De cette façon, tout le formatage difficile est fait pour vous et vous n'avez pas à pirater la bibliothèque standard.
la source
Pour ceux qui éprouvent des difficultés, ajoutez ce qui suit à syscalls.c:
Connectez-vous à votre port COM via du mastic et vous devriez être bon.
la source
Si vous voulez une approche différente et ne voulez pas écraser les fonctions ou déclarer la vôtre, vous pouvez simplement utiliser
snprintf
pour archiver le même objectif. Mais ce n'est pas aussi élégant.la source