]> code.bitgloo.com Git - clyne/stmos.git/commitdiff
unpriviledged sleep wip
authortcsullivan <tullivan99@gmail.com>
Thu, 11 Oct 2018 03:31:10 +0000 (23:31 -0400)
committertcsullivan <tullivan99@gmail.com>
Thu, 11 Oct 2018 03:31:10 +0000 (23:31 -0400)
run.sh [new file with mode: 0755]
src/kernel/clock.c
src/kernel/clock.h
src/kernel/init.c
src/kernel/task.c
src/kernel/task.h
src/user/user.c

diff --git a/run.sh b/run.sh
new file mode 100755 (executable)
index 0000000..a7efaa1
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# @file run.sh
+# Starts openocd and connects gdb to the target, for programming/debugging
+#
+# Copyright (C) 2018 Clyne Sullivan
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+#
+
+openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg &
+sleep 1
+gdb-multiarch -ex "target remote localhost:3333" main.elf
+pkill openocd
index 44b77221b38c3874a73dcb9f4430c1531e4d5f33..5bfc93ad7c026ded88acd1c158b7d61390f8d1f3 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "clock.h"
+#include "task.h"
 #include <arch/stm/stm32l476xx.h>
 
 // ticks since init
@@ -26,9 +27,16 @@ volatile uint32_t ticks = 0;
 
 volatile uint8_t tim2_finished = 1;
 
+extern task_t *current;
+
 void clock_svc(uint32_t *args)
 {
-       udelay(args[0]);
+       if (args[0] == 0) {
+               current->sleep = ticks + args[1];
+               SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
+       } else if (args[0] == 1) {
+               udelay(args[1]);
+       }
 }
 
 void clock_init(void)
@@ -71,6 +79,11 @@ void clock_init(void)
        TIM2->CR1 |= TIM_CR1_OPM | TIM_CR1_CEN;
 }
 
+uint32_t millis(void)
+{
+       return ticks;
+}
+
 void delay(uint32_t count)
 {
        uint32_t target = ticks + count;
index c3554f6268aa1aa91154bdc6aa54585f1738860e..3ec7857dec74ee15fdbf7e6faad081b09be263dc 100644 (file)
@@ -28,6 +28,8 @@
  */
 extern void clock_init(void);
 
+uint32_t millis(void);
+
 /**
  * Sleeps for given amount of milliseconds.
  * @param ms Number of milliseconds to sleep for
index e4ac115bdba550dbd47002f6236c047efb090de9..ca60c3ec37f92c349c4b7086482e192c24836490 100644 (file)
@@ -27,6 +27,7 @@
 extern uint8_t __bss_end__;\r
 \r
 extern void user_main(void);\r
+void init_idle(void);\r
 \r
 int main(void)\r
 {\r
@@ -46,7 +47,14 @@ int main(void)
        // enable FPU\r
        //SCB->CPACR |= (0xF << 20);\r
 \r
-       task_init(user_main);\r
+       task_init(init_idle, 512);\r
        while (1);\r
 }\r
 \r
+void init_idle(void)\r
+{\r
+       task_start(user_main, 4096);\r
+\r
+       while (1)\r
+               delay(100);\r
+}\r
index 1a1c16b47b24ff9f7e7e2f95c713abfbb7e2610c..19fa5ea99275c1c17ebd17370075ea4e9f25b1e0 100644 (file)
@@ -18,8 +18,9 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-#include "task.h"
+#include "clock.h"
 #include "heap.h"
+#include "task.h"
 #include <arch/stm/stm32l476xx.h>
 
 task_t *current, *prev;
@@ -71,7 +72,7 @@ void task_crt0(void)
        ");
 }
 
-task_t *task_create(void (*code)(void), uint32_t stackSize)
+task_t *task_create(void (*code)(void), uint16_t stackSize)
 {
        task_t *t = (task_t *)malloc(sizeof(task_t));
        t->next = 0;
@@ -95,15 +96,16 @@ task_t *task_create(void (*code)(void), uint32_t stackSize)
        t->sp[14] = (uint32_t)code;
        t->sp[15] = (uint32_t)task_crt0;
        t->sp[16] = 0x01000000;
+       t->sleep = 0;
        return t;
 }
 
-void task_init(void (*init)(void))
+void task_init(void (*init)(void), uint16_t stackSize)
 {
        current = (task_t *)malloc(sizeof(task_t));
        current->stack = 0;
 
-       task_t *init_task = task_create(init, 4096);
+       task_t *init_task = task_create(init, stackSize);
 
        prev = init_task;
        current->next = init_task;
@@ -166,33 +168,29 @@ void PendSV_Handler(void)
        if (task_disable != 0)
                asm("bx lr");
 
-       // TODO why, and what does this do
        // TODO get back to c, implement task sleeping
+
+       // Save current stack pointer
        asm("\
                mrs r0, psp; \
                isb; \
-               ldr r1, =current; \
-               ldr r2, [r1]; \
                stmdb r0!, {r4-r11, r14}; \
-               str r0, [r2, #8]; \
-               ldr r0, [r2, #0]; \
-               ldr r3, =prev; \
-               str r2, [r3]; \
-               str r0, [r1]; \
-               ldr r2, [r1]; \
-               ldr r0, [r2, #8]; \
+               mov %0, r0; \
+       " : "=r" (current->sp));
+
+       // Load next task
+       uint32_t ticks = millis();
+       do {
+               current = current->next;
+       } while (current->sleep > ticks);
+       current->sleep = 0;
+
+       // Load stack pointer, return
+       asm("\
+               mov r0, %0; \
                ldmia r0!, {r4-r11, r14}; \
                msr psp, r0; \
                bx lr; \
-       ");
-       // r1 = current
-       // r2 = *current
-       // r0 = sp
-       // *current.sp = sp
-       // r0 = current->next
-       // current = r0
-       // r2 = *current
-       // r0 = *current.sp
-       // unpack
+       " :: "r" (current->sp));
 }
 
index 3d331ae9b5968a5e8983baa13c7d36eaec1c2039..472e909e5d89992f8ca559842b7b143aef7468c2 100644 (file)
@@ -30,6 +30,7 @@ typedef struct {
        void *next;      /**< pointer to the next task_t instance */
        uint32_t *stack; /**< pointer to the task's stack */
        uint32_t *sp;    /**< pointer to the task's last sp register value */
+       uint32_t sleep;  /**< number of milliseconds task is sleeping for */
 } task_t;
 
 /**
@@ -37,7 +38,7 @@ typedef struct {
  * This task is given a 4kb stack.
  * @param init the initial thread to run
  */
-void task_init(void (*init)(void));
+void task_init(void (*init)(void), uint16_t stackSize);
 
 /**
  * Starts a new task.
index fc51d29c6ca60b63e381598adfebc746b2a8cc43..0bb26079fa3b046873571dc0d0b492ab559dcaf0 100644 (file)
@@ -5,7 +5,16 @@
 void task1(void);
 void task2(void);
 
+void user_delay(uint32_t ms)
+{
+       register uint32_t r1 asm("r1") = ms;
 
+       asm("\
+               mov r0, 0; \
+               mov r1, %0; \
+               svc 2; \
+       " :: "r" (r1));
+}
 
 void user_main(void)
 {
@@ -14,22 +23,22 @@ void user_main(void)
 
        for (int i = 0; i < 8; i++) {
                gpio(GPIO_OUT, 5, !(i & 1));
-               delay(200);
+               user_delay(200);
        }
 }
 
 void task1(void)
 {
-       delay(400);
+       user_delay(400);
        task_start(task2, 1024);
 }
 
 void task2(void)
 {
        int state = 0;
-       delay(2500);
+       user_delay(2500);
        while (1) {
                gpio(GPIO_OUT, 5, state ^= 1);
-               delay(500);
+               user_delay(500);
        }
 }