An operating system for CircuitPython devices
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.0 KiB

import bin #this is at the end of the script in case any functions from bin
#depend on anything here
from fibonaccios.exceptions import *
from fibonaccios.apploader import get_app
import fibonaccios.apploader # apploader hack
import time
import usb_cdc
import os
class App:
def __init__(self, os, pid, name, wd, *argv):
self.os = os
self.pid = pid
self.name = name
self.store = {}
self.next_function = 'main'
self.run_at = -1
self.wd = wd
self.argv = (self,) + argv
self.waiting_for = -1
def iterate(self):
os.chdir(self.wd)
if time.monotonic() >= self.run_at and not self.waiting_for in self.os.apps:
getattr(self, f'F_{self.next_function}')()
@property
def console(self):
if self.pid == self.os.controllers[-1]:
return self.os.console
else:
raise NotConsoleController(self.os.controllers[-1])
def transfer_console(self, recipient):
if self.pid == self.os.controllers[-1]:
self.os.controllers.append(recipient)
else:
raise NotConsoleController(self.os.controllers[-1])
def chdir(self, wd):
os.chdir(wd)
self.wd = os.getcwd()
def jump(self, function):
self.next_function = function
def sleep(self, seconds):
self.run_at = time.monotonic() + seconds
def exec(self, command, *argv):
self.os.apps[self.pid] = get_app(command)(self.os, self.pid, command, self.wd, *argv)
def launch(self, command, *argv):
return self.os.launch(command, self.wd, *argv)
def wait(self, pid):
self.waiting_for = pid
def end_wait(self):
self.waiting_for = -1
def on_exit(self):
pass
def exit(self):
del self.os.apps[self.pid]
apploader.App = App # apploader hack
class OS:
def __init__(self):
self.apps = {}
self.next_new = 0
self.controllers = [0]
self.console = usb_cdc.console
usb_cdc.console.timeout = 0
self.next_pidi = 0
self.launch('init', '/')
def iterate(self):
pid = list(self.apps.keys())[self.next_pidi]
function = self.apps[pid].iterate
function()
try:
self.apps[pid]
# If this succeds, the app did not exit and next_pidi should
# be incremented
self.next_pidi += 1
except KeyError:
# If self.apps[pid] failed, the app exited and next_pidi
# should not be incremented
pass
self.next_pidi = self.next_pidi % len(self.apps)
while not self.controllers[-1] in self.apps.keys():
self.controllers.pop()
def launch(self, app, wd, *argv):
self.apps[self.next_new] = get_app(app)(self, self.next_new, app, wd, *argv)
self.next_new += 1
return self.next_new - 1
def kill(self, pid):
try:
del self.apps[pid]
except KeyError:
raise(NoSuchProcess(pid))
def run():
os = OS()
while True:
os.iterate()