instant reset

This commit is contained in:
Devaev Maxim 2020-12-29 16:14:48 +03:00
parent 06040c8da9
commit b48a0606b7

View File

@ -88,12 +88,6 @@ class _TempRequestError(_RequestError):
pass pass
# =====
class _HardResetEvent(BaseEvent):
def make_request(self) -> bytes:
raise RuntimeError("Don't call me")
# ===== # =====
class BasePhyConnection: class BasePhyConnection:
def send(self, request: bytes) -> bytes: def send(self, request: bytes) -> bytes:
@ -137,6 +131,7 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many-
self.__phy = phy self.__phy = phy
self.__gpio = Gpio(gpio_device_path, reset_pin, reset_inverted, reset_delay) self.__gpio = Gpio(gpio_device_path, reset_pin, reset_inverted, reset_delay)
self.__reset_required_event = multiprocessing.Event()
self.__events_queue: "multiprocessing.Queue[BaseEvent]" = multiprocessing.Queue() self.__events_queue: "multiprocessing.Queue[BaseEvent]" = multiprocessing.Queue()
self.__notifier = aiomulti.AioProcessNotifier() self.__notifier = aiomulti.AioProcessNotifier()
@ -228,7 +223,7 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many-
await self.__notifier.wait() await self.__notifier.wait()
async def reset(self) -> None: async def reset(self) -> None:
self.__queue_event(_HardResetEvent(), clear=True) self.__reset_required_event.set()
@aiotools.atomic @aiotools.atomic
async def cleanup(self) -> None: async def cleanup(self) -> None:
@ -308,19 +303,21 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many-
with self.__phy.connected() as conn: with self.__phy.connected() as conn:
while not (self.__stop_event.is_set() and self.__events_queue.qsize() == 0): while not (self.__stop_event.is_set() and self.__events_queue.qsize() == 0):
if self.__reset_required_event.is_set():
try:
self.__set_state_busy(True)
self.__gpio.reset()
finally:
self.__reset_required_event.clear()
try: try:
event = self.__events_queue.get(timeout=0.1) event = self.__events_queue.get(timeout=0.1)
except queue.Empty: except queue.Empty:
self.__process_request(conn, REQUEST_PING) self.__process_request(conn, REQUEST_PING)
else: else:
if isinstance(event, _HardResetEvent): if isinstance(event, (SetKeyboardOutputEvent, SetMouseOutputEvent)):
self.__set_state_busy(True) self.__set_state_busy(True)
self.__gpio.reset() if not self.__process_request(conn, event.make_request()):
else: self.clear_events()
if isinstance(event, (SetKeyboardOutputEvent, SetMouseOutputEvent)):
self.__set_state_busy(True)
if not self.__process_request(conn, event.make_request()):
self.clear_events()
except Exception: except Exception:
self.clear_events() self.clear_events()
logger.exception("Unexpected error in the HID loop") logger.exception("Unexpected error in the HID loop")
@ -404,4 +401,4 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many-
reset_required = (1 if response[1] & 0b01000000 else 0) reset_required = (1 if response[1] & 0b01000000 else 0)
self.__state_flags.update(online=1, busy=reset_required, status=status) self.__state_flags.update(online=1, busy=reset_required, status=status)
if reset_required: if reset_required:
self.__gpio.reset() self.__reset_required_event.set()