EmbDev.net

Forum: ARM programming with GCC/GNU tools Printf, putc, and getc serial issues


von Rick M. (waterhazard)


Rate this post
useful
not useful
I am using Eclipse with the ARM GNU Toolset. The code I am using was 
ported from Keil, which used a retarget.c file to output to UART1 just 
fine. My problem is that printf, putc, and getc do not take/output any 
data to/from the serial port, but if I use my created fputc and fgetc 
functions directly they do. More oddly, when debugging and watching the 
variables, it appears that getc is taking its input from a printf 
statement earlier in the code! Another strange thing is that if I try 
the command fprintf(stdout,"A"); it outputs just fine to the serial 
terminal yet printf never shows up.

To try and fix this I have copied my fputc and fgetc code into _write 
and _read in the syscalls.c, and roughly configured the rest of the file 
per http://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html . I 
have also tried including the lines setbuf (stdout, NULL); and setvbuf( 
stdout, 0, _IONBF, 0 ); but that had no effect either. I have searched 
extensively but nobody else seems to be having a problem quite like 
mine, any help would be appreciated.

von William C. (bdk6)


Rate this post
useful
not useful
This sounds very much like the problem I had (have).  In my case, and it 
sounds like yours as well, the _write and _read calls that printf and 
family uses to talk with the "files" are defined within the newlib or 
newlib-nano libraries.  They are defined as weak symbols, which means 
that if you write another function with the same name (and not weak) it 
will override the weak version.  But that depends on it being linked in 
BEFORE the one in the library.
I assume you have have working _read and _write functions that you are 
using to talk with the serial port.  If you compile those functions and 
link them at the same time you compile the main program, it should work. 
If you put them into a library, it is very difficult to convince ld to 
link them instead of the built-in versions.  ld has to find the strong 
versions before the weak ones.
The simple answer is to put those functions into a separate file that is 
always compiled with your main program.  Say you put them in file 
my_io.c then compile your program something like this:
gcc -o myprog.elf main.c my_io.c [other files]
In that case, gcc and ld are forced to see the strong versions before 
trying to link in the weak versions in the library.  It isn't elegant 
and I am still trying to find a better solution.
Hope this helps

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.