ervplecter 1 Posted March 31, 2015 Share Posted March 31, 2015 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' Quote Link to post Share on other sites
roadrunner84 466 Posted March 31, 2015 Share Posted March 31, 2015 How about undefining the define? #undef putchar void putchar(int ch){/*stuff goes here*/} Ideally, the printf function should not exist in an embedded platform, due to lack of a console... Quote Link to post Share on other sites
ervplecter 1 Posted March 31, 2015 Author Share Posted March 31, 2015 thanks a lot, I'll give it a try !! I do have a terminal connected via serial (USB) on my module, I use it as a console, with a small command interpreter. Quote Link to post Share on other sites
ervplecter 1 Posted April 1, 2015 Author Share Posted April 1, 2015 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 '--' tokenv1_1.ino:34:5: error: expected ')' before '--' tokenv1_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 ? Quote Link to post Share on other sites
roadrunner84 466 Posted April 1, 2015 Share Posted April 1, 2015 I don't think this is in any way related to your putchar() issue, can you post your code, so we can see what's wrong? Quote Link to post Share on other sites
ervplecter 1 Posted April 1, 2015 Author Share Posted April 1, 2015 I've just added this. #undef putcharint 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). Quote Link to post Share on other sites
spirilis 1,265 Posted April 1, 2015 Share Posted April 1, 2015 I think the CC3200 uses Newlib, since it is using the ARM GCC compiler. Try providing a _write_r() function as detailed in this guide: http://www.billgatliff.com/newlib.html Sent from my Galaxy Note II with Tapatalk 4 Quote Link to post Share on other sites
spirilis 1,265 Posted April 1, 2015 Share Posted April 1, 2015 I have implemented the Newlib stubs before so printf() works perfectly, but it took some trial and error. Also recommend your newlib stub functions be surrounded with extern "C" { above and }; below the code functions. Sent from my Galaxy Note II with Tapatalk 4 Quote Link to post Share on other sites
westfw 10 Posted April 5, 2015 Share Posted April 5, 2015 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()... Quote Link to post Share on other sites
westfw 10 Posted April 5, 2015 Share Posted April 5, 2015 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()... oPossum 1 Quote Link to post Share on other sites
ervplecter 1 Posted April 13, 2015 Author Share Posted April 13, 2015 worked perferly thanks a lot Quote Link to post Share on other sites
spirilis 1,265 Posted April 13, 2015 Share Posted April 13, 2015 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! bluehash 1 Quote Link to post Share on other sites
westfw 10 Posted April 14, 2015 Share Posted April 14, 2015 >> I had never heard of fopencookie Me either. avr-libc has "fdev_open" and "fdev_setup_stream" on top of their much more primirive "stdio" library, and I figured that newlib (the libc used on ARM Energia implementations) must have something similar. Then it was just a matter of finding it :-( bluehash and spirilis 2 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.