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

dfu with IS_SRVC_CHANGED_CHARACT_PRESENT set to 0

Hi, I am develop a project with dfu and bond features. I found that in dfu project, IS_SRVC_CHANGED_CHARACT_PRESENT is always set to 1. In my understanding, if set this to 1, each time phone connect to my device, it will read the services, then slow down the connection process. Am I right? If above is true, is it possible to set IS_SRVC_CHANGED_CHARACT_PRESENT to 0, that I make bootloader and my application project with the same services?

Parents
  • Hi Loste,

    We set IS_SRVC_CHANGED_CHARACT_PRESENT to 1 is that when we switch from application to bootloader and vice versa, the attributable may change and we need to send service changed indication to tell the central to redo the service discovery.

    You were correct that it may take longer to discover the service if we have service changed characteristic. But I don't think it will increase the discovery time significantly. And note that the central don't do service discovery every time it connects to a bonded device. Only the first time and when receiving service changed indication.

    If your application and the bootloader has the same attribute table, it's true that you can set IS_SRVC_CHANGED_CHARACT_PRESENT to 0.

  • Hi Hung Bui, my application and my bootloader have the same attribute table (same Service, same Chacteristics). But  when i set IS_SRVC_CHANGED_CHARACT_PRESENT to 0, the dfu process can not be done. My question is here  Can not save boot loader setting . 

  • Hi Hoai, 

    Could you check what the error it was when calling bootloader_settings_save() ? 

    I don't see any relation between the service changed characteristic and bootloader setting. Have you made sure the code to send service changed indication has been disabled as well ? 

  • Thanks for your reply Hung Bui,

    This is my old code. When dfu process completed, we call bootloader_settings_save method to clear and save the boot loader setting. And we will not received callbacks from pstorage module, it's mean we can not save the bootloader_setting and can not jump to application.

    static void bootloader_settings_save(bootloader_settings_t * p_settings)
    {
        uint32_t err_code = pstorage_clear(&m_bootsettings_handle, sizeof(bootloader_settings_t));
        APP_ERROR_CHECK(err_code);
    
        err_code = pstorage_store(&m_bootsettings_handle,
                                  (uint8_t *)p_settings,
                                  sizeof(bootloader_settings_t),
                                  0);
        APP_ERROR_CHECK(err_code);
    }
    
    void bootloader_dfu_update_process(dfu_update_status_t update_status)
    {
        static bootloader_settings_t  settings;
        const bootloader_settings_t * p_bootloader_settings;
    
        bootloader_util_settings_get(&p_bootloader_settings);
    
        if (update_status.status_code == DFU_UPDATE_APP_COMPLETE)
        {
            settings.bank_0_crc  = update_status.app_crc;
            settings.bank_0_size = update_status.app_size;
            settings.bank_0      = BANK_VALID_APP;
            settings.bank_1      = BANK_INVALID_APP;
    
            m_update_status      = BOOTLOADER_SETTINGS_SAVING;
            bootloader_settings_save(&settings);
        }
        
        ....

    In my new code. I remove the line call pstorage_clear and the dfu process was successful and boot loader can jump in to application.

    static void bootloader_settings_save_completed(bootloader_settings_t * p_settings)
    {
        uint32_t err_code = pstorage_store(&m_bootsettings_handle,
                                  (uint8_t *)p_settings,
                                  sizeof(bootloader_settings_t),
                                  0);
        APP_ERROR_CHECK(err_code);
    }
    
    
    void bootloader_dfu_update_process(dfu_update_status_t update_status)
    {
        static bootloader_settings_t  settings;
        const bootloader_settings_t * p_bootloader_settings;
    
        bootloader_util_settings_get(&p_bootloader_settings);
    
        if (update_status.status_code == DFU_UPDATE_APP_COMPLETE)
        {
            settings.bank_0_crc  = update_status.app_crc;
            settings.bank_0_size = update_status.app_size;
            settings.bank_0      = BANK_VALID_APP;
            settings.bank_1      = BANK_INVALID_APP;
    
            m_update_status      = BOOTLOADER_SETTINGS_SAVING;
            bootloader_settings_save_completed(&settings);
        }
        
        ...

    So i think the reason for my problem is calling

    pstorage_clear(&m_bootsettings_handle, sizeof(bootloader_settings_t));

    But i can not understand why calling that method is making error?

  • Which SDK are you using ? SDK v11 ? 
    I don't see these has anything to do with IS_SRVC_CHANGED_CHARACT_PRESENT.  

    Removing pstorage_clear() is not a good idea. Without clearing the flash how can you store new data in it ? 
    What kind of modification you did ? Or only to disable Service changed characteristic? 
    I would suggest you to continue on the other case. 

Reply
  • Which SDK are you using ? SDK v11 ? 
    I don't see these has anything to do with IS_SRVC_CHANGED_CHARACT_PRESENT.  

    Removing pstorage_clear() is not a good idea. Without clearing the flash how can you store new data in it ? 
    What kind of modification you did ? Or only to disable Service changed characteristic? 
    I would suggest you to continue on the other case. 

Children
  • I use SDK 12.2.0.

    I agree that removing pstorage_clear() is not a good idea but when i call pstorage_clear() i not received any pstorage callback, it make the dfu process timeout. My problem here is i don't understand why disabling service change characteristic is make that error. When i enable service change characteristic, everything work fine, i can received the pstorage callback, the dfu process completed successfully.

  • If you test with the unmodified bootloader, do you see the same thing ? I would suggest you to create a new case for your issue. 

  • Thanks for your suggestion. I have test the unmodified bootloader with nRF-Toolbox and see the same result. If you are working with some kind of bootloader project, can you test and confirm my issue?

  • Hi Hoai, 

    I'm sorry, the issue happenned when you change IS_SRVC_CHANGED_CHARACT_PRESENT = 0 , right  ? Then if you test with the unmodified bootloader, there would be an problem because the phone will cache the attribute table and wouldn't see the DFU service. 

    I assume you would need to modify the bootloader to have your application's service as well ? 

    I would suggest you to create a private case that you can share with us your firmware. You can create a dummy version of your application that only do the buttonless DFU (but has all the service of your application). And the bootloader that you modified to have the services of your application as well. 

    Please mention my name in the case so the system knows to assign to me.

  • Thanks

    That the reason my bootloader and my application project have the same attribute table.

    Finally i found where my code go wrong.

    /**@brief Function for the Application's S110 SoftDevice event handler.
     *
     * @param[in] p_ble_evt S110 SoftDevice event.
     */
    static void on_ble_evt(ble_evt_t * p_ble_evt)
    {
        uint32_t                              err_code;
        ble_gatts_rw_authorize_reply_params_t auth_reply;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
    
                m_conn_handle    = p_ble_evt->evt.gap_evt.conn_handle;
                m_is_advertising = false;
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                {
                    uint8_t  sys_attr[128];
                    uint16_t sys_attr_len = 128;
    
                    m_direct_adv_cnt = APP_DIRECTED_ADV_TIMEOUT;
    
                    err_code = sd_ble_gatts_sys_attr_get(m_conn_handle,
                                                         sys_attr,
                                                         &sys_attr_len,
                                                         BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
                    APP_ERROR_CHECK(err_code);
    
                }
                if (!m_tear_down_in_progress)
                {
                    // The Disconnected event is because of an external event. (Link loss or
                    // disconnect triggered by the DFU Controller before the firmware update was
                    // complete).
                    // Restart advertising so that the DFU Controller can reconnect if possible.
                    advertising_start();
                }
    
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
    
                break;

    In above function, when we get BLE_GAP_EVT_DISCONNECTED,

    we also call

     

                    err_code = sd_ble_gatts_sys_attr_get(m_conn_handle,
                                                         sys_attr,
                                                         &sys_attr_len,
                                                         BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
                    APP_ERROR_CHECK(err_code);

    I don't know why we call that function, but it will return an NRF_ERROR_NOT_FOUND and make system reboot. I think that removing service change characteristic make my Generic Attribute Service empty and make that error. So my current solution is remove APP_ERROR_CHECK(err_code); line and use the original bootloader_settings_save method.

     

Related