Reply
Posts: 21
Registered: ‎08-31-2016
Accepted Solution

How to do printf over C2D interface

I have a board with a C8051F850. As can be seen from the attached schematic, i don't have access to the UART0 pins (P0.4 and P0.5). However the chip is programmed "in-circuit" via the J10 "Debug" pins which uses the C2D interface. I first test my code on a "Toolstick Daughter Card" where i have access to UART0 and thus can output printfs for debugging. The same code is then #ifdef'ed without UART0 for my target board. How can i get printf via C2D for the "in-circuit" chip on my target board? Debugging via Simplicty Studio v3 watchpoints/breakpoints is rather painful.

 

Appreciate your suggestions.

Posts: 2,308
Registered: ‎10-14-2014

Re: How to do printf over C2D interface

@Ramanathan_R

Very interesting requirement.

Basically I don't think C8051F850 firmware could make C2 interface to work as a COM port. The C2 is mainly work as debug and programming interface and accessed by external (like PC and Toolstick daughter card or UDA).

 

If you don't need to debug your code in real-time, maybe you could print the message in a part of internal flash, then use the "toolstick or UDA" read back the content of the flash.

 

But this is not convenient and I don't think it could satisfy your requirement. Using the SS debug feature still is the best solution for you.

 

For how the C2 interface works, you could get the protocol spec in below application note.

https://www.silabs.com/documents/public/application-notes/AN127.pdf

 

My views are my own and do not necessarily represent the views of Silicon Labs

 

 

WeiguoLu
Posts: 21
Registered: ‎08-31-2016

Re: How to do printf over C2D interface

@deluJust to clarify, i am looking for a way where i can output a sequence of characters (eg. printf) over C2 interface so that i can see all the output in the console window of SimplicityStudioV3. It doesn't have to be UART output per-se.

A comparable example is Eclipse/OpenOCD/BusblasterJTAG with STM32. Here i am using SimplicityStudio/Toolstick Debug Adapter/C2 with C8051F850.

Posts: 2,308
Registered: ‎10-14-2014

Re: How to do printf over C2D interface

@Ramanathan_R

I don't think this is possible with C2 interface.

My understanding is that the C2 is mainly accessed by debugger, the firmware run on the MCU could not control the C2 behavior.

 

For 32b Cortex-M based MCU like EFM32, they are different and use the standard ARM debug peripheral.

 

I don't think your requirement is feasible on the Silabs 8b MCU with C2 interface.

 

My views are my own and do not necessarily represent the views of Silicon Labs

WeiguoLu
Posts: 21
Registered: ‎08-31-2016

Re: How to do printf over C2D interface

@delu

Ok, Thanks for your responses. Tough luck for me :-)

 

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,173
Registered: ‎04-27-2004

Re: How to do printf over C2D interface


 How can i get printf via C2D for the "in-circuit" chip on my target board? 

As mentioned, this path is not supported.


i don't have access to the UART0 pins (P0.4 and P0.5). 

If you are all set up for UART debug, and started with USB debug, isn't the obvious step to get access to the UART pins ?!  

 

If you want a separate terminal path, something like CP2102N-MINIEK is a low cost way to have UART entirely separate from Debug.

 

The other workaround, is to printf to spare memory, and inspect that memory in the debugger.

However, the F850 does not have a lot of spare memory..., so you need to be frugal.

 

 

Posts: 3,092
Registered: ‎02-07-2002

Re: How to do printf over C2D interface

This would be possible if the debugger would support a polling implementation for reading a fifo/ringbuffer in memory. But it doesn't do that.

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface

Psh, all these naysayers...

 

One interesting thing about C2 is that it seems like it can read and write memory on-the-fly without halting the CPU. One other interesting thing is that Silicon Labs provides a DLL to access the debugger (documented in AN117, downloadable from... somewhere... maybe already in the old Flash Programmer download? Should be in AN117SW, but I can't seem to find this archive)

 

The DLL supports all sorts of operations -- the two you'd be interested in is:

 

HRESULT GetRAMMemory( BYTE * ptrMem, DWORD wStartAddress, unsigned int nLength)
HRESULT SetRAMMemory( BYTE * ptrMem, DWORD wStartAddress, unsigned int nLength);

(There's also an XRAM version that you'll probably end up using, now that I think about it)

 

 

As this is a "C"-style DLL, you should be able to easily call it from C/C++/C#/Java/Python/whatever.

 

On the microcontroller side, consider a blocking call like this:

 

char xdata printData[256]   _at_ 0xE000;   /* array at xdata 0xE000 */

void main()
{
   uint16_t i = 0;
   while(1) {
      sprintf(printData, "Hello, world #%u!\n", i); // print "Hello, world #0 (etc)
      printData[255] = 1; // tell the computer software we're ready to read
      while(printData[255] == 1); // wait for the computer software to reset our flag
   }
}

 

Your computer software could continually read 256 bytes of XDATA start at 0xE000, and as soon as it sees the last byte set to "1", know to print the contents of that message to the window. It would then reset the byte to a "0" to notify your MCU to continue program execution.

 

I haven't tested any of this -- but you got me excited to try it out when I get home! Could definitely come in handy, as I often have the UART in use for other stuff.

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface

Man, I wish I could edit posts. Few bugs in my code I wanted to fix, but it seems like Silicon Labs turned that feature off.

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface

Posts: 3,092
Registered: ‎02-07-2002

Re: How to do printf over C2D interface

Yes, you can probably roll your own. But that probably doesn't play well with a concurrent debugging session. Or does it?

 

Further I would prefer a ringbuffer over a blocking function. Implement your own putchar and you have printf redirected. A ringbuffer without count, but only tx- and rx-index is inherently atomic if size <= 256.

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,173
Registered: ‎04-27-2004

Re: How to do printf over C2D interface


funkathustra wrote:

Psh, all these naysayers...

.... 

The DLL supports all sorts of operations -- the two you'd be interested in is:

 

HRESULT GetRAMMemory( BYTE * ptrMem, DWORD wStartAddress, unsigned int nLength)
HRESULT SetRAMMemory( BYTE * ptrMem, DWORD wStartAddress, unsigned int nLength);

I haven't tested any of this -- but you got me excited to try it out when I get home! Could definitely come in handy, as I often have the UART in use for other stuff.


 

Let us know how you get on Robot Happy

 

A while back I played with 'C2D extras', and yes, I could look at areas of RAM (just the same as  one can on a debugger) after the part was flipped into C2D mode.

 

I also wanted to enter C2D, change SFRs and then RUN without reset, (just like Debug must do), but that vital piece seems to be missing from the DLL. (Debug itself must have this ability in order to step )

 

Overall comment :

In general Debug, I often dump capture reports aka printf type use, into spare IRAM or XRAM, then after break you can copy that from Debug View.

This has far less time and code overhead than sprinkled printf's.

This is a variant on "printf over C2D interface".

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface

gitkraken_2017-07-16_01-38-03.png

Alright, I tossed together a quick app demonstrating what I was talking about. Full source code is up on GitHub. I have some pre-built binaries, too.

 

This is more or less exactly what I mentioned in my previous post. The only major change is that the "flag" is no longer "1" or "0" -- but instead, indicates the length of the message the computer should read. C2 seems fairly slow, so the fewer bytes we read, the better. Variable-length packets seem to help a ton with speed.

 

Two big caveats:

  • Obviously, when my program is connected to your debugger, nothing else can connect to it.
  • Remember what I said about reading/writing RAM while the target was running? J/k... you can't do that. My program halts the target, reads the data, and resumes the target. Anyone reading should be able to understand the implications of this with respect to interrupts/etc.
  • My program uses SiUtil.dll, the only publically-available API for C2 debuggers that I know of. Unfortunately, the latest version I found will install Firmware Version 19 on your debugger. Whenever you fire up Simplicity Studio, it will silently/automatically replace it with Version 20. You may have to close Simplicity Studio (or disable the debugger auto-discovery), or you'll consistently get messages like this:
    FlashUtil_2017-07-16_01-46-29.png

 

Perhaps someone at SiLabs can get me an updated copy of SiUtil (or whatever is equivalent), and I can integrate it into my software?

 

 

Other than that, it seems more or less stable-ish. I haven't done any formal benchmarks, but it seems  slower than serial printing at 115200. I didn't see any way to adjust the debugger's clock speed through the SiUtil interface, but perhaps someone knows a way to do this.

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,173
Registered: ‎04-27-2004

Re: How to do printf over C2D interface


funkathustra wrote:

  •  My program halts the target, reads the data, and resumes the target. 

Sounds good.

When you resume, are the SFR's preserved, or does it resume-via-reset ?

When I last played with this, I could run-read, but could not find a way to resume without via-reset.

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface

When you first connect to it, it resets. But once the debugger is attached, the target halt/go commands seem to pause/resume the target; otherwise it wouldn't count up continuously in my testing. I wish there was a way to nonintrusively attach a debugger to the target.

I'll probably add a hex file flashing function to the app, so it's easier to iterate development. Maybe even a file watcher so it will automatically upload the new hex file on change.
Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface

Alright, after playing around a little, I realized that the slab8051.dll in Simplicity Studio has essentially the same API as the old SiUtil.dll file I was calling into. I switched the app over to the new DLL file, so the program can now be used concurrently with Simplicity Studio (obviously not while in a debug session).

 

There's some interesting undocumented functions in this DLL, like SetC2ClockStrobe(byte val), but it doesn't seem to affect performance from a macroscopic level.

 

I also added a 20 ms delay (this will eventually be user-configurable), just so the MCU has time to actually do stuff (other than print "hello world").

 

Grab that release here.

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,173
Registered: ‎04-27-2004

Re: How to do printf over C2D interface


funkathustra wrote:
When you first connect to it, it resets. But once the debugger is attached, the target halt/go commands seem to pause/resume the target; otherwise it wouldn't count up continuously in my testing. 

 FWIR, RAM is not changed (unless you have some init-clear), so RAM vars would INC ok,  but SFRs did reset.  Did you try with a SFR located counter ?

or can you read an incrementing 32b timer ?

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface


jmg wrote:
FWIR, RAM is not changed (unless you have some init-clear), so RAM vars would INC ok,  but SFRs did reset.  Did you try with a SFR located counter ?

or can you read an incrementing 32b timer ?


Instead of commenting from your armchair, why not check out the code and try it out yourself? I have pre-built binaries that should take you all of 5 minutes to download and get running.

 

Addressing your concerns specifically, my example program sets all the bytes in the buffer to 0 on start-up, so if it were resetting, the print messages would never increment.

 

Also, from an implementation standpoint, the ReadRAM/ReadXRAM functions would be pretty worthless if you could only do them by resetting the target. This is the same interface that Simplicity Studio uses to interact with the debugger during a debug session, so it behaves very similarly.

 

I put up a blog post that goes into some of the design/background of the C2 printf trace program in a bit more detail if you're curious.

 

It's funny how I was just in this predicament a few weeks ago, and didn't even think to frame it this way in my head. I haven't heard back from the OP, but I'd like to thank them for the inspiration Robot Happy.

 

 

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,173
Registered: ‎04-27-2004

Re: How to do printf over C2D interface


Addressing your concerns specifically, my example program sets all the bytes in the buffer to 0 on start-up, so if it were resetting, the print messages would never increment. 


OK, that's a useful test reference point.

When I'm next at the test bench I'll check again, ISTR I was not using the DLL, but a lower level C2D, and missing from that was any mention of a run-without-reset command.  

Clearly, the debugger has that, and your tests show the DLL can access it too.

I wonder what is actually sent over C2D to restart without reset ?

Posts: 21
Registered: ‎08-31-2016

Re: How to do printf over C2D interface

@funkathustra  Thanks for all your great suggestions and pointers. Will try it out.

Posts: 21
Registered: ‎08-31-2016

Re: How to do printf over C2D interface

@jmgGreat idea! Maybe i should change my code to do something like this for uniform debugging.

Posts: 21
Registered: ‎08-31-2016

Re: How to do printf over C2D interface

@funkathustraThanks very much for your code/sample how-to. I am sure it will be useful to a lot of folks.  It is always a pleasure to trigger some ingenuity in other folks brains Smiley Happy

 

Highlighted
Posts: 21
Registered: ‎08-31-2016

Re: How to do printf over C2D interface

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface


jmg wrote:

I wonder what is actually sent over C2D to restart without reset ?

 

When I decompiled slab8051.dll to figure out how to call into it, I got out the entire C2 protocol.

 

When you first connect to the debugger from your program, it resets the MCU using the C2CK/RST signal, I believe; it looks like the debugger does this implicitly; in other words, there's nothing in the DLL that explicitly tells the debugger to reset the target.

 

Once my program connects to the debugger, it doesn't issue a reset command -- just "go" and "halt" commands, between which it reads and writes the memory. It looks like the "go" command is an op-code of "36" and the "halt" command is an op-code of "37", if that's what you're wondering about.

 

Interestingly, it looks like the DLL itself is preventing reading RAM while the target is running; I don't think it's a technical limitation of the adapter itself. I might try to modify the DLL so I can call ReadRAM() without halting the target, just to see what I get out of it.

 

 

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,173
Registered: ‎04-27-2004

Re: How to do printf over C2D interface


When I decompiled slab8051.dll to figure out how to call into it, I got out the entire C2 protocol.


Very clever.


Once my program connects to the debugger, it doesn't issue a reset command -- just "go" and "halt" commands, between which it reads and writes the memory. It looks like the "go" command is an op-code of "36" and the "halt" command is an op-code of "37", if that's what you're wondering about. 


Great. Those sound different from what I could find, and do sound like the missing pieces, I'm guessing those are in HEX ?

I just have to find time to retry this...

 

Another thought : if you have C2D humming along nicely, can you try code fastest 'Enter Debug and Erase the Chip' ?  

It would be nice to have an 'unbrick pgm', for those who go too fast into power down.... Robot Happy

 

I'm not convinced this is a chip-level brick wall (pardon the pun), but more like upstream SW a bit lazy.

Silabs did add a 0x04 command recently, (now 0x02,0x04,0x01) which I think is some Halt cmd.

 

Posts: 67
Registered: ‎09-15-2015

Re: How to do printf over C2D interface


jmg wrote:

Another thought : if you have C2D humming along nicely, can you try code fastest 'Enter Debug and Erase the Chip' ?  

It would be nice to have an 'unbrick pgm', for those who go too fast into power down.... Robot Happy

 

I'm not convinced this is a chip-level brick wall (pardon the pun), but more like upstream SW a bit lazy.

Silabs did add a 0x04 command recently, (now 0x02,0x04,0x01) which I think is some Halt cmd. 


Good idea -- I'll have to play with that. I actually just ruined an EFM8SB1 last month because of an accidental comment-out that ended up sleeping my MCU on reset. Whoops!

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero</font></font> </a> jmg
Posts: 1,173
Registered: ‎04-27-2004

Re: How to do printf over C2D interface


Good idea -- I'll have to play with that. I actually just ruined an EFM8SB1 last month because of an accidental comment-out that ended up sleeping my MCU on reset. Whoops!

Was that a new revision part, with a bootloader ?

In another thread someone suggested using the boot pin to recover from sleep-too-fast syndrome.

Not sure if STKs have new parts yet, first ones do not.

Posts: 544
Registered: ‎10-12-2004

Re: How to do printf over C2D interface

Hey all,

 

First off, this is a really cool project, and something we've been looking at adding for a bit.  Thanks for putting this together!

 


funkathustra wrote:

 

Interestingly, it looks like the DLL itself is preventing reading RAM while the target is running; I don't think it's a technical limitation of the adapter itself. I might try to modify the DLL so I can call ReadRAM() without halting the target, just to see what I get out of it.

 


Note that there are some limitations in the device itself that prevents this from happening.  Unlike the ARM devices, the 8051's don't have an extra pathway for the debug logic to access registers at the same time as the core.  To make things work, you do need to halt the core, read a register through debug, then restart the core.

 

~Tabi

Tabitha Parker
Senior Manager of MCU and Micrium Applications
Silicon Laboratories