printf through uart
The way I got printf (and all other console-oriented stdio functions) to work was by creating custom implementations of the low-level I/O functions like _read() and _write().
The GCC C library makes calls to the following functions to perform low-level I/O :
int _read(int file, char *data, int len) int _write(int file, char *data, int len) int _close(int file) int _lseek(int file, int ptr, int dir) int _fstat(int file, struct stat *st) int _isatty(int file)
These functions are implemented witihin the GCC C library as stub routines with “weak” linkage. If a declaration of any of the above functions appears in your own code, your substitute routine will override the declaration in the library and be used instead of the default (non-functional) routine.
I have copied my implementations of these functions below. You will need to substitute the calls to UART_TxBlocking() and UART_RxBlocking() with calls to whatever functions you have created that do U(S)ART I/O.
#ifdef __GCC__ #include <errno.h> #include <stdio.h> #include <sys/stat.h> #include <sys/unistd.h> #include "stdio_helper_gcc.h" #include "UART.h" #undef errno extern int errno; /****************************************************************************** * ******************************************************************************/ void stdio_setup(int no_init) { if (! no_init) { UART_Init(0); } // Turn off buffers, so I/O occurs immediately setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); } /****************************************************************************** * ******************************************************************************/ int _read(int file, char *data, int len) { int bytes_read; if (file != STDIN_FILENO) { errno = EBADF; return -1; } for (bytes_read = 0; bytes_read < len; bytes_read++) { *data = (char) UART_RxBlocking(); data++; } return bytes_read; } /****************************************************************************** * ******************************************************************************/ int _write(int file, char *data, int len) { int bytes_written; if ((file != STDOUT_FILENO) && (file != STDERR_FILENO)) { errno = EBADF; return -1; } for (bytes_written = 0; bytes_written < len; bytes_written++) { UART_TxBlocking(*data); data++; } return bytes_written; } /****************************************************************************** * ******************************************************************************/ int _close(int file) { return -1; } /****************************************************************************** * ******************************************************************************/ int _lseek(int file, int ptr, int dir) { return 0; } /****************************************************************************** * ******************************************************************************/ int _fstat(int file, struct stat *st) { st->st_mode = S_IFCHR; return 0; } /****************************************************************************** * ******************************************************************************/ int _isatty(int file) { if ((file == STDOUT_FILENO) || (file == STDIN_FILENO) || (file == STDERR_FILENO)) { return 1; } errno = EBADF; return 0; } #endif