]> code.bitgloo.com Git - clyne/stmos.git/commitdiff
good tasks, svc cleaning
authorClyne Sullivan <tullivan99@gmail.com>
Mon, 29 Oct 2018 22:11:53 +0000 (18:11 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Mon, 29 Oct 2018 22:11:53 +0000 (18:11 -0400)
.gitignore
Makefile
src/kernel/init.c
src/kernel/svc.c
src/kernel/task.c
src/kernel/task.h
src/kernel/vfs.c [new file with mode: 0644]
src/kernel/vfs.h [new file with mode: 0644]
src/user/user.c

index d42ab353abaa3418f4624ee2fa23658524248795..8bbd2c8eafea90619d7af1f75ac91f1a14492c66 100644 (file)
@@ -1 +1,3 @@
-out/*
+*.o
+*.swp
+*.swo
index 02fbad2c676af3b0eb1679d942a5cb2e4cbc7dc9..c131a32d58c649870fa78300064234151bd5a358 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ AS = as
 
 MCUFLAGS = -mthumb -mcpu=cortex-m4 #-mfloat-abi=hard -mfpu=fpv4-sp-d16
 AFLAGS = $(MCUFLAGS) 
-CFLAGS = $(MCUFLAGS) -ggdb \
+CFLAGS = $(MCUFLAGS) -ggdb --specs=nosys.specs \
        -I.. \
        -fno-builtin -fsigned-char -ffreestanding \
        -Wall -Werror -Wextra -pedantic \
index 474ef8a78a1e1c87b3570facb6fa5674b79e4996..6bb7eb59c75a28c7245d11026715321003595389 100644 (file)
@@ -22,6 +22,7 @@
 #include "gpio.h"\r
 #include "heap.h"\r
 #include "task.h"\r
+#include "vfs.h"\r
 #include <arch/stm/stm32l476xx.h>\r
 \r
 extern uint8_t __bss_end__;\r
index 4aa156ebc2e9976eeb8d17a74aa06a32b15a87c4..1e03262349f3b641c938dd7229f07d9d74e668fa 100644 (file)
@@ -41,24 +41,31 @@ void SVC_Handler(void) {
 
        switch (svc_number) {
        case -1:
-       case 0:
-               _exit(args[0]);
+       case 0: /* Task-related calls
+                * 0 - _exit
+                * 1 - fork
+                * 2 - getpid
+                * 3 - waitpid
+                */
+               task_svc(args);
                break;
-       case 1:
+
+       case 1: /* GPIO-related calls
+                * 0 - gpio_mode
+                * 1 - gpio_type
+                * 2 - gpio_pupd
+                * 3 - gpio_speed
+                * 4 - gpio_dout
+                */
                gpio_svc(args);
                break;
-       case 2:
+
+       case 2: /* Clock-related calls
+                * 0 - delay
+                * 1 - udelay
+                */
                clock_svc(args);
                break;
-       case 3:
-               asm("\
-                       mrs r0, psp; \
-                       stmdb r0!, {r4-r11, r14}; \
-                       mov %0, r0; \
-               " : "=r" (args[0]));
-               task_svc(args);
-               asm("mov r0, %0" :: "r" (args[0])); // TODO doesn't work, r0 overwritten on exc. return
-               break;
        default:
                break;
        }
index 4f61e1d7d22543e5b1e3e669ac2c98070b6669d9..e4531db203346fa55d592a80332305cf3ce5ea02 100644 (file)
 #include "task.h"
 #include <arch/stm/stm32l476xx.h>
 
+#define YIELD { SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; }
+
 static task_t *task_current;
 static task_t *task_queue;
 static uint8_t task_disable = 0;
-static uint32_t task_next_pid = 0;
+static pid_t task_next_pid = 0;
+
+void task_exit(int code);
+int task_fork(void);
+pid_t task_getpid(void);
+pid_t task_waitpid(pid_t pid, int *wstatus, int options);
 
-int task_fork(uint32_t sp);
 void task_svc(uint32_t *args)
 {
-       int result = task_fork(args[0]);
-       args[0] = result;
+       switch (args[0]) {
+       case 0:
+               task_exit(args[1]);
+               break;
+       case 1:
+               *((int *)args[1]) = task_fork();
+               break;
+       case 2:
+               *((int *)args[1]) = task_getpid();
+               break;
+       case 3:
+               *((int *)args[4]) = task_waitpid(args[1], (int *)args[2],
+                       args[3]);
+               break;
+       default:
+               break;
+       }
 }
 
 void task_hold(uint8_t hold)
@@ -45,19 +66,54 @@ void task_hold(uint8_t hold)
 
 void task_sleep(uint32_t ms)
 {
-       task_current->sleep = millis() + ms;
-       SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
+       task_current->status.state = TASK_SLEEPING;
+       task_current->status.value = millis() + ms;
+       YIELD;
 }
 
-uint32_t task_getpid(void)
+pid_t task_getpid(void)
 {
        return task_current->pid;
 }
 
-void _exit(int code)
+pid_t task_waitpid(pid_t pid, int *wstatus, int options)
+{
+       (void)options;
+       *wstatus = 0;
+
+       // Find the process
+       task_t *task = task_queue;
+       while (task != 0 && task->pid != pid)
+               task = task->next;
+
+       if (task == 0)
+               return (pid_t)-1;
+
+       // Check process's state
+       if (task->status.state == TASK_EXITED) {
+               *wstatus = task->status.value | (1 << 8);
+               task->status.state = TASK_ZOMBIE;
+       }
+
+       return pid;
+}
+
+/*vfs_node *task_getcwd(void)
 {
-       (void)code;
+       return task_current->cwd;
+}*/
 
+void task_exit(int code)
+{
+       task_current->status.state = TASK_EXITED;
+       task_current->status.value = code & 0xFF;
+
+       YIELD;
+}
+
+void task_purge(void)
+{
+       // Remove task from the chain
        if (task_queue == task_current) {
                task_queue = task_queue->next;
        } else {
@@ -75,19 +131,17 @@ void _exit(int code)
        free(task_current->stack);
        free(task_current);
 
-       SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
-       // TODO if child proc. set return code in parent task handle?
-       // or something like that
+       YIELD;
+       while (1);
 }
 
-
 /**
  * Exits the task (userspace call).
  */
 __attribute__ ((naked))
 void task_doexit(void)
 {
-       asm("eor r0, r0; svc 0");
+       asm("eor r0, r0; eor r1, r1; svc 0");
        while (1);
 }
 
@@ -109,8 +163,10 @@ task_t *task_create(void (*code)(void), uint16_t stackSize)
 {
        task_t *t = (task_t *)malloc(sizeof(task_t));
        t->next = 0;
-       t->sleep = 0;
        t->pid = task_next_pid++;
+       t->pgid = t->pid;
+       t->status.state = TASK_RUNNING;
+       t->status.value = 0;
 
        t->stack = (uint32_t *)malloc(stackSize);
        void *sp = (uint8_t *)t->stack + stackSize - 68; // excep. stack + regs
@@ -141,7 +197,8 @@ void task_init(void (*init)(void), uint16_t stackSize)
        task_current->next = 0;
        task_current->stack = 0; // free() is called on this
        task_current->sp = 0;
-       task_current->sleep = 1000;
+       task_current->status.state = TASK_SLEEPING;
+       task_current->status.value = 1000;
 
        task_queue = task_create(init, stackSize);
 
@@ -177,10 +234,17 @@ int task_fork_ret(void)
 }
 
 // Return 0 for child, non-zero for parent
-int task_fork(uint32_t sp)
+int task_fork(void)
 {
        asm("cpsid i");
 
+       uint32_t sp;
+       asm("\
+               mrs r0, psp; \
+               stmdb r0!, {r4-r11, r14}; \
+               mov %0, r0; \
+       " : "=r" (sp));
+
        //// 1. Prepare child task
        // Get parent task's stack info
        alloc_t *stackInfo = (alloc_t *)(((uint8_t *)task_current->stack)
@@ -189,8 +253,10 @@ int task_fork(uint32_t sp)
        // Create child task data
        task_t *childTask = (task_t *)malloc(sizeof(task_t));
        childTask->stack = (uint32_t *)malloc(stackInfo->size - sizeof(alloc_t));
-       childTask->sleep = 0;
        childTask->pid = task_next_pid++;
+       childTask->pgid = task_current->pid;
+       childTask->status.state = TASK_RUNNING;
+       childTask->status.value = 0;
 
        // Copy parent's stack
        for (uint32_t i = 0; i < (stackInfo->size - sizeof(alloc_t)); i++)
@@ -198,6 +264,7 @@ int task_fork(uint32_t sp)
 
        childTask->sp = (uint32_t *)((uint32_t)childTask->stack + (sp
                - (uint32_t)task_current->stack));
+       childTask->sp[8] = 0xFFFFFFFD;
        childTask->sp[15] = (uint32_t)task_fork_ret;
        //childTask->sp[16] = 0x01000000;
 
@@ -208,7 +275,7 @@ int task_fork(uint32_t sp)
        //// 3. Re-enable scheduler, make change happen
        asm("cpsie i");
 
-       SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
+       YIELD;
        return childTask->pid;
 }
 
@@ -234,13 +301,14 @@ void PendSV_Handler(void)
                task_current = task_current->next;
                if (task_current == 0)
                        task_current = task_queue;
-       } while (task_current->sleep > ticks);
-       task_current->sleep = 0;
 
-       /*task_current = task_current->next;
-       if (task_current == 0)
-               task_current = task_queue;*/
+               if (task_current->status.state == TASK_SLEEPING &&
+                       task_current->status.value <= ticks)
+                       task_current->status.state = TASK_RUNNING;
+       } while (task_current->status.state != TASK_RUNNING);
 
+       task_current->status.state = TASK_RUNNING;
+       task_current->status.value = 0;
 
        // Load stack pointer, return
        asm("\
index 0e2e07a989ab62498f6afbf3ac8703d3776ecbf3..d78e1dafdd7e80f49a5aeb484a308169026b4f3c 100644 (file)
 #ifndef TASK_H_
 #define TASK_H_
 
+#include "vfs.h"
 #include <stdint.h>
 
+#define WIFEXITED(w)   (w & (1 << 8))
+#define WEXITSTATUS(w) (w & 0xFF)
+
+typedef uint16_t pid_t;
+
 /**
  * A structure to contain task data.
  */
@@ -30,10 +36,22 @@ typedef struct task_t {
        struct task_t *next; /**< pointer to the next task_t instance */
        uint32_t *sp;        /**< pointer to the task's last sp register value */
        uint32_t *stack;     /**< pointer to the task's stack */
-       uint32_t sleep;      /**< number of milliseconds task is sleeping for */
-       uint32_t pid;
+       pid_t pid;           /**< Task (Process) ID */
+       pid_t pgid;          /**< Process Group ID */
+       struct {
+               uint32_t state : 8;
+               uint32_t value : 24;
+       } status;
+//     vfs_node *cwd;
 } task_t;
 
+enum TASK_STATUS_FLAGS {
+       TASK_RUNNING,  /**< Task is actively running */
+       TASK_SLEEPING, /**< Task is sleeping for task_t.sleep ms */
+       TASK_EXITED,   /**< Task has exited, task_t.sleep has code */
+       TASK_ZOMBIE    /**< Task exited, accounted for, ready to go bye bye */
+};
+
 /**
  * Enters multitasking mode. The given function acts as the initial thread.
  * This task is given a 4kb stack.
@@ -56,14 +74,8 @@ void task_start(void (*task)(void), uint16_t stackSize);
  */
 void task_hold(uint8_t hold);
 
-/**
- * Frees the task's resources and removes it from the running task list.
- * @param code An unused exit code
- */
-void _exit(int code);
-
 void task_sleep(uint32_t ms);
 
-uint32_t task_getpid(void);
+//vfs_node *task_getcwd(void);
 
 #endif // TASK_H_
diff --git a/src/kernel/vfs.c b/src/kernel/vfs.c
new file mode 100644 (file)
index 0000000..a0d9bb4
--- /dev/null
@@ -0,0 +1,15 @@
+#include "vfs.h"
+#include "task.h"
+
+//static vfs_node vfs_root;
+
+int vfs_open(const char *path, int mode)
+{
+       (void)path;
+       (void)mode;
+//     vfs_node *cd = task_getcwd();
+//     if (cd == 0)
+//             cd = &vfs_root;
+
+       return 0;
+}
diff --git a/src/kernel/vfs.h b/src/kernel/vfs.h
new file mode 100644 (file)
index 0000000..6874905
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef VFS_H_
+#define VFS_H_
+
+#include <stdint.h>
+
+struct vfs_node;
+struct dirent;
+
+typedef struct {
+       uint32_t (*read)(struct vfs_node *, uint32_t, uint32_t, uint8_t *);
+       uint32_t (*write)(struct vfs_node *, uint32_t, uint32_t, const uint8_t *);
+       void (*open)(struct vfs_node *);
+       void (*close)(struct vfs_node *);
+} vfs_driver;
+
+typedef struct vfs_node {
+       char *name;
+       uint32_t flags;
+
+       struct vfs_node *parent;
+       union {
+               struct vfs_node* children;
+               vfs_driver *access;
+       } data;
+} vfs_node;
+
+struct dirent {
+       char *name;
+       vfs_node *node;
+};
+
+#endif // VFS_H_
index 87f4b49b594cc09277c5e2cf80512417d4880075..620ffd0bb24c90c53d6aed14d971acb676a999fe 100644 (file)
@@ -15,11 +15,12 @@ void user_delay(uint32_t ms)
 
 int fork(void)
 {
-       int result;
+       int result = 0;
        asm("\
-               svc 3; \
-               mov %0, r0; \
-       " : "=r" (result));
+               mov r0, 1; \
+               mov r1, %0; \
+               svc 0; \
+       " :: "r" (&result));
        return result;
 }