mirror of https://github.com/zmkfirmware/zmk.git
fix(split): Use our managed queue for input report to avoid deadlock
- Use our service work queue to process input report to avoid deadlock on the system work queue - Add config `CONFIG_ZMK_INPUT_SPLIT_MSG_QUEUE_SIZE`
This commit is contained in:
parent
7738924349
commit
f060e3f375
|
|
@ -102,6 +102,17 @@ config BT_GAP_AUTO_UPDATE_CONN_PARAMS
|
||||||
|
|
||||||
endif # !ZMK_SPLIT_ROLE_CENTRAL
|
endif # !ZMK_SPLIT_ROLE_CENTRAL
|
||||||
|
|
||||||
|
if ZMK_INPUT_SPLIT
|
||||||
|
|
||||||
|
config ZMK_INPUT_SPLIT_MSG_QUEUE_SIZE
|
||||||
|
int "Max number of input split messages to queue for sending over BLE"
|
||||||
|
default 32
|
||||||
|
help
|
||||||
|
Sets the maximum number of input split events that can be queued for BLE notifications.
|
||||||
|
Increasing this reduces drops during high-rate input bursts at the cost of additional RAM.
|
||||||
|
|
||||||
|
endif # ZMK_INPUT_SPLIT
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
endif # ZMK_SPLIT_BLE
|
endif # ZMK_SPLIT_BLE
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,27 @@ static int zmk_split_bt_sensor_triggered(uint8_t sensor_index,
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_INPUT_SPLIT)
|
#if IS_ENABLED(CONFIG_ZMK_INPUT_SPLIT)
|
||||||
|
|
||||||
|
struct input_event_notify_item {
|
||||||
|
uint16_t attr_index;
|
||||||
|
struct zmk_split_input_event_payload payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
K_MSGQ_DEFINE(input_event_msgq, sizeof(struct input_event_notify_item),
|
||||||
|
CONFIG_ZMK_INPUT_SPLIT_MSG_QUEUE_SIZE, 4);
|
||||||
|
|
||||||
|
static void send_input_event_callback(struct k_work *work) {
|
||||||
|
struct input_event_notify_item item;
|
||||||
|
while (k_msgq_get(&input_event_msgq, &item, K_NO_WAIT) == 0) {
|
||||||
|
int err = bt_gatt_notify(NULL, &split_svc.attrs[item.attr_index], &item.payload,
|
||||||
|
sizeof(item.payload));
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("Error notifying input event %d", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static K_WORK_DEFINE(service_input_notify_work, send_input_event_callback);
|
||||||
|
|
||||||
static int zmk_split_bt_report_input(uint8_t reg, uint8_t type, uint16_t code, int32_t value,
|
static int zmk_split_bt_report_input(uint8_t reg, uint8_t type, uint16_t code, int32_t value,
|
||||||
bool sync) {
|
bool sync) {
|
||||||
|
|
||||||
|
|
@ -326,7 +347,24 @@ static int zmk_split_bt_report_input(uint8_t reg, uint8_t type, uint16_t code, i
|
||||||
.sync = sync ? 1 : 0,
|
.sync = sync ? 1 : 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
return bt_gatt_notify(NULL, &split_svc.attrs[i], &payload, sizeof(payload));
|
struct input_event_notify_item item = {.attr_index = (uint16_t)i, .payload = payload};
|
||||||
|
int err = k_msgq_put(&input_event_msgq, &item, K_NO_WAIT);
|
||||||
|
|
||||||
|
if (err == 0) {
|
||||||
|
k_work_submit_to_queue(&service_work_q, &service_input_notify_work);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
LOG_WRN("Input event queue full, dropping one and retry");
|
||||||
|
|
||||||
|
struct input_event_notify_item discarded;
|
||||||
|
k_msgq_get(&input_event_msgq, &discarded, K_NO_WAIT);
|
||||||
|
err = k_msgq_put(&input_event_msgq, &item, K_NO_WAIT);
|
||||||
|
|
||||||
|
if (err != 0) {
|
||||||
|
LOG_WRN("Failed to queue input event (%d)", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue