Skip to content

Commit 6decbed

Browse files
committed
Fix local static initialization in USB
The local static initialization in USB was causing multiple problems: -Configurable descriptor values are set only once -USB descriptor initialization causes a trap in debug builds since this is acquiring a mutex in an interrupt handler -Extra ram used since all descriptors are in RAM This patch fixes these problems by making fixed descriptors static const so they are stored in flash and never need to be initialized and by making descriptors that do change a member of the class so they are always initialized when requested rather than once though lazy static local initialization.
1 parent 635a824 commit 6decbed

File tree

18 files changed

+142
-105
lines changed

18 files changed

+142
-105
lines changed

features/unsupported/USBDevice/USBAudio/USBAudio.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ USBAudio::USBAudio(uint32_t frequency_in, uint8_t channel_nb_in, uint32_t freque
5656

5757
volume = 0;
5858

59+
_build_configurationDesc();
60+
5961
// connect the device
6062
USBDevice::connect();
6163
}
@@ -377,8 +379,8 @@ void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {
377379
FEATURE_UNIT_DESCRIPTOR_LENGTH + \
378380
2*OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
379381

380-
uint8_t * USBAudio::configurationDesc() {
381-
static uint8_t configDescriptor[] = {
382+
void USBAudio::_build_configurationDesc() {
383+
uint8_t configDescriptorTemp[] = {
382384
// Configuration 1
383385
CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
384386
CONFIGURATION_DESCRIPTOR, // bDescriptorType
@@ -615,24 +617,28 @@ uint8_t * USBAudio::configurationDesc() {
615617
0x00, // bLockDelayUnits
616618
LSB(0x0000), // wLockDelay
617619
MSB(0x0000), // wLockDelay
618-
619-
// Terminator
620-
0 // bLength
621620
};
621+
622+
MBED_ASSERT(sizeof(configDescriptorTemp) == sizeof(configDescriptor));
623+
memcpy(configDescriptor, configDescriptorTemp, sizeof(configDescriptor));
624+
}
625+
626+
const uint8_t * USBAudio::configurationDesc() {
627+
622628
return configDescriptor;
623629
}
624630

625-
uint8_t * USBAudio::stringIinterfaceDesc() {
626-
static uint8_t stringIinterfaceDescriptor[] = {
631+
const uint8_t * USBAudio::stringIinterfaceDesc() {
632+
static const uint8_t stringIinterfaceDescriptor[] = {
627633
0x0c, //bLength
628634
STRING_DESCRIPTOR, //bDescriptorType 0x03
629635
'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio
630636
};
631637
return stringIinterfaceDescriptor;
632638
}
633639

634-
uint8_t * USBAudio::stringIproductDesc() {
635-
static uint8_t stringIproductDescriptor[] = {
640+
const uint8_t * USBAudio::stringIproductDesc() {
641+
static const uint8_t stringIproductDescriptor[] = {
636642
0x16, //bLength
637643
STRING_DESCRIPTOR, //bDescriptorType 0x03
638644
'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio

features/unsupported/USBDevice/USBAudio/USBAudio.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,21 +216,21 @@ class USBAudio: public USBDevice {
216216
*
217217
* @returns pointer to the string product descriptor
218218
*/
219-
virtual uint8_t * stringIproductDesc();
219+
virtual const uint8_t * stringIproductDesc();
220220

221221
/*
222222
* Get string interface descriptor
223223
*
224224
* @returns pointer to the string interface descriptor
225225
*/
226-
virtual uint8_t * stringIinterfaceDesc();
226+
virtual const uint8_t * stringIinterfaceDesc();
227227

228228
/*
229229
* Get configuration descriptor
230230
*
231231
* @returns pointer to the configuration descriptor
232232
*/
233-
virtual uint8_t * configurationDesc();
233+
virtual const uint8_t * configurationDesc();
234234

235235
/*
236236
* Called by USBDevice layer. Set interface/alternate of the device.
@@ -270,6 +270,20 @@ class USBAudio: public USBDevice {
270270

271271
private:
272272

273+
/*
274+
* Call to rebuild the configuration descriptor
275+
*
276+
* This function should be called on creation or when any
277+
* value that is part of the configuration descriptor
278+
* changes.
279+
* @note This function uses ~200 bytes of stack so
280+
* make sure your stack is big enough for it.
281+
*/
282+
void _build_configurationDesc();
283+
284+
// configuration descriptor
285+
uint8_t configDescriptor[183];
286+
273287
// stream available ?
274288
volatile bool available;
275289

features/unsupported/USBDevice/USBDevice/USBDevice.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ bool USBDevice::requestGetDescriptor(void)
5858
printf("device descr\r\n");
5959
#endif
6060
transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
61-
transfer.ptr = deviceDesc();
61+
transfer.ptr = (uint8_t*)deviceDesc();
6262
transfer.direction = DEVICE_TO_HOST;
6363
success = true;
6464
}
@@ -77,7 +77,7 @@ bool USBDevice::requestGetDescriptor(void)
7777
transfer.remaining = configurationDesc()[2] \
7878
| (configurationDesc()[3] << 8);
7979

80-
transfer.ptr = configurationDesc();
80+
transfer.ptr = (uint8_t*)configurationDesc();
8181
transfer.direction = DEVICE_TO_HOST;
8282
success = true;
8383
}
@@ -94,7 +94,7 @@ bool USBDevice::requestGetDescriptor(void)
9494
printf("1\r\n");
9595
#endif
9696
transfer.remaining = stringLangidDesc()[0];
97-
transfer.ptr = stringLangidDesc();
97+
transfer.ptr = (uint8_t*)stringLangidDesc();
9898
transfer.direction = DEVICE_TO_HOST;
9999
success = true;
100100
break;
@@ -103,7 +103,7 @@ bool USBDevice::requestGetDescriptor(void)
103103
printf("2\r\n");
104104
#endif
105105
transfer.remaining = stringImanufacturerDesc()[0];
106-
transfer.ptr = stringImanufacturerDesc();
106+
transfer.ptr = (uint8_t*)stringImanufacturerDesc();
107107
transfer.direction = DEVICE_TO_HOST;
108108
success = true;
109109
break;
@@ -112,7 +112,7 @@ bool USBDevice::requestGetDescriptor(void)
112112
printf("3\r\n");
113113
#endif
114114
transfer.remaining = stringIproductDesc()[0];
115-
transfer.ptr = stringIproductDesc();
115+
transfer.ptr = (uint8_t*)stringIproductDesc();
116116
transfer.direction = DEVICE_TO_HOST;
117117
success = true;
118118
break;
@@ -121,7 +121,7 @@ bool USBDevice::requestGetDescriptor(void)
121121
printf("4\r\n");
122122
#endif
123123
transfer.remaining = stringIserialDesc()[0];
124-
transfer.ptr = stringIserialDesc();
124+
transfer.ptr = (uint8_t*)stringIserialDesc();
125125
transfer.direction = DEVICE_TO_HOST;
126126
success = true;
127127
break;
@@ -130,7 +130,7 @@ bool USBDevice::requestGetDescriptor(void)
130130
printf("5\r\n");
131131
#endif
132132
transfer.remaining = stringIConfigurationDesc()[0];
133-
transfer.ptr = stringIConfigurationDesc();
133+
transfer.ptr = (uint8_t*)stringIConfigurationDesc();
134134
transfer.direction = DEVICE_TO_HOST;
135135
success = true;
136136
break;
@@ -139,7 +139,7 @@ bool USBDevice::requestGetDescriptor(void)
139139
printf("6\r\n");
140140
#endif
141141
transfer.remaining = stringIinterfaceDesc()[0];
142-
transfer.ptr = stringIinterfaceDesc();
142+
transfer.ptr = (uint8_t*)stringIinterfaceDesc();
143143
transfer.direction = DEVICE_TO_HOST;
144144
success = true;
145145
break;
@@ -790,7 +790,7 @@ uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
790790
}
791791

792792
/* Start at first descriptor after the configuration descriptor */
793-
ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
793+
ptr = &(((uint8_t*)configurationDesc())[CONFIGURATION_DESCRIPTOR_LENGTH]);
794794

795795
do {
796796
if (ptr[1] /* bDescriptorType */ == descriptorType)
@@ -926,8 +926,8 @@ bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, u
926926

927927

928928

929-
uint8_t * USBDevice::deviceDesc() {
930-
static uint8_t deviceDescriptor[] = {
929+
const uint8_t * USBDevice::deviceDesc() {
930+
uint8_t deviceDescriptorTemp[] = {
931931
DEVICE_DESCRIPTOR_LENGTH, /* bLength */
932932
DEVICE_DESCRIPTOR, /* bDescriptorType */
933933
LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
@@ -947,56 +947,58 @@ uint8_t * USBDevice::deviceDesc() {
947947
STRING_OFFSET_ISERIAL, /* iSerialNumber */
948948
0x01 /* bNumConfigurations */
949949
};
950+
MBED_ASSERT(sizeof(deviceDescriptorTemp) == sizeof(deviceDescriptor));
951+
memcpy(deviceDescriptor, deviceDescriptorTemp, sizeof(deviceDescriptor));
950952
return deviceDescriptor;
951953
}
952954

953-
uint8_t * USBDevice::stringLangidDesc() {
954-
static uint8_t stringLangidDescriptor[] = {
955+
const uint8_t * USBDevice::stringLangidDesc() {
956+
static const uint8_t stringLangidDescriptor[] = {
955957
0x04, /*bLength*/
956958
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
957959
0x09,0x04, /*bString Lang ID - 0x0409 - English*/
958960
};
959-
return stringLangidDescriptor;
961+
return (uint8_t *)stringLangidDescriptor;
960962
}
961963

962-
uint8_t * USBDevice::stringImanufacturerDesc() {
963-
static uint8_t stringImanufacturerDescriptor[] = {
964+
const uint8_t * USBDevice::stringImanufacturerDesc() {
965+
static const uint8_t stringImanufacturerDescriptor[] = {
964966
0x12, /*bLength*/
965967
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
966968
'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
967969
};
968970
return stringImanufacturerDescriptor;
969971
}
970972

971-
uint8_t * USBDevice::stringIserialDesc() {
972-
static uint8_t stringIserialDescriptor[] = {
973+
const uint8_t * USBDevice::stringIserialDesc() {
974+
static const uint8_t stringIserialDescriptor[] = {
973975
0x16, /*bLength*/
974976
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
975977
'0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
976978
};
977979
return stringIserialDescriptor;
978980
}
979981

980-
uint8_t * USBDevice::stringIConfigurationDesc() {
981-
static uint8_t stringIconfigurationDescriptor[] = {
982+
const uint8_t * USBDevice::stringIConfigurationDesc() {
983+
static const uint8_t stringIconfigurationDescriptor[] = {
982984
0x06, /*bLength*/
983985
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
984986
'0',0,'1',0, /*bString iConfiguration - 01*/
985987
};
986988
return stringIconfigurationDescriptor;
987989
}
988990

989-
uint8_t * USBDevice::stringIinterfaceDesc() {
990-
static uint8_t stringIinterfaceDescriptor[] = {
991+
const uint8_t * USBDevice::stringIinterfaceDesc() {
992+
static const uint8_t stringIinterfaceDescriptor[] = {
991993
0x08, /*bLength*/
992994
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
993995
'U',0,'S',0,'B',0, /*bString iInterface - USB*/
994996
};
995997
return stringIinterfaceDescriptor;
996998
}
997999

998-
uint8_t * USBDevice::stringIproductDesc() {
999-
static uint8_t stringIproductDescriptor[] = {
1000+
const uint8_t * USBDevice::stringIproductDesc() {
1001+
static const uint8_t stringIproductDescriptor[] = {
10001002
0x16, /*bLength*/
10011003
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
10021004
'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/

features/unsupported/USBDevice/USBDevice/USBDevice.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,60 +165,60 @@ class USBDevice: public USBHAL
165165
virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate) { return false; };
166166

167167
/*
168-
* Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
168+
* Get device descriptor.
169169
*
170170
* @returns pointer to the device descriptor
171171
*/
172-
virtual uint8_t * deviceDesc();
172+
virtual const uint8_t * deviceDesc();
173173

174174
/*
175175
* Get configuration descriptor
176176
*
177177
* @returns pointer to the configuration descriptor
178178
*/
179-
virtual uint8_t * configurationDesc(){return NULL;};
179+
virtual const uint8_t * configurationDesc(){return NULL;};
180180

181181
/*
182182
* Get string lang id descriptor
183183
*
184184
* @return pointer to the string lang id descriptor
185185
*/
186-
virtual uint8_t * stringLangidDesc();
186+
virtual const uint8_t * stringLangidDesc();
187187

188188
/*
189189
* Get string manufacturer descriptor
190190
*
191191
* @returns pointer to the string manufacturer descriptor
192192
*/
193-
virtual uint8_t * stringImanufacturerDesc();
193+
virtual const uint8_t * stringImanufacturerDesc();
194194

195195
/*
196196
* Get string product descriptor
197197
*
198198
* @returns pointer to the string product descriptor
199199
*/
200-
virtual uint8_t * stringIproductDesc();
200+
virtual const uint8_t * stringIproductDesc();
201201

202202
/*
203203
* Get string serial descriptor
204204
*
205205
* @returns pointer to the string serial descriptor
206206
*/
207-
virtual uint8_t * stringIserialDesc();
207+
virtual const uint8_t * stringIserialDesc();
208208

209209
/*
210210
* Get string configuration descriptor
211211
*
212212
* @returns pointer to the string configuration descriptor
213213
*/
214-
virtual uint8_t * stringIConfigurationDesc();
214+
virtual const uint8_t * stringIConfigurationDesc();
215215

216216
/*
217217
* Get string interface descriptor
218218
*
219219
* @returns pointer to the string interface descriptor
220220
*/
221-
virtual uint8_t * stringIinterfaceDesc();
221+
virtual const uint8_t * stringIinterfaceDesc();
222222

223223
/*
224224
* Get the length of the report descriptor
@@ -242,6 +242,7 @@ class USBDevice: public USBHAL
242242
uint16_t VENDOR_ID;
243243
uint16_t PRODUCT_ID;
244244
uint16_t PRODUCT_RELEASE;
245+
uint8_t deviceDescriptor[18];
245246

246247
private:
247248
bool addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket);

0 commit comments

Comments
 (0)