This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using System_printf with AM335x PDK

Other Parts Discussed in Thread: AM3358, SYSBIOS

Gentlemen,

I'm on a Windows 7 64-bit PC, developing code for an AM3358 on the AM335x Starter Kit, using CCS Version: 6.1.2.00015, and have recently installed Processor SDK RTOS AM335x v2.00.02.11, and SYS/BIOS 6.45.01.29  (installs with the PDK) released just about a week ago or so, and I am using XDCtools 3.32.00.06.

I am doing some test projects in order to get up to speed with TI-RTOS (SYS/BIOS with the PDK).

My adventure today started with setting up the functional clock to Timer3 with a 24 MHz input clock instead of 32KHz clock, so when the start-up code went to check that the frequency was correct, it called   Error_raise()  on line 1147 of XDCtools runtime library  Timer.c file, and ended me up (in the debugger) looking at the fact that I had hit the _exit() function and could not tell how I got there.

I pulled in the Startup.c and Error.c files into my project so I could step through them, and this is how I found it was calling the  Error_raise()   function.  This took a while.  And while I know how to fix the problem that got me there (the 32 KHz clock for the timer, and I have no problem doing this), I could not help but notice this VERY IMPORTANT FACT:  Error_raise()  appears to have been meant to present me with a VERY HELPFUL ERROR MESSAGE and I didn't get it!

And THAT is what I am pursuing with this E2E posting.

Error_raise()  eventually calls  System_printf()  with a nice error message indicating EXACTLY what went wrong.  But despite study and pursuing this for over and hour now, I have not been able to see this error message.  Nor have I been able to get System_printf()  (or just printf()) to work under any circumstances, and I'm hoping you can tell me what I'm doing wrong.

(Project attached.  3835.10_LEDBlink_SK_Clk.zip )

The instructions in the SYS/BIOS User's Guide (section 3.3.2) for using System_printf() seem VERY clear to me!  Use SysMin, I have set a 1024-byte buffer, and I have set a stop point (halting the processor), wherein it is my understanding that this is supposed to flush the buffer to the CCS Console.  But I have no messages (after having executed several System_printf()'s), and have checked all 3 Console windows, and none of them contain any hints of the  System_printf()  messages.

Help!

(I know this is going to GREATLY aid and speed up development, since if I HAD RECEIVED the helpful message from the  Error_raise()   earlier, it would have only taken me 2 minutes to fix the problem!  Now I CAN fix the problem, but I want to fix the fact that I didn't get the error message first, so I can take advantage of the (apparently) excellent error/diags system that is built into the SYS/BIOS!)

Kind regards,
Vic

  • Victor,

    I would expect the data to be rendered in the CCS CIO Console window. But this does require CCS to set a breakpoint to enable the CIO function. Check your CCS Debug Launch configuration and make sure this option is selected.

    Run > Debug Configurations...
    Select your configuration in the left-hand pane
    Target (tab) > Select
    Program/Memory Load Options > Select
    Enable CIO function use > Select

    As you figured out, System_printf delegates to the System.SupportProxy. Looking at your configuration, I see you are using xdc.runtime.SysMin. This means that the output from System_printf goes into the SysMin.output buffer, which you also figured out. I see you have set the size of this buffer to 1KB.

    To get the data from this buffer up to the CCS Console window requires "flushing" the buffer. To make this happen during your program execution, you must call System_flush. Maybe that is not happening. Call System_flush right after System_printf to force a flush. When flush is called, it will call the SysMin.outputFxn to physically move the data. I see that you did not configure this, so the default function is used, which is SysMin_output. This function calls HOSTwrite in the TI C Run Time Support library. This will write to the CIO buffer which CCS is watching (with the aid of the breakpoint). When this breakpoint is encountered, your target is actually halted while CCS uses the emulation support to read the target memory. CCS then renders the data in the console window and resumes execution on the target. This may happen several times depending on how much data to flush. The CIO buffer is quite small.

    Finally, if your program exits (e.g. assert fails), the default behavior is to flush the SysMin.output buffer. This is controlled by the SysMin.flushAtExit config param, which has a default of true. However, if exit is not called, then the final flush will not happen (for example, calling _exit).

    One last comment. This behavior is "nice" when you want to see data from your program while it is running. However, it is very intrusive (actually halts your program). A better way is to use the xdc.runtime.Log module, which also writes to a buffer but very efficiently. But, to see this data, you will have to halt the processor and use ROV. But the runtime performance (i.e. when the Logs are written) is much better.

    In your case where Error_raise was called before reaching main, I also wonder if this would work. Perhaps the error happened too early in the boot process for all the plumbing to be setup.

    ~Ramsey

  • Hi, Ramsey!

    And thank you very much for the quick turn-around time!  I do appreciate it.

    I have read about the Log_... functions and these ARE working, thankfully.  I do like how it moves some of the heavy lifting to the PC.

    However, still trying to get System_printf()  to work...

    I read the above carefully, and so far I THINK I have those bases covered.  Allow me to illustrate.  First, the launch configuration:

    Performing a flush after....  (this code is running in the context of a SWI which is posted in the context of an HWI):

    ...but nothing is showing up (as you can see) in the Console window.  (*shaking my head in disbelief* -- I AM SURE about 2 months ago I saw this actually WORKING -- including, I believe the  STDIO  printf was also (if I remember right) sending its data to the Console as well.  I was impressed at how easy it was, and now it's not working.  I checked the other 2 console windows too:  global build, and build outputs)

    Further, I tried the same thing:  System_printf()  followed by  System_flush()  inside the context of a task:

    ...but nothing in the output buffer (probably due to the flush?) and nothing in the Console window....

    So I get this silly feeling like what's getting in the road to this working is that I'm doing something silly like LOOKING IN THE WRONG PLACE, or missing something that is OBVIOUS to someone more familiar with this setup....

    This is the same project I uploaded while ago (I added the missing semicolon in main, and corrected the Timer3 clock so I could get past  main()).  Can you see what I'm missing here?

    Kind regards,
    Vic

  • ...for the record, the text passed to  System_printf()  is IN THE BUFFER before the  System_flush() is called.   (Note that I removed the FLUSH in main(), so the text from that  System_printf()  is also still in the buffer.

    But after System_flush(), I still can't find it in any of the Console windows....

  • Victor,

    In your screen shot of the Debug Configuration window, I see 'M3_wakeupSS' listed in the device menu. Would you pull down the device menu and see if there are any other options available. Sometimes, the device has multiple debug TAPs (Target Access Ports).

    In your Swi function (main_ToggleLed), I see you are calling System_printf and System_flush. Recall that Swi functions are not supposed to block. When using SysMin, the call to System_printf should be safe but if you were to reconfigure your application to use SysStd, then the call to System_printf might block. So that is risky. Also, I'm wondering if it is safe to call System_flush because that calls Hostwrite which might block. In general, I only call these functions from a task. I always use Log from a Swi. But, this also requires careful configuration because you might again use a logger which blocks (but that is more rare).

    Let's try a couple of debug experiments. Set a breakpoint right after a call to System_printf (but before any System_flush). Look in ROV a the SysMin output buffer. If you don't see your data, then that is problem #1. If this works, try the next experiment.

    Disable the CIO breakpoint in CCS. Re-launch your debug session. Set a breakpoint right after System_flush. Use a memory window to look at your CIO buffer. You should see your data. Remember the CIO buffer is small and circular. Keep your data short. If you don't see the data there, then the output function must not be correct.

    In your console screen shot, I see lots of data. Where is that coming from? Are you expecting to see your Sytem_printf data mixed in with this other data? What I see looks like the GEL command output, which I think is the wrong console. After loading and running your program to a breakpoint, pull down the console menu next to the icon in the toolbar. You should see a console name ending in ':CIO'. This is where your data should be.

    ~Ramsey

  • Victor,

    I've asked around and was informed that with GNU tool chain, you need to enable SemiHosting. This needs to be enabled in CCS and in your program. Looking at your screen shot above, it looks like you have already enabled SemiHosting in CCS. It is part of the Debug Launch Configuration.

    I'm guessing that you need to enable SemiHosting in your program. Add the following to your application config script.

    var SemiHostSupport = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport');

    Here is a link to a FAQ on SemiHosting. Click on item 5.1.

    The SYS/BIOS examples should also illustrate the SemiHost usage. You could import one of these and build it for GNU tool chain to see if it works.

    ~Ramsey

  • Hi, Ramsey!

    Re the Device dropdown being set that way -- I'm a little surprised, since I BELIEVE (and I could be wrong), the only thing I did along that line was select the debug probe here in Project Properties:

    ...and respond to a dialog box when I first built the project:  the dialog box had both the M3_wakeupSS and Cortex-A8 checkboxes checked, and I am fairly sure I unchecked the M3_wakeupSS and left the Cortex-A8 checked.  I actually DON'T know what it would mean to leave them both checked, so THIS may be part of my problem.  I ASSUMED that dialog box was asking me which CPU core I wanted to deal with, so I could have misunderstood what was being requested.

    Here is what I got when I opened the drop-down list you referred to (the XDS100v2 Debug Probe is part of the hardware on the Starter Kit board on the other side of a USB port i believe):

    What does it mean that it had "/M3_wakeupSS" at the end?  On a guess, I selected "/CortxA8" and tried it again, but got all the same results.

    In your Swi function (main_ToggleLed), I see you are calling System_printf and System_flush. Recall that Swi functions are not supposed to block. When using SysMin, the call to System_printf should be safe but if you were to reconfigure your application to use SysStd, then the call to System_printf might block. So that is risky. Also, I'm wondering if it is safe to call System_flush because that calls Hostwrite which might block. In general, I only call these functions from a task. I always use Log from a Swi. But, this also requires careful configuration because you might again use a logger which blocks (but that is more rare).

    I certainly wouldn't include such a function in a production application, since the SWI would have limited time to run.  Do you suppose this is "contaminating" something preventing output?  I tried removing the  System_flush()  from the SWI, but it didn't make any difference as far as text appearing in a console window.

    Let's try a couple of debug experiments. Set a breakpoint right after a call to System_printf (but before any System_flush). Look in ROV a the SysMin output buffer. If you don't see your data, then that is problem #1. If this works, try the next experiment.

    If you check out my first set of screen shots, I did this, and indeed the text IS in the buffer before the  System_flush()  is called.

    Disable the CIO breakpoint in CCS. Re-launch your debug session. Set a breakpoint right after System_flush. Use a memory window to look at your CIO buffer. You should see your data. Remember the CIO buffer is small and circular. Keep your data short. If you don't see the data there, then the output function must not be correct.

    You may have to help me with this part.  I have explored a bit with the Memory Browser (very cool tool!), but it would seem I need to be able to discover the address of the CIO buffer before going there, and a scan search in the source code and assembly code of A) the project, B) bios install directory, C) PDK installation directory, D) XDCtools installation directory only found 18 #define's and #ifdef's which didn't seem to lead to anything like a variable name & source file I could seek out in the debugger to determine the address.  Can you guide me here?

    In your console screen shot, I see lots of data. Where is that coming from? Are you expecting to see your Sytem_printf data mixed in with this other data? What I see looks like the GEL command output, which I think is the wrong console. After loading and running your program to a breakpoint, pull down the console menu next to the icon in the toolbar. You should see a console name ending in ':CIO'. This is where your data should be.

    If I'm understanding you correctly about "pull down the console menu next to the icon in the toolbar", this is what I have, and so you can see what I mean when I said above that I tried "all three console windows".  The one showing is indeed the GEL file execution output as the debugger was setting up the CPU for program loading and execution.  Previously, when (I believe) System_printf()  as well as  printf()   sent text to a window, I think I remember a NEW EMPTY console window popping up in this window's place and displaying the text, and ONLY the text output by one of the above functions -- if I am remembering correctly.  I have tried selecting the other 2 console windows and they only show the build output, and none of the text I'm looking for.

    The below screenshot shows the stop-point and the selection I have in terms of console windows (with none ending in ":CIO").

    1.  I will need your help about discovering where the CIO buffer is (I presume you're meaning in the processor), to inspect it and prove that the text is indeed being sent there.

    2.  I submit to your guidance on where I need to look next to get this debug text flowing again.

    Kind regards,
    Vic

  • Hi, Ramsey!

    Success!!!

    I saw your post about SemiHostSupport just after I posted the longer message with more screenshots in them.

    The results couldn't be more clear.  THAT was the answer.  (See screenshot below.)

    NOW I ALSO KNOW WHAT I CHANGED:  2 months ago, I was using TI compilers and pulling from existing examples.  Now I am using the GNU compiler (for no other reason than it seemed like it was my only choice for some TI-RTOS examples).  And I am also building my own examples from scratch now.  And THOSE TWO changes added an extra step it appears, that I was not doing.

    Here's the screenshot that shows it's now working.  Thanks a million!!!

    Kind regards,
    Vic

  • P.S. I got REALLY close to that HTML page yesterday (which also addresses System_printf() not working by the way in a separate section -- same answer: SemiHost). I read through:

    processors.wiki.ti.com/.../BIOS_FAQs

    and somehow found

    processors.wiki.ti.com/.../BIOS_for_the_28x

    which doesn't apply to my situation, but on a hunch, I tried to replace "28x" with "AM335x":

    processors.wiki.ti.com/.../BIOS_with_AM335x

    but the page is either empty, or that is the appearance (the Wiki software's response to a non-existent link?).

    I sure wish there was an exhaustive list of these links somewhere (all the /SYS/BIOS_with_... links), 'cause I probably would have already looked there. And I'm going to sit down now and study that whole page carefully in case I'm missing anything ELSE I need to know.... :-)

    Thanks again for the help, Ramsey!

    Kind regards,
    Vic
  • P.P.S.  To follow up some loose ends, I re-installed the original bug which brought me down this path (timer set at wrong clock speed), and was delighted now to see the following error message display on the (now visible) CIO console window.  Module#64 turns out to be

    <bios>/packages/ti/sysbios/timers/dmtimer/Timer.c  

    and line 1148 is where the  Timer_checkFreq()  function calls the  Error_raise()  function (and this is BEFORE entry to  main -- so as to answer one of your questions in your first reponse).

    So it works!

    Yeay!!!   :-)

    Kind regards,
    Vic

  • P.P.P.S. I also found out how to look in the CIO buffer:

    1. Go to RTOS Object View (ROV), select SysMin in the left pane, and Module Tab on the right pane.

    2. Observe "outBuf" column has address of buffer.

    3. Go to Memory Browser window and plug in that address in the top line and hit ENTER: the text (if the buffer is not flushed yet) is right there. In the Memory Browser window it is shown in HEX. However, in the RTOS Object View (ROV) in the "OutputBuffer" tab in the right pane, it shows the same text in ASCII (easier to read).

    :-)

    Kind regards,
    Vic
  • Victor,

    Great! I'm glad you worked it out. Thanks for posting your results and following up on the original timer output issue.

    Here are a couple of final comments.

    I don't know what each item in the device menu represents. You might ask on the hardware forum or CCS forum for more details. I would have used the CortxA8 entry.

    The memory browser understands symbol names. If you simply type in "cio" in the address text box, you will see a list of matching symbol names. You can then click on the one you want, __CIOBUF_ in this case. You can also search the generated map file for symbol names.

    You can also open multiple memory browsers, click the Open New View button in the memory browser toolbar. Then point one at the CIO buffer and the other at the SysMin.outputBuffer. They are two different buffers in memory. As you pointed out above, the address for the outputBuffer is displayed in ROV. You can also change the memory browser display from "32-Bit Hex - TI Style" to Character, use the pull-down menu on the left.

    Now, step over a System_printf call and you will see the outputBuffer update. Then step over a System_flush call and you will see the CIO buffer update.

    Happy coding.

    ~Ramsey

  • Hi, Ramsey!

    Outstanding tips! Thank you for following up the "loose ends". Much appreciated!

    Kind regards,
    Vic