Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

This shouldn't break, is my BLE unstable?

I happened to write some debug log code that broke my Bluetooth.  I don't think it should be doing that.  When I burrow into the logging, I don't see why this difference is important.  I haven't been able to burrow into the BLE, so I don't know what is going on there.

This project (for historical reasons) is nrf5 SDK and starts from the sample HID keyboard.
nRF5_SDK_17.1.0\examples\ble_peripheral\ble_app_hids_keyboard

This code is in my main.  With the first block, everything is as expected EXCEPT my device doesn't show up anymore when I try to attach using Windows.  In the other two cases everything is fine.  In my mind, all I'm doing is putting out a debug log string one or more times.  The case that breaks has the debug log statement in a loop with the same string pointer.  The logging always works fine (I'm using Segger RTT).  It is the Bluetooth that comes and goes!  I don't see any indication of a problem in the logging--other than sometimes when I use the Segger JLink to halt, I see a message about a SoftDevice assert, but it isn't correlated with the behavior run time.

This makes me think that either a) the Bluetooth code is really unstable and needs to be fixed, or b) there is something in the sample HID keyboard that is really bad (but it came that way from GitHub).  At this point I'm totally confounded as to what it might be.  (I know there is something about buffer alignment going into the "SoftDevice," or something, and that is why I tried options to try to make the memory map be identical.  Seems like it is a run time thing.)

int main(void)
{
    bool erase_bonds;
//    int i;

        sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
    nrf_power_dcdcen_set(true);
    
    // Initialize.
    log_init();
    timers_init();
//    buttons_leds_init(&erase_bonds);
    power_management_init();
    ble_stack_init();
    scheduler_init();
    gap_params_init();
    gatt_init();
    advertising_init();
    services_init();
    sensor_simulator_init();
    conn_params_init();
    buffer_init();
    peer_manager_init();

#ifdef DEBUG
    NRF_LOG_INFO("DEBUG is defined");
#endif

    // Start execution.
//    NRF_LOG_INFO("HID Keyboard example started.");

#define DONT_RUN_ME_I_BREAK (true)
#ifdef DONT_RUN_ME_I_BREAK
    char * startStr = "====================================HID Keyboard example started===================================";
    int i;
    i = 0;
    while (i < 2) {
        NRF_LOG_INFO(startStr);
        i++;
    }
    NRF_LOG_FLUSH();
#endif

//#define RUN_ME_I_WORK (true)
#ifdef RUN_ME_I_WORK
    char * startStr = "====================================HID Keyboard example started===================================";
    int i;
    i = 0;
    while (i < 1) {
        NRF_LOG_INFO(startStr);
        i++;
    }
    NRF_LOG_FLUSH();
#endif

//#define RUN_ME_I_ALSO_WORK (true)
#ifdef RUN_ME_I_ALSO_WORK
    char * startStr = "====================================HID Keyboard example started===================================";
    int i;
    i = 0;
    while (i < 1) {
        NRF_LOG_INFO(startStr);
        NRF_LOG_INFO(startStr);
        i++;
    }
    NRF_LOG_FLUSH();
#endif

//#define RUN_ME_I_WORK (true)
//#ifdef RUN_ME_I_WORK
//    char * startStr = "====================================HID Keyboard example started===================================";
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_INFO(startStr);
//    NRF_LOG_FLUSH();
//#endif

//    hardfault_genhf_invalid_fp();

    // Start init state
        func_main_init_status();        
        
    timers_start();
    advertising_start(erase_bonds);
        
        // Start state machine timer
        func_main_state_tmr_create();
        
    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
                func_main_state_machine_loop();
    }
}

Parents
  • The AI answer makes sense.  Sending a pointer (potentially to RAM) into the logging system can affect its behavior.  Sure.  But I'd like my code to be fixed, not just accidentally run.

    If there is a critical timing relationship among the initialization calls in my main, why is there no information about it in the initialization code?  How come I can log the string 8 times with the literal in the macro but not even twice with an actual pointer.  I CAN log it once with the regular pointer, so that by itself is apparently not a problem.  How much delay can be tolerated?  What if I have some other high priority initialization going on that causes delay?  (And the logging always works, it is the BLE that breaks.  That makes me think the problem is in the BLE code.)

    EDIT:  I forgot about the case where I'm logging with the regular pointer, but I make calls each on their own line, and it works.  Even if I log the line 8 times!  What I can't do is log from within a loop (unless the loop only runs once).  It is a true mystery...

  • Also, I'm fully aware that the answer might be, this is old code and not really supported.  But at least if that is the answer, I would like to see it.  And it would be good to hear that this problem has surely been fixed in later BLE code.

Reply Children
No Data
Related