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

drivers: usb: udc_stm32: Handle HAL callbacks on separate thread #80820

Merged
merged 3 commits into from
Jan 28, 2025

Conversation

topisani
Copy link
Contributor

@topisani topisani commented Nov 4, 2024

All HAL callback handling is offloaded to a separate thread.
Tested on STM32H747 (arduino portenta) with the high speed controller.

This is an attempt at fixing #61464.
Marked as a draft, as i would at least like to do some minor stylistic cleanup before submitting, but if anyone could help test, I would appreciate it. As far as i can tell, no additional locking should be required, and no timing invariants are broken, but I could use some extra eyes on that as well.

Fixes: #61464 (UDC STM32 part)

@erwango
Copy link
Member

erwango commented Nov 4, 2024

A huge thanks. We'll for sure help testing on extended sample of series.

@GeorgeCGV
Copy link
Collaborator

Is it safe to enqueue a stack-allocated msg pointer?

Perhaps the event approach is safer. Given that the combined number of IN and OUT endpoints is typically less than 32 (15 IN + 15 OUT), a k_event could be used to notify about IN, OUT, or SETUP.

Additionally, this approach helps prevent potential message queue overflows that might result in missed event/message handling and supports ordered processing.

@topisani
Copy link
Contributor Author

Is it safe to enqueue a stack-allocated msg pointer?

Yes, it is copied into the ringbuffer.

Perhaps the event approach is safer. Given that the combined number of IN and OUT endpoints is typically less than 32 (15 IN + 15 OUT), a k_event could be used to notify about IN, OUT, or SETUP.

Isnt it technically up to 16+16 endpoints including the control endpoint?

Additionally, this approach helps prevent potential message queue overflows that might result in missed event/message handling and supports ordered processing.

While I agree about the message queue overflows, I don't see how k_event would support ordered processing? Thats mostly why I chose the msgq based approach, to make sure the events were processed in the order they arrived

@GeorgeCGV
Copy link
Collaborator

Not trying to block, just discussing out of curiosity.

Yes, it is copied into the ringbuffer.

Apologies, I just noticed the message is passed not a pointer; all good.

Isnt it technically up to 16+16 endpoints including the control endpoint?

That fits.

I don't see how k_event would support ordered processing?

Not in a fifo way, but In the processing. I.e. process setup before in (process x before y).

@topisani
Copy link
Contributor Author

topisani commented Nov 19, 2024

Not in a fifo way, but In the processing. I.e. process setup before in (process x before y).

Ah, I dont think this is what we would want though. All of these callbacks are triggered from the same IRQ, i.e. have the same priority, and should be processed in the order they arrived. It should maybe be considered how the ordering interdependency with the udc_submit_event processing could impact things, but i think that requires a deeper knowledge of the STM32 USB stack than I have. I would personally be ok to leave this up to testing too.

@erwango I believe it is ready for testing. Is there anything else I can do to help the testing effort along?

@erwango
Copy link
Member

erwango commented Nov 19, 2024

@topisani It's failing on disco_l475_iot1. Before:

*** Booting Zephyr OS build v4.0.0-405-g2efc8598e39f ***
[00:00:00.010,000] <inf> cdc_acm_echo: USB device support enabled
[00:00:00.010,000] <inf> cdc_acm_echo: Wait for DTR
[00:00:25.413,000] <inf> cdc_acm_echo: USBD message: Device suspended
[00:00:25.568,000] <inf> cdc_acm_echo: USBD message: Bus reset
[00:00:25.683,000] <inf> cdc_acm_echo: USBD message: Bus reset
[00:00:25.760,000] <inf> cdc_acm_echo: USBD message: New device configuration
[00:00:25.761,000] <err> udc_stm32: ep 0x00 queue is empty
[00:00:25.761,000] <inf> cdc_acm_echo: USBD message: CDC ACM line coding
[00:00:25.761,000] <inf> cdc_acm_echo: Baudrate 9600

After:

*** Booting Zephyr OS build v4.0.0-409-g84574a1c389f ***
[00:00:00.010,000] <err> usbd_init: Failed to assign endpoint addresses
[00:00:00.010,000] <err> usbd_init: Failed to init HS configuration 1
[00:00:00.010,000] <err> usbd_sample_config: Failed to initialize device support
[00:00:00.010,000] <err> cdc_acm_echo: Failed to initialize USB device
[00:00:00.010,000] <err> cdc_acm_echo: Failed to enable USB

@topisani
Copy link
Contributor Author

@erwango Alright, i believe this is my attempt at detecting USB HS support that fails. I have an l432 board i can test on, if that is the case, it should fail there as well

@topisani
Copy link
Contributor Author

topisani commented Nov 20, 2024

I could reproduce the issue on a nucleo_l432kc, and it appears to have been the HS detection. It now follows the maximum-speed dts prop, like in most of the other udc drivers, which fixed the issue for me.

@topisani
Copy link
Contributor Author

topisani commented Dec 2, 2024

Alright, i did some testing using samples/subsys/usb/cdc_acm -DCONF_FILE=usbd_next_prj.conf on the various boards i could find.
test: open the cdc_acm terminal, and type characteres. The device should echo each character back.

nucleo_u575zi_q: PASS
stm32f469i_disco: PASS
stm32f769i_disco: FAIL

I have also done a test on an arduino_portenta_h7 based custom board, that also failed. The common factor is that both boards use HS USB.

Checking with main, these boards also fail in the same way, so I believe it is unrelated to these changes, that the current ucd_stm32 does not correctly implement usbotg_hs support. I will look at a fix separately from this PR.

@topisani topisani force-pushed the udc-stm32 branch 2 times, most recently from 2275c22 to 2a056c0 Compare December 2, 2024 16:09
@topisani topisani marked this pull request as ready for review December 2, 2024 16:37
@fpistm
Copy link
Contributor

fpistm commented Dec 3, 2024

Hi @topisani

I've started to test on my side, here my results using samples/subsys/usb/cdc_acm with -DCONF_FILE=usbd_next_prj.conf and sent a lorem ipsum buffer of 1024 bytes several times.

series boards controller cdc_acm sample plug/unplug
F2 nucleo_f207zg st,stm32-otgfs
F4 nucleo_f429zi st,stm32-otgfs
F7 stm32f746g_disco st,stm32-otgfs
H7 nucleo_h723zg st,stm32-otghs
L4 b_l4s5i_iot01a st,stm32-otgfs
U5 nucleo_u575zi_q st,stm32-otgfs

I will continue tests and report here.

@topisani
Copy link
Contributor Author

Addressed most review comments from @jfischer-no. For the remaining ones, I still need some clarification on how to proceed.

@erwango erwango requested a review from jfischer-no January 17, 2025 15:09
@carlescufi carlescufi requested review from erwango and fpistm January 27, 2025 13:20
erwango
erwango previously approved these changes Jan 27, 2025
@erwango
Copy link
Member

erwango commented Jan 27, 2025

@jfischer-no PTAL

@erwango
Copy link
Member

erwango commented Jan 28, 2025

@topisani Please rebase.

@topisani topisani dismissed stale reviews from henrikbrixandersen and erwango via e980fee January 28, 2025 11:00
@topisani topisani force-pushed the udc-stm32 branch 2 times, most recently from e980fee to 974c2bb Compare January 28, 2025 11:02
All HAL callback handling is offloaded to a separate thread, as they
involve non isr-compatible operations such as mutexes.

Fixes zephyrproject-rtos#61464

Signed-off-by: Tobias Pisani <mail@topisani.dev>
This fixes usbd_caps_speed(), which is used in sample_usbd_init, and the
documentation. Without it, no high speed configuration would be added.

Signed-off-by: Tobias Pisani <mail@topisani.dev>
On USB HS, the previous lower limit of 64 is too small, the value
160 has been chosen apparently through trial and error.

See 1204aa2 for the original implementation in the old device driver.

Signed-off-by: Tobias Pisani <mail@topisani.dev>
@kartben kartben merged commit 1ec660d into zephyrproject-rtos:main Jan 28, 2025
25 checks passed
@ddavidebor
Copy link

A big thank you for this PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: USB Universal Serial Bus platform: STM32 ST Micro STM32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

USB device stack (new and old) assertion on STM32