1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-02 20:48:30 +00:00
trezor-firmware/src/trezor/loop.py

123 lines
2.6 KiB
Python
Raw Normal View History

import utime
2016-04-29 19:19:25 +00:00
from uheapq import heappop, heappush
from .utils import type_gen
2016-04-29 12:49:47 +00:00
from . import msg
2016-04-29 15:58:57 +00:00
from . import ui
2016-04-29 20:24:27 +00:00
from . import log
2016-04-29 19:19:25 +00:00
EVT_TSTART = const(-1)
EVT_TMOVE = const(-2)
EVT_TEND = const(-3)
EVT_MSG = const(-4)
evt_handlers = { EVT_TSTART: None,
EVT_TMOVE: None,
EVT_TEND: None,
EVT_MSG: None, }
time_queue = []
if __debug__:
# For performance stats
import array
log_delay_pos = 0
log_delay_rb_len = const(10)
log_delay_rb = array.array('i', [0] * log_delay_rb_len)
2016-04-29 23:20:57 +00:00
def __call_at(time, gen):
if __debug__:
2016-04-29 23:20:57 +00:00
log.debug(__name__, 'Scheduling %s %s', time, gen)
if not time:
time = utime.ticks_us()
2016-04-29 23:20:57 +00:00
heappush(time_queue, (time, gen))
def __wait_gen(gen, cb):
if isinstance(gen, int):
ret = yield gen
else:
ret = yield from gen
cb.throw(StopIteration())
def __wait_cb():
while True:
try:
yield sleep(1000000)
except StopIteration:
break
def wait(gens):
cb = __wait_cb()
cb.send(None)
for g in gens:
__call_at(None, __wait_gen(g, cb))
return cb
def sleep(us):
return utime.ticks_us() + us
2016-04-29 19:19:25 +00:00
def run_forever(start_gens):
if __debug__:
global log_delay_pos
global log_delay_rb
global log_delay_rb_len
2016-04-29 19:19:25 +00:00
delay_max = const(1000000)
for gen in start_gens:
__call_at(None, gen)
2016-04-29 19:19:25 +00:00
while True:
if time_queue:
2016-04-29 23:20:57 +00:00
t, _ = time_queue[0]
2016-04-29 19:19:25 +00:00
delay = t - utime.ticks_us()
else:
delay = delay_max
if __debug__:
# Adding current delay to ring buffer for performance stats
log_delay_rb[log_delay_pos] = delay
log_delay_pos = (log_delay_pos + 1) % log_delay_rb_len
event = msg.select(delay)
2016-04-29 19:19:25 +00:00
if event:
# run interrupt handler
log.info(__name__, "Received data: %s", event)
continue
2016-04-29 19:19:25 +00:00
else:
# run something from the time queue
2016-04-29 23:20:57 +00:00
_, gen = heappop(time_queue)
2016-04-29 19:19:25 +00:00
try:
2016-04-29 23:20:57 +00:00
ret = gen.send(None)
2016-04-29 19:19:25 +00:00
except StopIteration as e:
# gen ended, forget it and go on
continue
2016-04-29 23:20:57 +00:00
except Exception as e:
log.exception(__name__, e)
2016-04-29 23:20:57 +00:00
continue
2016-04-29 19:19:25 +00:00
2016-04-29 23:20:57 +00:00
if isinstance(ret, int):
2016-04-29 19:19:25 +00:00
if ret >= 0:
# sleep until ret, call us later
2016-04-29 23:20:57 +00:00
__call_at(ret, gen)
2016-04-29 19:19:25 +00:00
else:
# wait for event
raise NotImplementedError()
elif ret is None:
# just call us asap
2016-04-29 23:20:57 +00:00
__call_at(None, gen)
else:
raise Exception("Unhandled result %s" % gen)