Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Exchange ble_hrs_t variable between different files

Hi, I need to use a ble_hrs_t variable between two different files, I used the BLE_HRS_DEF() macro to instantiate the variable in a header file that I've included in both files, but it doesn't work, any suggestions?

  • I need to use a ble_hrs_t variable between two different files

    That's basic 'C' programming - nothing specific to Nowrdic!

    http://c-faq.com/decl/decldef.html

    I used the BLE_HRS_DEF() macro to instantiate the variable

    'C' doesn't have "instatiation" - it has definitions & declarations (see the above link).

    Look carefully at the macro - you'll probably find that it creates a definition ...

    it doesn't work

    In what way, exactly, does it "not work" ?

    http://www.catb.org/esr/faqs/smart-questions.html#code

  • This is my bleservices.h file

    #ifndef BLESERVICES_H_
    #define BLESERVICES_H_
    #ifdef __cplusplus
    extern "C" 
    {
    #endif /* __cplusplus */
    
    #include <stdbool.h>
    #include <nrfsd/nrf_sdh.h>
    #include <nrfsd/nrf_sdh_ble.h>
    #include <nrfbleservices/ble_hrs/ble_hrs.h>
    
    BLE_HRS_DEF(hrsStruct);             /**< Heart rate service instance. */
    
    bool_t BleServices_Init(void);
    
    
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */
    
    #endif /* BLESERVICES_H_ */

    this is my bleservices.c file

    #include "bleservices.h"
    #include "../middleware/nrfbleservices/ble_dis/ble_dis.h"
    #include <nrfble/nrf_ble_qwr/nrf_ble_qwr.h>
    #include <nrflib/util/app_error.h>
    
    #define DIS_MANUFACTURER_NAME "Manufact."
    
    static void nrf_qwr_error_handler(uint32_t nrf_error);
    
    NRF_BLE_QWR_DEF(qwrStruct);     /**< Context for the Queued Write module.*/
    extern ble_hrs_t hrsStruct;
    
    bool_t BleServices_Init(void)
    {
        bool_t result = false;
        ret_code_t         retVal;
        ble_hrs_init_t     hrsInit;
    
        ble_dis_init_t     disInit;
        nrf_ble_qwr_init_t qwrInit = {0};
        uint8_t            body_sensor_location;
    
        // Initialize Queued Write Module.
        qwrInit.error_handler = nrf_qwr_error_handler;
    
        retVal = nrf_ble_qwr_init(&qwrStruct, &qwrInit);
        APP_ERROR_CHECK(retVal);
    
        // Initialize Heart Rate Service.
        body_sensor_location = BLE_HRS_BODY_SENSOR_LOCATION_FINGER;
    
        memset(&hrsInit, 0, sizeof(hrsInit));
    
        hrsInit.evt_handler                 = NULL;
        hrsInit.is_sensor_contact_supported = true;
        hrsInit.p_body_sensor_location      = &body_sensor_location;
    
        // Here the sec level for the Heart Rate Service can be changed/increased.
        hrsInit.hrm_cccd_wr_sec = SEC_OPEN;
        hrsInit.bsl_rd_sec      = SEC_OPEN;
    
        retVal = ble_hrs_init(&hrsStruct, &hrsInit);
        APP_ERROR_CHECK(retVal);
    
        // Initialize Device Information Service.
        memset(&disInit, 0, sizeof(disInit));
    
        ble_srv_ascii_to_utf8(&disInit.manufact_name_str, (char *)DIS_MANUFACTURER_NAME);
    
        disInit.dis_char_rd_sec = SEC_OPEN;
    
        retVal = ble_dis_init(&disInit);
        APP_ERROR_CHECK(retVal);
    
        result = true;
        return result;
    }
    
    
    static void nrf_qwr_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    

    this is my  hrssim.h file

    #ifndef BLE_HRSSIM_H_
    #define BLE_HRS_SIM_H_
    #ifdef __cplusplus
    extern "C" 
    {
    #endif /* __cplusplus */
    
    #include <stdbool.h>
    
    bool HrsSim_Init(void);
    
    void HrsSim_MeasTimeoutHandler(void * p_context);
    
    
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */
    
    #endif /* BLE_HRSSIM_H_ */
    

    this is my hrssim.c file

    #include "hrssim.h"
    #include <ble/bleservices.h>
    #include <nrflib/util/app_error.h>
    #include <nrfble/nrf_ble_gatt/nrf_ble_gatt.h>
    #include <sensorsim/sensorsim.h>
    
    #include <log/log.h>
    
    #define MIN_HEART_RATE                      140                                     /**< Minimum heart rate as returned by the simulated measurement function. */
    #define MAX_HEART_RATE                      300                                     /**< Maximum heart rate as returned by the simulated measurement function. */
    #define HEART_RATE_INCREMENT                10                                      /**< Value by which the heart rate is incremented/decremented for each call to the simulated measurement function. */
    
    static sensorsim_state_t m_heart_rate_sim_state;  /**< Heart Rate sensor simulator state. */
    static sensorsim_cfg_t   m_heart_rate_sim_cfg;    /**< Heart Rate sensor simulator configuration. */
    
    bool_t HrsSim_Init(void)
    {
        /*m_battery_sim_cfg.min          = MIN_BATTERY_LEVEL;
        m_battery_sim_cfg.max          = MAX_BATTERY_LEVEL;
        m_battery_sim_cfg.incr         = BATTERY_LEVEL_INCREMENT;
        m_battery_sim_cfg.start_at_max = true;
    
        sensorsim_init(&m_battery_sim_state, &m_battery_sim_cfg);*/
    
        m_heart_rate_sim_cfg.min          = MIN_HEART_RATE;
        m_heart_rate_sim_cfg.max          = MAX_HEART_RATE;
        m_heart_rate_sim_cfg.incr         = HEART_RATE_INCREMENT;
        m_heart_rate_sim_cfg.start_at_max = false;
    
        sensorsim_init(&m_heart_rate_sim_state, &m_heart_rate_sim_cfg);
    
        /*m_rr_interval_sim_cfg.min          = MIN_RR_INTERVAL;
        m_rr_interval_sim_cfg.max          = MAX_RR_INTERVAL;
        m_rr_interval_sim_cfg.incr         = RR_INTERVAL_INCREMENT;
        m_rr_interval_sim_cfg.start_at_max = false;
    
        sensorsim_init(&m_rr_interval_sim_state, &m_rr_interval_sim_cfg);*/
    
        return true;
    }
    
    void HrsSim_MeasTimeoutHandler(void * p_context)
    {
        NRF_LOG_INFO("HrsSim_MeasTimeoutHandler");
        static uint32_t cnt = 0;
        ret_code_t retVal;
        uint16_t heartRate;
    
        UNUSED_PARAMETER(p_context);
    
        heartRate = (uint16_t)sensorsim_measure(&m_heart_rate_sim_state, &m_heart_rate_sim_cfg);
    
        cnt++;
        retVal = ble_hrs_heart_rate_measurement_send(&hrsStruct, heartRate);
        if ((retVal != NRF_SUCCESS) &&
            (retVal != NRF_ERROR_INVALID_STATE) &&
            (retVal != NRF_ERROR_RESOURCES) &&
            (retVal != NRF_ERROR_BUSY) &&
            (retVal != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
           )
        {
            APP_ERROR_HANDLER(retVal);
        }
    
        // Disable RR Interval recording every third heart rate measurement.
        // NOTE: An application will normally not do this. It is done here just for testing generation
        // of messages without RR Interval measurements.
        //m_rr_interval_enabled = ((cnt % 3) != 0);
    }
    

    the compiler compiles without error, the problem is when bleservices.c calls hrsStruct in BleServices_Init() function, the hrsStruct address is 0x20004cb8, but when hrssim.c calls hrsStruct in HrsSim_MeasTimeoutHandler() the hrsStruct address is 0x20003a28

  • Hello, 

    You will need to be more specific with what the problem is. 

    • Have you tried to debug the issue? 
    • What does the APP_ERROR_HANDLER return?
    • What are you expecting the application to do?

    Thanks!

    Kind regards,
    Øyvind

Related