feat: 添加HID流控制模块和相关事件处理

- 添加hid_flowctrl_module.c实现HID报告流控制功能,包括FIFO队列管理和
  报告发送控制
- 新增hid_report_sent_event、hid_transport_state_event和
  hid_tx_report_event事件类型及其对应的头文件和实现
- 在CMakeLists.txt中注册新模块和事件源文件
- 修改keyboard_core_module.c以支持队列策略,并添加编码器事件处理逻辑
- 更新usb_hid_module.c将直接的键盘HID报告事件改为通过
  hid_tx_report_event进行传输,并添加状态报告事件
- 在keyboard_hid_report_event中增加queue_policy字段以支持不同
  队列策略
This commit is contained in:
2026-04-10 13:46:50 +08:00
parent e97bd47e36
commit 70381192d9
13 changed files with 856 additions and 10 deletions

View File

@@ -0,0 +1,105 @@
#include <stdio.h>
#include "hid_tx_report_event.h"
#define HID_TX_REPORT_EVENT_LOG_BUF_LEN 192
static const char *transport_name(enum hid_transport transport)
{
switch (transport) {
case HID_TRANSPORT_USB:
return "USB";
default:
return "?";
}
}
static const char *report_type_name(enum keyboard_report_type report_type)
{
switch (report_type) {
case KEYBOARD_REPORT_TYPE_KEYS:
return "keys";
case KEYBOARD_REPORT_TYPE_CONSUMER:
return "consumer";
default:
return "?";
}
}
static const char *protocol_mode_name(enum keyboard_protocol_mode protocol_mode)
{
switch (protocol_mode) {
case KEYBOARD_PROTOCOL_MODE_BOOT:
return "boot";
case KEYBOARD_PROTOCOL_MODE_REPORT:
return "report";
default:
return "?";
}
}
static void log_hid_tx_report_event(const struct app_event_header *aeh)
{
const struct hid_tx_report_event *event = cast_hid_tx_report_event(aeh);
char log_buf[HID_TX_REPORT_EVENT_LOG_BUF_LEN];
int pos;
pos = snprintf(log_buf, sizeof(log_buf),
"transport:%s type:%s protocol:%s seq:%u len:%zu",
transport_name(event->transport),
report_type_name(event->report_type),
protocol_mode_name(event->protocol_mode),
event->sequence,
event->dyndata.size);
if ((pos > 0) && (pos < sizeof(log_buf))) {
for (size_t i = 0; i < event->dyndata.size; i++) {
int tmp = snprintf(&log_buf[pos], sizeof(log_buf) - pos,
" %02x", event->dyndata.data[i]);
if (tmp < 0) {
log_buf[sizeof(log_buf) - 2] = '~';
pos = tmp;
break;
}
pos += tmp;
if (pos >= sizeof(log_buf)) {
break;
}
}
}
if (pos < 0) {
APP_EVENT_MANAGER_LOG(aeh, "log message preparation failure");
return;
}
APP_EVENT_MANAGER_LOG(aeh, "%s", log_buf);
}
static void profile_hid_tx_report_event(struct log_event_buf *buf,
const struct app_event_header *aeh)
{
const struct hid_tx_report_event *event = cast_hid_tx_report_event(aeh);
nrf_profiler_log_encode_uint8(buf, event->transport);
nrf_profiler_log_encode_uint8(buf, event->report_type);
nrf_profiler_log_encode_uint8(buf, event->protocol_mode);
nrf_profiler_log_encode_uint16(buf, event->sequence);
nrf_profiler_log_encode_uint8(buf, (uint8_t)event->dyndata.size);
}
APP_EVENT_INFO_DEFINE(hid_tx_report_event,
ENCODE(NRF_PROFILER_ARG_U8,
NRF_PROFILER_ARG_U8,
NRF_PROFILER_ARG_U8,
NRF_PROFILER_ARG_U16,
NRF_PROFILER_ARG_U8),
ENCODE("transport", "report_type", "protocol_mode", "sequence", "len"),
profile_hid_tx_report_event);
APP_EVENT_TYPE_DEFINE(hid_tx_report_event,
log_hid_tx_report_event,
&hid_tx_report_event_info,
APP_EVENT_FLAGS_CREATE(
APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE));