From 7cf6490fbaea88410c91755f57cf8703806ab4a1 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sat, 23 Mar 2024 00:11:05 +0000 Subject: usb: remove device_descriptor buffer, store bytes in UsbDevice.inner instead --- embassy-usb/src/builder.rs | 7 ------ embassy-usb/src/descriptor.rs | 51 +++++++++++++++++++++++-------------------- embassy-usb/src/lib.rs | 9 +++----- embassy-usb/src/msos.rs | 6 ++--- 4 files changed, 33 insertions(+), 40 deletions(-) (limited to 'embassy-usb/src') diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index c4705d041..c06107396 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -128,7 +128,6 @@ pub struct Builder<'d, D: Driver<'d>> { driver: D, next_string_index: u8, - device_descriptor: DescriptorWriter<'d>, config_descriptor: DescriptorWriter<'d>, bos_descriptor: BosWriter<'d>, @@ -144,7 +143,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { pub fn new( driver: D, config: Config<'d>, - device_descriptor_buf: &'d mut [u8], config_descriptor_buf: &'d mut [u8], bos_descriptor_buf: &'d mut [u8], msos_descriptor_buf: &'d mut [u8], @@ -167,11 +165,9 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { _ => panic!("invalid max_packet_size_0, the allowed values are 8, 16, 32 or 64"), } - let mut device_descriptor = DescriptorWriter::new(device_descriptor_buf); let mut config_descriptor = DescriptorWriter::new(config_descriptor_buf); let mut bos_descriptor = BosWriter::new(DescriptorWriter::new(bos_descriptor_buf)); - device_descriptor.device(&config); config_descriptor.configuration(&config); bos_descriptor.bos(); @@ -183,7 +179,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { control_buf, next_string_index: STRING_INDEX_CUSTOM_START, - device_descriptor, config_descriptor, bos_descriptor, @@ -199,7 +194,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { self.bos_descriptor.end_bos(); // Log the number of allocator bytes actually used in descriptor buffers - info!("USB: device_descriptor used: {}", self.device_descriptor.position()); info!("USB: config_descriptor used: {}", self.config_descriptor.position()); info!("USB: bos_descriptor used: {}", self.bos_descriptor.writer.position()); info!("USB: msos_descriptor used: {}", msos_descriptor.len()); @@ -209,7 +203,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { self.driver, self.config, self.handlers, - self.device_descriptor.into_buf(), self.config_descriptor.into_buf(), self.bos_descriptor.writer.into_buf(), msos_descriptor, diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index fa83ef583..eb3d1f53a 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs @@ -82,30 +82,6 @@ impl<'a> DescriptorWriter<'a> { self.position = start + length; } - pub(crate) fn device(&mut self, config: &Config) { - self.write( - descriptor_type::DEVICE, - &[ - 0x10, - 0x02, // bcdUSB 2.1 - config.device_class, // bDeviceClass - config.device_sub_class, // bDeviceSubClass - config.device_protocol, // bDeviceProtocol - config.max_packet_size_0, // bMaxPacketSize0 - config.vendor_id as u8, - (config.vendor_id >> 8) as u8, // idVendor - config.product_id as u8, - (config.product_id >> 8) as u8, // idProduct - config.device_release as u8, - (config.device_release >> 8) as u8, // bcdDevice - config.manufacturer.map_or(0, |_| 1), // iManufacturer - config.product.map_or(0, |_| 2), // iProduct - config.serial_number.map_or(0, |_| 3), // iSerialNumber - 1, // bNumConfigurations - ], - ); - } - pub(crate) fn configuration(&mut self, config: &Config) { self.num_interfaces_mark = Some(self.position + 4); @@ -269,6 +245,33 @@ impl<'a> DescriptorWriter<'a> { } } +/// Create a new Device Descriptor array. +/// +/// All device descriptors are always 18 bytes, so there's no need for +/// a variable-length buffer or DescriptorWriter. +pub(crate) fn device_descriptor(config: &Config) -> [u8; 18] { + [ + 18, // bLength + 0x01, // bDescriptorType + 0x10, + 0x02, // bcdUSB 2.1 + config.device_class, // bDeviceClass + config.device_sub_class, // bDeviceSubClass + config.device_protocol, // bDeviceProtocol + config.max_packet_size_0, // bMaxPacketSize0 + config.vendor_id as u8, + (config.vendor_id >> 8) as u8, // idVendor + config.product_id as u8, + (config.product_id >> 8) as u8, // idProduct + config.device_release as u8, + (config.device_release >> 8) as u8, // bcdDevice + config.manufacturer.map_or(0, |_| 1), // iManufacturer + config.product.map_or(0, |_| 2), // iProduct + config.serial_number.map_or(0, |_| 3), // iSerialNumber + 1, // bNumConfigurations + ] +} + /// A writer for Binary Object Store descriptor. pub struct BosWriter<'a> { pub(crate) writer: DescriptorWriter<'a>, diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 241e33a78..d58950838 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -168,8 +168,6 @@ struct Interface { #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct UsbBufferReport { - /// Number of device descriptor bytes used - pub device_descriptor_used: usize, /// Number of config descriptor bytes used pub config_descriptor_used: usize, /// Number of bos descriptor bytes used @@ -191,7 +189,7 @@ struct Inner<'d, D: Driver<'d>> { bus: D::Bus, config: Config<'d>, - device_descriptor: &'d [u8], + device_descriptor: [u8; 18], config_descriptor: &'d [u8], bos_descriptor: &'d [u8], msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, @@ -217,7 +215,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { driver: D, config: Config<'d>, handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>, - device_descriptor: &'d [u8], config_descriptor: &'d [u8], bos_descriptor: &'d [u8], msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, @@ -227,6 +224,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { // Start the USB bus. // This prevent further allocation by consuming the driver. let (bus, control) = driver.start(config.max_packet_size_0 as u16); + let device_descriptor = descriptor::device_descriptor(&config); Self { control_buf, @@ -256,7 +254,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { /// Useful for tuning buffer sizes for actual usage pub fn buffer_usage(&self) -> UsbBufferReport { UsbBufferReport { - device_descriptor_used: self.inner.device_descriptor.len(), config_descriptor_used: self.inner.config_descriptor.len(), bos_descriptor_used: self.inner.bos_descriptor.len(), msos_descriptor_used: self.inner.msos_descriptor.len(), @@ -720,7 +717,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { match dtype { descriptor_type::BOS => InResponse::Accepted(self.bos_descriptor), - descriptor_type::DEVICE => InResponse::Accepted(self.device_descriptor), + descriptor_type::DEVICE => InResponse::Accepted(&self.device_descriptor), descriptor_type::CONFIGURATION => InResponse::Accepted(self.config_descriptor), descriptor_type::STRING => { if index == 0 { diff --git a/embassy-usb/src/msos.rs b/embassy-usb/src/msos.rs index 3858c0f51..a285a3ccd 100644 --- a/embassy-usb/src/msos.rs +++ b/embassy-usb/src/msos.rs @@ -255,7 +255,7 @@ use sealed::*; unsafe fn transmute_write_to(t: &T, buf: &mut [u8]) { let bytes = core::slice::from_raw_parts((t as *const T) as *const u8, size_of::()); assert!(buf.len() >= bytes.len(), "MS OS descriptor buffer full"); - (&mut buf[..bytes.len()]).copy_from_slice(bytes); + buf[..bytes.len()].copy_from_slice(bytes); } /// Table 9. Microsoft OS 2.0 descriptor wDescriptorType values. @@ -444,9 +444,9 @@ impl CompatibleIdFeatureDescriptor { pub fn new(compatible_id: &str, sub_compatible_id: &str) -> Self { assert!(compatible_id.len() <= 8 && sub_compatible_id.len() <= 8); let mut cid = [0u8; 8]; - (&mut cid[..compatible_id.len()]).copy_from_slice(compatible_id.as_bytes()); + cid[..compatible_id.len()].copy_from_slice(compatible_id.as_bytes()); let mut scid = [0u8; 8]; - (&mut scid[..sub_compatible_id.len()]).copy_from_slice(sub_compatible_id.as_bytes()); + scid[..sub_compatible_id.len()].copy_from_slice(sub_compatible_id.as_bytes()); Self::new_raw(cid, scid) } -- cgit