How to display ITM-based output in Atmel Studio - Arduino Due & J-Link

Go To Last Post
37 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all!

Sorry if this is not the right  place to raise the question, do let me know if that is the case.

I have a simple project in Atmel Studio 7 (latest version) for my Arduino Due (using a J-Link debugger) which works well and which sends the right printf-type strings to the SWO, which I can view with J-Link SWO Viewer, outside the Atmel Studio. Is there a way of monitoring that output from within Atmel Studio itself, by any chance? So that I do not have to use two pieces of software? Any help would be much appreciated.

Thanks a lot!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Before going into a debug session, go to Debug->Percepio Trace->Settings. Since you are using a J-Link you can set Frequency to 0 to use the detect feature in the J-Link. Ensure that Application Output is checked and in the Settings box, choose the ITM port and the datatype you are sending. Note that strings need terminating \n for it to be displayed.

Then, enter a debug session, and go to Debug->Percepio Trace->Enable. Once ITM messages are received, a new 'tab' in the output window should appear and show the messages.

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks a lot for the prompt reply! I believe there is something wrong with the Atmel Studio configuration. Before I waste your or anyone else's time with silly things, it may be worthwhile asking if there is a defined method of using the printf function properly within Atmel Studio for debugging via the ITM? I would like to start from a strong footing, but documentation on how to use this feature is very thin on the ground. Do you think you could guide me first, and then after I tried it I could come back with more questions? I really like Atmel Studio, for all its idiosyncrasies, and I would like to use it, especially for the ASF, which is a very good way of learning about the ARM processors. I hope this is not too much hassle.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Huh? The steps above shows ITM data in Atmel Studio. Given that you already use the J-Link SWO Viewer, this should 'just work'.

 

How you wire up ITM to printf is sort of up to you (also depends on which c library you use).

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe if I shared the code it might make more sense. Here's the code in main.c, no other file in the project changed:

#include <asf.h>
#include <stdio.h>

// these are needed to write the strings and to keep the linker happy
int _write(int file, char *ptr, int len);
int _read(int file, char *ptr, int len);

volatile uint32_t sTicks = 0;

void SysTick_Handler(void)
{
 if(sTicks <10)
 {
  sTicks++;
 }
 else
 {
  printf("Interrupt one second.\n");
  sTicks = 0;
 }
}

int _write(int file, char *ptr, int len)
{
 int i=0;

 for(i=0 ; i<len ; i++)
 {
  ITM_SendChar((*ptr++));
 }
 return len;
}

int _read(int file, char *ptr, int len)
{
 //dummy, does nothing, just to avoid linker error
 return len;
}

int main (void)
{
 uint32_t return_value = 1u, idx;
 
 /* Insert system clock initialization code here (sysclk_init()). */
 sysclk_init();
 board_init();

 // Configure SysTick_handler for 100ms rate
 if((return_value = SysTick_Config(SystemCoreClock / 10)) == 0)
 {
  printf("Clock configured successfully.\n");
 }
 else
 {
  printf("Clock NOT configured successfully!!!\n");
 }

 /* Insert application code here, after the board has been initialized. */
 for(;;)
 {
  //give the loop something to do
  for(idx=0;idx<100000000;idx++)
  {
   nop(); //just waste time
  };
  printf("In the loop.\n");
 }
}

This code builds and runs on the Arduino Due and J-Link SWO Viewer shows this:

which seems rather good, as far as I can see, given that the messages from the interrupt come about once a second. Bear in mind the frequencies at which SWO Viewer reads the data, auto-detected.

 

In the project Tools settings they look like so:

 

And the J-Link Control Panel launched from this window shows this:

 

The PercepioTrace settings are as this:

(enabling all combinations that include Application Output seem to make no difference; frequency at 0 to allow J-Link to set).

 

The port is configured so:

 

To test it I started from an erase flash, set a breakpoint right after board_init(), in the if() line. Once the program stopped there I enabled Trace, and let the program run (instructions followed from https://www.youtube.com/watch?v=GiVeCPWrPco).

 

With all these options update I can view Control-Flow Trace for example:

but still no printfs in the Output windows:

 

Now, a new development, when I tried it for this post, when I stopped the debugging session, I was presented with this message:

Whilst I was capturing the window and making selections I had the following message popping up behind:

I selected 'Wait 1 more minute' and the message went away. I then was able to close Atmel Studio and no other tasks was present in Windows Task Manager.

 

 

I hope that the problem is clearer now. I am more than happy to try other things, if anyone has any ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hmh, this all looks pretty good.. The horizontal red lines in the flow views shows that some data is lost though... I would start with only ApplicationOutput on and see if it works then (as far as I remember, ITM messages have low priority in the TPIU)

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for coming back to me!

 

If I only enable Interrupt Trace and Application Output I get this in the Control-Flow Trace:

At the same time, J-Link Control Panel seems to see the SWO data:

But nothing appears in the Output windows, at all.

 

Any ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just for the sake of diversity, I also tried hooking up the Atmel-ICE I've got. All setting were kept the same, apart from the debugger, and the Frequency for Percepio Trace set to 2Mhz in clear. With Atmel-ICE not even the Control-Flow Trace works. More than happy with any further suggestions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have just tried the same project in Atmel Studio 6.2, with the J-Link debugger, and the behaviour is the same as with Atmel Studio 7, i.e. no output in the Output, and Control-flow Trace working. Is it something to do with Atmel Studio not getting the SVO data from the debugger somehow? Is there a way to test this further?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I managed to get it work, in case it helps anyone. I found in the Help of Atmel Studio 6.2 a section on Percepio Trace which does not seem to exist in Atmel Studio 7. In it there is code that is recommended to get the ITM Application Output to work:

#define ITM_TER *(volatile int*)0xE0000E00 // Trace Enable Register
#define ITM_TCR *(volatile int*)0xE0080E80 // Trace Control Register
#define ITM_STIM_8(n) *(volatile uint8_t*)(0xE0000000 + ((n) * 4)) // 8 Bit N < 32

void SWO_print_char(int port, char c);
void SWO_print_string(int port, const char *s);

void SWO_print_char(int port, char c)
{
    while ((ITM_STIM_8(port) & 1) == 0);
    ITM_STIM_8(port) = c;
}

void SWO_print_string(int port, const char *s)
{
    if ((ITM_TCR & 1) == 0) return;
    if ((ITM_TER & 1) == 0) return;
    while (*s) SWO_print_char(port, *s++);
    SWO_print_char(port, 0);
}

This assumes a bare metal, no thrills scenario. If you have an ASF project, though, it includes by default CMSIS, which contains all the definitions of all the registers in the microcontroller. Moreover, CMSIS suggests that of the 32 ports of the ITM one should use Port #0 for printf()-style strings sent to the debugger, and Port #31 for RTOS relevant messages. Moreover, it defines a set of standard functions for accessing the ITM Port #0, on of which is ITM_SendChar():

__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
{
  if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
      (ITM->TER & (1UL << 0)        ))   /* ITM Port #0 enabled */
  {
    while (ITM->PORT[0].u32 == 0);
    ITM->PORT[0].u8 = (uint8_t) ch;
  }
  return (ch);
}

The checks for ITM Enable and Port #0 enable are already there, so they are not required anymore again in SWO_print_string, so the whole code needed now becomes:

void SWO_print_string(const char *s);

void SWO_print_string(const char *s )
{
 while (*s) ITM_SendChar(*s++);
 ITM_SendChar(0);
}

With the code added, the whole program looks like this:

#include <asf.h>
#include <stdio.h>

void SWO_print_string(const char *s);

void SWO_print_string(const char *s )
{
 while (*s) ITM_SendChar(*s++);
 ITM_SendChar(0);
}


volatile uint32_t sTicks = 0;

void SysTick_Handler(void)
{
 if(sTicks <10)
 {
  sTicks++;
 }
 else
 {
  SWO_print_string("Interrupt one second.");
  sTicks = 0;
 }
}


int main (void)
{
 uint32_t return_value = 1u, idx;
 
 /* Insert system clock initialization code here (sysclk_init()). */
 sysclk_init();
 board_init();

 // Configure SysTick_handler for 100ms rate
 if((return_value = SysTick_Config(SystemCoreClock / 10)) == 0)
 {
  SWO_print_string("Clock configured successfully.");
 }
 else
 {
  SWO_print_string("Clock NOT configured successfully!!!");
 }

 /* Insert application code here, after the board has been initialized. */
 for(;;)
 {
  //give the loop something to do
  for(idx=0;idx<100000000;idx++)
  {
   nop(); //just waste time
  };
  SWO_print_string("In the loop.");
 }
}

 

I am pleased to report that the output now works in the Percepio Trace window, as expected. On the J-Link Ultra, that is. On Atmel-ICE it doesn't work, for love, nor money. Does anyone know why, by any chance? Atmel-ICE documentation claims that it is capable of receiving SWO information, but neither the Percepio Trace, nor the Control-flow Trace work at all.

 

Also, I am curious in knowing why the printf()-style implementation did not get displayed in the Percepio Trace window, when J-Link SWO Viewer did see them? The source for my implementation relies on overriding the _write() function and is found here:

http://blog.atollic.com/cortex-m-debugging-printf-redirection-to-a-debugger-console-using-swv/itm-part-1

There is another option which overrides puts() instead of _write(), which I haven't tried, here:

https://www.doulos.com/knowhow/arm/Retargetting_a_C_library_function/

 

I believe it would be quite useful to have a working printf(), with at least integer parsing in hex and decimal, which would be the next step, so I am curious of hearing from others if they have any ideas. The information on the web seems to suggest the first solution should work, i.e. the one with providing a _write() function, but in our case it doesn't. Any thoughts would be very useful.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Atmel-ICE needs to know the core frequency. It is also not as powerfull as the J-Link (far from it), so I usually have to turn the core down to the 1,1.5 MHz range for the Atmel-ICE to be able to keep up with SWO.

 

As for the String, I don't know.. Only thing I can think of is if you needed a (correct) newline...

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried SWD interface frequencies in the Project Properties -> Tool: 2 MHz (it defaults to that), 1 MHz, 500 kHz, 250 kHz, 100 kHz, 20 kHz, with matching frequencies for Percepio Trace Frequency Setting, no joy.

 

It's a good point with the printf(), as the Percepio Trace solution seems to favour the sending of '\0' at the end, presumably as a terminating character. So I tried it after changing the _write function thus:

int _write(int file, char *ptr, int len)
{
 int i=0;

 for(i=0 ; i<len ; i++)
 {
  ITM_SendChar((*ptr++));
 }
 ITM_SendChar(0);
 return len;
}

and, what do you know, it works! It shows the message nicely in Percepio Trace, and J-Link SWO Viewer does not seem too bothered by it, showing the message correctly. This leads to my concluding that for a good Percepio Trace display we need a terminating '\0' to be sent to the ITM for its being displayed in the window. That is marvellous, thanks a lot for your help!

 

For those who only have an Atmel-ICE, though, this does not seem to be working. Any suggestions what I can try to make Atmel-ICE work?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By the way, the printf() solution also works with integer parameter, including the call from the SysTick_Handler(), which it shouldn't, so it is a real joy! The whole world should know about this (or is it just me who didn't?).

Last Edited: Mon. Mar 6, 2017 - 03:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The SWD frequency does not affect the SWO frequency. The frequency in the percepio box is the core frequency (mainclk) which is needed to calculate the needed TPIU prescaler. To avoid having this prescaler too large, the core usually needs to be clocked down so that the TPIU doesn't overflow.

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do wish to get to the bottom of it. After more reading, I figured I'd try to see the value of the TPI->ACPR register after clock initialisation and Trace Enable for both debuggers, and some interesting facts popped up. The behaviour is the same in both Atmel Studio 6.2 and Atmel Studio 7.

 

With the J-Link debugger, the SWD defaults to 4 MHz (In Project Properties -> Tool). When the Frequency in Trace Settings is set to 0, TPI->ACPR register reads 0x01 on the very next statement after enabling Trace, the Trace Output is displayed properly, J-Link Control Panel reports the SWD interface speed as 1 MHz, the SWV as "UART Encoding, 42666667 bps", and shows SWO traffic with only "SW Source Packets" as per the Trace Output - which shows what it should - and all is well.

 

The same debugger, Frequency Trace Setting 42 MHz, TPI->ACPR register reads 0x00 as soon the program enters main(), and enabling Trace does not change it, J-Link Control Panel shows again "UART Encoding, 42666667 bps", a lot of HW source packets, and no SW source packets - consistent with the fact that Trace Output shows nothing.

 

Next test is Frequency Trace Setting 12 MHz, TPI->ACPR register does not change throughout the test even when enabling Trace, J-Link Control Panel shows "UART Encoding, 12307692 bps", it shows the first 10 SW source packets by the first printf() but nothing in Trace Window, and then as the software is left to run the number of SW source packets reported increased in line with what is expected from the microcontroller, but also a lot of HW source packets, at a ratio of about 1:3 SW:HW. No Trace Output whatsoever.

 

Next test is Frequency Trace Setting 6 MHz, which results in J-Link Control Panel showing "UART Encoding, 6165703 bps", the same TPI->ACPR register in 0x00 (i.e. no change) as at 12 MHz, but now no SW source packets are shown at all by J-Link Control Panel, only HW and Extension packets. Obviously, no Trace Output messages.

 

Next test is Frequency Trace Setting 3 MHz, which results in J-Link Control Panel showing "UART Encoding, 3085824 bps", the same TPI->ACPR register in 0x00 (i.e. no change) as at 6 MHz, now many HW source packets are sent but the odd SW source packets too, but far fewer than expected. Nothing in Trace Output.

 

Last test is Frequency Trace Setting 500 kHz, which results in J-Link Control Panel showing "UART Encoding, 514883 bps", the same TPI->ACPR register in 0x00 (i.e. no change) as at 3 MHz, now only HW source packets are sent, and nothing in Trace Output.

 

 

I couldn't find an Atmel application similar to J-Link Control Panel to use with the Atmel-ICE, but the behaviour at all Frequency Trace Settings tried (2 MHz, 1 MHz, 500kHz, 250 kHz, 100 kHz) with it connected is that TPI->ACPR stays in 0x00 whether or not trace is enabled, and of course nothing goes to Trace Window.

 

So J-Link Ultra seems to only work when it chooses its own speed, which is somewhere along 42.666 MHz, otherwise it all falls apart. Needless to say, Atmel-ICE does nothing useful. There may be something wrong with the way Percepio Trace give the commands to the debugger? What do you make of this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is frequency trace setting? If you refer to the percepio box, that is where you tell the core frequency so that we can calculate the trace frequency. With J-Link you can say it to 0, which means that the jlink will upload a ram snippet to check the real core frequency before calculating the trace frequency.

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Frequency Trace Setting  is the setting in the Percepio Trace Settings. So that is the core frequency of the TPIU unit, from which, through the prescaler, will produce the actual speed of the SWO clock? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Upon further reading, it appears to me as though the value in the TPI->ACPR register should be written by the Debugger upon starting Trace with a value of (CPU_CORE_FREQUENCY / SWO_DESIRED_SPEED) - 1. The setting in the Percepio Trace Setting (Frequency) should be SWO_DESIRED_SPEED, and I am wondering then where does the Atmel-ICE get its CPU_CORE_FREQUENCY from? I can understand J-Link doing the RAM thing you mentioned to get CPU_CORE_FREQUENCY, but how about Atmel-ICE? Because for sure the register TPI->ACPR does not get written with a value other than 0, no matter what Frequency I put in the Percepio Trace Settings. And a value of 0 in TPI->ACPR means that (CPU_CORE_FREQUENCY / SWO_DESIRED_SPEED) would be equal to 1. J-Link, when left to its own and works, puts 1 in the TPI->ACPR register, meaning that (CPU_CORE_FREQUENCY / SWO_DESIRED_SPEED) would be equal to 2, which makes sense as the SWO frequency in that case is 42.666 MHz, roughly half that of the processor, which is 84 MHz. If so, again, how to tell Atmel-ICE the processor speed?

 

Again, this may all be just silly, and I got it all wrong, but it would be useful to know.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Bloody hell, I got it to work. In the Percepio Trace -> Trace Settings... in the Frequency (Hz) field one must put the actual frequency of the processor core. With this set to 84 MHz the TPI->ACPR register got loaded with 0x1B, which is 27 in decimal, meaning that (CPU_CORE_FREQUENCY / SWO_DESIRED_SPEED) would be 27 + 1 = 28. As I know that CPU_CORE_FREQUENCY is 84 MHz, it follows that SWO_DESIRED_SPEED would be CPU_CORE_FREQUENCY / 28, which is 3 MHz. This is exactly the maximum SWO frequency specified by the Atmel-ICE documentation. So the debugger does not know the CPU_CORE_FREQUENCY, which has to be put into Percepio Trace -> Trace Settings... -> Frequency (Hz), but it does know its own maximum SWO_DESIRED_SPEED and it calculates the value of the TPI->ACPR register accordingly. Ruddy hell, this should be put into a serious tutorial about using Percepio Trace.

 

Do you think my understanding is correct at this point?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

... as I've repeated a couple of times already...

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

...well, that what happens when one doesn't see the wood for the trees. Thanks for your support, by the way!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

smiley  I'm actually surprised that you got SWO to work... It's a big beast to tickle that even I have problems with sometimes (and I wrote most of the SWO parts in Atmel Studio...)

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was attracted to the Arduino ecosystem, for which Atmel-ICE is ideal, as it can cover both AVR-based and ARM-based Arduinos for about £75 here in the UK. I bought the hardware years ago but I didn't have time to delve deeper. Last year I had a quick issue I had to provide a solution for and an Arduino seemed like the best option, but with Atmel-ICE I couldn't get the debugging working, so I bought a J-Link Ultra. The proposition of an Arduino Due at about £40 with an Atmel-ICE give a very reasonably priced solution for embedded development, and with the SWO working on an Atmel-ICE it's a damn good way to start playing around. I had not written embedded code for 14 years until last year, so it was fun.

 

The point of the documentation is useful, though, as such a powerful feature should be better documented. Atmel Studio 6.2 Help has a section on Percepio Trace, but Atmel Studio 7 lost it. Maybe a YouTube video to explain such a powerful feature?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

It is probably worth summarising my findings in regards to making use of the ITM debugging facility. Again, it is very easy to use Atmel Studio 7 and the ASF Framework, in which case all register definitions are available.

 

The first solution to using the ITM is the one where it allows you to print message to the Port #0, the default port for sending strings for debugging. the following needs defining:

void SWO_print_string(const char *s);

void SWO_print_string(const char *s)
{
    while (*s) ITM_SendChar(*s++);
    ITM_SendChar(0);
}

This is by far the easiest option, which uses the CMSIS-defined function ITM_SendChar(), which write directly to the Port #0 of the ITM. Using it is then just as simple as:

SWO_print_string("All is well thus far.");

 

The second, more complex option, is to allow the strings to be sent to any of the ITM ports, from Port #0 to Port #31. For that we need a bit more code, and the ability to pass the Port # to the function writing the character. As ITM_SendChar() only writes to Port#0, we need to write our own equivalent option including the Port #. The printing function also needs updating:

void SWO_print_char(int port, char c);
void SWO_print_string(int port, const char *s);

void SWO_print_char(int port, char c)
{
    while ((ITM->PORT[port].u8 & 1) == 0);
    ITM->PORT[port].u8 = c;
}

void SWO_print_string(int port, const char *s)
{
    if ((ITM->TCR & 1) == 0) return;
    if ((ITM->TER & 1) == 0) return;
    while (*s) SWO_print_char(port, *s++);
    SWO_print_char(port, 0);
}

Now we can print to whatever port we want, and Percepio Trace, I find, will display that message and will also be showing which port it is sent at. Handy.

 

The third option is to use the tried and tested printf() solution, redirected to the Port #0 of the ITM. In doing so, we can also enable the printf()-style parameter passing, and we can display various variables' values. The caveat is that, like any printf()-style function, it is buffered, meaning that usually we need to terminate any string we display with a "\n", Carriage Return, otherwise nothing will be displayed in the Percepio Trace window for quite a while, until the buffer is full and then a huge amount of data will be sent to the Percepio Trace. In order to do this, though, we need to define two functions, _write() and _read(), which are the low-level functions that printf() calls to do the actual displaying of the formatted and processed string. Here's how we can do that:

#include <stdio.h>

int _write(int file, char *ptr, int len);
int _read(int file, char *ptr, int len);

int _write(int file, char *ptr, int len)
{
 int i=0;

 for(i=0 ; i<len ; i++)
 {
  ITM_SendChar(*ptr++);
 }
 ITM_SendChar(0);
 
 return len;
}

int _read(int file, char *ptr, int len)
{
 //dummy, does nothing, just to avoid linker error
 return len;
}

After that one can use printf() with normal parameters as one would on any other system, and all will be displayed in the Percepio Trace window:

printf("The value of idx is %d.\n", idx);

 

Again, if you don't place the Carriage Return to terminate the string, you might not see much I Percepio Trace. Also, the Carriage Return makes Percepio Trace not to look too well, due to the extra end of line. Here then comes the fourth solution.

 

 

What if I wanted to have a function that does not require my having to end the strings in the printf() with "\n", i.e. is there another way to flush the buffer? Apparently there is, and the function is fflush() and is called as fflush(stdout), which is what the ITM is in our case. Now we can pass fancy messages without worrying about the Carriage Returns. Here's the trick:

#include <stdio.h>
#include <stdarg.h>

int _write(int file, char *ptr, int len);
int _read(int file, char *ptr, int len);
_ATTRIBUTE ((__format__ (__printf__, 1, 2))) int myprintf(const char *__restrict format, ...);

int _write(int file, char *ptr, int len)
{
 int i=0;

 for(i=0 ; i<len ; i++)
 {
  ITM_SendChar(*ptr++);
 }
 ITM_SendChar(0);
 
 return len;
}

int _read(int file, char *ptr, int len)
{
 //dummy, does nothing, just to avoid linker error
 return len;
}

_ATTRIBUTE ((__format__ (__printf__, 1, 2))) int myprintf(const char *__restrict format, ...)
{
 __VALIST args;
 int return_value;

 va_start(args, format);
 
 return_value = vprintf(format, args);
 fflush(stdout);
 
 va_end(args);
 return return_value;
}

In this way I produced my own printf()-style function, myprintf(), which I don't have to terminate with a Carriage Return, as it flushes the stdout buffer after each call. Now all I have to do is:

myprintf("The value of idx is %d.", idx);

 

 

So here are four ways in which to instrument your code to get it work with Percepio Trace. Hope it helps.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meolsen wrote:
Debug->Percepio Trace->Settings

I was going to try this, could be useful but I don't have the Percepio Trace menu. I know I have seen it before but it's gone now (since the recent Atmel Studio update maybe?).

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Percepio Trace is an add-in, it needs to be installed from Atmel Extensions and Updates, it does not come as standard with the default Atmel Studio installation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes I did look there also, it's not listed. This is with version 7.0.1417.

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know about Atmel Studio 7.0.1417, as my version, which seems to be the latest, is 7.0.1188. Where did you get yours from?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's what you get if you update now. 

https://www.avrfreaks.net/forum/a...

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you know? I just checked for updates in my Atmel Studio, and, low and behold, there's an Atmel Studio 7.0.1417 update, 2.40 MB in size, saying "Changed USB drivers. Fixes issues reported with the installer. Improved handling of device support. Fixed issues."

 

I started the install, fingers all crossed....

Last Edited: Mon. Mar 20, 2017 - 12:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By Jove, you are right. Where has Percepio Trace gone?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ouch, I suppose it's good for me that it's not a problem with my Atmel Studio installation but you were actually using Percepio Trace sad
/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just curious, what is the difference between ITM and RTT for your needs? I have never used ITM, but with a Segger, I have always used RTT for terminal like real time output, including the Sam D series I have been playing with lately. The setup is pretty easy, include a RTT library and start printing to terminal from there. Is ITM more capable in some applications?

FI

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have had an Arduino Due for ages, and also Arduino Uno and Mega2560. Atmel ICE is a very good value debugger for covering both the AVR Arduinos and the ARM Arduino Due. My investigation was to see how much can be squeezed from an Atmel ICE if one wishes to go above and beyond the Arduino IDE. Atmel Studio is a logical stepping stone from Arduino IDE, and it has CMSIS and ASF to make your life easier if you want to do a bit more serious work, and to learn more about embedded software. RTT is Segger-specific, and although I have a J-Link Ultra, I was curious to get Atmel ICE to work with Perpecio Trace and the ITM, which I did not find investigated clearly on the Internet.

 

To sum it up, it was and is a pet project to maybe help others with getting more out of their Atmel ICEs and their Atmel Arduinos.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry to bring up a old topic, but I can't seem to get the printf to work with an ATMEL-ICE and Keil uVision4.   The debugger settings are pointing to CMSIS-DAP. http://www.keil.com/support/man/...

And and I can't tell if it SHOULD work... 

The link to the 'online user guide' that I would imagine should have the ICE/ITM compatibility, is dead:

https://www.microchip.com/Develo...

 

And according to the AN (apnt_274.pdf), it doesn't specifically mention ATMEL-ICE as not having it:

"15)  printf with ITM (Instrumentation Trace Macrocell):  ITM uses Serial Wire Viewer: 
This feature is only available with a Keil ULINK2, ULINKpro or a J-Link.  EDBG does not currently support SWV." 

And unforutnately, the Keil adapter listings don't spell out ITM, although they do list Instruction Trace on just the ULINKpro

Is it possibly a configuration/driver issue, or does the ATMEL-ICE not have SWD?

 

Thanks!

 

 

Last Edited: Mon. Jan 8, 2018 - 06:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm suffering on a similar problem on a SAME70-XPLD board using JLINK and the KEIL SDK. Even the standard examples did not work. The support from ARM/Keil let me know that on this board just the ULINKPro works. Not the ULINK2. I'm about to quit this task because it's too frustrating for me to dig in someones open development issues. RTT from SEGGER seems to be a good alternative.