Skip to content

Commit f3f9b46

Browse files
committed
shared/tinyusb: Eliminate descriptor duplication in runtime mode.
In runtime mode (MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE=1), the previous implementation stored both a static descriptor (using TinyUSB macros) and runtime descriptor templates, resulting in ~180-200 bytes of duplicate descriptor data. This commit eliminates the duplication by: - Making the static descriptor conditional on !MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE - In runtime mode, generating the default/fallback descriptor from templates using mp_usbd_get_default_desc() instead of referencing the static descriptor - Updating mp_usbd_runtime.c to call the new function conditionally Also removes lingering calls to mp_usbd_update_class_state() which was removed in the macro refactoring, replacing them with direct flag assignments. Code size (STM32H563, TinyUSB stack): - Runtime mode: 514,396 bytes (text) - Static mode: 512,020 bytes (text) Saves ~180-200 bytes in runtime mode by eliminating descriptor duplication. Signed-off-by: Andrew Leech <[email protected]>
1 parent 6cd353a commit f3f9b46

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

extmod/machine_usb_device.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,13 @@ static mp_obj_t usb_device_active(size_t n_args, const mp_obj_t *args) {
213213
// Update class state based on current builtin_driver
214214
if (mp_obj_is_type(usbd->builtin_driver, &mp_type_usb_builtin)) {
215215
mp_obj_usb_builtin_t *builtin = MP_OBJ_TO_PTR(usbd->builtin_driver);
216-
mp_usbd_update_class_state(builtin->flags);
216+
extern mp_usbd_class_state_t mp_usbd_class_state;
217+
mp_usbd_class_state.flags = builtin->flags;
217218
}
218219
} else {
219220
// Disable all classes when deactivating
220-
mp_usbd_update_class_state(USB_BUILTIN_FLAG_NONE);
221+
extern mp_usbd_class_state_t mp_usbd_class_state;
222+
mp_usbd_class_state.flags = USB_BUILTIN_FLAG_NONE;
221223
}
222224
#endif
223225
}
@@ -315,9 +317,6 @@ static size_t mp_usbd_get_desc_cfg_len(uint8_t flags);
315317

316318
#endif // MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
317319

318-
// Function from mp_usbd_descriptor.c to update class state based on flags
319-
extern void mp_usbd_update_class_state(uint8_t flags);
320-
321320
// Create a new builtin configuration object with specified flags
322321
static mp_obj_t mp_usbd_create_builtin_config(uint8_t flags) {
323322
mp_obj_usb_builtin_t *builtin = mp_obj_malloc(mp_obj_usb_builtin_t, &mp_type_usb_builtin);

shared/tinyusb/mp_usbd_descriptor.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ static const uint8_t *mp_usbd_generate_desc_cfg(void) {
208208
}
209209
#endif
210210

211-
// Static fallback descriptor (needed for boot before Python initializes in runtime mode)
211+
#if !MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
212+
// Static mode: Use TinyUSB macros directly for fixed descriptor
212213
const uint8_t mp_usbd_builtin_desc_cfg[MP_USBD_BUILTIN_DESC_CFG_LEN] = {
213214
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_BUILTIN_MAX, USBD_STR_0, MP_USBD_BUILTIN_DESC_CFG_LEN,
214215
0, USBD_MAX_POWER_MA),
@@ -221,6 +222,23 @@ const uint8_t mp_usbd_builtin_desc_cfg[MP_USBD_BUILTIN_DESC_CFG_LEN] = {
221222
TUD_MSC_DESCRIPTOR(USBD_ITF_MSC, USBD_STR_MSC, EPNUM_MSC_OUT, EPNUM_MSC_IN, USBD_MSC_IN_OUT_MAX_SIZE),
222223
#endif
223224
};
225+
#else
226+
// Runtime mode: Generate default descriptor from templates into buffer at init
227+
// This eliminates duplication - we use templates for both dynamic and fallback descriptors
228+
static bool mp_usbd_default_desc_generated = false;
229+
230+
const uint8_t *mp_usbd_get_default_desc(void) {
231+
if (!mp_usbd_default_desc_generated) {
232+
// Generate default descriptor (CDC only by default in runtime mode)
233+
mp_usbd_generate_desc_cfg_unified(
234+
(CFG_TUD_CDC ? USB_BUILTIN_FLAG_CDC : 0),
235+
mp_usbd_desc_cfg_buffer
236+
);
237+
mp_usbd_default_desc_generated = true;
238+
}
239+
return mp_usbd_desc_cfg_buffer;
240+
}
241+
#endif
224242

225243
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
226244
char serial_buf[MICROPY_HW_USB_DESC_STR_MAX + 1]; // Includes terminating NUL byte

shared/tinyusb/mp_usbd_runtime.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,16 @@ const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
130130
result = mp_usbd_generate_desc_cfg_unified(usbd->builtin_driver, mp_usbd_desc_cfg_buffer);
131131
}
132132
}
133-
// Fallback to static descriptor (needed for boot before Python initializes)
134-
return result ? result : &mp_usbd_builtin_desc_cfg;
133+
// Fallback to descriptor (needed for boot before Python initializes)
134+
#if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
135+
// Runtime mode: Generate default descriptor from templates
136+
extern const uint8_t *mp_usbd_get_default_desc(void);
137+
return result ? result : mp_usbd_get_default_desc();
138+
#else
139+
// Static mode: Use static descriptor
140+
extern const uint8_t mp_usbd_builtin_desc_cfg[];
141+
return result ? result : mp_usbd_builtin_desc_cfg;
142+
#endif
135143
}
136144

137145
const char *mp_usbd_runtime_string_cb(uint8_t index) {

0 commit comments

Comments
 (0)