different errors with different compiler optimization settings

Hello,

I'm having a very strange issue where changing the compiler optimization level will generate different errors in the ble_ess_init() function (sometimes even in sd_enable() )

in particular:

optimization set to None = everything works fine

optimization set to Level 2 for size= NRF_ERROR_DATA_SIZE

optimization set to Level 2 for speed = NRF_ERROR_INVALID_ADDR

 

how do I fix this issue?

Regards,

Rocco

Parents
  • Hi Rocco

    Is this based on one of the standard examples, or have you made your own?

    Do you know which code line it is that is generating the error?

    Are you able to share the code with me so I can have a look at the implementation?

    Normally if changing the optimization level causes an error it is a sign of some vulnerability in the code. 

    Best regards
    Torbjørn

  • hi , 

    in attachment the module causing the issue. the function is ble_ess_init()

    /* Attention!
     * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
     * qualification listings, this section of source code must not be modified.
     */
    #include "sdk_common.h"
    #if NRF_MODULE_ENABLED(BLE_ESS)
    #include "ble_ess.h"
    #include <string.h>
    #include "ble_srv_common.h"
    
    
    #define OPCODE_LENGTH 1                                                              /**< Length of opcode inside Temperature Measurement packet. */
    #define HANDLE_LENGTH 2                                                              /**< Length of handle inside Temperature Measurement packet. */
    #define MAX_TPM_LEN      (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Temperature Measurement. */
    
    
    /**@brief Function for handling the Connect event.
     *
     * @param[in]   p_ess       Environmental Sensing Service structure.
     * @param[in]   p_ble_evt   Event received from the BLE stack.
     */
    static void on_connect(ble_ess_t * p_ess, ble_evt_t const * p_ble_evt)
    {
        p_ess->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    }
    
    
    /**@brief Function for handling the Disconnect event.
     *
     * @param[in]   p_ess       Environmental Sensing Service structure.
     * @param[in]   p_ble_evt   Event received from the BLE stack.
     */
    static void on_disconnect(ble_ess_t * p_ess, ble_evt_t const * p_ble_evt)
    {
        UNUSED_PARAMETER(p_ble_evt);
        p_ess->conn_handle = BLE_CONN_HANDLE_INVALID;
    }
    
    
    /**@brief Function for handling write events to the Environmental Sensing Temperature characteristic.
     *
     * @param[in]   p_ess         Environmental Sensing Service structure.
     * @param[in]   p_evt_write   Write event received from the BLE stack.
     */
    static void on_tpm_cccd_write(ble_ess_t * p_ess, ble_gatts_evt_write_t const * p_evt_write)
    {
        if (p_evt_write->len == 2)
        {
            // CCCD written, update notification state
            if (p_ess->evt_handler != NULL)
            {
                ble_ess_evt_t evt;
    
                if (ble_srv_is_notification_enabled(p_evt_write->data))
                {
                    evt.evt_type = BLE_ESS_EVT_NOTIFICATION_ENABLED;
                }
                else
                {
                    evt.evt_type = BLE_ESS_EVT_NOTIFICATION_DISABLED;
                }
    
                p_ess->evt_handler(p_ess, &evt);
            }
        }
    }
    
    
    /**@brief Function for handling the Write event.
     *
     * @param[in]   p_ess       Environmental Sensing Service structure.
     * @param[in]   p_ble_evt   Event received from the BLE stack.
     */
    static void on_write(ble_ess_t * p_ess, ble_evt_t const * p_ble_evt)
    {
        ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
        if (p_evt_write->handle == p_ess->tpm_handles.cccd_handle)
        {
            on_tpm_cccd_write(p_ess, p_evt_write);
        }
    }
    
    
    void ble_ess_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ble_ess_t * p_ess = (ble_ess_t *) p_context;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                on_connect(p_ess, p_ble_evt);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                on_disconnect(p_ess, p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_WRITE:
                on_write(p_ess, p_ble_evt);
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    uint32_t ble_ess_init(ble_ess_t * p_ess, const ble_ess_init_t * p_ess_init)
    {
        uint32_t              err_code;
        ble_uuid_t            ble_uuid;
        ble_add_char_params_t add_char_params;
    
    
        // Initialize service structure
        p_ess->evt_handler                 = p_ess_init->evt_handler;
        p_ess->conn_handle                 = BLE_CONN_HANDLE_INVALID;
        p_ess->max_tpm_len                 = CC_TPM_FRAME_LENGTH;
    
        // Add service
        BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE);
    
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                            &ble_uuid,
                                            &p_ess->service_handle);
    
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        // Add TPM measurement characteristic
        memset(&add_char_params, 0, sizeof(add_char_params));
    
        add_char_params.uuid              = BLE_UUID_CC_CHARACTERISTC_UUID;
        add_char_params.char_props.read   = 1;
        add_char_params.char_props.notify = 1;
        add_char_params.uuid_type         = 0;
    
        add_char_params.max_len           = CC_TPM_FRAME_LENGTH;
        add_char_params.init_len          = CC_TPM_FRAME_LENGTH;
        add_char_params.p_init_value      = 0;
        add_char_params.is_var_len        = true;
        add_char_params.cccd_write_access = p_ess_init->esm_cccd_wr_sec;
    
        err_code = characteristic_add(p_ess->service_handle, &add_char_params, &(p_ess->tpm_handles));
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        return NRF_SUCCESS;
    }
    
    
    uint32_t ble_ess_temperature_measurement_send(ble_ess_t * p_ess, uint8_t *temperature)
    {
        uint32_t err_code;
    
        // Send value if connected and notifying
        if (p_ess->conn_handle != BLE_CONN_HANDLE_INVALID)
        {
            uint8_t                encoded_tpm[MAX_TPM_LEN];
            uint16_t               len;
            uint16_t               hvx_len;
            ble_gatts_hvx_params_t hvx_params;
    
            len     = CC_TPM_FRAME_LENGTH;
            hvx_len = len;
    
            memset(&hvx_params, 0, sizeof(hvx_params));
    
            hvx_params.handle = p_ess->tpm_handles.value_handle;
            hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
            hvx_params.offset = 0;
            hvx_params.p_len  = &hvx_len;
            hvx_params.p_data = temperature;
    
            err_code = sd_ble_gatts_hvx(p_ess->conn_handle, &hvx_params);
            if ((err_code == NRF_SUCCESS) && (hvx_len != len))
            {
                err_code = NRF_ERROR_DATA_SIZE;
            }
        }
        else
        {
            err_code = NRF_ERROR_INVALID_STATE;
        }
    
        return err_code;
    }
    
    
    void ble_ess_on_gatt_evt(ble_ess_t * p_ess, nrf_ble_gatt_evt_t const * p_gatt_evt)
    {
        if (    (p_ess->conn_handle == p_gatt_evt->conn_handle)
            &&  (p_gatt_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
        {
            p_ess->max_tpm_len = p_gatt_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
        }
    }
    
    #endif // NRF_MODULE_ENABLED(BLE_ESS)
    

  • Hi,

    in attachment my project. I have commented out all code specific to our custom hardware, you should be able to run it on a nrF52 DK. probably there are some include paths that need to be modified. the way I can see the error is the follow:

    • enable log over uart (you might need to change the TX pin in sdk_config.h
    • compile Release build with different optimization settings
    • connect the serial terminal and run the code
    • you will see different errors generated at startup according to the optimisation level

    tPCB_Temp_mod.zip

  • Hi 

    Which SDK did you build it for? 

    I tried to make it run in my local Thingy52 SDK installation, but the library folders don't quite match up. 

    Best regards
    Torbjørn

  • As I said, you can run it on a nrF52 Development Kit. I use the nRF5_SDK v17.1.0

  • Hi 

    Thanks, now I can find most of the library files, but it seems the source code for the ble_cus module is missing?

    I also get some build errors in the ble_dtm.c module, but I can probably patch this out somehow. What are you using the ble_dtm module for in the project?

    When you said "no modifications at all" earlier did you mean to say that the unmodified Thingy project will also show this error? 

    The project you sent me is obviously changed a lot from the Thingy project. 

    Best regards
    Torbjørn 

  • Hi,

    here you are the missing file.

    #include "sdk_common.h"
    #include "ble_cus.h"
    
    
    static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
    {
        ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
        if (   (p_evt_write->handle == p_cus->cus_char_handles.value_handle)
            && (p_evt_write->len == 2)
            && (p_cus->cus_write_handler != NULL))
        {
            
            p_cus->cus_data = (uint16_t)(((uint16_t)p_evt_write->data[0] << 8) | (uint16_t)p_evt_write->data[1])  ; // Update the cus data in the server instance
            p_cus->write_event = CUS_CHAR_WRITTEN; // Set LED4 Characteristic was written in the server instance
            p_cus->cus_write_handler(p_ble_evt->evt.gap_evt.conn_handle, p_cus); //Forward the event to the user handler.
        } 
    }
    
    
    
    void ble_cus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ble_cus_t * p_cus = (ble_cus_t *)p_context;//Cast the context as a service instance
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTS_EVT_WRITE:
                on_write(p_cus, p_ble_evt);
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    uint32_t ble_cus_init(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
    {
        uint32_t              err_code; // Return value for the initialization function
        ble_uuid128_t         base_uuid = {BLE_CC_UUID_BASE}; //Base UUID
        ble_uuid_t            service_uuid; //Service UUID
        ble_add_char_params_t add_char_params;  //Add characteristic parameters needed by characteristic_add()
        uint8_t               cus_initial_state = 0 ; //A variable to hold the initial value for the LED4 Blinking Frequency characteristic
    	
        /* Copy all members from the initialization structure to the service instance. We only have one member to set.*/
        p_cus->cus_write_handler = p_cus_init->cus_write_handler;
        
        /* Add our base UUID to the BLE stack's table*/
        err_code = sd_ble_uuid_vs_add(&base_uuid, &p_cus->uuid_type);
        VERIFY_SUCCESS(err_code);
    
        /* Initialize the service UUID and its type. */
        service_uuid.uuid = BLE_UUID_CC_SERVICE;
        service_uuid.type = p_cus->uuid_type;
    
    
        /* Add the service to the GATT server*/
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &service_uuid, &p_cus->service_handle);
        VERIFY_SUCCESS(err_code);
    
    
        /* Initialize all members of the add_char_params variable to zero.*/
        memset(&add_char_params, 0, sizeof(add_char_params));
    
        /* Set the UUID ,UUID type , initial size, max size , and the initial value for the characteristic.*/
        add_char_params.uuid             = BLE_UUID_CC_CUS_CHAR; //Set the UUID for the characteristic
        add_char_params.uuid_type        = p_cus->uuid_type; //Set the type of UUID for the characteristic
        add_char_params.init_len         = 2*sizeof(uint8_t); //Set the inital size for the characteristic
        add_char_params.max_len          = 2*sizeof(uint8_t); //Set the max size for the characteristic
        add_char_params.p_init_value     = &cus_initial_state; //Set the initial value for the characteristic
    
    
        /* Specify the standard properties supported by the characteristic.*/
        add_char_params.char_props.read  = 1;
        add_char_params.char_props.write = 1;
        add_char_params.char_props.notify = 0; 
       
    
        /* Specify the security level for reading, writing, CCCD writing (if applicable) of that characteristic.*/
        add_char_params.read_access  = SEC_OPEN;
        add_char_params.write_access = SEC_OPEN;
    
       /* Call the characteristic_add()to add the csalibration characteristic*/
        err_code =  characteristic_add(p_cus->service_handle, &add_char_params, &p_cus->cus_char_handles);
    	
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        } 
    
        return err_code;
    
    }
    
    

    I'm using the dtm module to increase the transmission power to +4dBm

    I have inherited the project from another the person, so I don't know the exact source of the ble_ess module, I assumed it was from Nordic , whether nrF52 or Thingy, but I'm pretty sure that the original code hasn't been modified

    do you know where I can find the source code of  ble_ess module for Thingy project?

Reply
  • Hi,

    here you are the missing file.

    #include "sdk_common.h"
    #include "ble_cus.h"
    
    
    static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
    {
        ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
        if (   (p_evt_write->handle == p_cus->cus_char_handles.value_handle)
            && (p_evt_write->len == 2)
            && (p_cus->cus_write_handler != NULL))
        {
            
            p_cus->cus_data = (uint16_t)(((uint16_t)p_evt_write->data[0] << 8) | (uint16_t)p_evt_write->data[1])  ; // Update the cus data in the server instance
            p_cus->write_event = CUS_CHAR_WRITTEN; // Set LED4 Characteristic was written in the server instance
            p_cus->cus_write_handler(p_ble_evt->evt.gap_evt.conn_handle, p_cus); //Forward the event to the user handler.
        } 
    }
    
    
    
    void ble_cus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ble_cus_t * p_cus = (ble_cus_t *)p_context;//Cast the context as a service instance
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTS_EVT_WRITE:
                on_write(p_cus, p_ble_evt);
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    uint32_t ble_cus_init(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
    {
        uint32_t              err_code; // Return value for the initialization function
        ble_uuid128_t         base_uuid = {BLE_CC_UUID_BASE}; //Base UUID
        ble_uuid_t            service_uuid; //Service UUID
        ble_add_char_params_t add_char_params;  //Add characteristic parameters needed by characteristic_add()
        uint8_t               cus_initial_state = 0 ; //A variable to hold the initial value for the LED4 Blinking Frequency characteristic
    	
        /* Copy all members from the initialization structure to the service instance. We only have one member to set.*/
        p_cus->cus_write_handler = p_cus_init->cus_write_handler;
        
        /* Add our base UUID to the BLE stack's table*/
        err_code = sd_ble_uuid_vs_add(&base_uuid, &p_cus->uuid_type);
        VERIFY_SUCCESS(err_code);
    
        /* Initialize the service UUID and its type. */
        service_uuid.uuid = BLE_UUID_CC_SERVICE;
        service_uuid.type = p_cus->uuid_type;
    
    
        /* Add the service to the GATT server*/
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &service_uuid, &p_cus->service_handle);
        VERIFY_SUCCESS(err_code);
    
    
        /* Initialize all members of the add_char_params variable to zero.*/
        memset(&add_char_params, 0, sizeof(add_char_params));
    
        /* Set the UUID ,UUID type , initial size, max size , and the initial value for the characteristic.*/
        add_char_params.uuid             = BLE_UUID_CC_CUS_CHAR; //Set the UUID for the characteristic
        add_char_params.uuid_type        = p_cus->uuid_type; //Set the type of UUID for the characteristic
        add_char_params.init_len         = 2*sizeof(uint8_t); //Set the inital size for the characteristic
        add_char_params.max_len          = 2*sizeof(uint8_t); //Set the max size for the characteristic
        add_char_params.p_init_value     = &cus_initial_state; //Set the initial value for the characteristic
    
    
        /* Specify the standard properties supported by the characteristic.*/
        add_char_params.char_props.read  = 1;
        add_char_params.char_props.write = 1;
        add_char_params.char_props.notify = 0; 
       
    
        /* Specify the security level for reading, writing, CCCD writing (if applicable) of that characteristic.*/
        add_char_params.read_access  = SEC_OPEN;
        add_char_params.write_access = SEC_OPEN;
    
       /* Call the characteristic_add()to add the csalibration characteristic*/
        err_code =  characteristic_add(p_cus->service_handle, &add_char_params, &p_cus->cus_char_handles);
    	
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        } 
    
        return err_code;
    
    }
    
    

    I'm using the dtm module to increase the transmission power to +4dBm

    I have inherited the project from another the person, so I don't know the exact source of the ble_ess module, I assumed it was from Nordic , whether nrF52 or Thingy, but I'm pretty sure that the original code hasn't been modified

    do you know where I can find the source code of  ble_ess module for Thingy project?

Children
  • Hi Rocco

    My bad. It seems the file was there all along, it was just not added to the project for some reason (the project had ble_nus.c added rather than ble_ess.c). 

    Adding the right file to the project I can now get it to build. 

    As for the original issue I am wondering if this could be related to an inconsistency in Segger Embedded Studio when flashing SoftDevice based applications to the device. When the issue happens, what will happen if you reset the board by pressing the reset button on the DK?

    Alternatively, try to start the application in the debugger and see if the same issue occurs. 

    If a reset or starting a debug session solves the issue then this is a known issue in the way that Segger Embedded Studio starts the application after downloading an application update. 

    The various Thingy52 files can be found here (the source code is located in the SDK), but there is no ble_ess module in the original Thingy52 firmware. There is a ble_tes module (Thingy Environment Service), but I must assume that ble_ess is something this other person implemented. 

    Best regards
    Torbjørn 

  • hi,

    I have managed to fix the issue.

    As I have been told in this other thread   can't compile bootloader SES SDK v17.1.0, linker error , SDK v17.1.0 needs SES v5.42a, but I was using the latest version of Segger Embedded Studio. Installing SES  v5.42a has fixed the issue, I can compile the release code with different optimization levels without any errors

  • Hi

    That is great news Slight smile

    I didn't think of this possibility, often when using the latest SES version it is impossible to build the application at all. Anyway, good to hear that you figured it out. 

    Best regards
    Torbjørn

Related