This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

CLI and wait_for_event

I am using ATT MTU throughput example and I noticed that using CLI (calling cli_start) causes the main while(1) loop forever. In other words, wait_for_event does not block until it gets an event. I verified it using the breakpoint.

Is there a way to use CLI and also block until we get an event?

I am using nRF52840 and S140 nRF5_SDK_14.2.0.

  • See source code below: This is based off the ATT_MTU throughput example available in SDK under ble_central_and_peripheral/experimental folder.

    int main(void)
    {
        log_init();
    
        cli_init();
        leds_init();
        timer_init();
        counter_init();
        buttons_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        advertising_data_set();
    
        peer_manager_init();
        
        client_init();
    
        gatt_mtu_set(m_test_params.att_mtu);
        data_len_ext_set(m_test_params.data_len_ext_enabled);
        conn_evt_len_ext_set(m_test_params.conn_evt_len_ext_enabled);
        preferred_phy_set(&m_test_params.phys);
    
        cli_start();
    
        buttons_enable();
    
        NRF_LOG_INFO("Starting central device...");
        
        for (;;)
        {
    
            cli_process();
    
    
            if (NRF_LOG_PROCESS() == false)
            {
                wait_for_event();
            }
        }
    }
    
    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    ret_code_t app_timer_init(void)
    {
        // Stop RTC to prevent any running timers from expiring (in case of reinitialization)
        rtc1_stop();
    
        // Initialize operation queue
        m_op_queue.first           = 0;
        m_op_queue.last            = 0;
        m_op_queue.size            = APP_TIMER_CONFIG_OP_QUEUE_SIZE+1;
    
        mp_timer_id_head            = NULL;
        m_ticks_elapsed_q_read_ind  = 0;
        m_ticks_elapsed_q_write_ind = 0;
    
    #if APP_TIMER_WITH_PROFILER
        m_max_user_op_queue_utilization   = 0;
    #endif
    
        NVIC_ClearPendingIRQ(SWI_IRQn);
        NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI);
        NVIC_EnableIRQ(SWI_IRQn);
    
        rtc1_init(APP_TIMER_CONFIG_RTC_FREQUENCY);
    
        m_ticks_latest = rtc1_counter_get();
    
        return NRF_SUCCESS;
    }
    
  • I will be at office in. 12 hours. I will chcecie that and let you know.

  • What is implementation of "wait_for_event" funciton? I still do not fully understand your problem.

    Btw. when using CLI over UART you will have a wakeup event every 100ms caused by app_timer. CLI checks if there is a new data in ring buffer.

  • Thanks for pointing it out. I see CLI_UART_RX_TIMEOUT is set to 100 in nrf_cli_uart.c.

    Is there a way to wake up the SoC when a command is received (for example carriage return is entered on the serial terminal)? That way, we don't need a timer and SoC sleeps for most of the time.

    The cli_uart_enable takes a parameter "blocking". What is this used for? Is there a way for application to set this blocking flag to TRUE ?

  • "blocking" parameter is used to configure how to print logs in certain crash situation.

    Existing solution with UART transport is not very power efficient because the peripheral is active almost all the time in order to receive characters. What is more HFCLK is always active all the time. Extra current caused by app_timer wakeup is not adding a lot of power to the equation. Especially if you are using Soft Device witch also wakes SoC.

    Solution you have proposed is of course possible but it would require to re-write CLI UART transport. To be honest I am not sure if it is worth it. With your proposal instead of cyclic wakeup we would need to have an interrpt every recived byte what could increase current consumtion compering to existing solution.

    We are no working on more robust and power efficient UART driver but it will be available in Q1-Q2 2018.

Related