cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO L496ZG SWO not able to make it work

RPG
Senior

Hi

I am trying to enable the SWO to debug with printf. I have a NUCLEO L496ZG board. The ITM_SendChar function seems to get called but no data on the ITM console. What am I doing wrong?

This is the main.c code:

/**
 ******************************************************************************
 * @file      syscalls.c
 * @author    Auto-generated by STM32CubeIDE
 * @brief     STM32CubeIDE Minimal System calls file
 *
 *            For more information about which c-functions
 *            need which of these lowlevel functions
 *            please consult the Newlib libc-manual
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2022 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
 
/* Includes */
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//					Implementation of printf like feature using ARM Cortex M3/M4/ ITM functionality
//					This function will not work for ARM Cortex M0/M0+
//					If you are using Cortex M0, then you can use semihosting feature of openOCD
/////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 
//Debug Exception and Monitor Control Register base address
#define DEMCR        			*((volatile uint32_t*) 0xE000EDFCU )
 
/* ITM register addresses */
#define ITM_STIMULUS_PORT0   	*((volatile uint32_t*) 0xE0000000 )
#define ITM_TRACE_EN          	*((volatile uint32_t*) 0xE0000E00 )
 
void ITM_SendChar(uint8_t ch)
{
 
	//Enable TRCENA
	DEMCR |= ( 1 << 24);
 
	//enable stimulus port 0
	ITM_TRACE_EN |= ( 1 << 0);
 
	// read FIFO status in bit [0]:
	while(!(ITM_STIMULUS_PORT0 & 1));
 
	//Write to ITM stimulus port0
	ITM_STIMULUS_PORT0 = ch;
}
 
 
/* Variables */
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));
 
 
char *__env[1] = { 0 };
char **environ = __env;
 
 
/* Functions */
void initialise_monitor_handles()
{
}
 
int _getpid(void)
{
	return 1;
}
 
int _kill(int pid, int sig)
{
	errno = EINVAL;
	return -1;
}
 
void _exit (int status)
{
	_kill(status, -1);
	while (1) {}		/* Make sure we hang here */
}
 
__attribute__((weak)) int _read(int file, char *ptr, int len)
{
	int DataIdx;
 
	for (DataIdx = 0; DataIdx < len; DataIdx++)
	{
		*ptr++ = __io_getchar();
	}
 
return len;
}
 
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
	int DataIdx;
 
	for (DataIdx = 0; DataIdx < len; DataIdx++)
	{
		//__io_putchar(*ptr++);
		ITM_SendChar(*ptr++);
	}
	return len;
}
 
int _close(int file)
{
	return -1;
}
 
 
int _fstat(int file, struct stat *st)
{
	st->st_mode = S_IFCHR;
	return 0;
}
 
int _isatty(int file)
{
	return 1;
}
 
int _lseek(int file, int ptr, int dir)
{
	return 0;
}
 
int _open(char *path, int flags, ...)
{
	/* Pretend like we always fail */
	return -1;
}
 
int _wait(int *status)
{
	errno = ECHILD;
	return -1;
}
 
int _unlink(char *name)
{
	errno = ENOENT;
	return -1;
}
 
int _times(struct tms *buf)
{
	return -1;
}
 
int _stat(char *file, struct stat *st)
{
	st->st_mode = S_IFCHR;
	return 0;
}
 
int _link(char *old, char *new)
{
	errno = EMLINK;
	return -1;
}
 
int _fork(void)
{
	errno = EAGAIN;
	return -1;
}
 
int _execve(char *name, char **argv, char **env)
{
	errno = ENOMEM;
	return -1;
}

In syscalls.c file I have replaced the _write function:

__attribute__((weak)) int _write(int file, char *ptr, int len)
{
	int DataIdx;
 
	for (DataIdx = 0; DataIdx < len; DataIdx++)
	{
		//__io_putchar(*ptr++);
		ITM_SendChar(*ptr++);
	}
	return len;
}

This are the settings on the ioc project file:

0693W00000QO4yRQAT.png 

And this are the settings on Debug configuration:

0693W00000QO4ybQAD.png 

And the ITM settings:

0693W00000QO4zFQAT.pngThis is my board:

0693W00000QO53CQAT.jpg 

PB3 is connected to SWO.

Thanks in advance.

1 ACCEPTED SOLUTION

Accepted Solutions

And you're clocking the MCU at 16 or 80 MHz?​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

3 REPLIES 3

And you're clocking the MCU at 16 or 80 MHz?​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

That was the issue. Thank you. Didn't set correctly the clock on IOC settings. Now is 16 MHz and it works.

0693W00000QO59yQAD.png 

Thank you very much!

FBL
ST Employee

Hi @Raúl Pérez Gómez​, 

For more information, please refer to AN4989 STM32 microcontroller debug toolbox section 7.3 describes the Printf via SWO/SWV. Also, this article How to use semihosting with STM32CubeIDE and STM32 may be useful.

Firas

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.