diff options
author | Paul Brook <paul@nowt.org> | 2014-03-20 22:44:41 +0000 |
---|---|---|
committer | Cristian Maglie <c.maglie@bug.st> | 2014-05-24 00:34:56 +0200 |
commit | b57b2ae3c163a855efca331bf817d566e328f88b (patch) | |
tree | d5a8415cbe0d0ff2a36b772eaec928a6846f15c5 | |
parent | 872c88bb5f643702edcc8d0ebfc1f6cd13bcf414 (diff) |
Fix race condition in USB CDC transmit
If the Start of Frame interrupt triggers just after the call
to USB_SendSpace in USB_Send then we can get data loss.
When the first bank is full and the second partially full,
the SOF handler will release the second bank via USB_Flush.
Data is then lost due to overflow as USB_Send continues writing data
to the now-closed bank.
Fix this by re-checking the FIFO status inside LockEP, immediately before
doing the data write.
Signed-off-by: Paul Brook <paul@nowt.org>
-rw-r--r-- | cores/arduino/USBCore.cpp | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index d3e0170..76ceb01 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -290,9 +290,12 @@ int USB_Send(u8 ep, const void* d, int len) if (n > len) n = len; - len -= n; { LockEP lock(ep); + // Frame may have been released by the SOF interrupt handler + if (!ReadWriteAllowed()) + continue; + len -= n; if (ep & TRANSFER_ZERO) { while (n--) |