Add two space saving knobs

* Reduce the number of supported HID reports of IDs per descriptor.
  This saves ~200 bytes in the default HID objects.
* (Not enabled) Compute QSTR attrs on init. This trades 1k RAM for
  flash. Flash is the default (1).
This commit is contained in:
Scott Shawcroft 2021-08-31 13:02:34 -07:00
parent cc0a6c8a5f
commit 771b4c7464
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
5 changed files with 47 additions and 18 deletions

View File

@ -61,6 +61,9 @@
#define MICROPY_FATFS_EXFAT 0
// Only support simpler HID descriptors on SAMD21.
#define CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR (1)
#endif // SAMD21
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -717,6 +717,13 @@ void supervisor_run_background_tasks_if_tick(void);
#define CIRCUITPY_VERBOSE_BLE 0
// This trades ~1k flash space (1) for that much in RAM plus the cost to compute
// the values once on init (0). Only turn it off, when you really need the flash
// space and are willing to trade the RAM.
#ifndef CIRCUITPY_PRECOMPUTE_QSTR_ATTR
#define CIRCUITPY_PRECOMPUTE_QSTR_ATTR (1)
#endif
// USB settings
// If the port requires certain USB endpoint numbers, define these in mpconfigport.h.
@ -761,6 +768,16 @@ void supervisor_run_background_tasks_if_tick(void);
#define USB_HID_EP_NUM_IN (0)
#endif
// The most complicated device currently known of is the head and eye tracker, which requires 5
// report ids.
// https://usb.org/sites/default/files/hutrr74_-_usage_page_for_head_and_eye_trackers_0.pdf
// The default descriptors only use 1, so that is the minimum.
#ifndef CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR
#define CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR (6)
#elif CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR < 1
#error "CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR must be at least 1"
#endif
#ifndef USB_MIDI_EP_NUM_OUT
#define USB_MIDI_EP_NUM_OUT (0)
#endif

View File

@ -77,7 +77,8 @@ mp_uint_t qstr_compute_hash(const byte *data, size_t len) {
return hash;
}
const qstr_attr_t mp_qstr_const_attr[] = {
#if CIRCUITPY_PRECOMPUTE_QSTR_ATTR
const qstr_attr_t mp_qstr_const_attr[MP_QSTRnumber_of] = {
#ifndef NO_QSTR
#define QDEF(id, hash, len, str) { hash, len },
#define TRANSLATION(id, length, compressed ...)
@ -86,6 +87,9 @@ const qstr_attr_t mp_qstr_const_attr[] = {
#undef QDEF
#endif
};
#else
qstr_attr_t mp_qstr_const_attr[MP_QSTRnumber_of];
#endif
const qstr_pool_t mp_qstr_const_pool = {
NULL, // no previous pool
@ -115,6 +119,16 @@ void qstr_init(void) {
MP_STATE_VM(last_pool) = (qstr_pool_t *)&CONST_POOL; // we won't modify the const_pool since it has no allocated room left
MP_STATE_VM(qstr_last_chunk) = NULL;
#if CIRCUITPY_PRECOMPUTE_QSTR_ATTR == 0
if (mp_qstr_const_attr[MP_QSTR_circuitpython].len == 0) {
for (size_t i = 0; i < mp_qstr_const_pool.len; i++) {
size_t len = strlen(mp_qstr_const_pool.qstrs[i]);
mp_qstr_const_attr[i].hash = qstr_compute_hash((const byte *)mp_qstr_const_pool.qstrs[i], len);
mp_qstr_const_attr[i].len = len;
}
}
#endif
#if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
mp_thread_mutex_init(&MP_STATE_VM(qstr_mutex));
#endif

View File

@ -81,7 +81,7 @@ const usb_hid_device_obj_t usb_hid_device_keyboard_obj = {
.usage = 0x06,
.num_report_ids = 1,
.report_ids = { 0x01, },
.in_report_lengths = { 8, 0, 0, 0, 0, 0, },
.in_report_lengths = { 8, },
.out_report_lengths = { 1, },
};
@ -131,7 +131,7 @@ const usb_hid_device_obj_t usb_hid_device_mouse_obj = {
.usage = 0x02,
.num_report_ids = 1,
.report_ids = { 0x02, },
.in_report_lengths = { 4, 0, 0, 0, 0, 0, },
.in_report_lengths = { 4, },
.out_report_lengths = { 0, },
};
@ -160,7 +160,7 @@ const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = {
.usage = 0x01,
.num_report_ids = 1,
.report_ids = { 0x03 },
.in_report_lengths = { 2, 0, 0, 0, 0, 0, },
.in_report_lengths = { 2, },
.out_report_lengths = { 0, },
};
@ -170,7 +170,7 @@ STATIC size_t get_report_id_idx(usb_hid_device_obj_t *self, size_t report_id) {
return i;
}
}
return MAX_REPORT_IDS_PER_DESCRIPTOR;
return CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR;
}
// See if report_id is used by this device. If it is -1, then return the sole report id used by this device,
@ -180,16 +180,16 @@ uint8_t common_hal_usb_hid_device_validate_report_id(usb_hid_device_obj_t *self,
return self->report_ids[0];
}
if (!(report_id_arg >= 0 &&
get_report_id_idx(self, (size_t)report_id_arg) < MAX_REPORT_IDS_PER_DESCRIPTOR)) {
get_report_id_idx(self, (size_t)report_id_arg) < CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR)) {
mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_report_id);
}
return (uint8_t)report_id_arg;
}
void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint8_t usage_page, uint8_t usage, size_t num_report_ids, uint8_t *report_ids, uint8_t *in_report_lengths, uint8_t *out_report_lengths) {
if (num_report_ids > MAX_REPORT_IDS_PER_DESCRIPTOR) {
if (num_report_ids > CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR) {
mp_raise_ValueError_varg(translate("More than %d report ids not supported"),
MAX_REPORT_IDS_PER_DESCRIPTOR);
CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR);
}
// report buffer pointers are NULL at start, and are created when USB is initialized.

View File

@ -32,21 +32,16 @@
#include "py/obj.h"
// The most complicated device currently known of is the head and eye tracker, which requires 5
// report ids.
// https://usb.org/sites/default/files/hutrr74_-_usage_page_for_head_and_eye_trackers_0.pdf
#define MAX_REPORT_IDS_PER_DESCRIPTOR (6)
typedef struct {
mp_obj_base_t base;
// Python buffer object whose contents are the descriptor.
const uint8_t *report_descriptor;
uint8_t *in_report_buffers[MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t *out_report_buffers[MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t *in_report_buffers[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t *out_report_buffers[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR];
uint16_t report_descriptor_length;
uint8_t report_ids[MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t in_report_lengths[MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t out_report_lengths[MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t report_ids[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t in_report_lengths[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t out_report_lengths[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR];
uint8_t usage_page;
uint8_t usage;
uint8_t num_report_ids;