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

Not possible to detect interrupt-driven UART API support in a useful way #53155

Open
xyzzy42 opened this issue Dec 16, 2022 · 3 comments
Open
Labels
area: UART Universal Asynchronous Receiver-Transmitter Enhancement Changes/Updates/Additions to existing features

Comments

@xyzzy42
Copy link
Contributor

xyzzy42 commented Dec 16, 2022

Is your enhancement proposal related to a problem? Please describe.
There are three UART APIs, polling, interrupt-driven, and async. The latter two are not supported by all UART drivers. Support for the APIs is also a build time configuration option. But even when the API is enabled, any given UART may or may not support it.

Support must be detected at run time. This can be done during initialization for the async API: the call to uart_callback_set() will return -ENOSYS if the UART does not support the async API or -ENOTSUP if the API was not enabled.

But for the interrupt-driven API, uart_irq_callback_user_data_set() returns void. Other methods in the interrupt-driven API have -ENOSYS returns, but they all cause actions on the UART and aren't suitable to use when the UART user is initializing.

Compile time support for the interrupt-driven API in general can be done through IS_ENABLED() of course.

Describe the solution you'd like
uart_irq_callback_user_data_set() should return an error code, like uart_callback_set(). All the information to do this appears to be there and it's a trivial change. Existing users will just ignore the return value.

Describe alternatives you've considered
Support could in most cases be detected at compile tiime. All the information is known. Which UART device is used. What driver that UART has. If that driver supports interrupt-driven and/or async APIs. The API could be determined at compile time and unused code paths optimized away.

Additional context
The uart logging backend would be much faster on a USB CDC ACM UART if it used the interrupt-driven API. But there is no good way to know if it's supported. The backend is used on many different UARTs and not all support interrupt-driven mode.

@xyzzy42 xyzzy42 added the Enhancement Changes/Updates/Additions to existing features label Dec 16, 2022
@xyzzy42 xyzzy42 changed the title Not possible to detect initerrupt-driven UART API support in a useful way Not possible to detect interrupt-driven UART API support in a useful way Dec 16, 2022
@carlescufi carlescufi added the area: UART Universal Asynchronous Receiver-Transmitter label Dec 19, 2022
@carlescufi
Copy link
Member

Describe the solution you'd like
uart_irq_callback_user_data_set() should return an error code, like uart_callback_set(). All the information to do this appears to be there and it's a trivial change. Existing users will just ignore the return value.

Thanks for the suggestion. Would you be able to propose a Pull Request with this change?

@xyzzy42
Copy link
Contributor Author

xyzzy42 commented Dec 19, 2022

I take it the compile time detection is too much of a change?

I think it could be done without that much difficulty with a device tree property. This would allow:

  • Optimizing away code paths for the APIs that aren't in use in use by a given uart API comsumer.
  • Detecting at build time the use of an unsupported API for a given UART. There is no way to do this now. Using an API that the configure time selected uart doesn't support will produce no build errors but will fail at run time.
  • Per-UART API selection. Currently enabling the interrupt-driven API enables it globally for every instance of every driver. There's no way to enable the interrupt or async APIs, but still control individual UARTs to use a specific API.

xyzzy42 added a commit to xyzzy42/zephyr that referenced this issue Dec 28, 2022
If the interrupt-driven aka FIFO API is not enabled or not supported by
a given UART, have the functions for setting the irq callback return an
error code.  They previously returned void.

This is the same way the analogous functions in the async UART API work.

This way it is possible to detect API support when a UART consumer
initializes.

Issue zephyrproject-rtos#53155

Signed-off-by: Trent Piepho <tpiepho@gmail.com>
carlescufi pushed a commit that referenced this issue Dec 31, 2022
If the interrupt-driven aka FIFO API is not enabled or not supported by
a given UART, have the functions for setting the irq callback return an
error code.  They previously returned void.

This is the same way the analogous functions in the async UART API work.

This way it is possible to detect API support when a UART consumer
initializes.

Issue #53155

Signed-off-by: Trent Piepho <tpiepho@gmail.com>
@TorstenRobitzki
Copy link
Contributor

I feel the pain. Implementing something, just to later find out, that a certain device (USB CDC with an nRF53) does not implement one (at least) of the provided interfaces takes a lot of time that could have been saved at configuration time. Till now, I can not even find something in the documentation that states, that the async. UART interface is not supported with the nRF53 USB CDC Uart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: UART Universal Asynchronous Receiver-Transmitter Enhancement Changes/Updates/Additions to existing features
Projects
None yet
Development

No branches or pull requests

3 participants