commit a02be354e0eb5493518c00786cc2fd5643693d06 Author: Adam Pippin Date: Fri Apr 17 16:58:56 2020 -0700 Initial commit diff --git a/Colours.h b/Colours.h new file mode 100644 index 0000000..64be257 --- /dev/null +++ b/Colours.h @@ -0,0 +1,19 @@ +#define TFT_BLACK 0x0000 +#define TFT_NAVY 0x000F +#define TFT_DARKGREEN 0x03E0 +#define TFT_MAROON 0x7800 +#define TFT_PURPLE 0x780F +#define TFT_OLIVE 0x7BE0 +#define TFT_LIGHTGREY 0xC618 +#define TFT_DARKGREY 0x7BEF +#define TFT_BLUE 0x001F +#define TFT_GREENYELLOW 0xB7E0 +#define TFT_GREEN 0x07E0 +#define TFT_YELLOW 0xFFE0 +#define TFT_ORANGE 0xFDA0 +#define TFT_PINK 0xFC9F +#define TFT_CYAN 0x07FF +#define TFT_DARKCYAN 0x03EF +#define TFT_RED 0xF800 +#define TFT_MAGENTA 0xF81F +#define TFT_WHITE 0xFFFF diff --git a/Kernel.cpp b/Kernel.cpp new file mode 100644 index 0000000..b59187c --- /dev/null +++ b/Kernel.cpp @@ -0,0 +1,170 @@ +#include +#include "Kernel.h" +#include "Util.h" +#include "Colours.h" + +#define MAX_TASKS 8 + +struct Task *Kernel_get_task(int pid); + +struct Task tasks[MAX_TASKS]; +int next_pid = 1; +unsigned long last_tick; + +void Kernel_panic(char* message) +{ + M5.Lcd.setRotation(3); + M5.Lcd.fillScreen(TFT_BLUE); + M5.Lcd.setTextColor(TFT_WHITE, TFT_BLUE); + M5.Lcd.setCursor(0, 0); + M5.Lcd.print("Panic! "); + M5.Lcd.print(message); + while(true) {} +} + +void Kernel_setup() +{ + last_tick = millis(); +} + +void Kernel_start(int (*callback)(unsigned int), unsigned long interval) +{ + struct Task *process = Kernel_get_task(0); + if (process->pid == -1) + { + Kernel_panic("Could not start process -- reached MAX_TASKS"); + } + + process->pid = next_pid++; + process->callback = callback; + process->run_interval = interval; + process->run_accumulator = interval; + process->signal = SIGNAL_START | SIGNAL_TICK; + process->running = true; +} + +void Kernel_enable(int pid) +{ + struct Task *process = Kernel_get_task(pid); + if (process->pid == pid) + { + process->running = true; + } +} + +void Kernel_disable(int pid) +{ + struct Task *process = Kernel_get_task(pid); + if (process->pid == pid) + { + process->running = false; + } +} + +void Kernel_reap(int pid) +{ + struct Task *process = Kernel_get_task(pid); + if (process->pid != pid || process->running) + { + return; + } + process->pid = 0; + process->running = false; + process->exit_code = 0; + process->run_interval = 0; + process->run_accumulator = 0; + process->signal = SIGNAL_NONE; + process->signal_mask = 0xFFFF; +} + +int Kernel_get_exit_code(int pid) +{ + struct Task *process = Kernel_get_task(pid); + int exit_code = process->pid != pid || process->running == true ? -1 : process->exit_code; + Kernel_reap(pid); + return exit_code; +} + +bool Kernel_is_exited(int pid) +{ + struct Task *process = Kernel_get_task(pid); + return process->pid != pid || process->running == false; +} + +struct Task *Kernel_get_task(int pid) +{ + for (int i=0; i tasks[i].run_interval) + { + // Set signal + tasks[i].signal |= SIGNAL_TICK; + // Reset accumulator so we can start counting again + tasks[i].run_accumulator = 0; + } + else + { + // Otherwise, accumulate time + tasks[i].run_accumulator += duration; + } + + // If the process has any non-masked signals pending, run it + if ((tasks[i].signal & tasks[i].signal_mask) != 0) + { + // Run the task + int task_return = (*tasks[i].callback)(tasks[i].signal); + // Reset the signal + tasks[i].signal = SIGNAL_NONE; + + // If the tasks's return value was non-zero, it has exited. + if (task_return != 0) + { + // Mark it as no longer running + tasks[i].running = false; + // Store the exit code + tasks[i].exit_code = task_return; + } + } + + + // Check each task to see if it's the one scheduled to run on the next closest tick, and track it + // so we can put the processor to sleep until then. + if (tasks[i].run_interval - tasks[i].run_accumulator < next_tick_due) + { + next_tick_due = tasks[i].run_interval - tasks[i].run_accumulator; + } + } + } + + // Put processor to sleep until the next scheduled run of a task + // Leave the home button enabled to force a wake-up before then + esp_sleep_enable_timer_wakeup(next_tick_due * 1000); + esp_sleep_enable_ext0_wakeup((gpio_num_t)37, LOW); + esp_light_sleep_start(); +} diff --git a/Kernel.h b/Kernel.h new file mode 100644 index 0000000..78cf6f7 --- /dev/null +++ b/Kernel.h @@ -0,0 +1,37 @@ + +struct Task +{ + int pid = 0; + bool running = false; + int exit_code = 0; + int (*callback)(unsigned int); + unsigned long run_interval = 0; + unsigned long run_accumulator = 0; + unsigned int signal = 0; + unsigned int signal_mask = 0xFFFF; +}; + +void Kernel_setup(); +void Kernel_tick(); + +// Panic and stop everything +void Kernel_panic(char* message); + +// Start a new process +void Kernel_start(int (*callback)(unsigned int), unsigned long interval); +// Continue execution of a process +void Kernel_enable(int pid); +// Pause execution of a process +void Kernel_disable(int pid); +// Clean up exited process +void Kernel_reap(int pid); + +// Check if process has exited +bool Kernel_is_exited(int pid); +// Get exit code of process +int Kernel_get_exit_code(int pid); + +#define SIGNAL_NONE 0 +#define SIGNAL_TICK 1 +#define SIGNAL_START 2 +#define SIGNAL_STOP 4 diff --git a/PowerManagement.cpp b/PowerManagement.cpp new file mode 100644 index 0000000..1b0ef84 --- /dev/null +++ b/PowerManagement.cpp @@ -0,0 +1,10 @@ + +void PowerManagement_setup() +{ + +} + +void PowerManagement_tick() +{ + +} diff --git a/PowerManagement.h b/PowerManagement.h new file mode 100644 index 0000000..da44c18 --- /dev/null +++ b/PowerManagement.h @@ -0,0 +1,3 @@ + +void PowerManagement_setup(); +void PowerManagement_tick(); diff --git a/Util.cpp b/Util.cpp new file mode 100644 index 0000000..41356ba --- /dev/null +++ b/Util.cpp @@ -0,0 +1,16 @@ +#include +#include "Util.h" + +unsigned long millis_since(unsigned long timestamp) +{ + unsigned long now = millis(); + + if (now < timestamp) + { + return (4294967295 - timestamp) + millis(); + } + else + { + return millis() - timestamp; + } +} diff --git a/Util.h b/Util.h new file mode 100644 index 0000000..77ceed9 --- /dev/null +++ b/Util.h @@ -0,0 +1,2 @@ + +unsigned long millis_since(unsigned long timestamp); diff --git a/watchos.ino b/watchos.ino new file mode 100644 index 0000000..22a4d10 --- /dev/null +++ b/watchos.ino @@ -0,0 +1,44 @@ +#include +#include "PowerManagement.h" +#include "Kernel.h" +#include "Colours.h" + +int count = 0; +int test_func(unsigned int signal) +{ + M5.Lcd.fillScreen(TFT_DARKGREY); + M5.Lcd.setCursor(0, 0); + if (signal & SIGNAL_START) + { + M5.Lcd.setRotation(3); + M5.Lcd.print("Initializing..."); + } + if (signal & SIGNAL_STOP) + { + M5.Lcd.print("Stopping"); + return 255; + } + if (signal & SIGNAL_TICK) + { + count++; + M5.Lcd.print("Ran: "); + M5.Lcd.print(String(count)); + M5.Lcd.print(" times"); + } + return 0; +} + +void setup() +{ + M5.begin(); + Kernel_setup(); + PowerManagement_setup(); + + Kernel_start(&test_func, 1000); +} + +void loop() +{ + Kernel_tick(); + PowerManagement_tick(); +}