printf/LOG_printf on DSP side

Hello, I'm having some issues with printf on the DSP. I'm not clear
on how it is supposed to function and where the output is supposed to
go. Section 8.2 of the c6x compiler user's guide (SPRU187O) seems to
indicate that it should go to the console of the host (it also
indicates that the library source is in a file called rtssrc.zip which
I can't seem to find). According to the DSP/BIOS user's guide
(SPRU303B), LOG_printf output is sent to the trace manager, however
this seems to require CCS.

Interestingly, if I embed printfs in my DSP side code and time the
execution, it seem to take an order of magnitude longer to run, which
seems to imply it's trying to do something printfish. My current
setup is as follows:

Board rev C3
2.6.29-omap1
dsplink 1.61.03
code gen tools 6.0.16
bios 5.33.02
compiler 6.0.16

I've looked into using some of the various dsplink trace features, but
have generally found them lacking, although I'm aware that they are
designed to have minimal performance impact on the code. As an
alternative to printf, I'm considering writing a notification based
module that implements printf-like functionality using shared memory.
Obviously I'd rather not reinvent the wheel so it would be great if
someone could steer me in the right direction.

Thank you.

- Eric

Eric Cohen wrote:

Hello, I'm having some issues with printf on the DSP. I'm not clear
on how it is supposed to function and where the output is supposed to
go.

Hi Eric.

As far as I know the text ends up in the nirvana unless you have a
jtag-debugger attached.

I worked around this by writing my own printf-replacement using the
NOTIFY-mechanism of dsplink. E.g. the same thing that you've pland to
do. It worked well for me so far. The only issue is, that it does not
work directly from main. It needs a Task-environment because I use
semaphores to syncronize .

If you're interested I can rip the relevant code out of my test setup
and post it on my blog.

Interestingly, if I embed printfs in my DSP side code and time the
execution, it seem to take an order of magnitude longer to run, which
seems to imply it's trying to do something printfish.

I think the formated text ends up somewhere in a debug buffer that the
jtag polls. Oh and it does not only take a lot of time, it takes a lot
of stack as well.

Cheers,
    Nils Pipenbrinck

Nils Pipenbrinck wrote:

If you're interested I can rip the relevant code out of my test setup
and post it on my blog.

It's not as much code that I thought.. Here it is:

On the DSP-side:

// need a semaphore for syncronization:
static SEM_Handle dprint_sema;

// buffer for data-transfer, L2 cache aligned.
#pragma DATA_ALIGN(printf_buffer, 128);
static char printf_buffer[512];

void dprintf (const char * format, ...)
{
  int n;
  va_list args;
  va_start (args, format);
  n = vsprintf (printf_buffer,format, args);
  va_end (args);
  if (n<=0) return;

  // writeback cache:
  BCACHE_wb (printf_buffer, n, 1);
  // notify GPP:
  NOTIFY_notify (ID_GPP, 0, 6, (Uint32)printf_buffer);
  // wait for GPP acknowledge
  SEM_pendBinary (dprint_sema, SYS_FOREVER);
}

Void dprint_callback (Uint32 EventNo, Ptr arg, Ptr a_Info)
{
  // acknowledge gpp is done with reading the print-buffer:
  SEM_postBinary (dprint_sema);
}

static int TaskMain()
{
  dprintf ("Hello world from dsp-side\n");

  // your app goes here..

  for (;:wink: {}
}

Void main(Int argc, Char *argv[])
{
  // create the semaphore
  dprint_sema = SEM_create (0, NULL);

  // connect with gpp:
  DSPLINK_init ();

  // register callback from the gpp side:
  NOTIFY_register (ID_GPP, 0, 6, dprint_callback, 0);

  // start task:
  TSK_create(TaskMain, NULL, &0);

  // task will start as soon as main ends!
  // don't call dprintf from here!
}

Nils, thanks for the quick and helpful reply. That's pretty much
exactly what I had in mind. Would be nice if TI wrapped something
similar into dsplink, perhaps a DEBUG_ module or something.

Best,

Eric

Just wanted to say THANKS A LOT. This got me started with some easy
way to debug my apps! :smiley:

Actually, for some reason, my dprintf calls from inside the task dont
work :frowning:

From the main function, they work fine however. Any ideas why?

-Aditya

ApeWithABrain wrote:

Actually, for some reason, my dprintf calls from inside the task dont
work :frowning:

>From the main function, they work fine however. Any ideas why?
  
Hi Aditya,

calling the function from main is not a good idea. Semaphores are used
synchronize the ARM and DSP, and they need a task-context on the DSP.
The behavior outside a task is undefined and anything can happen.
Usually you'll just miss a message or two, but it could confuse the heck
out of the tasking system as well.

If dprintf doesn't work from inside a task make sure you have enough
stack space. vsprintf needs a lot of it, and it gets even more hungry if
you want to print floating point values. By default dspbios creates
tasks with only 4kb of stack. That may not be enough for your needs.

You can use the TSK_Attrs to change the stack size during task creation
like this:

  TSK_Attrs attrs = TSK_ATTRS;
  attrs.stacksize = 16384;
  TSK_create(TaskMain, &attrs, NULL);

Cheers,
    Nils

Hmm, that didn't seem to solve it :frowning:

I've posted my gpp and dsp src below. I just want to get something
very very basic going:

DSP : http://pastebin.com/uASDf5TQ

GPP: http://pastebin.com/j7tTECaC

Any help would be appreciated. I would assume 16K would be enough for
the dprintf

- Aditya

Please? Help? I tried walking through my code using the DSP_LINK
guide, but can't figure out why something like notify wouldn't work...

When I use LOG_printf with Code Composer Studio, it doesn't write the
message at the same place than printf. They are not the same, but you
can use printf with the DSP.

I dont have access to Code Composer, which is why I am trying to debug
using this printf statement specified above by Nils Pipenbrinck.