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

C++ changes required after changing main.c to main.cpp

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
}
Parents Reply Children
  • At least for those of us who are building certain parts using C++, I would hope that the headers and plain C implementations from Nordic can compile without too many warnings.

    The lack of full C++ support is, for me, a bit a disappointing though, because instead of properly using the compiler to instantiate hardware driver instances, I see way too much preprocessor magic in the SDK, which neither Eclipse, nor NetBeans, nor Segger Embedded Studio can really understand.

    I actually get a bit more exhausted working with your SDK every time I see another parameterized #define macro.

  • Hi,

    The SDK team are aware of your concerns and suggestions. I can't make any promises as to changes in future SDKs but we very much appreciate your feedback.

    Ketil

Related