2021-08-29 10:53 PM
I have been using the APP_LOG() macro from stm32_adv_trace.c to output messages while developing with the STM32WL55. This uses DMA transfers with the UART.
I thought it would be useful to use the SWD debug port for console output, instead of the UART. I have got it working, but my code is
involved a few hacks and I wondered if ST or others have a proper version they could share?
If not, here is some of what I learnt.
Console output (and other useful features) are available on the SWO pin (which is PB3 on my processor). If properly enabled in STM32Cube then characters can be displayed on a "SWV ITM Data Console".
You will find quite a few online tutorials for directing printf() output to SWO instead of UART TxD. At the lowest level this involves changing this:
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
to this:
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
Most examples use this only while debugging, with the debug tools enabling the processor hardware to set up the SWO operation.
There are suggestions that SWO configuration can be done by software and SWO operation can occur in run mode as well as debug,
but I did not attempt this.
After some trouble I managed to get printf() running on my board. Problems along the way included ensuring my own code did not
use the PB3 pin, and that the DBG_Init() code did not disable the SWO pin (comment out DBG_Init()!) Also the Gpio_PreInit() stops any debugging by switching SWD pins to analog inputs. The printf() stops working as soon as you call APP_LOG().
This shows console output through SWO is possible, but the APP_LOG() code does not use HAL_UART_Transmit() so further work is required.
It looks like the advanced trace utility uses DMA for the UART, and manages a circular buffer as well as a semaphore that enables/disables output. At the lowest level, a vcom_Trace_DMA() call uses HAL_UART_Transmit_DMA() to send characters, and it looks like
there is an end of DMA interrupt that manages the circular buffer and semaphore.
So I change vcom_Trace_DMA() as follows:
UTIL_ADV_TRACE_Status_t vcom_Trace_DMA(uint8_t *p_data, uint16_t size) {
#ifdef USEPB3ASSWO
uint16_t i;
for (i=0; i<size; i++) {
ITM_SendChar(p_data[i]);
}
#else
HAL_UART_Transmit_DMA(&huart2, p_data, size);
#endif // USEPB3ASSWO
return UTIL_ADV_TRACE_OK;
}
which works for the first call to APP_LOG() but there is no further output as the semaphore is not cleared. I made this further change at the end of the UTIL_ADV_TRACE_COND_FSend() routine:
#ifdef USEPB3ASSWO
UTIL_ADV_TRACE_Status_t ret = TRACE_Send(); // calls vcom_Trace_DMA()
TRACE_UnLock(); // Clear semaphore
ADV_TRACE_Ctx.TraceWrPtr = 0; // reset circular buffer
return ret;
#else
return TRACE_Send();
#endif // USEPB3ASSWO
So I have it working, but I know it is not clean.
Irritatingly, the ASCII colour escape sequences I have been using with the UART are not implemented by SWV ITM Data Console.
Further references to SWO console output:
AN4989 Application note STM32 microcontroller debug toolbox section 7.3
http://www.embedded-communication.com/en/misc/printf-with-st-link/