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?
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" ?
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
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.
Thanks!
Kind regards,
Øyvind