Skip to content

Commit c352105

Browse files
Remove IRQ-level malloc from USB setup
Fixes a hang found while debugging #614. Do all memory allocations and USB descriptor setup in main code prior to `tusb_init()`. Avoids potential deadlock in cases where the app is allocating while the USB port is being set up.
1 parent c4623f4 commit c352105

File tree

1 file changed

+31
-27
lines changed

1 file changed

+31
-27
lines changed

cores/rp2040/RP2040USB.cpp

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -120,49 +120,49 @@ int __USBGetMouseReportID() {
120120
return __USBInstallKeyboard ? 2 : 1;
121121
}
122122

123-
static uint8_t *GetDescHIDReport(int *len) {
124-
static uint8_t *report = nullptr;
125-
int report_len = 0;
123+
static int __hid_report_len = 0;
124+
static uint8_t *__hid_report = nullptr;
126125

127-
if (report) {
128-
free(report);
129-
report = nullptr;
126+
static uint8_t *GetDescHIDReport(int *len) {
127+
if (len) {
128+
*len = __hid_report_len;
130129
}
130+
return __hid_report;
131+
}
131132

133+
static void __SetupDescHIDReport() {
132134
if (__USBInstallKeyboard && __USBInstallMouse) {
133135
uint8_t desc_hid_report[] = {
134136
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)),
135137
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(2))
136138
};
137-
report_len = sizeof(desc_hid_report);
138-
report = (uint8_t *)malloc(report_len);
139-
if (report) {
140-
memcpy(report, desc_hid_report, report_len);
139+
__hid_report = (uint8_t *)malloc(sizeof(desc_hid_report));
140+
if (__hid_report) {
141+
__hid_report_len = sizeof(desc_hid_report);
142+
memcpy(__hid_report, desc_hid_report, __hid_report_len);
141143
}
142144
} else if (__USBInstallKeyboard && ! __USBInstallMouse) {
143145
uint8_t desc_hid_report[] = {
144146
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1))
145147
};
146-
report_len = sizeof(desc_hid_report);
147-
report = (uint8_t *)malloc(report_len);
148-
if (report) {
149-
memcpy(report, desc_hid_report, report_len);
148+
__hid_report = (uint8_t *)malloc(sizeof(desc_hid_report));
149+
if (__hid_report) {
150+
__hid_report_len = sizeof(desc_hid_report);
151+
memcpy(__hid_report, desc_hid_report, __hid_report_len);
150152
}
151-
} else { // if (!__USBInstallKeyboard && __USBInstallMouse) {
153+
} else if (! __USBInstallKeyboard && __USBInstallMouse) {
152154
uint8_t desc_hid_report[] = {
153155
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1))
154156
};
155-
report_len = sizeof(desc_hid_report);
156-
report = (uint8_t *)malloc(report_len);
157-
if (report) {
158-
memcpy(report, desc_hid_report, report_len);
157+
__hid_report = (uint8_t *)malloc(sizeof(desc_hid_report));
158+
if (__hid_report) {
159+
__hid_report_len = sizeof(desc_hid_report);
160+
memcpy(__hid_report, desc_hid_report, __hid_report_len);
159161
}
162+
} else {
163+
__hid_report = nullptr;
164+
__hid_report_len = 0;
160165
}
161-
162-
if (len) {
163-
*len = report_len;
164-
}
165-
return report;
166166
}
167167

168168
// Invoked when received GET HID REPORT DESCRIPTOR
@@ -173,11 +173,13 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) {
173173
return GetDescHIDReport(nullptr);
174174
}
175175

176-
176+
static uint8_t *usbd_desc_cfg = nullptr;
177177
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
178178
(void)index;
179-
static uint8_t *usbd_desc_cfg = nullptr;
179+
return usbd_desc_cfg;
180+
}
180181

182+
static void __SetupUSBDescriptor() {
181183
if (!usbd_desc_cfg) {
182184
bool hasHID = __USBInstallKeyboard || __USBInstallMouse;
183185

@@ -229,7 +231,6 @@ const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
229231
}
230232
}
231233
}
232-
return usbd_desc_cfg;
233234
}
234235

235236
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
@@ -295,6 +296,9 @@ void __USBStart() {
295296
return;
296297
}
297298

299+
__SetupDescHIDReport();
300+
__SetupUSBDescriptor();
301+
298302
mutex_init(&__usb_mutex);
299303

300304
tusb_init();

0 commit comments

Comments
 (0)