• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » printf to RS232
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • printf to RS232

    printf to RS232

    This question is answered
    WILS ESE
    Posted by WILS ESE
    on Sep 06 2010 05:55 AM
    Prodigy60 points

    Hello,

    Does any one know how to modify the printf fonction and the UART in a way that when IAR executes a pritnf ("azerty = %d",var), i get the text of the printf fonction in my I/O terminal via an RS 232 link that comes from the MCU hardware board directly? I need this fonction to debug my code when NOT in simulation mode. Please help, any example code will be helpful !

     

    William

    printf support
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Jeff Tenney
      Posted by Jeff Tenney
      on Sep 06 2010 10:54 AM
      Verified Answer
      Verified by WILS ESE
      Guru10795 points

      William,

      Luckily, IAR has tried to make this pretty simple.  You don't have to rebuild the whole DLIB or CLIB.  Instead, start with the library copy of putchar.c and modify it for your target.  Then add your modified file to your IAR project.  If you also want to redirect scanf, use your own customized getchar.c too.  These files define the lowest level character I/O for printf and similar functions.  The files are decorated so IAR knows what to do with them when they are in your project.

      In the IAR "Compiler Reference", there is a section called "Overriding Library Modules".

      Jeff

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • WILS ESE
      Posted by WILS ESE
      on Sep 06 2010 13:30 PM
      Prodigy60 points

      hi Jeff,

      Thank you for your answer, so if i go down to the code, i have to put the return field of the printf fonction to the transmit buffer of my uart right?

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jeff Tenney
      Posted by Jeff Tenney
      on Sep 06 2010 16:46 PM
      Guru10795 points

      No, actually you want to change the implementation of putchar( ).  The original library version (in putchar.c) writes the character to a logical device, but your customized (modified, hacked) version will write the character to your UART after waiting for it to become available (or perhaps write the character to a queue serviced by a TX ISR).

      The printf( ) function does all of its complicated formatting and then it calls putchar( ) for every output character.  You don't need to mess with printf( ) or change the way you're calling it.  Instead, you are changing putchar( ), the low-level function that sends output characters for printf( ).

      When you look at putchar.c, you'll see the function, and you should see the part you want to modify / hack.  In my copy of the library, the code to be changed is inside the brackets of the following if statement:

      if (c != EOF)

      {

         // Your code here.  Put <c> into the TX buffer or queue.  Then return <c>.

      }

      Jeff

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • WILS ESE
      Posted by WILS ESE
      on Sep 06 2010 17:55 PM
      Prodigy60 points

      Okay, thanks a lot Jeff, i see the solution now !

      This will help me alot to debug in run time,  Because IAR does not update timer register values in real time ! i have  alot of trouble debugging my app !

      thanks again !

      William

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Cory Frey
      Posted by Cory Frey
      on Apr 02 2011 02:14 AM
      Prodigy230 points

      Jeff Tenney

      ...start with the library copy of putchar.c and modify it for your target.  Then add your modified file to your IAR project.

      Where can I find a copy of the putchar.c file?  I looked in the directory where the IAR is installed and I could not find anything there.

       

      -CoryF

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jeff Tenney
      Posted by Jeff Tenney
      on Apr 02 2011 14:44 PM
      Guru10795 points

      That's strange.  On my PC, it's at:

      C:\Program Files\IAR Systems\Embedded Workbench X.Y\430\src\lib\dlib\putchar.c.

      And here's the relevant excerpt from the manual.

      Good luck!

      Jeff

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Cory Frey
      Posted by Cory Frey
      on Apr 02 2011 21:45 PM
      Prodigy230 points

      I found some of the files here: "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0 Kickstart\430\src\lib\clib" but there is no putchar.c,  I found a getchar.c but there is no putchar.c which is what I need to put out a string/char to UART_A0.

      My "..\src\lib\dlib" does not contain a file called putchar.c

      -CoryF

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jeff Tenney
      Posted by Jeff Tenney
      on Apr 04 2011 10:38 AM
      Guru10795 points

      Hi Cory,

      I wrote this for you.  Put it in a file called putchar.c in your project.  Edit as necessary of course.

      // putchar function to write standard output to serial port

      #include "xstdio.h"
      #include <processor_specific.h>

      _STD_BEGIN

      int (putchar)(int c)
      {
         // **** BEGIN SPECIFIC CODE FOR ANSI TERMINAL ***** //
         //
         // For I/O with ANSI terminal (or equivalent), convert C
         // line end (\n) to carriage-return + linefeed combo (\r\n).
         //
         if (c == '\n') putchar('\r');
         //
         // (**** END SPECIFIC CODE FOR ANSI TERMINAL ***** //

         if (c != EOF)
         {
            while (!(UCA0IFG & UCTXIFG))
            {
               // keep waiting;
            }
            UCA0TXBUF = c;
         }
         return (c);
      }

      _STD_END

      Hope that helps!

      Jeff

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 05 2011 06:46 AM
      Guru140085 points

      Nice simple implementation.

      But I don't think it is fully correct.

      Putchar is not supposed to do any end-of-line char conversion (it's the job of the main program or the terminal function driver, if any). The data could be binary, putchar does not know. Only fputc would know that the stream is text mode, and do the conversion. But then, the putchar implementation would be

      int purchar (int char) { return fputc(stdout, char);}

      Also, putchar is not supposed to check c for EOF. it is supposed to return EOF if the put fails (which never happens in this implementation: worst case, it stalls if USCI hasn't been properly initialized and UCTXIFG is never set).

      I'd add

      if(UCA0CTL1 & UCSWRST) return EOF; // USCI not active

      right at the start of putchar.

      However, this implementation can be as complex as one wants, including buffered background transfers, or using I2C/SPI instead of UART or any oither method of pushing data, including a complex handling of a display.

       

      Additional explanation of the missing putchar():

      The MSP does not have a 'standard output', so there cannot be a putchar implementation. The IAR implementaion in DLIB is based on a breakpoint placed in an empty putchar, so the debugger is notified whe someone is calling this funciton and it can silently 'peek' the char from the MSP. (with all side-effects of a debugger interruption). THis is, however, not portable and not usable for communication with own PC software such as putty.

       

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jeff Tenney
      Posted by Jeff Tenney
      on Apr 05 2011 12:54 PM
      Guru10795 points

      In IAR, putchar( ) is used only for printf( ).  Low-level stream insertion occurs in __write( ), not putchar( ).  In fact, the default implementation of putchar( ) uses  __write( ) to do the work.  So "hacking" putchar is generally a safe thing to do since you're only affecting printf( ) (and not affecting all stream output).

      Also the std streams are by definition character based, right?  They are not intended to operate in binary mode.

      Also the quick version of putchar( ) above works whether the target application uses CLIB or DLIB and regardless of DLIB configuration.

      Also std streams are not to be closed, so sending EOF over the standard stream is probably not wise.  The stream listener could potentially stop.

      The IAR implementation of putchar in DLIB merely calls fputc( ) (for DLIB with file support) or directly calls __write() otherwise.  The C-Spy terminal mechanism is not normally included.  However, if the developer requests the terminal mechanism at build time, then the linker uses different low-level code to support the breakpoint approach.  Note that this mechanism does not work in putchar( ) since putchar( ) isn't called for "cout".  Instead, the __write( ) function invokes the breakpoint mechanism (among half a dozen other functions).

       

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 06 2011 13:17 PM
      Guru140085 points

      Jeff Tenney
      In IAR, putchar( ) is used only for printf( ).

      But there' snothing that forbids using putchar() yourself to output a single char. Instead of putch(). Putch() writes to the console, while putchar() writes to stdout (which is usually the same on most standard configurations and has the same non-existent meaning on plain MSP)

      Jeff Tenney
      n fact, the default implementation of putchar( ) uses  __write( ) to do the work

      That's an assumption you may only make if you intend to never link to a different CLIB ever. It may change without notice between compiler versions and also across compilers.

      Jeff Tenney
      std streams are by definition character based, right?  They are not intended to operate in binary mode.

      Ah, no. character based, yes, but character bases is not the opposite to binary mode. It i svalid to assign a totally different stream to stdout:

      flcose(stdout);
      stdout=fopen(...);

      Whether a CR/LF expansion is to be done depends on the parameter to fopen and is totally unknown to putchar. As well as the existence (or not) of EOF.

      putchar(x) is effectively an alias to fputch(stdout,x), where stdout is not a constant, but a normal stream pointer. Which usually is preloaded with an implicit fopen("con:","w") (for DOS/WIndows) on program start. (or in case of the MSP with a simulated fopen).

      Jeff Tenney
      putchar( ) isn't called for "cout".

      Right. Since cout is console output, not stdout. cout uses putch(). Which may be implemented as alias to __write(), but this is an implementation detail and therefore internal to the library.

       

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use