$search
00001 /***********************************************************************/ 00002 /* */ 00003 /* SYSCALLS.C: System Calls Remapping */ 00004 /* most of this is from newlib-lpc and a Keil-demo */ 00005 /* */ 00006 /* these are "reentrant functions" as needed by */ 00007 /* the WinARM-newlib-config, see newlib-manual */ 00008 /* collected and modified by Martin Thomas */ 00009 /* TODO: some more work has to be done on this */ 00010 /***********************************************************************/ 00011 00012 #include <stdlib.h> 00013 #include <reent.h> 00014 #include <sys/stat.h> 00015 #include "uart.h" 00016 00017 // new code for _read_r provided by Alexey Shusharin - Thanks 00018 _ssize_t _read_r(struct _reent *r, int file, void *ptr, size_t len) 00019 { 00020 char c; 00021 int i; 00022 unsigned char *p; 00023 00024 p = (unsigned char*)ptr; 00025 00026 for (i = 0; i < len; i++) 00027 { 00028 c = UARTReadChar(); 00029 00030 *p++ = c; 00031 UARTWriteChar(c); 00032 00033 if (c == 0x0D && i <= (len - 2)) 00034 { 00035 *p = 0x0A; 00036 UARTWriteChar(0x0A); 00037 return i + 2; 00038 } 00039 } 00040 return i; 00041 } 00042 00043 00044 #if 0 00045 // old version - no longer in use 00046 _ssize_t _read_r( 00047 struct _reent *r, 00048 int file, 00049 void *ptr, 00050 size_t len) 00051 { 00052 char c; 00053 int i; 00054 unsigned char *p; 00055 00056 p = (unsigned char*)ptr; 00057 00058 for (i = 0; i < len; i++) { 00059 // c = uart0Getch(); 00060 c = UARTReadChar(); 00061 if (c == 0x0D) { 00062 *p='\0'; 00063 break; 00064 } 00065 *p++ = c; 00066 UARTWriteChar(c); 00067 } 00068 return len - i; 00069 } 00070 #endif 00071 00072 _ssize_t _write_r ( 00073 struct _reent *r, 00074 int file, 00075 const void *ptr, 00076 size_t len) 00077 { 00078 int i; 00079 const unsigned char *p; 00080 00081 p = (const unsigned char*) ptr; 00082 00083 for (i = 0; i < len; i++) { 00084 if (*p == '\n' ) UARTWriteChar('\r'); 00085 UARTWriteChar(*p++); 00086 } 00087 00088 return len; 00089 } 00090 00091 int _close_r( 00092 struct _reent *r, 00093 int file) 00094 { 00095 return 0; 00096 } 00097 00098 _off_t _lseek_r( 00099 struct _reent *r, 00100 int file, 00101 _off_t ptr, 00102 int dir) 00103 { 00104 return (_off_t)0; /* Always indicate we are at file beginning. */ 00105 } 00106 00107 00108 int _fstat_r( 00109 struct _reent *r, 00110 int file, 00111 struct stat *st) 00112 { 00113 /* Always set as character device. */ 00114 st->st_mode = S_IFCHR; 00115 /* assigned to strong type with implicit */ 00116 /* signed/unsigned conversion. Required by */ 00117 /* newlib. */ 00118 00119 return 0; 00120 } 00121 00122 int isatty(int file); /* avoid warning */ 00123 00124 int isatty(int file) 00125 { 00126 return 1; 00127 } 00128 00129 #if 0 00130 static void _exit (int n) { 00131 label: goto label; /* endless loop */ 00132 } 00133 #endif 00134 00135 /* "malloc clue function" */ 00136 00137 /**** Locally used variables. ****/ 00138 extern char _end[]; /* end is set in the linker command */ 00139 /* file and is the end of statically */ 00140 /* allocated data (thus start of heap). */ 00141 00142 static char *heap_ptr; /* Points to current end of the heap. */ 00143 00144 /************************** _sbrk_r *************************************/ 00145 /* Support function. Adjusts end of heap to provide more memory to */ 00146 /* memory allocator. Simple and dumb with no sanity checks. */ 00147 /* struct _reent *r -- re-entrancy structure, used by newlib to */ 00148 /* support multiple threads of operation. */ 00149 /* ptrdiff_t nbytes -- number of bytes to add. */ 00150 /* Returns pointer to start of new heap area. */ 00151 /* Note: This implementation is not thread safe (despite taking a */ 00152 /* _reent structure as a parameter). */ 00153 /* Since _s_r is not used in the current implementation, the following */ 00154 /* messages must be suppressed. */ 00155 00156 void * _sbrk_r( 00157 struct _reent *_s_r, 00158 ptrdiff_t nbytes) 00159 { 00160 char *base; /* errno should be set to ENOMEM on error */ 00161 00162 if (!heap_ptr) { /* Initialize if first time through. */ 00163 heap_ptr = _end; 00164 } 00165 base = heap_ptr; /* Point to end of heap. */ 00166 heap_ptr += nbytes; /* Increase heap. */ 00167 00168 return base; /* Return pointer to start of new heap area. */ 00169 }