From 2caa1fbb207084e62f39a4f5b623e940d28fce3a Mon Sep 17 00:00:00 2001 From: treymarc Date: Wed, 1 Jan 2014 09:42:14 +0100 Subject: [PATCH] add newlib stubs --- Makefile | 1 + src/newlib_stubs.c | 278 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+) create mode 100644 src/newlib_stubs.c diff --git a/Makefile b/Makefile index 174a62fe4..34e8c1458 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ BIN_DIR = $(ROOT)/obj # Source files common to all targets COMMON_SRC = startup_stm32f10x_md_gcc.S \ + newlib_stubs.c \ buzzer.c \ cli.c \ config.c \ diff --git a/src/newlib_stubs.c b/src/newlib_stubs.c new file mode 100644 index 000000000..706e893fe --- /dev/null +++ b/src/newlib_stubs.c @@ -0,0 +1,278 @@ + +/* + * newlib_stubs.c + * + * Created on: 2 Nov 2010 + * Author: nanoage.co.uk + */ +#include +#include +#include +#include +#include "stm32f10x_usart.h" + + +#ifndef STDOUT_USART +#define STDOUT_USART 2 +#endif + +#ifndef STDERR_USART +#define STDERR_USART 2 +#endif + +#ifndef STDIN_USART +#define STDIN_USART 2 +#endif + +#undef errno +extern int errno; + +/* + environ + A pointer to a list of environment variables and their values. + For a minimal environment, this empty list is adequate: + */ +char *__env[1] = { 0 }; +char **environ = __env; + +int _write(int file, char *ptr, int len); + +void _exit(int status) { + _write(1, "exit", 4); + while (1) { + ; + } +} + +int _close(int file) { + return -1; +} +/* + execve + Transfer control to a new process. Minimal implementation (for a system without processes): + */ +int _execve(char *name, char **argv, char **env) { + errno = ENOMEM; + return -1; +} +/* + fork + Create a new process. Minimal implementation (for a system without processes): + */ + +int _fork() { + errno = EAGAIN; + return -1; +} +/* + fstat + Status of an open file. For consistency with other minimal implementations in these examples, + all files are regarded as character special devices. + The `sys/stat.h' header file required is distributed in the `include' subdirectory for this C library. + */ +int _fstat(int file, struct stat *st) { + st->st_mode = S_IFCHR; + return 0; +} + +/* + getpid + Process-ID; this is sometimes used to generate strings unlikely to conflict with other processes. Minimal implementation, for a system without processes: + */ + +int _getpid() { + return 1; +} + +/* + isatty + Query whether output stream is a terminal. For consistency with the other minimal implementations, + */ +int _isatty(int file) { + switch (file){ + case STDOUT_FILENO: + case STDERR_FILENO: + case STDIN_FILENO: + return 1; + default: + //errno = ENOTTY; + errno = EBADF; + return 0; + } +} + + +/* + kill + Send a signal. Minimal implementation: + */ +int _kill(int pid, int sig) { + errno = EINVAL; + return (-1); +} + +/* + link + Establish a new name for an existing file. Minimal implementation: + */ + +int _link(char *old, char *new) { + errno = EMLINK; + return -1; +} + +/* + lseek + Set position in a file. Minimal implementation: + */ +int _lseek(int file, int ptr, int dir) { + return 0; +} + +/* + sbrk + Increase program data space. + Malloc and related functions depend on this + */ +caddr_t _sbrk(int incr) { + + extern char _ebss; // Defined by the linker + static char *heap_end; + char *prev_heap_end; + + if (heap_end == 0) { + heap_end = &_ebss; + } + prev_heap_end = heap_end; + +char * stack = (char*) __get_MSP(); + if (heap_end + incr > stack) + { + _write (STDERR_FILENO, "Heap and stack collision\n", 25); + errno = ENOMEM; + return (caddr_t) -1; + //abort (); + } + + heap_end += incr; + return (caddr_t) prev_heap_end; + +} + +/* + read + Read a character to a file. `libc' subroutines will use this system routine for input from all files, including stdin + Returns -1 on error or blocks until the number of characters have been read. + */ + + +int _read(int file, char *ptr, int len) { + int n; + int num = 0; + switch (file) { + case STDIN_FILENO: + for (n = 0; n < len; n++) { +#if STDIN_USART == 1 + while ((USART1->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {} + char c = (char)(USART1->DR & (uint16_t)0x01FF); +#elif STDIN_USART == 2 + while ((USART2->SR & USART_FLAG_RXNE) == (uint16_t) RESET) {} + char c = (char) (USART2->DR & (uint16_t) 0x01FF); +#elif STDIN_USART == 3 + while ((USART3->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {} + char c = (char)(USART3->DR & (uint16_t)0x01FF); +#endif + *ptr++ = c; + num++; + } + break; + default: + errno = EBADF; + return -1; + } + return num; +} + +/* + stat + Status of a file (by name). Minimal implementation: + int _EXFUN(stat,( const char *__path, struct stat *__sbuf )); + */ + +int _stat(const char *filepath, struct stat *st) { + st->st_mode = S_IFCHR; + return 0; +} + +/* + times + Timing information for current process. Minimal implementation: + */ + +clock_t _times(struct tms *buf) { + return -1; +} + +/* + unlink + Remove a file's directory entry. Minimal implementation: + */ +int _unlink(char *name) { + errno = ENOENT; + return -1; +} + +/* + wait + Wait for a child process. Minimal implementation: + */ +int _wait(int *status) { + errno = ECHILD; + return -1; +} + +/* + write + Write a character to a file. `libc' subroutines will use this system routine for output to all files, including stdout + Returns -1 on error or number of bytes sent + */ +int _write(int file, char *ptr, int len) { + int n; + switch (file) { + case STDOUT_FILENO: /*stdout*/ + for (n = 0; n < len; n++) { +#if STDOUT_USART == 1 + while ((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET) {} + USART1->DR = (*ptr++ & (uint16_t)0x01FF); +#elif STDOUT_USART == 2 + while ((USART2->SR & USART_FLAG_TC) == (uint16_t) RESET) { + } + USART2->DR = (*ptr++ & (uint16_t) 0x01FF); +#elif STDOUT_USART == 3 + while ((USART3->SR & USART_FLAG_TC) == (uint16_t)RESET) {} + USART3->DR = (*ptr++ & (uint16_t)0x01FF); +#endif + } + break; + case STDERR_FILENO: /* stderr */ + for (n = 0; n < len; n++) { +#if STDERR_USART == 1 + while ((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET) {} + USART1->DR = (*ptr++ & (uint16_t)0x01FF); +#elif STDERR_USART == 2 + while ((USART2->SR & USART_FLAG_TC) == (uint16_t) RESET) { + } + USART2->DR = (*ptr++ & (uint16_t) 0x01FF); +#elif STDERR_USART == 3 + while ((USART3->SR & USART_FLAG_TC) == (uint16_t)RESET) {} + USART3->DR = (*ptr++ & (uint16_t)0x01FF); +#endif + } + break; + default: + errno = EBADF; + return -1; + } + return len; +} +