Estoy tratando de descubrir cómo usar la función printf para imprimir en el puerto serie.
Mi configuración actual es código generado por STM32CubeMX y SystemWorkbench32 con la placa de descubrimiento STM32F407 .
Veo en stdio.h que el prototipo printf se define como:
int _EXFUN(printf, (const char *__restrict, ...)
_ATTRIBUTE ((__format__ (__printf__, 1, 2))));
Qué significa eso? ¿Dónde está la ubicación exacta de esta definición de función? ¿Cuál sería el punto general de descubrir cómo usar este tipo de función para generar?
microcontroller
c
stm32
stm32f4
stm32cubemx
usuario505160
fuente
fuente
_write()
función es lo que hice. Detalles en mi respuesta a continuación.Respuestas:
Obtuve el primer método de esta página trabajando en mi STM32F072.
http://www.openstm32.org/forumthread1055
Como se indica allí,
Utilicé STM32CubeMX para configurar USART1 (
huart1
) como puerto serie. Como solo queríaprintf()
, solo necesitaba llenar la_write()
función, lo que hice de la siguiente manera. Esto está contenido convencionalmente ensyscalls.c
.fuente
_EXFUN es una macro, que probablemente contenga algunas directivas interesantes que le dicen al compilador que debe verificar que la cadena de formato sea compatible con printf y garantizar que los argumentos para printf coincidan con la cadena de formato.
Para aprender a usar printf, sugiero la página de manual y un poco más de google. Escriba algunos programas C simples que usen printf y ejecútelos en su computadora antes de intentar hacer la transición para usarlos en el micro.
La pregunta interesante será "¿a dónde va el texto impreso?". En un sistema similar a Unix, pasa a "salida estándar", pero un microcontrolador no tiene tal cosa. Las bibliotecas de depuración CMSIS pueden enviar texto printf al puerto de depuración semihosting del brazo, es decir, a su sesión gdb u openocd, pero no tengo idea de lo que hará SystemWorkbench32.
Si no está trabajando en un depurador, podría tener más sentido usar sprintf para formatear las cadenas que desea imprimir y luego enviar esas cadenas a través de un puerto serie o a cualquier pantalla que haya conectado.
Cuidado: printf y su código relacionado son muy grandes. Eso probablemente no importa mucho en un 32F407, pero es un problema real en dispositivos con poco flash.
fuente
__cdecl
para evitar errores. Al menos en newlib / cygwin, _EXFUN solo se usa para configurar__cdecl
.La respuesta de @ AdamHaun es todo lo que necesita, ya
sprintf()
que es fácil crear una cadena y luego enviarla. Pero si realmente quieres unaprintf()
función propia, entonces las Funciones de Argumento Variable (va_list) son el camino.Con
va_list
una función de impresión personalizada se ve así:Ejemplo de uso:
Tenga en cuenta que, si bien esta solución le brinda una función conveniente para usar, es más lenta que enviar datos sin procesar o incluso usar
sprintf()
. Con altas tasas de datos, creo que no será suficiente.Otra opción, y probablemente una mejor opción, es utilizar ST-Link, depurador de SWD junto con ST-Link Utility. Y use Printf a través del visor SWO , aquí está el manual de la utilidad ST-Link , la parte relevante comienza en la página 31.
fuente
printf () es (generalmente) parte de la biblioteca estándar de C. Si su versión de la biblioteca viene con código fuente, es posible que encuentre una implementación allí.
Probablemente sería más fácil usar sprintf () para generar una cadena, luego usar otra función para enviar la cadena a través del puerto serie. De esa manera, todo el formato difícil se realiza por usted y no tiene que piratear la biblioteca estándar.
fuente
Para aquellos que luchan, agregue lo siguiente a syscalls.c:
Conéctese a su puerto COM a través de masilla y debería ser bueno.
fuente
Si desea un enfoque diferente y no desea sobrescribir las funciones o declarar las suyas, simplemente puede usar
snprintf
para archivar el mismo objetivo. Pero no es tan elegante.fuente