From 6b136a162f3eb30f7429c49a9d61834a414cf6dd Mon Sep 17 00:00:00 2001 From: Andelf Date: Mon, 20 Feb 2023 08:56:07 +0800 Subject: [PATCH] fix: libusb read timeout on linux Fix #22 --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ src/transport/mod.rs | 4 +++- src/transport/usb.rs | 12 +++++++++--- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1c963f..123e31f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), @@ -6,69 +7,95 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Hang on Linux caused by libusb timeout #22 + ## [0.2.1] - 2023-01-28 + ### [Added] + - EEPROM erase support - EEPROM write support - Config register for CH57x ### Fixed + - Enable adaptive timeout setting ## [0.2.0] - 2022-11-13 + ### [Added] + - EEPROM dump support, fix #12 - Refactor all subcommands, using clap v4 - Probe support, multiple chips can be selected by an index - Progressbar for flash and verify commands ### Changed + - Disable debug log by default ### Fixed + - Wrong timeout setting for usb transport ## [0.1.4] - 2022-11-13 + ### Added + - Config register definition for CH32F10x, CH32V20x, CH55x, CH58x - Code erase impl - Add schema for device description yaml - Add no-verify, no-reset, no-erase to flash cmd ### Fixed + - Wrong verify impl - Ignore reset protocol errors - Wrong field definitions #2 #3 - Wrong chip info of CH55x ## [0.1.3] - 2022-05-14 + ### Added + - Basic config register parsing - Config register reset support (buggy for old chips) ### Changed + - Refine chip family naming ## [0.1.2] - 2022-05-11 + ### Added + - New style chip DB, now parses MCU variants more accurately - dump `info` support ### Changed + - BTVER, UID formating ### Fxied + - Wrong ELF parsing - Check response code for `verify` ## [0.1.1] - 2022-05-09 + ### Added + - flash support - ELF parsing ### Changed + - Debug print format ## [0.1.0] - 2022-05-08 + ### Added + - Initialize project - first release diff --git a/src/transport/mod.rs b/src/transport/mod.rs index c418349..00e3fc1 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -9,6 +9,8 @@ pub use self::usb::UsbTransport; mod usb; +const DEFAULT_TRANSPORT_TIMEOUT_MS: u64 = 1000; + /// Abstraction of the transport layer. /// Might be a USB, a serial port, or Network. pub trait Transport { @@ -16,7 +18,7 @@ pub trait Transport { fn recv_raw(&mut self, timeout: Duration) -> Result>; fn transfer(&mut self, cmd: Command) -> Result { - self.transfer_with_wait(cmd, Duration::default()) + self.transfer_with_wait(cmd, Duration::from_millis(DEFAULT_TRANSPORT_TIMEOUT_MS)) } fn transfer_with_wait(&mut self, cmd: Command, wait: Duration) -> Result { diff --git a/src/transport/usb.rs b/src/transport/usb.rs index c04f26b..b432809 100644 --- a/src/transport/usb.rs +++ b/src/transport/usb.rs @@ -9,7 +9,7 @@ use super::Transport; const ENDPOINT_OUT: u8 = 0x02; const ENDPOINT_IN: u8 = 0x82; -const TIMEOUT_MS: u64 = 1; +const USB_TIMEOUT_MS: u64 = 5000; pub struct UsbTransport { device_handle: DeviceHandle, @@ -92,16 +92,22 @@ impl UsbTransport { } } +impl Drop for UsbTransport { + fn drop(&mut self) { + self.device_handle.release_interface(0).unwrap(); + // self.device_handle.reset().unwrap(); + } +} + impl Transport for UsbTransport { fn send_raw(&mut self, raw: &[u8]) -> Result<()> { self.device_handle - .write_bulk(ENDPOINT_OUT, raw, Duration::from_millis(TIMEOUT_MS))?; + .write_bulk(ENDPOINT_OUT, raw, Duration::from_millis(USB_TIMEOUT_MS))?; Ok(()) } fn recv_raw(&mut self, timeout: Duration) -> Result> { let mut buf = [0u8; 64]; - let nread = self .device_handle .read_bulk(ENDPOINT_IN, &mut buf, timeout)?;