-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
CDC without DTR being set #506
Conversation
hihi, sorry for late response, I am scratching my head with another race condition bug, will check this out as soon as I could. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you again, great PR, I think this over most of our discussion on this topic before. Strangely the code is actually much less than the discussion itself, which is actually a really good things, since we write less but cover most scenario. I only has a few comments, most importantly to remove the edpt_abort() since that is lots of works and may not needed since the case is not that severe. Most user won't even notice that. I like to add code step by step, it takes lots more time to get thing mature but ensure that we don't spent much time implement feature that 90% user don't need.
@hathach thanks for your review. I kept this draft pending as it is right now, because I hoped someone else could take a look and comment on it. Since I am defining a very new functionality for the CDC, some more ideas might be useful. I'm a bit busy at the moment, but I'll work on the changes you recommended and push the update we made because of the race condition bug as soon as possible. |
No rush, I am busy at the moment at well :( . |
Hi @duempel. Thank you for working on this. I suspect that this is what I'm looking for. However, currently there are conflicts with the master branch. I've tried to resolve the conflicts myself because I also need patches from the master branch. Probably I did something wrong because I'm getting the following error with the latest version of ESP-IDF:
Are you still working on this? Could you please resolve the conflicts in your branch? Thank you very much! |
Hello @dobairoland , thank you for your interest in this feature. Since TinyUSB's master branch has received a lot of updates in the last months, there are currently conflicts with this PR. I will try to merge the current master into my branch tomorrow to update the PR draft quickly. The further changes to create the final PR will be done in the following days. If you want to test the changes, I would be very happy. Keeping you updated. |
Alright, I just merged all the changes into the feature branch. @dobairoland you can check if it's working for you now (I sadly don't have an esp32s2 to test here right now - but it's working on other platforms). In a couple of days I also want to finalize the PR with the changes that @hathach requested. |
@duempel Thank you for resolving the conflicts. Unfortunately, I'm getting the same error as before. There is no device connected in the beginning when it fails on the first call of I don't have this issue with 075334a. I believe that it can work on other platforms because the exception occurs in the ESP32-S2-specific code. I'm ready to help with any further testing and debugging but unfortunately, I don't know the internals of tinyusb well enough to fix it by myself. |
Ok, I've fixed my previous issue with a |
I'm sorry for posting again. Unfortunately, this doesn't solve my original problem I was hoping to solve: to be able to read and write while DTR is not set. |
@dobairoland thanks for your feedback. It's not easy to spot the cause of this issue now. As far as I understand you are using your own user application. Have you tried to run the cdc_msc_freertos example on your esp? My first thoughts were: It seems that an endpoint transfer (dcd_edpt_xfer) is called before the endpoint was opened correctly. This could happen for example if you write and flush data before calling I would recommend to 1st try the cdc_msc_freertos exmaple. If you already did this please turn on TinyUSB's logging function for debugging (CFG_TUSB_DEBUG = 2). We could see here if functions were called in wrong order.
This is exactly what this PR is trying to solve. Let's hope to find the cause as soon as possible. |
@hathach based on the explained behaviour from my last comment I think it is useful to provide more stability and block application mistakes. In this PR I deleted the |
Thank you @duempel for the ideas. I see in my logs that everything has been initialized.
It is not possible for my application to write before initialization because TASK A calls I will try the |
The issue can be reproduced with the
|
All other API must be called after
We could add necessary check but first we need to locate the root cause first, if the scenario is tusb_init() isn't called yet, then I don't think it is the stack responsibility at all @dobairoland please try to post only necessary info in the log, it also help to point out where thing go wrong as well. People have their own preferred hardware for developing the stack, and may not be familiar with esp32s2 your do. When you do modify the example, it is better to post your modification line here in code block as well. |
@dobairoland sorry for my late reply. The initialization process you described with task A,B and C seems to be good. But even in this scenario task C should not directly write to a cdc interface. The init call only prepares memory for cdc to work. But it is not opening an endpoint. This is done by the usb host when setting a configuration. You can see when a configuration is set within the log:
This is an example of just one cdc interface with data endpoint 2. Calling the read and write api before this event can result in unexpected behaviour. A more detailed log can be helpful here.
Did you only remove the |
Yes, that was the only change:
I'm used to working with tinyusb as a submodule of ESP-IDF so I have a little trouble enabling the log here. These doesn't seem to work for me: make BOARD=esp32s2_saola_1 PORT=1 DEBUG=1 LOG=2 all
make BOARD=esp32s2_saola_1 CFG_TUSB_DEBUG=2 PORT=1 DEBUG=1 LOG=2 all |
|
I'm sorry but I tried the following sequence of commands but still I see no tinyusb debug output in the log. The output remains the same as I posted earlier. rm -r _build/
make BOARD=esp32s2_saola_1 DEBUG=1 LOG=2 all
make BOARD=esp32s2_saola_1 PORT=1 flash |
ah esp32s2 doesn't get
|
Thank you for the help. So I see only this:
There is nothing else from tinyusb in the log. |
there is divide by zero exception, the cpu is hanged. You should try to see at where and when this happens. |
- auto flush welcome message at connection event - provide information to the user if the terminal did not set DTR
@hathach I finally got some minutes to make the changes you suggested within your review. I kept this PR as draft, because I just add some changes to cdc example code, which I don't know if you like them. But we can make this to merge very soon. 😉 The updated cdc example uses If you like the changes I will add them to the freertos example as well. |
@dobairoland it's very difficult to help you debugging because I do not have the ESP here. But you could check if the error still occurs if you do the following changes:
If you are only using one single interface you could change the TU_VERIFY check to exactly the endpoints you use with your descriptor to make it more precise. If you still get the same error then I do not have more ideas at the moment. But we can excluse the cause by referencing unopened entpoints. |
I'm getting a different behavior with the new commits in this PR.
This continues until I connect to ttyACM0: And in loop it reboots. The exceptions are now different than before. I have the same changes in |
Here are the logs with the requested changes: |
thanks @duempel sorry for being late on response, I am on the run with other issue. And don't worry too much about the ESP if you don't have the mcu to test with. Just focus on the actual MCU you could test with, I will do the test on esp32s2 and fix it if needed later on. This PR will be probably used very often by esp32s2 user. @dobairoland would you mind moving the log on a gist or something, the long log make pr discussion more difficult to follow. |
I'm sorry. I moved them into files. |
@@ -189,7 +189,7 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf) | |||
// Pull data from FIFO | |||
uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf)); | |||
|
|||
if ( count && tud_cdc_n_connected(itf) ) | |||
if ( count ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are right, we have to add a check whether usb is enumerated to prevent executing edpt_xfer(). I will do it in a follow up PR
examples/device/cdc_msc/src/main.c
Outdated
uint8_t const line_state = tud_cdc_get_line_state(); | ||
|
||
// Provide information that terminal did not set DTR bit | ||
if( !(line_state & 0x01) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not necessary for example to send out the warning. I will do a follow up clean up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit of testing does show it work rather well as currently. I didn't know any terminal that doesn't set DTR to test with with the overwritable, but the code look good enough. Since it has been going for a while, I will merge it now and do a follow up with tud_ready() check
Update: look like I could do a push to your branch which the PR is based on. Once the PR is done, I think we could finally merge this one. There is probably a bit of mixed behavior using terminal without DTR but we could fix it later on. The terminal with DTR should remain the same.
@hathach thanks for merging your latest changes in here. If you want to test out the functionallity I could recommend HTerm to you. Usually I use this terminal on windows, but it's also available for linux. HTerm has the ability to manually control DTR and RTS bits with buttons.
Alright, I feel good with this. Thanks for your help and I'm happy we finally get this to master. |
@dobairoland I couldn't reproduce your issue with my esp32s2 saola board but omitting the |
Ah thank you, just downloaded and tested, so far so good. |
@HiFiPhile and @me-no-dev may be interested in this merged PR, let me know if there is an hiccups |
Will try in a day or two and report back :) thanks! |
As previously discussed, I'd like to share ideas how we could solve the DTR bit problem within CDC class. Sorry if you have been waiting for this. I couldn't work on it before since I've been on vacation. 🙈
Describe the PR
This PR is one possibility to solve #482 . The most important change is, that
tud_cdc_n_connected(itf)
is not checked withintud_cdc_n_write_flush
anymore. This will allow us to transmit data, even if the host does not support control line states. In case the DTR bit is not set, we do not know if a host actually drains data from tx fifo or not. To make only the newest data available to a new connected host (e.g. logs), the tx fifo will be modified to become overwritable.Whenever a new connection with DTR bit is esatblished, we know that connection is valid from now and can optionally remove all old data.
Additional context
This is just a draft PR to get a view on what was discussed in #401 and #482 . Please everyone feel free to bring up new ideas or changes to get the best behaviour for all applications.
A main goal is to not change the behaviour of old applications. Since the current implementation works only with DTR being set, we have the chance to define a new behaviour for all other cases.