Estoy tratando de desarrollar una aplicación para el microcontrolador NXP LPC1788 y me gustaría poder registrar cadenas formateadas en puntos arbitrarios dentro del código fuente en un archivo de registro de una manera que tenga un impacto insignificante en el rendimiento del programa. Esencialmente, me gustaría algo lo más parecido posible a las utilidades Logger que obtienes con Java.
Actualmente, estoy usando un depurador iJet y con eso puedo imprimir valores numéricos individuales de 8 o 32 bits en la ventana de eventos IAR EW usando ITM_EVENT8_WITH_PC
y ITM_EVENT32_WITH_PC
, junto con el contador del programa y la marca de tiempo. Sin embargo, los números por sí solos no son lo suficientemente descriptivos y estoy limitado a cuatro canales. Esto significa que a menudo tengo que elegir una pequeña parte del programa para iniciar sesión en cualquier momento, comentando las llamadas en ITM_EVENT...
partes no relacionadas y agregando otras nuevas o descomentando las existentes en la parte que quiero monitorear de cerca. Esto no es realmente un enfoque muy eficiente.
Una cosa que he intentado investigar es crear un archivo de macro que contenga una función que tome una cadena como parámetro y la pase a la macro LogMessage
integrada . __message
Sin embargo, no estoy seguro de cómo puedo incluir esta macro en el programa para poder invocarla LogMessage
dentro del código fuente. Intenté especificarla en Debugger -> Setup Macros
, pero esto no se vincula LogMessage
con el código fuente.
Cualquier ayuda sería apreciada.
EDITAR
Cómo se hace en Java
Para dar un ejemplo de cómo se puede usar el marco Logger (específicamente de la variedad SLF4J) en Java, tomaré el del manual SLF4J y explicaré lo que está sucediendo:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
En este caso, estamos creando una clase con un main
método estático que sirve como punto de entrada a la aplicación. Luego, llamamos a un método de fábrica getLogger
para producir un objeto de registro que hacemos consciente de la clase en la que lo instanciamos: HelloWorld.class
. Esta información se puede configurar para que se incluya en las salidas de registro.
Luego podemos usar este objeto de registro para producir registros de diferentes niveles de registro según la importancia y la naturaleza de lo que estamos registrando. En el ejemplo, generamos "Hello World" en el INFO
nivel de registro, que se usa para registrar información relativamente importante, y el marco de registro tratará esa salida de manera adecuada en función de su nivel de registro y la configuración del marco; esto puede incluir enviarlo a stdout o guardarlo en un archivo.
como me gustaria hacerlo
Sería bueno si pudiera obtener algo similar trabajando con las aplicaciones IAR Embedded Workbench. Discutí el problema con un colega y descubrí que podíamos enrutar datos desde los puertos de estímulo ITM a la ventana Terminal IO a través de I-jet/JTAGjet -> SWO Configuration...
la barra de menú en la parte superior y luego registrar la ventana Terminal I/O. Puede iniciar sesión directamente desde los puertos ITM a un archivo de registro, pero parece que sobrescribe el archivo cada vez que escribe un nuevo valor en un puerto ITM por algún motivo.
Lo que estoy experimentando ahora es crear un método como logData(uint16_t logId, uint8_t logLevel, uint32_t value)
, que hará que los datos se guarden en un archivo de registro de una manera particular:
El archivo de registro producido no es legible, pero podría armar una secuencia de comandos de Python que tomará el archivo de registro generado y producirá uno legible por humanos con un buen formato en el mismo estilo que un archivo de registro SLF4J.
Al menos esa es la idea.
EDITAR 2
Reuní lo que se siente como un marco de registro lo suficientemente decente para mis requisitos, aunque aún no he intentado usarlo ampliamente para ver cómo resiste bajo presión.
En el método de mi aplicación de microcontrolador main
, puedo hacer una llamada como LOGGER_Init(LOG_LEVEL_DEBUG, 5);
, donde el primer argumento es el nivel de registro del registrador y el segundo argumento es el puerto de estímulo ITM para imprimir los datos de registro. El registrador solo imprimirá mensajes de registro con un nivel de registro igual o superior al suyo (p. ej., un registrador configurado en LOG_LEVEL_INFO
imprimirá LOG_LEVEL_WARN
mensajes y LOG_LEVEL_INFO
mensajes pero no LOG_LEVEL_DEBUG
mensajes).
Entonces puedo registrar datos de la siguiente manera:
LOGGER_Info(0x1, 0x20);
LOGGER_Debug(0x2, 0x3A, 0xFF);
Estos métodos tratan el primer valor como un identificador de registro y los argumentos restantes se tratan de forma variable como datos de registro.
En un archivo de 'mapa de registro', mantengo una asignación de identificadores de registro a mensajes de salida de registro de marcador de posición, donde '{}' representa un valor de marcador de posición como en SLF4J:
static const LOG_MAP_T logMappings[] = {
{1, "The first log message in main provides {}"},
{2, "The second log message provides {} and also {}"}
};
El registrador imprime mensajes de registro de los niveles apropiados al puerto de estímulo ITM configurado, que luego lo envía a través de la ventana de E/S de la terminal donde se guarda en un archivo de registro.
Luego tengo un script de Python que pasa por las salidas de registro y el archivo de mapeo y une todo para producir algo como esto:
>>>
INFO The first log message in main provides 32
DEBUG The second log message provides 58 and also 255
Le recomendaría que habilite la función ETM del chip LPC que está utilizando. La macrocelda de seguimiento incrustada es esencialmente una ubicación de memoria en la que puede escribir caracteres que se abrirán camino a través de la conexión JTAG/SWD a su EWARM en las ventanas de la terminal (o incluso en el complemento de Eclipse).
Simplemente puede escribir una macro para escribir los caracteres directamente en la dirección de memoria, o puede usar lo que IAR llama "modo de host", creo que piratean su salida estándar y lo hacen por usted. Luego, simplemente use printf de cualquier envoltorio que desee.
Busque la nota de aplicación en su sitio e ignore todas las capacidades de seguimiento sofisticadas que proporciona ETM (si no las necesita) y solo busque las cosas de salida de depuración.
Si está en mantenimiento, llame a la oficina de IAR más cercana y solicite un FAE y lo guiarán.
usuario694733
Etiquetac
usuario694733
Etiquetac
RHaguiuda