Skip to content
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

USBCDC support ZLP #15473

Merged
merged 6 commits into from
Dec 19, 2023
Merged

USBCDC support ZLP #15473

merged 6 commits into from
Dec 19, 2023

Conversation

cyliangtw
Copy link
Contributor

@cyliangtw cyliangtw commented Dec 1, 2023

This PR is to support ZLP handling in USBCDC.
It could resolve #15451.


Pull request type

[x] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[] No Tests required for this change (E.g docs only update)
[x] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers


@daniel-starke
Copy link
Contributor

daniel-starke commented Dec 1, 2023

This does not work if there is no ongoing data stream but just some request/response interaction.
I suggest something like this:

--- drivers/usb/source/USBCDC.cpp	2023-02-23 15:00:40 +0000
+++ drivers/usb/source/USBCDC.cpp	2023-12-01 20:39:54 +0000
@@ -186,6 +186,7 @@
     _rx_in_progress = false;
     _rx_buf = _rx_buffer;
     _rx_size = 0;
+    _trans_zlp = false;
 }
 
 void USBCDC::callback_reset()
@@ -402,6 +403,9 @@
     if (!_tx_in_progress && _tx_size) {
         if (USBDevice::write_start(_bulk_in, _tx_buffer, _tx_size)) {
             _tx_in_progress = true;
+            if (_tx_size == CDC_MAX_PACKET_SIZE) {
+                _trans_zlp = true;
+            }
         }
     }
 }
@@ -414,6 +418,11 @@
 {
     assert_locked();
 
+    if (_trans_zlp && USBDevice::write_start(_bulk_in, _tx_buffer, 0)) {
+        _trans_zlp = false;
+        return;
+    }
+
     write_finish(_bulk_in);
     _tx_buf = _tx_buffer;
     _tx_size = 0;

Note that something similar needs to be done for USBCDC_ECM and maybe other devices.
P.S.: Tested with NUCLEO-H723ZG.

@cyliangtw
Copy link
Contributor Author

@daniel-starke ,
thanks of your advice, I update it to send "ZLP write start" after last alignment packet sent.
More, USBCDC_ECM already handle ZLP at https://github.com/cyliangtw/mbed-os/blob/ca616c865acb59c6f6311952787f242831ced02f/drivers/usb/source/USBCDC_ECM.cpp#L226

@daniel-starke
Copy link
Contributor

I believe that the condition for _trans_zlp = true; is still wrong as it does not appear to handle transfer continuation (e.g. send 63 byte without flush and 1 byte afterwards to a total of CDC_MAX_PACKET_SIZE). Important is the actual transfer size not any intermediate buffer handling size. See my diff above.

@cyliangtw
Copy link
Contributor Author

@daniel-starke,
For accurency, to move the judgement of ZLP into USBCDC::AsyncWrite.
It will be the better choice. Then send_nb() with zero size to trigger trans-zlp.

@daniel-starke
Copy link
Contributor

@cyliangtw
I will have a deeper look at it around the end of the week.
Your change basically moves the responsibility for multi-packet transactions from the driver to the user space. Which is ok in my opinion. However, this probably also requires an update for the USBCDC_ECM driver for homogeneity and definitely of the documentation. Most users do not have such in-depth knowledge about the USB protocol.
Also, what tests did you run with these changes? When I wrote my diff above I had troubles putting the ZPL transmission in _send_isr_start(). Which is why I moved it to _send_isr().

@cyliangtw
Copy link
Contributor Author

Hi @daniel-starke,
In USBCDC_ECM, there is no async-write and already handle ZLP at USBCDC_ECM::send() /USBCDC_ECM.cpp#L226
In USBCDC, USBCDC::send() will invoke async-write. This PR was to follow original async-write mechansim and verified on 2 platforms M467 & M487, also verified the scenario as my expextation on transfer 64 bytes, 128 bytes, 127 bytes and so on.

Copy link
Contributor

@ccli8 ccli8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified on NUMAKER_IOT_M467/NUMAKER_IOT_M487 targets

@0xc0170 0xc0170 added needs: review release-type: patch Indentifies a PR as containing just a patch labels Dec 8, 2023
@@ -641,4 +663,4 @@ const uint8_t *USBCDC::configuration_desc(uint8_t index)
} else {
return NULL;
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add an empty line as it was

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks of your reminder.
I rollback the empty line.

@daniel-starke
Copy link
Contributor

@cyliangtw
I can confirm that it works. Tested on NUCLEO-H723ZG.
Note that I still believe that send_nb() needs an update of its documentation as mentioned before.
send_nb() also appears to be broken for the continuation case. Someone may want to fix that:

--- drivers/usb/source/USBCDC.cpp  2023-12-10 15:37:58.259849800 +0100
+++ drivers/usb/source/USBCDC.cpp  2023-12-10 15:58:26.240938600 +0100
@@ -391,7 +391,7 @@
         uint32_t free = sizeof(_tx_buffer) - _tx_size;
         uint32_t write_size = free > size ? size : free;
         if (size > 0) {
-            memcpy(_tx_buf, buffer, write_size);
+            memcpy(_tx_buf + _tx_size, buffer, write_size);
         }
         _tx_size += write_size;
         *actual = write_size;

@cyliangtw
Copy link
Contributor Author

@daniel-starke,
Thanks of your confirmation pass on NUCLEO-H723ZG.

About send_nb() memcpy possible break the continuation use case, I agree with your point and it's no matter with ZLP, you could add another PR to contribute your good viewpoint.
If you prefer to append this change into this ZLP PR, it's fine to me to add one more commit.

@daniel-starke
Copy link
Contributor

@cyliangtw
Yes, feel free to add it here.

@mergify mergify bot added needs: CI and removed needs: review labels Dec 13, 2023
@0xc0170
Copy link
Contributor

0xc0170 commented Dec 13, 2023

CI started

@mbed-ci
Copy link

mbed-ci commented Dec 13, 2023

Jenkins CI Test : ❌ FAILED

Build Number: 1 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_greentea-test

@mergify mergify bot added needs: work and removed needs: CI labels Dec 13, 2023
@cyliangtw
Copy link
Contributor Author

@0xc0170 ,
CI Test failed on NUCLEO_WB55RG at: storage-blockdevice-tests-tests-blockdevice-general_block_device | TIMEOUT | 1800.63 | default |
mbedgt: test suite results: 1 TIMEOUT

After review the update of USBCDC, seems unrelated with this PR.
Could send "CI start" again ?

@mbed-ci
Copy link

mbed-ci commented Dec 18, 2023

Jenkins CI Test : ❌ FAILED

Build Number: 4 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_greentea-test

@mergify mergify bot added needs: work and removed needs: CI labels Dec 18, 2023
@cyliangtw
Copy link
Contributor Author

I can't spot anything merged recently causing this, I'll check nightly and find out what is going on. Meanwhile, happy to merge this as it is.

@0xc0170 ,
The system seems abnormal, mergify added "need CI" and removed "need CI" repeatedly over 700 times.
Should I close this PR and new another PR to replace it ?

@0xc0170 0xc0170 merged commit 6403ec7 into ARMmbed:master Dec 19, 2023
18 of 20 checks passed
@0xc0170
Copy link
Contributor

0xc0170 commented Dec 19, 2023

Mergify sometimes find 2 conditions that are met and goes back and forth.. we might revisit the rules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-type: patch Indentifies a PR as containing just a patch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Host receiving data from USBSerial will timeout if data size is 64
5 participants