1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-20 09:09:02 +00:00

fix(core): make mod_trezorio_poll return False only on timeout

[no changelog]
This commit is contained in:
cepetr 2025-04-10 17:57:49 +02:00 committed by cepetr
parent 07ad01220c
commit 8a636bd9cf
8 changed files with 113 additions and 108 deletions

View File

@ -186,7 +186,7 @@ static void kernel_loop(applet_t *coreapp) {
sysevents_t awaited = {0};
sysevents_t signalled = {0};
sysevents_poll(&awaited, &signalled, 100);
sysevents_poll(&awaited, &signalled, ticks_timeout(100));
} while (applet_is_alive(coreapp));
}

View File

@ -157,9 +157,9 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
case SYSCALL_SYSEVENTS_POLL: {
const sysevents_t *awaited = (sysevents_t *)args[0];
sysevents_t *signalled = (sysevents_t *)args[1];
uint32_t timeout = args[2];
uint32_t deadline = args[2];
if (!g_in_app_callback) {
sysevents_poll__verified(awaited, signalled, timeout);
sysevents_poll__verified(awaited, signalled, deadline);
}
} break;

View File

@ -77,8 +77,8 @@ uint64_t systick_us_to_cycles(uint64_t us) {
#include <sys/sysevent.h>
void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled,
uint32_t timeout) {
syscall_invoke3((uint32_t)awaited, (uint32_t)signalled, timeout,
uint32_t deadline) {
syscall_invoke3((uint32_t)awaited, (uint32_t)signalled, deadline,
SYSCALL_SYSEVENTS_POLL);
}

View File

@ -46,7 +46,7 @@
// ---------------------------------------------------------------------
void sysevents_poll__verified(const sysevents_t *awaited,
sysevents_t *signalled, uint32_t timeout) {
sysevents_t *signalled, uint32_t deadline) {
if (!probe_read_access(awaited, sizeof(*awaited))) {
goto access_violation;
}
@ -55,7 +55,7 @@ void sysevents_poll__verified(const sysevents_t *awaited,
goto access_violation;
}
sysevents_poll(awaited, signalled, timeout);
sysevents_poll(awaited, signalled, deadline);
return;
access_violation:

View File

@ -25,7 +25,7 @@
#include <sys/sysevent.h>
void sysevents_poll__verified(const sysevents_t *awaited,
sysevents_t *signalled, uint32_t timeout);
sysevents_t *signalled, uint32_t deadline);
// ---------------------------------------------------------------------
#include <sys/systask.h>

View File

@ -46,11 +46,11 @@ typedef struct {
} sysevents_t; // sys_events_t
// Polls for the specified events. The function blocks until at least
// one event is signaled or the timeout (in milliseconds) expires.
// one event is signaled or deadline expires.
//
// Multiple events may be signaled simultaneously.
//
// Returns the events that were signaled. If the timeout expires, both
// fields in the result are set to 0.
void sysevents_poll(const sysevents_t* awaited, sysevents_t* signalled,
uint32_t timeout);
uint32_t deadline);

View File

@ -157,7 +157,7 @@ static inline void insert_poller(sysevent_dispatcher_t *dispatcher,
}
void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled,
uint32_t timeout) {
uint32_t deadline) {
sysevent_dispatcher_t *dispatcher = &g_sysevent_dispatcher;
memset(signalled, 0, sizeof(*signalled));
@ -177,7 +177,7 @@ void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled,
dispatcher->pollers[prio].task = systask_active();
dispatcher->pollers[prio].awaited = awaited;
dispatcher->pollers[prio].signalled = signalled;
dispatcher->pollers[prio].deadline = ticks_timeout(timeout);
dispatcher->pollers[prio].deadline = deadline;
if (active_task != kernel_task) {
systask_yield_to(kernel_task);

View File

@ -115,121 +115,126 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
// just coerce it to an uint. Deliberately assigning *get_int* to *uint_t*
// will give us C's wrapping unsigned overflow behavior, and the `deadline`
// result will come out correct.
const mp_uint_t timeout = MAX(trezor_obj_get_int(timeout_ms), 0);
sysevents_t signalled = {0};
const mp_uint_t deadline = ticks_timeout(trezor_obj_get_int(timeout_ms));
sysevents_poll(&awaited, &signalled, timeout);
for (;;) {
sysevents_t signalled = {0};
sysevents_poll(&awaited, &signalled, deadline);
if (signalled.read_ready == 0 && signalled.write_ready == 0) {
return mp_const_false;
}
#ifdef USE_TOUCH
if (signalled.read_ready & (1 << SYSHANDLE_TOUCH)) {
const uint32_t evt = touch_get_event();
if (evt != 0) {
// ignore TOUCH_MOVE events if they are too frequent
if ((evt & TOUCH_MOVE) == 0 ||
(hal_ticks_ms() - last_touch_sample_time > 10)) {
last_touch_sample_time = hal_ticks_ms();
if (signalled.read_ready & (1 << SYSHANDLE_TOUCH)) {
const uint32_t evt = touch_get_event();
if (evt != 0) {
// ignore TOUCH_MOVE events if they are too frequent
if ((evt & TOUCH_MOVE) == 0 ||
(hal_ticks_ms() - last_touch_sample_time > 10)) {
last_touch_sample_time = hal_ticks_ms();
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
const uint32_t etype = (evt >> 24) & 0xFFU; // event type
const uint32_t ex = (evt >> 12) & 0xFFFU; // x position
const uint32_t ey = evt & 0xFFFU; // y position
uint32_t exr; // rotated x position
uint32_t eyr; // rotated y position
switch (display_get_orientation()) {
case 90:
exr = ey;
eyr = DISPLAY_RESX - ex;
break;
case 180:
exr = DISPLAY_RESX - ex;
eyr = DISPLAY_RESY - ey;
break;
case 270:
exr = DISPLAY_RESY - ey;
eyr = ex;
break;
default:
exr = ex;
eyr = ey;
break;
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
const uint32_t etype = (evt >> 24) & 0xFFU; // event type
const uint32_t ex = (evt >> 12) & 0xFFFU; // x position
const uint32_t ey = evt & 0xFFFU; // y position
uint32_t exr; // rotated x position
uint32_t eyr; // rotated y position
switch (display_get_orientation()) {
case 90:
exr = ey;
eyr = DISPLAY_RESX - ex;
break;
case 180:
exr = DISPLAY_RESX - ex;
eyr = DISPLAY_RESY - ey;
break;
case 270:
exr = DISPLAY_RESY - ey;
eyr = ex;
break;
default:
exr = ex;
eyr = ey;
break;
}
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(exr);
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(eyr);
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_TOUCH);
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
return mp_const_true;
}
}
}
#endif
#ifdef USE_BUTTON
if (signalled.read_ready & (1 << SYSHANDLE_BUTTON)) {
button_event_t btn_event = {0};
if (button_get_event(&btn_event)) {
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
uint32_t etype = btn_event.event_type;
uint32_t en = btn_event.button;
if (display_get_orientation() == 180) {
en = (en == BTN_LEFT) ? BTN_RIGHT : BTN_LEFT;
}
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(exr);
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(eyr);
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_TOUCH);
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(en);
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BUTTON);
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
return mp_const_true;
}
}
}
#endif
#ifdef USE_BUTTON
if (signalled.read_ready & (1 << SYSHANDLE_BUTTON)) {
button_event_t btn_event = {0};
if (button_get_event(&btn_event)) {
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
uint32_t etype = btn_event.event_type;
uint32_t en = btn_event.button;
if (display_get_orientation() == 180) {
en = (en == BTN_LEFT) ? BTN_RIGHT : BTN_LEFT;
}
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(en);
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BUTTON);
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
return mp_const_true;
}
}
#endif
#ifdef USE_BLE
if (signalled.read_ready & (1 << SYSHANDLE_BLE_IFACE_0)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0);
ret->items[1] = MP_OBJ_NEW_SMALL_INT(BLE_RX_PACKET_SIZE);
return mp_const_true;
}
if (signalled.write_ready & (1 << SYSHANDLE_BLE_IFACE_0)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0 | POLL_WRITE);
ret->items[1] = mp_const_none;
return mp_const_true;
}
if (signalled.read_ready & (1 << SYSHANDLE_BLE)) {
ble_event_t event = {0};
if (ble_get_event(&event)) {
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(event.type);
tuple->items[1] = parse_ble_event_data(&event);
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE);
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
return mp_const_true;
}
}
#endif
if (signalled.read_ready & (1 << SYSHANDLE_USB)) {
usb_event_t event = usb_get_event();
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_USB);
ret->items[1] = MP_OBJ_NEW_SMALL_INT((int32_t)event);
return mp_const_true;
}
for (syshandle_t h = SYSHANDLE_USB_IFACE_0; h <= SYSHANDLE_USB_IFACE_7; h++) {
if (signalled.read_ready & (1 << h)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(h);
ret->items[1] = MP_OBJ_NEW_SMALL_INT(USB_PACKET_LEN);
if (signalled.read_ready & (1 << SYSHANDLE_BLE_IFACE_0)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0);
ret->items[1] = MP_OBJ_NEW_SMALL_INT(BLE_RX_PACKET_SIZE);
return mp_const_true;
}
if (signalled.write_ready & (1 << h)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(h | POLL_WRITE);
if (signalled.write_ready & (1 << SYSHANDLE_BLE_IFACE_0)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0 | POLL_WRITE);
ret->items[1] = mp_const_none;
return mp_const_true;
}
}
return mp_const_false;
if (signalled.read_ready & (1 << SYSHANDLE_BLE)) {
ble_event_t event = {0};
if (ble_get_event(&event)) {
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(event.type);
tuple->items[1] = parse_ble_event_data(&event);
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE);
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
return mp_const_true;
}
}
#endif
if (signalled.read_ready & (1 << SYSHANDLE_USB)) {
usb_event_t event = usb_get_event();
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_USB);
ret->items[1] = MP_OBJ_NEW_SMALL_INT((int32_t)event);
return mp_const_true;
}
for (syshandle_t h = SYSHANDLE_USB_IFACE_0; h <= SYSHANDLE_USB_IFACE_7;
h++) {
if (signalled.read_ready & (1 << h)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(h);
ret->items[1] = MP_OBJ_NEW_SMALL_INT(USB_PACKET_LEN);
return mp_const_true;
}
if (signalled.write_ready & (1 << h)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(h | POLL_WRITE);
ret->items[1] = mp_const_none;
return mp_const_true;
}
}
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_poll_obj, mod_trezorio_poll);