*\r
* Description:\r
* Implements the glue between different clibs and ArcCore "system"\r
+ *\r
+ * Implementation Notes:\r
+ * Heavily inspired by http://neptune.billgatliff.com/newlib.html\r
*/\r
\r
/* ----------------------------[includes]------------------------------------*/\r
#include <stddef.h>\r
#include "Std_Types.h"\r
\r
+#include "device_serial.h"\r
+\r
+#if defined(USE_TTY_UDE)\r
+#include "serial_dbg_ude.h"\r
+#endif\r
+\r
/* ----------------------------[private define]------------------------------*/\r
/* ----------------------------[private macro]-------------------------------*/\r
/* ----------------------------[private typedef]-----------------------------*/\r
/* ----------------------------[private function prototypes]-----------------*/\r
/* ----------------------------[private variables]---------------------------*/\r
\r
+#if defined(USE_TTY_T32)\r
+extern DeviceSerialType T32_Device;\r
+#endif\r
+\r
+DeviceSerialType *deviceList[] = {\r
+#if defined(USE_TTY_T32)\r
+ &T32_Device,\r
+#endif\r
+};\r
+\r
+\r
+/* Global file descriptor to device list */\r
+DeviceSerialType *fileList[] = {\r
+#if defined(USE_TTY_T32)\r
+ [0] = &T32_Device, /* stdin */\r
+ [1] = &T32_Device, /* stdout */\r
+ [2] = &T32_Device, /* stderr */\r
+#elif defined(USE_TTY_UDE)\r
+ [0] = &T32_Device, /* stdin */\r
+ [1] = &T32_Device, /* stdout */\r
+ [2] = &T32_Device, /* stderr */\r
+#endif\r
+};\r
+\r
+\r
\r
/* Errno is made reentrant by using malloc and we don't want this. This is usually fixed\r
* by undef errno and declaring it as extern int. It does not work when using GCC for\r
/* ----------------------------[public functions]----------------------------*/\r
\r
\r
-\r
+/**\r
+ * POSIX open function\r
+ *\r
+ * Should probably support some O and S flags here\r
+ * See http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html\r
+ *\r
+ * @param name Name of the file to open\r
+ * @param flags O_xx flags\r
+ * @param mode S_xx modes.\r
+ * @return The file descriptor or -1 if failed to open.\r
+ */\r
int open(const char *name, int flags, int mode){\r
- (void)name;\r
- (void)flags;\r
- (void)mode;\r
+ int i;\r
+ int fd = -1;\r
+\r
+ for( i=0; i<sizeof(fileList)/sizeof(fileList[0]); i++ ) {\r
+ if( strcmp(name,fileList[i]->name) == 0 ) {\r
+ fd = i;\r
+ }\r
+ }\r
\r
- return -1;\r
+ if( fd != -1) {\r
+ if( fileList[fd]->open != NULL ) {\r
+ fileList[fd]->open(name,flags,mode);\r
+ }\r
+ } else {\r
+ /* TODO: Set errno?! */\r
+ }\r
+\r
+ return fd;\r
}\r
\r
\r
\r
int read( int fd, void *buf, size_t nbytes )\r
{\r
- (void)fd;\r
- (void)buf;\r
- (void)nbytes;\r
+\r
+ Device_Get(fd)->read(buf,nbytes);\r
\r
return 0;\r
}\r
-int write( int fd, const void *_buf, size_t nbytes) {\r
+\r
+/**\r
+ * Write data to\r
+ *\r
+ * @param fd The file descriptor\r
+ * @param _buf\r
+ * @param nbytes\r
+ * @return\r
+ */\r
+int write( int fd, const void *buf, size_t nbytes) {\r
+\r
+ Device_Get(fd)->write(buf,nbytes);\r
\r
return (nbytes);\r
}\r
int fputc(int, FILE *);\r
int fputs(const char *, FILE *);\r
\r
+int getchar( void ) getc(stdin)\r
+\r
+\r
\r
#endif /* STDIO_H_ */\r
*\r
*\r
*\r
+ * fd = open("/serial/serial_t32",O_RDWR);\r
+ * write(fd, "hejsan", 5);\r
+ * file = fdopen(fd,"w");\r
+ * fputs("hello",file);\r
*\r
*\r
+ * file = fopen("serial_t32","r");\r
+ * fputs("hello",file);\r
*\r
+ * !! Somewhere we must map a device with a file descriptor !!\r
+ *\r
+ * Use case: Set "global" console\r
+ * Console_SetDevice("/serial/serial_t32");\r
+ * fputs("hello",stdout);\r
+ * Console_SetDevice("/ramlog");\r
+ * fputs("hello",stdout);\r
+ *\r
+ *\r
+ * Use case: Set console for a specific thing (for example telnet)\r
+ * This should set local configuration ( not global )\r
+ * Console_SetDevice("/serial/lwip");\r
+ * fputs("hello",stdout);\r
+ *\r
+ *\r
+ *\r
+ * It seems that we must assume that read() is blocking until all the characters\r
+ * are read. This means that we must check if a character is present in some way.\r
+ * There is select() but it's just to much....this leaves us having to have a\r
+ * kbhit() function that goes all the way to the driver.\r
+ *\r
+ *\r
+ * http://www.kegel.com/dkftpbench/nonblocking.html\r
+ * http://pubs.opengroup.org/onlinepubs/7908799/xsh/read.html\r
+ *\r
+ * Sooo.... read() should always support O_NONBLOCK\r
*\r
*\r
*/\r
NULL,\r
};\r
\r
-DeviceSerialType *fileList[] = {\r
- [0] = &T32_Device, /* stdin */\r
- [1] = &T32_Device, /* stdout */\r
- [2] = &T32_Device, /* stderr */\r
-};\r
\r
\r
\r
* arc_putchar((int)(file->_file), c);\r
* )\r
*\r
+ *\r
+ *\r
+ *\r
+ * http://ubuntuforums.org/showthread.php?t=936816\r
+ *\r
+ * What we don't want to use:\r
+ * - Terminal stuff, tcsetattr(),etc..makes everything very complicated.\r
+ * - Use of select() to set to check for keyboard hit, ie\r
+ * select(STDIN_FILENO+1..);\r
+ * Then check FD_ISSET( STDIN_FILENO, .. )\r
+ *\r
+ *\r
*/\r
\r
#if defined(__IAR_SYSTEMS_ICC__)\r
}\r
\r
\r
+/**\r
+ * Get a character from stream. Assume for now\r
+ * that it's blocking.\r
+ *\r
+ *\r
+ * @param file\r
+ * @return\r
+ */\r
+int fgetc( FILE *file ) {\r
+ char c;\r
+ int rv;\r
+\r
+\r
+ do {\r
+ rv = read(fd,&c,1);\r
+ } while( rv == 0 );\r
+}\r
+\r
+\r
+/**\r
+ * Read to EOF or newline\r
+ *\r
+ * @param file\r
+ * @return\r
+ */\r
+int fgets( FILE *file ) {\r
+ char c;\r
+ read(fd,&c,)\r
+}\r
+\r
+\r
+\r
int printf(const char *format, ...) {\r
va_list ap;\r
int rv;\r
/* ----------------------------[private function prototypes]-----------------*/
static int t32_Write( uint8_t *data, size_t nbytes);
static int t32_Read( uint8_t *data, size_t nbytes );
+static int t32_Open( uint32_t flags );
#if defined(__CWCC__)
#pragma section RW ".nocache" ".nocache_bss"
// .init = T32_Init,
.read = t32_Read,
.write = t32_Write,
+ .open = t32_Open,
};
/* ----------------------------[private functions]---------------------------*/
}
return b;
}
+
+static int t32_Open( const char *path, int oflag, int mode ) {
+ /* Save O_NONBLOCK to
+}
#define DEVICE_NAME_MAX 16
+/* Device type that maps well to POSIX open/read/write */
+
typedef struct DeviceSerial {
char name[DEVICE_NAME_MAX];
uint32_t data;
- void (*open)( uint32_t data );
+ void (*open)( const char *path, int oflag, int mode );
void (*close)( uint8_t *data, size_t nbytes);
/* Reads nbytes from device to data.
* Non-blocking read */