It'd be great if the Nordic nRF5 SDK team had a bit more time to test the code under C++, to shake out a few smaller issues.
Here are some changes that needed to be made, to fix compiler warnings and errors when changing the ble_app_hrs_freertos_pca10040_s132 project to build as a C++ project.
When compiling with C++, the compiler generates the error:
4> from C:\nRF5_SDK_15.0.0_a53641a\examples\ble_peripheral\ble_app_hrs_freertos\main.cpp:57:
4> ../../../../../../components/libraries/util/app_util.h:211:65: error: '_Static_assert' was not declared in this scope
4> ../../../../../../components/libraries/util/app_util.h:233:62: note: in definition of macro '_SELECT_ASSERT_FUNC'
4> ../../../../../../components/libraries/util/app_util.h:249:25: note: in expansion of macro 'STATIC_ASSERT_MSG'
4> ../../../../../../components/softdevice/common/nrf_sdh_ble.h:83:1: note: in expansion of macro 'STATIC_ASSERT'
In app_util.h, the static assert macro should allow for the C++11 static_assert mechanism to be called.
#ifdef __GNUC__
#ifdef __cplusplus
#define STATIC_ASSERT_SIMPLE(EXPR) static_assert(EXPR, "unspecified message")
#define STATIC_ASSERT_MSG(EXPR, MSG) static_assert(EXPR, MSG)
#else
#define STATIC_ASSERT_SIMPLE(EXPR) _Static_assert(EXPR, "unspecified message")
#define STATIC_ASSERT_MSG(EXPR, MSG) _Static_assert(EXPR, MSG)
#endif
#endif
In main.cpp, the BLE_GAP_EVT_PHY_UPDATE_REQUEST needs to set the fields in the correct order, to fix the "sorry, unimplemented: non-trivial designated initializers not supported" error:
ble_gap_phys_t const phys =
{
.tx_phys = BLE_GAP_PHY_AUTO,
.rx_phys = BLE_GAP_PHY_AUTO,
};
The tasks.c file from FreeRTOS tries to call a C-accesible function:
#if ( configUSE_IDLE_HOOK == 1 )
{
extern void vApplicationIdleHook( void );
/* Call the user defined function from within the idle task. This
allows the application designer to add background functionality
without the overhead of a separate task.
NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
CALL A FUNCTION THAT MIGHT BLOCK. */
vApplicationIdleHook();
}
#endif /* configUSE_IDLE_HOOK */
So, in main.cpp, where the function is implemented, it needs to be marked extern "C", at least initially.
extern "C" void vApplicationIdleHook( void )
{
#if NRF_LOG_ENABLED
vTaskResume(m_logger_thread);
#endif
}