Async UART and shell module in Zephyr on nRF52480

I have shell working with the following configuration

CONFIG_SHELL=y
CONFIG_SHELL_BACKENDS=y
CONFIG_SHELL_BACKEND_SERIAL=y #also selects serial
CONFIG_SHELL_CMDS=y
CONFIG_SHELL_ECHO_STATUS=y
Now I need to add async UART to send some data outside the shell
I added 
CONFIG_UART_ASYNC_API=y
but the call  uart_callback_set() fails with ENOSYS ( async not supported in the device )
If I explicitly set 
CONFIG_UART_0_INTERRUPT_DRIVEN=n uart_callback_setI() succeeds but I cannot type in the shell window
Is there a way to use UART async API with the shell?
Thanks
  • Hi,

    Now I need to add async UART to send some data outside the shell

    Could you check out this detailed sample using asynchronous UART in our nRF Connect SDK course to see if you have missed anything in the setup of the asynchronous UART? uart_callback_set() should only return ENOSYS if async api is not supported by the device, but this should be supported by the nRF52840, leading me to think there is something missing in your setup.

    Is there a way to use UART async API with the shell?

    Regarding this, I will ask around and come back with more details before Wednesday (within 2 working days). In the meanwhile, you may investigate this open ticket with a somewhat similar issue to see if you are able to spot your issue through their fix.

    Let me know if these guides help you before I am able to reach back to you with additional information.

    Kind regards,
    Andreas

  • Revisiting... I have a shell module  and I need to send data asynchronously over UART from a thread other than the shell. Is this possible? Is there a way to temporarily disable shell UART handlers and re-enable them when I'm done sending the data?

    Thanks

  • It might be possible but you need to have some inter-thread communication implemented between the shell module and your thread to synchronize the access to uart in your application. There is no config to temporarily disable shell to give other threads access to uart.

  • Found the solution

    shell_print(shell_backend_uart_get_ptr(),"%s",data);
  • AndyM, I'm glad that you were able to find an answer to your 2nd question (how to send data asynchronously over UART from a thread other than the shell), but did you get the 1st (original) question answered?

    ...is it possible to enable async UART support and the shell module in the same project?

    I'm trying to use the shell on uart0 and the UART async API on uart1, but I'm beginning to think that these features are mutually exclusive.

    When I enable UART async API support with these settings (in prj.conf),

    CONFIG_SERIAL=y
    CONFIG_UART_ASYNC_API=y

    I see these settings being applied to the project as a whole (in .config):

    #
    # Serial Drivers
    #
    CONFIG_UART_NRFX=y
    CONFIG_UART_ASYNC_TX_CACHE_SIZE=8
    CONFIG_UART_0_NRF_UARTE=y
    CONFIG_UART_0_ENHANCED_POLL_OUT=y
    CONFIG_UART_0_ASYNC=y # <======================================
    # CONFIG_UART_0_NRF_PARITY_BIT is not set
    CONFIG_UART_0_NRF_TX_BUFFER_SIZE=32
    # CONFIG_UART_0_NRF_HW_ASYNC is not set
    # CONFIG_UART_0_NRF_ASYNC_LOW_POWER is not set
    CONFIG_UART_1_NRF_UARTE=y
    CONFIG_UART_1_ASYNC=y # <======================================
    CONFIG_UART_1_ENHANCED_POLL_OUT=y
    # CONFIG_UART_1_NRF_PARITY_BIT is not set
    # CONFIG_UART_1_NRF_HW_ASYNC is not set
    # CONFIG_UART_1_NRF_ASYNC_LOW_POWER is not set
    CONFIG_UART_ENHANCED_POLL_OUT=y
    CONFIG_NRF_UARTE_PERIPHERAL=y

    Note the "CONFIG_UART_0_ASYNC=y" and "CONFIG_UART_1_ASYNC=y" settings.

    However, when I add shell module support with these settings (in prj.conf),

    CONFIG_SERIAL=y
    CONFIG_UART_ASYNC_API=y
    CONFIG_SHELL=y # <======================================

    I see these settings being applied to the project as a whole (in .config):

    #
    # Serial Drivers
    #
    CONFIG_UART_NRFX=y
    CONFIG_UART_ASYNC_TX_CACHE_SIZE=8
    CONFIG_UART_0_NRF_UARTE=y
    CONFIG_UART_0_ENHANCED_POLL_OUT=y
    CONFIG_UART_0_INTERRUPT_DRIVEN=y # <======================================
    # CONFIG_UART_0_NRF_PARITY_BIT is not set
    CONFIG_UART_0_NRF_TX_BUFFER_SIZE=32
    # CONFIG_UART_0_NRF_HW_ASYNC is not set
    # CONFIG_UART_0_NRF_ASYNC_LOW_POWER is not set
    CONFIG_UART_1_NRF_UARTE=y
    CONFIG_UART_1_INTERRUPT_DRIVEN=y # <======================================
    CONFIG_UART_1_ENHANCED_POLL_OUT=y
    # CONFIG_UART_1_NRF_PARITY_BIT is not set
    CONFIG_UART_1_NRF_TX_BUFFER_SIZE=32
    # CONFIG_UART_1_NRF_ASYNC_LOW_POWER is not set
    CONFIG_UART_ENHANCED_POLL_OUT=y
    CONFIG_NRF_UARTE_PERIPHERAL=y

    Note the "CONFIG_UART_0_INTERRUPT_DRIVEN=y" and "CONFIG_UART_1_INTERRUPT_DRIVEN=y" settings.

    With this project change, the async API function "uart_callback_set" now errors out because the define "UARTE_INTERRUPT_DRIVEN" is now defined instead of "UARTE_ANY_ASYNC" in uart_nrfx_uarte.c, line 1771 (SDK v2.1.0) since the struct element ".callback_set" no longer exists.

    Is there a way to have "CONFIG_UART_0_INTERRUPT_DRIVEN=y" (the 2nd project settings window above - compatible with the shell module) while "CONFIG_UART_1_ASYNC=y" (the 1st project settings window above - compatible with the UART async API)?

    FYI, I am using the DevAcademy, lesson 5, exercise 1 example code to reproduce this on an nRF52840 DK.

Related