From acf3a4570b92f340b94f6df2e616c95513f390b2 Mon Sep 17 00:00:00 2001 From: Michal Sieron Date: Mon, 26 Jul 2021 15:30:25 +0200 Subject: [PATCH] Create __iob for picolibc Picolibc requires __iob array for its IO functions This commit creates such array with dummy functions using putchar/readchar from console.c To prevent name conflicts printf and others were removed from console.c Also putchar had to be renamed to base_putchar --- litex/soc/software/libbase/console.c | 162 +-------------------------- litex/soc/software/libc/Makefile | 19 ++++ litex/soc/software/libc/iob.c | 30 +++++ 3 files changed, 52 insertions(+), 159 deletions(-) create mode 100644 litex/soc/software/libc/iob.c diff --git a/litex/soc/software/libbase/console.c b/litex/soc/software/libbase/console.c index d8d942413..a2a5f129c 100644 --- a/litex/soc/software/libbase/console.c +++ b/litex/soc/software/libbase/console.c @@ -5,8 +5,6 @@ #include -FILE *stdin, *stdout, *stderr; - static console_write_hook write_hook; static console_read_hook read_hook; static console_read_nonblock_hook read_nonblock_hook; @@ -23,13 +21,13 @@ void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn) } #ifdef CSR_UART_BASE -int putchar(int c) +int base_putchar(int c) { uart_write(c); if(write_hook != NULL) write_hook(c); if (c == '\n') - putchar('\r'); + base_putchar('\r'); return c; } @@ -51,7 +49,7 @@ int readchar_nonblock(void) #else -int putchar(int c) +int base_putchar(int c) { if(write_hook != NULL) write_hook(c); @@ -73,13 +71,6 @@ int readchar_nonblock(void) #endif -int puts(const char *s) -{ - putsnonl(s); - putchar('\n'); - return 1; -} - void putsnonl(const char *s) { while(*s) { @@ -88,150 +79,3 @@ void putsnonl(const char *s) } } -int skip_atoi(const char **s) -{ - int i=0; - - while (isdigit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type) -{ - char c,sign,tmp[66]; - const char *digits; - static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - int i; - - digits = (type & PRINTF_LARGE) ? large_digits : small_digits; - if (type & PRINTF_LEFT) - type &= ~PRINTF_ZEROPAD; - if (base < 2 || base > 36) - return NULL; - c = (type & PRINTF_ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & PRINTF_SIGN) { - if ((signed long) num < 0) { - sign = '-'; - num = - (signed long) num; - size--; - } else if (type & PRINTF_PLUS) { - sign = '+'; - size--; - } else if (type & PRINTF_SPACE) { - sign = ' '; - size--; - } - } - if (type & PRINTF_SPECIAL) { - if (base == 16) - size -= 2; - else if (base == 8) - size--; - } - i = 0; - if (num == 0) - tmp[i++]='0'; - else while (num != 0) { - tmp[i++] = digits[num % base]; - num = num / base; - } - if (i > precision) - precision = i; - size -= precision; - if (!(type&(PRINTF_ZEROPAD+PRINTF_LEFT))) { - while(size-->0) { - if (buf < end) - *buf = ' '; - ++buf; - } - } - if (sign) { - if (buf < end) - *buf = sign; - ++buf; - } - if (type & PRINTF_SPECIAL) { - if (base==8) { - if (buf < end) - *buf = '0'; - ++buf; - } else if (base==16) { - if (buf < end) - *buf = '0'; - ++buf; - if (buf < end) - *buf = digits[33]; - ++buf; - } - } - if (!(type & PRINTF_LEFT)) { - while (size-- > 0) { - if (buf < end) - *buf = c; - ++buf; - } - } - while (i < precision--) { - if (buf < end) - *buf = '0'; - ++buf; - } - while (i-- > 0) { - if (buf < end) - *buf = tmp[i]; - ++buf; - } - while (size-- > 0) { - if (buf < end) - *buf = ' '; - ++buf; - } - return buf; -} - -/** - * vscnprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space - * @fmt: The format string to use - * @args: Arguments for the format string - * - * The return value is the number of characters which have been written into - * the @buf not including the trailing '\0'. If @size is <= 0 the function - * returns 0. - * - * Call this function if you are already dealing with a va_list. - * You probably want scnprintf() instead. - */ -int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) -{ - size_t i; - - i=vsnprintf(buf,size,fmt,args); - return (i >= size) ? (size - 1) : i; -} - -#define PRINTF_BUFFER_SIZE 256 - -int vprintf(const char *fmt, va_list args) -{ - int len; - char outbuf[PRINTF_BUFFER_SIZE]; - len = vscnprintf(outbuf, sizeof(outbuf), fmt, args); - outbuf[len] = 0; - putsnonl(outbuf); - return len; -} - -int printf(const char *fmt, ...) -{ - int len; - va_list args; - va_start(args, fmt); - len = vprintf(fmt, args); - va_end(args); - return len; -} diff --git a/litex/soc/software/libc/Makefile b/litex/soc/software/libc/Makefile index c2c495840..d730ad5f2 100644 --- a/litex/soc/software/libc/Makefile +++ b/litex/soc/software/libc/Makefile @@ -1,6 +1,25 @@ include ../include/generated/variables.mak include $(SOC_DIRECTORY)/software/common.mak +pINCLUDES = -I$(PICOLIBC_DIRECTORY)/newlib/libc/tinystdio \ + -I$(PICOLIBC_DIRECTORY)/newlib/libc/include \ + -I$(SOC_DIRECTORY)/software/include \ + -I$(BUILDINC_DIRECTORY)/../libc \ + -I$(BUILDINC_DIRECTORY) \ + -I$(CPU_DIRECTORY) + +pCOMMONFLAGS = -Os $(CPUFLAGS) -g3 -fomit-frame-pointer -Wall -fno-builtin -nostdlib -fno-stack-protector $(pINCLUDES) +pCFLAGS = $(pCOMMONFLAGS) -fexceptions -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes + +all: libc.a iob.c.o + +iob.c.o: + $(CC) \ + -c $(LIBC_DIRECTORY)/iob.c \ + -o $@ \ + $(pCFLAGS) + $(AR) csr libc.a iob.c.o + libc.a: meson $(PICOLIBC_DIRECTORY) \ -Dmultilib=false \ diff --git a/litex/soc/software/libc/iob.c b/litex/soc/software/libc/iob.c new file mode 100644 index 000000000..fe77e4017 --- /dev/null +++ b/litex/soc/software/libc/iob.c @@ -0,0 +1,30 @@ +#include +#include +//#include + + +static int +dummy_putc(char c, FILE *file) +{ + (void) file; + return base_putchar(c); +} + +static int +dummy_getc(FILE *file) +{ + (void) file; + return readchar(); +} + +static int +dummy_flush(FILE *file) +{ + (void) file; + return 0; +} + +static FILE __stdio = FDEV_SETUP_STREAM(dummy_putc, dummy_getc, dummy_flush, _FDEV_SETUP_RW); + +FILE *const __iob[3] = { &__stdio, &__stdio, &__stdio }; +