Commits

Pierre Surply  committed f479f5e

Added exit syscall

  • Participants
  • Parent commits 5c0a52e

Comments (0)

Files changed (13)

File include/atucos.h

 int read(int fd, char *buff, size_t len);
 int open(const char *path);
 int exec(const char *path, int fd[]);
-int sysexit(int retval);
+int _exit(int retval);
 int ioctl(int fd, int op, void *arg);
 
 #endif /* ATUCOS_H */

File include/atucos/process.h

 #define PROC_NAME_LEN 32
 #define NB_FRAMES     16
 
+#define PROC_STATUS_NEW     0
+#define PROC_STATUS_RUNNING 1
+#define PROC_STATUS_EXITED  2
+
 struct context
 {
     uint32_t r7;
 struct process
 {
     char     id[PROC_NAME_LEN];
+    uint8_t  status;
     uint8_t  builtin;
-    uint8_t  first_launch;
     uint32_t pc;
     uint32_t sp;
     size_t   fd_size;
     uint16_t frames;
     struct   context context;
     struct   process *next;
+    struct   process *prev;
 };
 
 struct process *process_create(const char *id,
                                struct dev *stdcom,
                                struct vfs_inode *wd);
 
+void process_destroy(void);
+
 void proc_run(struct process *proc);
 void process_set_context(struct process *proc, struct context *context);
 

File src/app/game.c

 
     player.pos.x = 0;
     player.pos.y = 1;
-    player.lifes = 3;
+    player.lifes = 5;
 
     set_leds(leds);
 

File src/app/hello.c

     write(lcd, "Hello World !", 13);
     write(STDOUT_FILENO, "Hello World !\r\n", 15);
 
-    for (;;)
-        continue;
+    _exit(0);
 }

File src/app/shell.c

 {
     char c;
 
-    while (read(STDIN_FILENO, &c, 1))
+    while (read(STDIN_FILENO, &c, 1) < 1)
         continue;
 
     return c;

File src/drv/usart.c

     .ioctl = usart_ioctl
 };
 
-static int recv_char(volatile avr32_usart_t *usart)
-{
-    int c;
-
-    while (usart_read_char(usart, &c) != USART_SUCCESS)
-        continue;
-
-    return c;
-}
-
 void usart_init(struct dev *dev)
 {
     klog("[... ] Setting up %s", dev->id);
 int usart_read(struct dev *dev, void *buffer, size_t len)
 {
     int i;
+    int c;
+    int ret;
     char *s = buffer;
 
     for (i = 0; i < len; ++i)
-        s[i] = recv_char(dev->addr);
+    {
+        if (usart_read_char(dev->addr, &c) != USART_SUCCESS)
+                return i;
+        s[i] = c;
+    }
 
-    return 0;
+    return i;
 }
 
 int usart_write(struct dev *dev, const void *buffer, size_t len)
 
 void env_init(void)
 {
-    klog("Setting up environment variables...\r\n");
+    klog("[... ] Setting up environment variables");
 
 #define ENV_VAR(I, V)                           \
     addenv(I, V)
 
 #undef ENV_VAR
 
+    klog("\r[OK  ]\r\n");
 }
 
 void cmd_printenv(char *arg[])

File src/exception.S

-/**
- * \file
- *
- * \brief Exception and interrupt vectors mapping for the INTC Software Driver.
- *
- * Copyright (c) 2009-2011 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- *    Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#if !__AVR32_UC__ && !__AVR32_AP__
-  #error Implementation for the AVR32 architecture only.
-#endif
-
-
 #include <avr32/io.h>
-
-
-//! @{
-//! \verbatim
-
-
 .section  .exception, "ax", @progbits
 
-
-// Start of Exception Vector Table.
-
-/*
- * EVBA must be aligned with a power of two strictly greater than the
- * EVBA-relative offset of the last vector.
- */
 .balign 0x200
 
-// Export symbol.
 .global _evba
 .type _evba, @function
 _evba:
 __segfault:
         .word segfault
 
-/*
- * Interrupt support.
- * The interrupt controller must provide the offset address relative to EVBA.
- * Important note:
- * All interrupts call a C function named _get_interrupt_handler.
- * This function will read group and interrupt line number to then return in
- *R12 a pointer to a user-provided interrupt handler.
- */
-
 .balign 4
 
 .irp    priority, 0, 1, 2, 3
         st.w    --sp, r5
         st.w    --sp, r6
         st.w    --sp, r7
-	// Pass the int_level parameter to the _get_interrupt_handler function.
-	mov     r12, \priority
-	call    _get_interrupt_handler
-	// Get the pointer to the interrupt handler returned by the function.
-	cp.w    r12, 0
-	/*
-	 * If this was not a spurious interrupt (R12 != NULL), jump to the
-	 * handler.
-	 */
+        mov     r12, \priority
+        call    _get_interrupt_handler
+        cp.w    r12, 0
         icall r12
         ld.w r7, sp++
         ld.w r6, sp++
         ld.w r2, sp++
         ld.w r1, sp++
         ld.w r0, sp++
-	rete
+        rete
 .endr
-
-
-//! \endverbatim
-//! @}

File src/process.c

 {
     struct process *proc = malloc(sizeof (struct process));
     strncpy(proc->id, id, PROC_NAME_LEN);
-    proc->first_launch = 1;
+    proc->status = PROC_STATUS_NEW;
     proc->fd = malloc(sizeof (struct dev *) * 4);
     proc->fd_size = 4;
     proc->fd_maxsize = 4;
     proc->builtin = 0;
     mem_process(proc);
     if (current_process == NULL)
+    {
         proc->next = proc;
+        proc->prev = proc;
+        current_process = proc;
+    }
     else
     {
         proc->next = current_process->next;
+        proc->prev = current_process;
+        current_process->next->prev = proc;
         current_process->next = proc;
     }
     proc->context.pc = pc;
     proc->context.r10 = 0;
     proc->context.r9 = 0;
     proc->context.r8 = 0;
-    current_process = proc;
     return proc;
 }
 
+void process_destroy(void)
+{
+    struct process *cp = current_process;
+    if (cp->next != cp)
+    {
+        cp->next->prev = cp->prev;
+        cp->prev->next = cp->next;
+        current_process = cp->next;
+    }
+    else
+        current_process = NULL;
+    free(cp->fd);
+    free(cp);
+}
+
 void proc_run(struct process *proc)
 {
     current_process = proc;

File src/scheduler.c

                   : "=r" (context)
                   :
                   : "r8");
-    if (!current_process->first_launch)
+    if (current_process->status != PROC_STATUS_NEW)
         process_set_context(current_process, context);
     else
-        current_process->first_launch = 0;
-    current_process = current_process->next;
+        current_process->status = PROC_STATUS_RUNNING;
+    if (current_process->status == PROC_STATUS_EXITED)
+        process_destroy();
+    else
+        current_process = current_process->next;
     mem_setmpu(current_process);
     memcpy(context, &current_process->context, sizeof (struct context));
     asm volatile ("st.w  --sp, %0"       "\n\r"

File src/syscall.c

                 current_process->fd[3],
                 current_process->wd);
         proc->builtin = 1;
+        return 0;
     }
     return -1;
 }
 
 int sys_exit(int retval)
 {
+    klog("%s exited with %d\r\n", current_process->id, retval);
+    current_process->status = PROC_STATUS_EXITED;
 }
 
 int sys_ioctl(int fd, int op, void *arg)
 
 void vfs_init(void)
 {
-    klog("Setting up virtual file system...\r\n");
+    klog("[... ] Setting up environment variables");
     vfs.type = VFS_DIR;
     vfs.content.dir = vfs_create_dir(".", &vfs, NULL);
     vfs.content.dir = vfs_create_dir("..", &vfs, vfs.content.dir);
+    klog("\r[OK  ]\r\n");
 }
 
 struct vfs_inode *vfs_getroot(void)

File userland/syscall.c

     return atucos_syscall(3, cmd, fd, NULL, NULL);
 }
 
-int sysexit(int retval)
+int _exit(int retval)
 {
-    return atucos_syscall(4, (void *) retval, NULL, NULL, NULL);
+    atucos_syscall(4, (void *) retval, NULL, NULL, NULL);
+    for (;;)
+        continue;
+    return 0;
 }
 
 int ioctl(int fd, int op, void *arg)