• AVR Freaks

Hot!Anyone know how to make printf/fprintf write an entire line at a time?

Author
RDS Cliff
Junior Member
  • Total Posts : 56
  • Reward points : 0
  • Joined: 2016/09/23 11:50:05
  • Location: 0
  • Status: offline
2019/07/02 16:31:17 (permalink)
0

Anyone know how to make printf/fprintf write an entire line at a time?

I want to use printf/fprintf to write debug messages out of a Bluetooth connection.  Up to now, I've been using a UART, and was able to take over the write() function and redirect output as described in the Libraries Reference Manual. But the printf function has a little quirk that makes using it with BT difficult.
 
As others in the forum have observed, if the format string does not have any conversion markers(%), the string is passed in its entirety to the write() function in a single call.  But if any conversion is necessary, printf dribbles the string out one character at a time, making a separate write() call for each character.  This works fine for a UART but for Bluetooth, everything is in packets. So it is necessary to know when the last character in a string is received so a packet can be created and sent.
 
This is somewhat like the way a block device would operate so I looked in the FILE definition but couldn't figure out what the parameters in the FILE do.
 
So has anyone solved this problem?  Right now, I think I'm just going to cobble my own version of fprintf together using the sprintf() function.
#1

8 Replies Related Threads

    NorthGuy
    Super Member
    • Total Posts : 5479
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/02 16:41:50 (permalink)
    0
    You can accumulate characters until you get "\r\n" (or until your buffer is full), then pass the whole line to your BT.
    #2
    du00000001
    Just Some Member
    • Total Posts : 2767
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: online
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/02 17:04:25 (permalink)
    +2 (2)
    That's what sprintf() is for.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #3
    NKurzman
    A Guy on the Net
    • Total Posts : 17485
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/02 17:32:15 (permalink)
    0
    If you write to a Ring Buffer , instead of direct to the UART, then the Buffer can feed the bytes out as they are needed. And printf() does not need to sit and wait for the bytes to leave.
    But sprintf() to a buffer will work too if you have the RAM to spare. (or snprintf())
    #4
    aschen0866
    Super Member
    • Total Posts : 4459
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/02 18:17:05 (permalink)
    +2 (2)
    RDS Cliff
    This is somewhat like the way a block device would operate so I looked in the FILE definition but couldn't figure out what the parameters in the FILE do.

    According to the 16-Bit Language Tools Libraries Reference Manual, on Page 47, it states

    There are three types of buffering: unbuffered, line buffered and fully buffered. Unbuffered
    means a character or byte is transferred one at a time. Line buffered collects and
    transfers an entire line at a time (i.e., the newline character indicates the end of a line).
    Fully buffered allows blocks of an arbitrary size to be transmitted. The functions setbuf
    and setvbuf control file buffering.

    #5
    RDS Cliff
    Junior Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2016/09/23 11:50:05
    • Location: 0
    • Status: offline
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/08 21:46:51 (permalink)
    0
    Thanks for pointing out the setbuf and setvbuf functions.  I read page 47 early on and completely missed those functions.
     
    So I experimented with those functions for several days but I still can't get fprintf to do what I want.  Changed modes, set buffers. It looks like the fprintf function doesn't even use the buffer you give it.  And I had to dig deeper into pointers as it looked like fwrite was being called with a PSV pointer according to the MPLAB debugger.
     
    I've wasted too much time with this already.  Waving the white flag.
    #6
    NKurzman
    A Guy on the Net
    • Total Posts : 17485
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/08 21:53:55 (permalink)
    +1 (1)
    As noted you can use sprintf() or snprintf() to a buffer and then transmit that.
    You could then even print in the background with an interrupt instead of sit waiting for the transmission to finish.
    #7
    RDS Cliff
    Junior Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2016/09/23 11:50:05
    • Location: 0
    • Status: offline
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/08 23:24:06 (permalink)
    0
    Yes. Achieving the needed functionality is not a problem.  Using fprintf() just seemed more elegant since the mechanism for redirecting the output seemed to be there, ready to use.
    #8
    aschen0866
    Super Member
    • Total Posts : 4459
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: Anyone know how to make printf/fprintf write an entire line at a time? 2019/07/09 13:43:57 (permalink)
    0
    RDS Cliff
    ... It looks like the fprintf function doesn't even use the buffer you give it.  ...

    A simple test (simulator using UART 1) shows it does.

    char printBuf[20];
    int main(void)
    {
        int foo = 1234;
        setvbuf(stdout, printBuf, _IOLBF, sizeof printBuf);
        fprintf(stdout, "%s %d\n", "Hello World", foo);
       
        while (1);
        return (0);
    }

    printBuf contains "Hello World 1234\n" after fprintf.
    #9
    Jump to:
    © 2019 APG vNext Commercial Version 4.5