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

fix issue that out_xfer unintentionally returned by previous transmission (IEC-121) #40

Conversation

radiotommy
Copy link

for timeout or any reason the semaphore could left untaken before the new transmission start. it causing the transmission pick up the previous actual_num_bytes and return failure because of incorrect number of bytes transferred.

@github-actions github-actions bot changed the title fix issue that out_xfer unintentionally returned by previous transmission fix issue that out_xfer unintentionally returned by previous transmission (IEC-121) Jun 12, 2024
@tore-espressif
Copy link
Collaborator

Thank you @radiotommy for the PR, I'll have a look ASAP

@radiotommy
Copy link
Author

@tore-espressif
The test run failure seems not caused by this change, is anyone looking into it?

@tore-espressif
Copy link
Collaborator

The test run failure seems not caused by this change, is anyone looking into it?

Yes, we got a regression few days ago that should not be caused by your changes.

We had a slightly different proposal to fix this issue. Let me check with my colleagues and I'll get back to you

uint32_t start = xTaskGetTickCount();
uint32_t timeout_ticks = pdMS_TO_TICKS(timeout_ms);

while (cdc_dev->data.out_xfer->actual_num_bytes < data_len) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you please explain the reason for this loop?

I can see two cases:

  1. The transfer finishes with actual_num_bytes == data_len -> all OK, transfer finished.
  2. The transfer finishes with actual_num_bytes < data_len -> not OK. In this case we try to take the semaphore again, but we will never get it because we did not resubmit the transfer. So we end up with ESP_ERR_TIMEOUT, same as before.

Could you please describe the bug (or provide a link to a GH issue) that you are trying to fix? It could help me understand better.

Copy link
Collaborator

Choose a reason for hiding this comment

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

for timeout or any reason the semaphore could left untaken before the new transmission start

To workaround this issue, we could

xSemaphoreTake((SemaphoreHandle_t)cdc_dev->data.out_xfer->context, 0);

before we submit the transfer. If we set timeout to 0, the function will immediately return and we will make sure that the semaphore is not given from previous transfer. Does that make sense?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Even better solution is to

if (!taken) {
        // Reset the endpoint
        cdc_acm_reset_transfer_endpoint(cdc_dev->dev_hdl, cdc_dev->data.out_xfer);
        xSemaphoreTake((SemaphoreHandle_t)cdc_dev->data.out_xfer->context,  portMAX_DELAY);
        ret = ESP_ERR_TIMEOUT;
        goto unblock;

Here we take the semaphore only if the transfer really timed-out

Copy link
Author

Choose a reason for hiding this comment

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

Great idea. I will give it a test on my board this weekend.

@tore-espressif
Copy link
Collaborator

Related to espressif/esp-protocols#514

tore-espressif added a commit that referenced this pull request Jun 14, 2024
After TX transfer timeout we reset the endpoint which causes all
in-flight transfers to complete. The transfer finished callback gives
a transfer finished semaphore which we must take, so we would not
affect next TX transfers.

Closes espressif/esp-protocols#514
Closes #40
tore-espressif added a commit that referenced this pull request Jun 14, 2024
After TX transfer timeout we reset the endpoint which causes all
in-flight transfers to complete. The transfer finished callback gives
a transfer finished semaphore which we must take, so we would not
affect next TX transfers.

Closes espressif/esp-protocols#514
Closes #40
tore-espressif added a commit that referenced this pull request Jun 14, 2024
After TX transfer timeout we reset the endpoint which causes all
in-flight transfers to complete. The transfer finished callback gives
a transfer finished semaphore which we must take, so we would not
affect next TX transfers.

Closes espressif/esp-protocols#514
Closes #40
tore-espressif added a commit that referenced this pull request Jun 17, 2024
After TX transfer timeout we reset the endpoint which causes all
in-flight transfers to complete. The transfer finished callback gives
a transfer finished semaphore which we must take, so we would not
affect next TX transfers.

Closes espressif/esp-protocols#514
Closes #40
Closes espressif/esp-idf#13797
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants