How to Create an Instance of RPC (Remote Procedural Call) using the NRF52840

Hello,

I'm using SDK 17.0.2 with S113, v7.2.0 on the NRF52840. We currently have an instance of CLI running in our executive loop, and it works fine. We'd also like to implement RPC as well for calling functions from a remote processor. 

This is what we have so far:

    // Entering executive loop. Please note, the system WILL NOT EXIT this loop
    // unless a reset occurs.
    for ( ;; )
    {

        if (getRpcActivateFlagStatus())
        {   
            // Then service the RPC bytes!
            rpcServerBytePull(); // Not working
        }
        else
        {
             nrf_cli_process(&m_cli_uart); // Working fine
        }

        idle_state_handle();
             
        // Handle all of the events that were scheduled in the EMQ per
        // iteration of our executive loop. Please note, this is an nRF
        // driver-level API, which dispatches all pushed events to the system
        // EMQ (Event Message Queue).
        app_sched_execute();

    }

Is there a special HW flag in sdk_config.h that needs to be set in order for RPC to operate on UART? My sdk_config.h already enables UART by the way. Also, are there any examples of RPC that I can follow as our SDK does. not come with an RPC example.

Parents
  • Thank you for confirming...using CLI over UART was at the root of my problem. I'm now creating an instance of standard UART in order to send and receive byte-packed data structs. Do I need to stop my CLI process when using my standard instance of UART or can they co-exist together?

    // Spawn an instance of UART
        static bool uart_instance_activated = false;
    
        if (!uart_instance_activated)
        {
            uart_instance_activated = true;
            uint32_t err_code = NRF_SUCCESS;
            const app_uart_comm_params_t comm_params =
            {
                UART_RX_PIN,
                UART_TX_PIN,
                UART_RTS_PIN_NUMBER,
                UART_CTS_PIN_NUMBER,
                UART_HWFC,
                false,
                NRF_UART_BAUDRATE_115200
            };
    
            APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                          uart_error_handle,
                    APP_IRQ_PRIORITY_LOWEST,
                                  err_code);
    
            APP_ERROR_CHECK(err_code); 

  • If the CLI UART backend is enabled, you will need to disable this or not start the CLI at all when using the UART instance for anything else. If you are using different UART instances (0 and 1) for the two libraries, you do not need to disable the CLI.

  • Interesting issue that I'm seeing. Okay, so app_uart_get() is able to receive bytes over the RX line from a requesting app, however, app_uart_put() cannot send any data back in response. We have confirmed this by logic analyzer.

    Here is my code:

    int8_t transportSend( const uint16_t bufferSize, uint8_t *pBuffer )
    {
        if ( pBuffer == NULL )
        {
            NRF_LOG_INFO("NULL?");
            return TRANSPORT_ERROR;
        }
        
        uint32_t status = NRF_SUCCESS;
    
        status = app_uart_put( START_BYTE );
    
        if (status != NRF_SUCCESS)
        {
            NRF_LOG_INFO("Failure in %s() @line %d", __FUNCTION__, __LINE__);
            return status;
        }
    
        for ( uint16_t i = 0; i < bufferSize; i++ )
        {
            NRF_LOG_INFO("pBuffer[%d] = %d", i, pBuffer[i]);
            // UART is spaming 0xFF so it has to be escaped
            if ( ( pBuffer[i] == START_BYTE ) ||
                 ( pBuffer[i] == STOP_BYTE ) ||
                 ( pBuffer[i] == ESCAPE_BYTE ) ||
                 ( pBuffer[i] == 0xFF ) )
            {
                status = app_uart_put( ESCAPE_BYTE );
                if (status != NRF_SUCCESS)
                {
                    NRF_LOG_INFO("Failure in %s() @line %d", __FUNCTION__, __LINE__);
                    return status;
                }
    
                status = app_uart_put( escapeByte( pBuffer[i] ) );
                if (status != NRF_SUCCESS)
                {
                    NRF_LOG_INFO("Failure in %s() @line %d", __FUNCTION__, __LINE__);
                    return status;
                }
            }
            else
            {
                status = app_uart_put( pBuffer[i] );
                if (status != NRF_SUCCESS)
                {
                    NRF_LOG_INFO("Failure in %s() @line %d", __FUNCTION__, __LINE__);
                    return status;
                }
            }
        } // end of for-loop
    
        status = app_uart_put( STOP_BYTE );
        if (status != NRF_SUCCESS)
        {
            NRF_LOG_INFO("Failure in %s() @line %d", __FUNCTION__, __LINE__);
            return status;
        }
    
        return TRANSPORT_SUCCESS;
    }

    Am I using app_uart_put() incorrectly? Also, do functions like 

    nrf_pwr_mgmt_run()

    UART functionality?
  • Does your call to app_uart_put() return any error codes?

    Where are you calling this from? Is it called from interrupt context?

Reply Children
No Data
Related