1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\r
6 * This source code is free software; you can redistribute it and/or modify it
\r
7 * under the terms of the GNU General Public License version 2 as published by the
\r
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
\r
10 * This program is distributed in the hope that it will be useful, but
\r
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
\r
14 * -------------------------------- Arctic Core ------------------------------*/
\r
18 #include <sys/stat.h>
\r
19 #include <sys/types.h>
\r
25 #include "Std_Types.h"
\r
28 #if defined(CFG_ARM_CM3)
\r
29 #include "irq_types.h"
\r
30 #include "stm32f10x.h"
\r
33 #ifdef USE_TTY_TCF_STREAMS
\r
34 #include "streams.h"
\r
38 #if defined(CFG_ARM)
\r
41 #define fstat _fstat
\r
42 #define getpid _getpid
\r
44 #define close _close
\r
45 #define isatty _isatty
\r
48 #define write _write
\r
49 #define lseek _lseek
\r
52 // Operation on Winidea terminal buffer
\r
55 #define TWBUFF_SIZE 0x100
\r
56 #define TRBUFF_SIZE 0x100
\r
61 #define TWBUFF_LEN (TWBUFF_SIZE+TBUFF_PTR)
\r
62 #define TRBUFF_LEN (TRBUFF_SIZE+TBUFF_PTR)
\r
63 #define TWBUFF_TPTR (g_TWBuffer[TWBUFF_SIZE+0])
\r
64 #define TWBUFF_CPTR (g_TWBuffer[TWBUFF_SIZE+1])
\r
65 #define TWBUFF_INC(n) ((n + 1)&(TWBUFF_SIZE-1))
\r
66 #define TWBUFF_FULL() (TWBUFF_TPTR==((TWBUFF_CPTR-1)&(TWBUFF_SIZE-1)))
\r
68 #ifdef USE_TTY_WINIDEA
\r
70 #if defined(MC912DG128A)
\r
71 static volatile unsigned char g_TWBuffer[TWBUFF_LEN];
\r
72 static volatile unsigned char g_TRBuffer[TRBUFF_LEN];
\r
73 volatile char g_TConn __attribute__ ((section (".winidea_port")));
\r
76 static volatile unsigned char g_TWBuffer[TWBUFF_LEN] __attribute__ ((aligned (0x100))); // Transmit to WinIDEA terminal
\r
77 static volatile unsigned char g_TRBuffer[TRBUFF_LEN] __attribute__ ((aligned (0x100)));
\r
78 volatile char g_TConn __attribute__ ((section (".winidea_port")));
\r
84 #ifdef USE_TTY_CODE_COMPOSER
\r
86 #define _DTOPEN (0xF0)
\r
87 #define _DTCLOSE (0xF1)
\r
88 #define _DTREAD (0xF2)
\r
89 #define _DTWRITE (0xF3)
\r
90 #define _DTLSEEK (0xF4)
\r
91 #define _DTUNLINK (0xF5)
\r
92 #define _DTGETENV (0xF6)
\r
93 #define _DTRENAME (0xF7)
\r
94 #define _DTGETTIME (0xF8)
\r
95 #define _DTGETCLK (0xF9)
\r
96 #define _DTSYNC (0xFF)
\r
98 #define LOADSHORT(x,y,z) { x[(z)] = (unsigned short) (y); \
\r
99 x[(z)+1] = (unsigned short) (y) >> 8; }
\r
101 #define UNLOADSHORT(x,z) ((short) ( (short) x[(z)] + \
\r
102 ((short) x[(z)+1] << 8)))
\r
104 #define PACKCHAR(val, base, byte) ( (base)[(byte)] = (val) )
\r
106 #define UNPACKCHAR(base, byte) ( (base)[byte] )
\r
109 static unsigned char parmbuf[8];
\r
110 #define CC_BUFSIZ 512
\r
111 #define CC_BUFFER_SIZE ((CC_BUFSIZ)+32)
\r
112 volatile unsigned int _CIOBUF_[CC_BUFFER_SIZE] __attribute__ ((section (".cio")));
\r
113 static unsigned char CIOTMPBUF[CC_BUFSIZ];
\r
114 static uint16 cio_tmp_buf_index = 0;
\r
116 /***************************************************************************/
\r
118 /* WRITEMSG() - Sends the passed data and parameters on to the host. */
\r
120 /***************************************************************************/
\r
121 void writemsg(unsigned char command,
\r
122 register const unsigned char *parm,
\r
123 register const char *data,
\r
124 unsigned int length)
\r
126 volatile unsigned char *p = (volatile unsigned char *)(_CIOBUF_+1);
\r
129 /***********************************************************************/
\r
130 /* THE LENGTH IS WRITTEN AS A TARGET INT */
\r
131 /***********************************************************************/
\r
132 _CIOBUF_[0] = length;
\r
134 /***********************************************************************/
\r
135 /* THE COMMAND IS WRITTEN AS A TARGET BYTE */
\r
136 /***********************************************************************/
\r
139 /***********************************************************************/
\r
140 /* PACK THE PARAMETERS AND DATA SO THE HOST READS IT AS BYTE STREAM */
\r
141 /***********************************************************************/
\r
142 for (i = 0; i < 8; i++) PACKCHAR(*parm++, p, i);
\r
143 for (i = 0; i < length; i++) PACKCHAR(*data++, p, i+8);
\r
145 /***********************************************************************/
\r
146 /* THE BREAKPOINT THAT SIGNALS THE HOST TO DO DATA TRANSFER */
\r
147 /***********************************************************************/
\r
148 __asm(" .global C$$IO$$");
\r
149 __asm("C$$IO$$: nop");
\r
152 /***************************************************************************/
\r
154 /* READMSG() - Reads the data and parameters passed from the host. */
\r
156 /***************************************************************************/
\r
157 void readmsg(register unsigned char *parm,
\r
158 register char *data)
\r
160 volatile unsigned char *p = (volatile unsigned char *)(_CIOBUF_+1);
\r
162 unsigned int length;
\r
164 /***********************************************************************/
\r
165 /* THE LENGTH IS READ AS A TARGET INT */
\r
166 /***********************************************************************/
\r
167 length = _CIOBUF_[0];
\r
169 /***********************************************************************/
\r
170 /* UNPACK THE PARAMETERS AND DATA */
\r
171 /***********************************************************************/
\r
172 for (i = 0; i < 8; i++) *parm++ = UNPACKCHAR(p, i);
\r
174 for (i = 0; i < length; i++) *data++ = UNPACKCHAR(p, i+8);
\r
177 /****************************************************************************/
\r
178 /* HOSTWRITE() - Pass the write command and its arguments to the host. */
\r
179 /****************************************************************************/
\r
180 int HOSTwrite(int dev_fd, const char *buf, unsigned count)
\r
184 // WARNING. Can only handle count == 1!
\r
185 if (count != 1) _exit(1);
\r
187 if (count > CC_BUFSIZ) count = CC_BUFSIZ;
\r
189 if (cio_tmp_buf_index < CC_BUFSIZ) {
\r
190 CIOTMPBUF[cio_tmp_buf_index++] = *buf;
\r
192 if (*buf != 0xA) { // Only flush if newline
\r
198 LOADSHORT(parmbuf,dev_fd,0);
\r
199 LOADSHORT(parmbuf,cio_tmp_buf_index,2);
\r
200 writemsg(_DTWRITE,parmbuf,(char *)CIOTMPBUF,cio_tmp_buf_index);
\r
201 readmsg(parmbuf,NULL);
\r
203 result = UNLOADSHORT(parmbuf,0);
\r
205 cio_tmp_buf_index = 0;
\r
212 #ifdef USE_TTY_TMS570_KEIL
\r
216 #define FILE_RAMLOG 3
\r
218 /* Location MUST match NoICE configuration */
\r
219 #ifdef USE_TTY_NOICE
\r
220 static volatile char VUART_TX __attribute__ ((section (".noice_port")));
\r
221 static volatile char VUART_RX __attribute__ ((section (".noice_port")));
\r
222 volatile unsigned char START_VUART = 0;
\r
229 // This must be in un-cached space....
\r
231 static volatile char t32_outport __attribute__ ((section (".t32_outport")));
\r
233 void t32_writebyte(char c)
\r
235 /* T32 can hang here for several reasons;
\r
236 * - term.view e:address.offset(v.address(t32_outport)) e:0
\r
239 while (t32_outport != 0 ) ; /* wait until port is free */
\r
240 t32_outport = c; /* send character */
\r
248 int close( int fd ) {
\r
253 char *__env[1] = { 0 };
\r
254 char **environ = __env;
\r
262 int execve(const char *path, char * const argv[], char * const envp[] ) {
\r
263 //int execve(char *name, char **argv, char **env){
\r
276 #include <sys/stat.h>
\r
277 int fstat(int file, struct stat *st) {
\r
279 st->st_mode = S_IFCHR;
\r
283 /* Returns 1 if connected to a terminal. T32 can be a terminal
\r
286 int isatty( int fd )
\r
293 int fstat( int fd, struct stat *buf )
\r
295 buf->st_mode = S_IFCHR;
\r
296 buf->st_blksize = 0;
\r
302 /* reposition read/write file offset
\r
303 * We can't seek, return error.*/
\r
304 off_t lseek( int fd, off_t offset,int whence)
\r
311 return ((off_t)-1);
\r
314 int open(const char *name, int flags, int mode){
\r
319 #if defined(USE_RAMLOG)
\r
320 if( strcmp(name,"ramlog") == 0 ) {
\r
321 return FILE_RAMLOG;
\r
328 int read( int fd, void *buf, size_t nbytes )
\r
333 #ifdef USE_TTY_WINIDEA
\r
334 (void)g_TRBuffer[0];
\r
337 #ifdef USE_TTY_NOICE
\r
338 // Not tested at all
\r
340 while (VUART_RX != 0)
\r
348 /* Only support write for now, return 0 read */
\r
353 int write( int fd, const void *_buf, size_t nbytes)
\r
355 //(void)fd; // Normally 0- ?, 1-stdout, 2-stderr,
\r
359 if( fd <= STDERR_FILENO ) {
\r
360 #ifdef USE_TTY_NOICE
\r
361 char *buf1 = (char *)_buf;
\r
364 for (int i = 0; i < nbytes; i++) {
\r
368 while (VUART_TX != 0)
\r
375 while (VUART_TX != 0)
\r
384 #ifdef USE_TTY_WINIDEA
\r
387 char *buf = (char *)_buf;
\r
388 unsigned char nCnt,nLen;
\r
389 for(nCnt=0; nCnt<nbytes; nCnt++)
\r
391 while(TWBUFF_FULL()) ;
\r
393 g_TWBuffer[nLen]=buf[nCnt];
\r
394 nLen=TWBUFF_INC(nLen);
\r
401 char *buf = (char *)_buf;
\r
402 for (int i = 0; i < nbytes; i++) {
\r
403 if (*(buf + i) == '\n') {
\r
404 t32_writebyte ('\r');
\r
405 // t32_writebyte ('\n');
\r
407 t32_writebyte (*(buf + i));
\r
411 #ifdef USE_TTY_ARM_ITM
\r
412 char *buf = (char *)_buf;
\r
413 for (int i = 0; i < nbytes; i++) {
\r
414 ITM_SendChar(*(buf + i));
\r
418 #ifdef USE_TTY_TCF_STREAMS
\r
419 char *buf = (char *)_buf;
\r
420 for (int i = 0; i < nbytes; i++) {
\r
421 TCF_TTY_SendChar(*(buf + i));
\r
425 #ifdef USE_TTY_CODE_COMPOSER
\r
426 HOSTwrite(fd, _buf, nbytes);
\r
429 #ifdef USE_TTY_TMS570_KEIL
\r
430 for (int i = 0; i < nbytes; i++) {
\r
431 GLCD_PrintChar((char *)(_buf + i));
\r
435 #if defined(USE_RAMLOG)
\r
437 char *buf = (char *)_buf;
\r
438 for (int i = 0; i < nbytes; i++) {
\r
439 ramlog_chr (*(buf + i));
\r
447 #if defined(USE_RAMLOG)
\r
448 /* RAMLOG support */
\r
449 if(fd == FILE_RAMLOG) {
\r
450 char *buf = (char *)_buf;
\r
451 for (int i = 0; i < nbytes; i++) {
\r
452 ramlog_chr (*(buf + i));
\r
461 int arc_putchar(int fd, int c) {
\r
468 /* If we use malloc and it runs out of memory it calls sbrk()
\r
471 #if defined(CFG_PPC)
\r
473 /* linker symbols */
\r
474 extern char _heap_start[]; // incomplete array to ensure not placed in small-data
\r
475 extern char _heap_end[];
\r
477 void * sbrk( ptrdiff_t incr )
\r
480 static char *nextAvailMemPtr = _heap_start;
\r
482 if( nextAvailMemPtr + incr > _heap_end) {
\r
483 write( 2, "Heap overflow!\n", 15 );
\r
486 prevEnd = nextAvailMemPtr;
\r
487 nextAvailMemPtr += incr;
\r
491 extern char _end[];
\r
493 //static char *curbrk = _end;
\r
496 #define HEAPSIZE 16000
\r
500 * The heap sadly have alignment that depends on the pagesize that
\r
501 * you compile malloc newlib with. From what I can tell from the
\r
502 * code that is a pagesize of 4096.
\r
505 unsigned char _heap[HEAPSIZE] __attribute__((aligned (4)));
\r
506 //__attribute__((section(".heap")));
\r
508 void * sbrk( ptrdiff_t incr )
\r
510 static unsigned char *heap_end;
\r
511 unsigned char *prev_heap_end;
\r
514 if( heap_end == 0 ){
\r
517 prev_heap_end = heap_end;
\r
519 if( heap_end + incr - _heap > HEAPSIZE ) {
\r
520 /* heap overflow - announce on stderr */
\r
521 write( 2, "Heap overflow!\n", 15 );
\r
527 return (caddr_t) prev_heap_end;
\r
531 int stat( const char *file, struct stat *st ) {
\r
532 //int stat(char *file, struct stat *st) {
\r
534 st->st_mode = S_IFCHR;
\r
546 int kill(int pid, int sig){
\r
554 /* Should not really be here, but .. */
\r
562 #if defined(__GNUC__)
\r
563 void __init( void )
\r
568 #if defined(CFG_ARM)
\r
569 void _exit( int status ) {
\r
570 #ifdef USE_TTY_CODE_COMPOSER
\r
571 __asm(" .global C$$EXIT");
\r
572 __asm("C$$EXIT: nop");
\r