]> rtime.felk.cvut.cz Git - arc.git/commitdiff
stdio: Started with devices.
authormahi <devnull@localhost>
Thu, 11 Apr 2013 11:35:24 +0000 (13:35 +0200)
committermahi <devnull@localhost>
Thu, 11 Apr 2013 11:35:24 +0000 (13:35 +0200)
clib/clib_port.c
clib/stdio.h
common/console.c
common/printf.c
drivers/serial_dbg_t32.c
include/device_serial.h

index 5ca39484ce47c1c87d8d39f1d9af75054c1099d0..c029db0af39eb0efa278c5280fc8e4768f32f713 100644 (file)
@@ -19,6 +19,9 @@
  *\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
@@ -55,13 +89,36 @@ extern int errno;
 /* ----------------------------[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
@@ -168,13 +225,23 @@ void * sbrk( ptrdiff_t incr )
 \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
index 74593ad963cdf3085244a247675cb58050a6a090..40576c77c4858127e2c16abc82f514920df01d85 100644 (file)
@@ -46,5 +46,8 @@ int fileno( FILE *);
 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
index c4734fe24f657dd07226a342107f5c25864500b8..beece15896c00d45be05bfde9af8e8cb71a599c5 100644 (file)
  *\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
@@ -114,11 +146,6 @@ DeviceSerialType deviceList[] = {
        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
index d75161ef139c3d1026db7df2131646892cd7bd0f..a29607bd3bf3793dc512ef4855983009462dfccb 100644 (file)
  *       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
@@ -93,6 +105,38 @@ int fputs( const char *s, FILE *file ) {
 }\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
index 553255fb8932194c9a94ee1bdbc21495b1e89894..f091e59178514412150b135df272b4cffb2a055e 100644 (file)
@@ -28,6 +28,7 @@
 /* ----------------------------[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"
@@ -42,6 +43,7 @@ DeviceSerialType T32_Device = {
 //     .init = T32_Init,
        .read = t32_Read,
        .write = t32_Write,
+       .open = t32_Open,
 };
 
 /* ----------------------------[private functions]---------------------------*/
@@ -102,3 +104,7 @@ static int t32_Read( uint8_t *data, size_t nbytes )
        }
        return b;
 }
+
+static int t32_Open( const char *path, int oflag, int mode ) {
+       /* Save O_NONBLOCK to
+}
index 4e066bd2cbac44c9faa688fbfc39b23dad98828e..7df4b8e2fbe6348be1412561f096a5a1586b45b4 100644 (file)
 
 #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 */