Skip to content

USBDevice: Trying to send when not connected halts/blocks #2838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
larsgk opened this issue Sep 28, 2016 · 3 comments
Closed

USBDevice: Trying to send when not connected halts/blocks #2838

larsgk opened this issue Sep 28, 2016 · 3 comments

Comments

@larsgk
Copy link

larsgk commented Sep 28, 2016

Description

  • Type: Bug
  • Priority: Major

Bug

Target
KL25Z

Toolchain:
GCC_ARM

Toolchain version:
Toolchain version: arm-none-eabi-g++ (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977]

mbed-cli version:
0.9.5

Expected behavior
Program not halting when trying to send data over USBSerial with the USB cable not connected (the board is battery powered) - but can report when/if a USB cable is connected/disconnected.

Actual behavior
Program halts.

Steps to reproduce
Create an application sending some data over USBSerial. Pull the cable - see that things halt/block.

Speculation
It might be that there is no way to easily detect if the USB port is connected or not on the FRDM-KL25Z board - however, it should be possible to change the functionality of USBDevice/USBCDC to be able to try to write something without blocking when nothing is connected (and expose that to the developers).

@larsgk
Copy link
Author

larsgk commented Sep 28, 2016

Related to #53

@devanlai
Copy link
Contributor

I encountered the same issue on the LPCXpresso1549 board.

To elaborate a bit on @larsgk's speculation, it is indeed possible to make endpoint writes non-blocking to avoid hanging. We need a method that either successfully enqueues data to send or fails without enqueuing anything. Then we can simply retry sending the data later if USB is busy or unavailable. Unfortunately, USBDevice::writeNB() is not a suitable building block, since it also returns false if the data was enqueued but not yet sent, which could cause the caller to send a duplicate packet when retrying later.

For my use case, I ended up doing something along the lines of:

bool NonBlockingUSBSerial::writeBlockNB(uint8_t* buf, uint16_t size) {
    if (size <= MAX_PACKET_SIZE_EPBULK && configured()) {
        return (endpointWrite(EPBULK_IN, buf, size) == EP_PENDING);
    }
    return false;
}

With this function, it's always safe to retry later if it doesn't immediately succeed.

I'm not familiar enough with the details of the Stream interface to say if USBSerial could be rewritten to make methods like printf() non-blocking, but it would be straightforward to add a USBCDC::sendNB() method for users that need non-blocking behavior.

@ghost
Copy link

ghost commented Oct 27, 2017

GitHib issue review: Closed due to inactivity. Please re-file if critical issues found.

@ghost ghost closed this as completed Oct 27, 2017
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants