This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Lost printf() output using ULink2

I've got code in my project to dump out a data buffer using printf.  STDOUT is redirected to the ULink2/uVision "Debug (printf) viewer".

It should produce output like this:

00000000:  00020400 00000000 5C0C0000 5C0C0000  ........\...\...
00000010:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
00000020:  5C0C0000 5C0C0000 C2030000 5C0C0000  \...\.......\...
00000030:  5C0C0000 B4050000 5C0C0000 5C0C0000  \.......\...\...
00000040:  5C0C0000 F4050000 5C0C0000 5C0C0000  \.......\...\...
00000050:  20060000 5C0C0000 5C0C0000 5C0C0000   ...\...\...\...
00000060:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
00000070:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
00000080:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
00000090:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
000000A0:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
000000B0:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
000000C0:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
000000D0:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
000000E0:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
000000F0:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...

but what I get in the debug viewer is this:

0000 5C0C0000  \...\...\...\...
00000050:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
00000060:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
00000070:  5C0C0000 5C0C0000 5C0C0000 5C0C0000  \...\...\...\...
00000080:  5C0C0000 C8020000 5C0C0000 5C0C0000  \.......\...\...
FFFFF00  ................

I suspect some form of overrun is occurring.  If I step through the code I get all the output as I expect.

Code:

void dumpHex(const void* DataPointer, size_t DataLength)
{
	if (NULL != DataPointer)
	{
		char             StringBuffer[100] = { '\0' };
		const unsigned char* p = (const unsigned char*)DataPointer;
		unsigned char* pd;
		unsigned char* pa;
		size_t           PointerSize = sizeof(void*);
		size_t           DataOffset = (PointerSize * 2) + 2;
		size_t           AsciiOffset = DataOffset + 38;
		size_t           LineLength = AsciiOffset + 16;
		size_t           index, i;
		int              n;


		index = 0;
		while (index < DataLength)
		{
			pd = (unsigned char*)StringBuffer + DataOffset;
			pa = (unsigned char*)StringBuffer + AsciiOffset;

			memset(StringBuffer, ' ', LineLength);
			n = snprintf(StringBuffer, sizeof(StringBuffer), "%p", (void*)(index));	
			StringBuffer[n] = ':';

			for (i = 0; (i < 16) && (index < DataLength); i++)
			{
				if ((i % 4) == 0) pd++;

				*pd++ = HEX[*p / 16];
				*pd++ = HEX[*p % 16];
				*pa++ = (' ' == *p || isgraph(*p)) ? *p : '.';

				index++;
				p++;
			}

			printf("%s\n", StringBuffer);
		}
	}
}


I tried adding timer delays after the printf for each line of the data but that didn't change things much :(

What do I need to do to ensure I get all the output?

Thank you, David

  • I added 500ms delays between every printf() in the code and I'm still getting Trace: HW Buffer overrun and entire lines are going missing.  Surely the ULink2 isn't *that* slow?

    I even tried extending the delay to 1000ms (yes a WHOLE second) and the problem still occurs.

    Puzzled, David

  • Hmmm This has to be a problem with the ULink2 firmware - I added every increasing delays to my code that sends the data on the ITM port and it didn't change the behaviour:

    #define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
    #define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
    #define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))
    
    #define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
    #define TRCENA          0x01000000
    FILE __stdout;
    FILE __stdin;
    
    int fputc(int ch, FILE *f)
    {
        microDelay(10);     // wait 10us before sending character
        if (DEMCR & TRCENA)            // Only if ITM is available
        {
            while (ITM_Port32(0) == 0);  // Block until room in ITM FIFO
            ITM_Port8(0) = ch;          // Write the data
     	}
        return(ch);
    }

    Anyone from Keil ULink team watching?

    David

  • Hello, this could be a baud-rate configuration issue.

    I'm not familiar with the particular device you are using, but you can measure the output rate of SWO pin with an oscilloscope, then set the SWO speed appropriately in Target Options > Debug > (ULINK2/ME) > Settings > Trace.

  • That makes a good deal of sense to me - next time I use ITM redirection I'll take a look at that.

    Many thanks, David