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

nrf52832 optimization Level 3 result ble cannot re-advertise

I am using BLE for NUS template example to create my app , and when I Compile my code with Keil 5.23.0.0 with optimization Level 0, It behaves good with the following operations:

 1. Download app to chip, connect with APP on mobilephone

 2. disconnet the ble connection on the phone

 3. connect with APP on the mobile phone, OK

But:     

  when I compile the code with optimization Level 3 , re-do the operation 1.2.3 ,  I cannot find the device when step 3

It seems than the chip stop advertiing when I disconnect the first time!

Any one met this case?

Parents
  • Hi,

    The first thing that comes to mind is volatile variables. Could that be something? If not, can you upload your code so I can have a look at it?

  • BLE_CUBIC-testLevel3.7z Here is my project, it's Level 0 Now, You can search a ECube_XXX ble devive from your phone app, you can reconnect to the device; But if you change build setting to Level 3, you cannot reconnect

  • When I run your project on my nRF52 DK development kit I can only see the device advertising for about a second, but then it stops and LED 1 and 3 turn on. I'm not able to connect and I get all kinds of weird behaviour when debugging. Is it supposed to be possible to run this project on a simple nRF52 DK without any external circuitry etc.?

    What S132 version are you using? 

    Have you tried debugging yourself? Are you able to determine what the application is doing when it is not advertising?

    Are you able to use UART or RTT to print some logging information?

    Can you try to implement an error handler for the Advertising Library? You can do it as simple as this:

    void advertising_error_handler(uint32_t nrf_error)
    {
        // Use a debugger and/or LEDs etc. to check for errors. 
    }
    
    /**@brief Function for initializing the Advertising functionality.
     */
    static void advertising_init(void)
    {
        uint32_t               err_code;
        ble_advertising_init_t init;
        
        // Use an Advertising Library error handler
        init.error_handler = advertising_error_handler;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        
        etc...
        ....

  • 1.  LED 1 and 3 turn on is beacuse I use the IO for GPIOTE input

    2.  External device is MPU9250/6 channel GPIOTE / 6 button / 74HC595 etc .  But I think it will not stop ble advertising, I decrease the project init operation, please help me re-check it!

    3. UART / RTT / LOG module is disabled in my project

    4. the suggest code "init.error_handler = advertising_error_handler;" I have added in main.c

    5. S132 version is SDK14.1.0   s132_nrf52_5.0.0_softdevice.hex  pca10040

    6. I am sure that the code is usable to advertise for a long time, And perform well in LEVEL 0, and this code is written for a product.

    3007.BLE_CUBIC-testLevel3.7z 电路图.zip

  • It seems like the application is testing the battery at startup and if the voltage is less than a certain level you put the application in system off mode. If I comment out enterSystemOff() inside battery_applications() in ADC.c my kit continues to advertise and I can connect. 

    I now see similar behavior as you. I can connect once, but after disconnecting the device doesn't start advertising again. Here is why:

    1. When you disconnect, a BLE_GAP_EVT_DISCONNECTED event is sent from the Softdevice to your application. 
    2. The advertising library picks up this event in ble_advertising_on_ble_evt() in ble_advertisign.c
    3. The advertising library calls on_disconnected().
    4. The library checks if it is ok to start advertising again:
      static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
      {
          uint32_t ret;
      
          p_advertising->whitelist_temporarily_disabled = false;
      
          if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
              p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
          {
             ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED);
             if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
             {
                 p_advertising->error_handler(ret);
             }
          }
      }
    5. The problem is that you change the advertising mode configuration incorrectly in check_adv_mode_on_connect() which is called on every BLE_GAP_EVT_CONNECTED event. 
    6. You need zero-initialize the p_adv_modes_config structure to make sure it is not filled with garbage data and random variables. Typically we do it like this in the SDK:
      memset(&p_adv_modes_config, 0, sizeof(p_adv_modes_config));
    7. If you don't do this, then p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled is going to get a random value. This value might be read as true and the advertising library will not start advertising again after you have disconnected. 

    After adding the memset() function I was able to reconnect. 

    One strange thing though, is that for me it didn't work with neither optimization level 0 nor level 3. I'm guessing it is a compiler thing. In your case, optimization level 0 caused the compiler to set p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled to 0 at instantiation, but on level 3 it got some other value. In my case, it got the wrong value in both cases. 

    So the bottom line is: make sure to zero-initialize all the structs that you use to configure the Softdevice and SDK in general. 

     

Reply
  • It seems like the application is testing the battery at startup and if the voltage is less than a certain level you put the application in system off mode. If I comment out enterSystemOff() inside battery_applications() in ADC.c my kit continues to advertise and I can connect. 

    I now see similar behavior as you. I can connect once, but after disconnecting the device doesn't start advertising again. Here is why:

    1. When you disconnect, a BLE_GAP_EVT_DISCONNECTED event is sent from the Softdevice to your application. 
    2. The advertising library picks up this event in ble_advertising_on_ble_evt() in ble_advertisign.c
    3. The advertising library calls on_disconnected().
    4. The library checks if it is ok to start advertising again:
      static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
      {
          uint32_t ret;
      
          p_advertising->whitelist_temporarily_disabled = false;
      
          if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
              p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
          {
             ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED);
             if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
             {
                 p_advertising->error_handler(ret);
             }
          }
      }
    5. The problem is that you change the advertising mode configuration incorrectly in check_adv_mode_on_connect() which is called on every BLE_GAP_EVT_CONNECTED event. 
    6. You need zero-initialize the p_adv_modes_config structure to make sure it is not filled with garbage data and random variables. Typically we do it like this in the SDK:
      memset(&p_adv_modes_config, 0, sizeof(p_adv_modes_config));
    7. If you don't do this, then p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled is going to get a random value. This value might be read as true and the advertising library will not start advertising again after you have disconnected. 

    After adding the memset() function I was able to reconnect. 

    One strange thing though, is that for me it didn't work with neither optimization level 0 nor level 3. I'm guessing it is a compiler thing. In your case, optimization level 0 caused the compiler to set p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled to 0 at instantiation, but on level 3 it got some other value. In my case, it got the wrong value in both cases. 

    So the bottom line is: make sure to zero-initialize all the structs that you use to configure the Softdevice and SDK in general. 

     

Children
No Data
Related