-
Notifications
You must be signed in to change notification settings - Fork 2
/
newlib_stubs.c
291 lines (254 loc) · 6.12 KB
/
newlib_stubs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/*
* newlib_stubs.c
*
* Created on: 2 Nov 2010
* Author: nanoage.co.uk
*/
#include <errno.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/unistd.h>
#include <sys/types.h>
//#include "stm32f10x_usart.h"
extern int _ebss;
// Disabled:
#define STDOUT_USART 0
#define STDERR_USART 0
#define STDIN_USART 0
#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) {
static char *heap_end = NULL;
char *prev_heap_end;
if (heap_end == NULL) {
heap_end = (unsigned char *)&_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);
#else
// Do nothing
char c = '0';
#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);
#else
// Do nothing
#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);
#else
// Do nothing
#endif
}
break;
default:
errno = EBADF;
return -1;
}
return len;
}