]> rtime.felk.cvut.cz Git - arc.git/blob - clib/clib_port.c
stdio: Started with devices.
[arc.git] / clib / clib_port.c
1 \r
2 /* -------------------------------- Arctic Core ------------------------------\r
3  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
4  *\r
5  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
6  *\r
7  * This source code is free software; you can redistribute it and/or modify it\r
8  * under the terms of the GNU General Public License version 2 as published by the\r
9  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
10  *\r
11  * This program is distributed in the hope that it will be useful, but\r
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
14  * for more details.\r
15  * -------------------------------- Arctic Core ------------------------------*/\r
16 \r
17 /* ----------------------------[information]----------------------------------\r
18  * Author: mahi\r
19  *\r
20  * Description:\r
21  *   Implements the glue between different clibs and ArcCore "system"\r
22  *\r
23  * Implementation Notes:\r
24  *   Heavily inspired by http://neptune.billgatliff.com/newlib.html\r
25  */\r
26 \r
27 /* ----------------------------[includes]------------------------------------*/\r
28 \r
29 #include <unistd.h>\r
30 #include <sys/stat.h>\r
31 #include <sys/types.h>\r
32 #include <errno.h>\r
33 #include <stdlib.h>\r
34 #include <string.h>\r
35 #include <stdio.h>\r
36 #include <stddef.h>\r
37 #include "Std_Types.h"\r
38 \r
39 #include "device_serial.h"\r
40 \r
41 #if defined(USE_TTY_UDE)\r
42 #include "serial_dbg_ude.h"\r
43 #endif\r
44 \r
45 /* ----------------------------[private define]------------------------------*/\r
46 /* ----------------------------[private macro]-------------------------------*/\r
47 /* ----------------------------[private typedef]-----------------------------*/\r
48 /* ----------------------------[private function prototypes]-----------------*/\r
49 /* ----------------------------[private variables]---------------------------*/\r
50 \r
51 #if defined(USE_TTY_T32)\r
52 extern DeviceSerialType T32_Device;\r
53 #endif\r
54 \r
55 DeviceSerialType *deviceList[] = {\r
56 #if defined(USE_TTY_T32)\r
57                 &T32_Device,\r
58 #endif\r
59 };\r
60 \r
61 \r
62 /* Global file descriptor to device list */\r
63 DeviceSerialType *fileList[] = {\r
64 #if defined(USE_TTY_T32)\r
65         [0] = &T32_Device,              /* stdin  */\r
66         [1] = &T32_Device,              /* stdout */\r
67         [2] = &T32_Device,              /* stderr */\r
68 #elif defined(USE_TTY_UDE)\r
69         [0] = &T32_Device,              /* stdin  */\r
70         [1] = &T32_Device,              /* stdout */\r
71         [2] = &T32_Device,              /* stderr */\r
72 #endif\r
73 };\r
74 \r
75 \r
76 \r
77 /* Errno is made reentrant by using malloc and we don't want this. This is usually fixed\r
78  * by undef errno and declaring it as extern int. It does not work when using GCC for\r
79  * HC1X and this ifdef takes care of that.\r
80  */\r
81 #undef errno\r
82 #if  defined(__GNUC__) && defined(CFG_HC1X)\r
83 int errno;\r
84 #else\r
85 extern int errno;\r
86 #endif\r
87 \r
88 /* ----------------------------[private functions]---------------------------*/\r
89 /* ----------------------------[public functions]----------------------------*/\r
90 \r
91 \r
92 /**\r
93  * POSIX open function\r
94  *\r
95  * Should probably support some O and S flags here\r
96  *   See http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html\r
97  *\r
98  * @param name  Name of the file to open\r
99  * @param flags O_xx flags\r
100  * @param mode  S_xx modes.\r
101  * @return      The file descriptor or -1 if failed to open.\r
102  */\r
103 int open(const char *name, int flags, int mode){\r
104         int i;\r
105         int fd = -1;\r
106 \r
107         for( i=0; i<sizeof(fileList)/sizeof(fileList[0]); i++ ) {\r
108                 if( strcmp(name,fileList[i]->name) == 0 ) {\r
109                         fd = i;\r
110                 }\r
111         }\r
112 \r
113         if( fd != -1) {\r
114                 if( fileList[fd]->open != NULL ) {\r
115                         fileList[fd]->open(name,flags,mode);\r
116                 }\r
117         } else {\r
118                 /* TODO: Set errno?! */\r
119         }\r
120 \r
121     return fd;\r
122 }\r
123 \r
124 \r
125 \r
126 #include <sys/stat.h>\r
127 int fstat(int file, struct stat *st) {\r
128         (void)file;\r
129         st->st_mode = S_IFCHR;\r
130         return 0;\r
131 }\r
132 \r
133 pid_t getpid() {\r
134   return 1;\r
135 }\r
136 \r
137 int kill(int pid, int sig){\r
138         (void)pid;\r
139         (void)sig;\r
140         errno=EINVAL;\r
141         return(-1);\r
142 }\r
143 \r
144 /* Do nothing */\r
145 int close( int fd ) {\r
146         (void)fd;\r
147         return (-1);\r
148 }\r
149 \r
150 /**\r
151  *\r
152  * @param fd\r
153  * @return 1 if connected to a terminal\r
154  */\r
155 int isatty( int fd )\r
156 {\r
157         (void)fd;\r
158         return 1;\r
159 }\r
160 \r
161 /* If we use malloc and it runs out of memory it calls sbrk()\r
162  */\r
163 \r
164 #if defined(CFG_PPC)\r
165 \r
166 /* linker symbols */\r
167 extern char _heap_start[];  // incomplete array to ensure not placed in small-data\r
168 extern char _heap_end[];\r
169 \r
170 void * sbrk( ptrdiff_t incr )\r
171 {\r
172     char *prevEnd;\r
173     static char *nextAvailMemPtr = _heap_start;\r
174 \r
175     if( nextAvailMemPtr + incr >  _heap_end) {\r
176                 write( 2, "Heap overflow!\n", 15 );\r
177                 abort();\r
178         }\r
179     prevEnd = nextAvailMemPtr;\r
180     nextAvailMemPtr += incr;\r
181     return prevEnd;\r
182 }\r
183 #else\r
184 extern char _end[];\r
185 \r
186 //static char *curbrk = _end;\r
187 \r
188 #ifndef HEAPSIZE\r
189 #define HEAPSIZE 16000\r
190 #endif\r
191 \r
192 /*\r
193  * The heap sadly have alignment that depends on the pagesize that\r
194  * you compile malloc newlib with. From what I can tell from the\r
195  * code that is a pagesize of 4096.\r
196  */\r
197 \r
198 unsigned char _heap[HEAPSIZE] __attribute__((aligned (4)));\r
199 //__attribute__((section(".heap")));\r
200 \r
201 void * sbrk( ptrdiff_t incr )\r
202 {\r
203     static unsigned char *heap_end;\r
204     unsigned char *prev_heap_end;\r
205 \r
206 /* initialize */\r
207     if( heap_end == 0 ){\r
208         heap_end = _heap;\r
209     }\r
210     prev_heap_end = heap_end;\r
211 \r
212         if( heap_end + incr - _heap > HEAPSIZE ) {\r
213         /* heap overflow - announce on stderr */\r
214                 write( 2, "Heap overflow!\n", 15 );\r
215                 abort();\r
216         }\r
217 \r
218    heap_end += incr;\r
219 \r
220    return (caddr_t) prev_heap_end;\r
221 }\r
222 #endif\r
223 \r
224 \r
225 \r
226 int read( int fd, void *buf, size_t nbytes )\r
227 {\r
228 \r
229         Device_Get(fd)->read(buf,nbytes);\r
230 \r
231         return 0;\r
232 }\r
233 \r
234 /**\r
235  * Write data to\r
236  *\r
237  * @param fd      The file descriptor\r
238  * @param _buf\r
239  * @param nbytes\r
240  * @return\r
241  */\r
242 int write(  int fd, const void *buf, size_t nbytes) {\r
243 \r
244         Device_Get(fd)->write(buf,nbytes);\r
245 \r
246         return (nbytes);\r
247 }\r
248 \r
249 /* reposition read/write file offset\r
250  * We can't seek, return error.*/\r
251 off_t lseek( int fd, off_t offset,int whence)\r
252 {\r
253         (void)fd;\r
254         (void)offset;\r
255         (void)whence;\r
256 \r
257         errno = ESPIPE;\r
258         return ((off_t)-1);\r
259 }\r
260 \r
261 void __init( void )\r
262 {\r
263 }\r
264 \r
265 \r
266 #if defined(CFG_ARM)\r
267 void _exit( int status ) {\r
268 #ifdef USE_TTY_CODE_COMPOSER\r
269         __asm("        .global C$$EXIT");\r
270         __asm("C$$EXIT: nop");\r
271 #endif\r
272 \r
273         ShutdownOS( E_OS_EXIT_ABORT );\r
274 \r
275         while(1) ;\r
276 }\r
277 #endif\r
278 \r