Jump to content
43oh

(yet again another boring) question about energia / printf


Recommended Posts

greetings,

 

my wireless sensor project using the CC3200(mod) is coming up great and progressing fast.

 

As I'm porting some code from my previous platform (pic + CC3000), I'm having trouble with the usual suspect printf.

 

on the one hand, I've used simplified variants of printf in some arduino programs but I would definitely have the use of the full versatility of the stock printf as I'm far from the code size limit.

 

In my previous platform / compiler, I just needed to provide the low level function that maps the output of printf to the UART, like putc or putchar.

I've also read a similar post / question with the suggestion to redefine / override putchchar in the main code,

 

however, this doesn't compile as I'm trying to redefine something that is a #define and not a function.

 

my printf calls compile, they just don't output anything. What would be the best practice to have printf properly redirected to the UART ? I've read that it's not so good to try to override stock functions from the standard libraries, so I feel a bit stuck there.

 

thank you for your help,

Erv'

Link to post
Share on other sites

Well, actually it doesn't compile :(

 

error links to stdio.h. I've noticed that the structure for code structure for printf, puchar and putc in stdio.h is quite different between the msp version and the one used with the CC3200.

 

v1_1.ino:34:5: error: expected unqualified-id before '--' token
v1_1.ino:34:5: error: expected ')' before '--' token
v1_1.ino:203:1: error: expected declaration before '}' token

 

don't know what to do next. Anybody has done it with energia on an arm platform ?

Link to post
Share on other sites

I've just added this.

 

#undef putchar
int putchar(int c) {
    Serial.write©;
    return©;
}
 

 

It doens't matter where it's located in the main .ino. Same when inserted in another C file.

 

if I comment the line

//#define    putchar(x)    putc(x, stdout)

 

in stdio.h, it does compile but still doesn't work (doesn't produce any char).

I've tested compiling the above in a blank project without commenting stdio.h, same errors. Again, the stdio.h structure seems quite different compared to the MSP430 version where you're just asked to actually *provide* your own putchar (what I was doing on my previous platform).

Link to post
Share on other sites

I didn't manage to get _write_r() working with printf(), but if you're willing to use fprintf(), you can use fopencookie() in obvious ways (once you find the documentation!)

#include <stdio.h>

ssize_t myWrite(void *cookie, const char *buf, size_t n)
// wrapper function
{
  return Serial.write((uint8_t*)buf, n);
}

cookie_io_functions_t myVectors = { 0, myWrite, 0, 0 };
FILE *myOut;

void setup() {                
  Serial.begin(115200);
  myOut = fopencookie((void *)(&Serial), "w", myVectors);
  setlinebuf(myOut);
  fprintf(myOut, "This is an fprintf demo\n");
}

Including printf and stdio stuff adds about 20k to your sketch, apparently, and there are subtleties to stdio buffering so you might need some fflush() calls as well (or play with buffering options other than setlinebuf())

There's probably a way to "redirect" stdout to the cookie file so you could use regular printf()...

Link to post
Share on other sites

There's probably a way to "redirect" stdout to the cookie file so you could use regular printf()...

OK.   Now I'm feeling a little embarassed, thinking that stdout was more magical than it actually is.  How about just:

ssize_t myWrite(void *cookie, const char *buf, size_t n)
{
  return Serial.write((uint8_t*)buf, n);
}

cookie_io_functions_t myVectors = { 0, myWrite, 0, 0 };

void setup() {                
  Serial.begin(115200);
  stdout = fopencookie((void *)0, "w", myVectors);
  setlinebuf(stdout);
  printf( "This is an fprintf demo\n");
}

To me, this seems cleaner and more obvious than the mechanations you'd otherwise have to go through to provide a C _write_r() function that called C++ Wiring core functions...  I don't know whether it has "baggage" brought in my calling fopen()...

Link to post
Share on other sites

OK.   Now I'm feeling a little embarassed, thinking that stdout was more magical than it actually is.  How about just:

ssize_t myWrite(void *cookie, const char *buf, size_t n)
{
  return Serial.write((uint8_t*)buf, n);
}

cookie_io_functions_t myVectors = { 0, myWrite, 0, 0 };

void setup() {                
  Serial.begin(115200);
  stdout = fopencookie((void *)0, "w", myVectors);
  setlinebuf(stdout);
  printf( "This is an fprintf demo\n");
}

To me, this seems cleaner and more obvious than the mechanations you'd otherwise have to go through to provide a C _write_r() function that called C++ Wiring core functions...  I don't know whether it has "baggage" brought in my calling fopen()...

I had never heard of fopencookie 'til now.  Wow!

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...