Our BLE peripheral product (nRF52810, SDK 15.3.0, SD 112 6.1.1) is relatively simple. iOS device (central) connects to peripheral. Data is exchanged between the central and peripheral. Peripheral watches a sensor and responds to events (by sending data to the central). The size of data sent between central and peripheral does not exceed 16 bytes (future expansion might increase this by a few bytes). Encryption unnecessary. Peripheral device is powered by 2 AA batteries with adequate battery life. Power optimization is not needed.
I'm new to Nordic SDK and started with the ble_app_uart example. I would like to learn about important considerations in moving towards a final app. Here's, generally, how I've migrated ble_app_uart:
1) Removed all use and reference of/to UART as it's not needed. Simply sending data between central and peripheral.
2) Removed all use and reference of/to Board Support Package, and use nrf_gpio directly for IO.
3) Removed Board.c.
4) Replaced NUS UUIDs with our UUIDs.
App functionality is complete and is working well. I'm able to flash to our custom nRF52810 board using the debug out port of the nRF52 dev kit. All appears good.
Given basic requirements, is there more that can be trimmed to reduce app size and complexity?
Is the Queued Write module necessary?
Low and relatively consistent latency of delivery of messages between central and peripheral is important. Is there anything I can do to reduce message delivery latency? I understand there are many factors out of my control, such as the BLE stack on the iOS device and its sharing of RF resources, etc.
I'm using the Logger module (NRF_LOG_INIT, etc.) for debugging. To build and flash release product, how do I essentially turn off logging? Should I be using #define DEBUG and then surround all NRF_LOG statements with #ifdef DEBUG ... #endif, then remove #define DEBUG for building release app?
Anything else for building/flashing a release app?
Enjoying the learning ... thanks for any guidance.
Step 1-3 sound like reasonable choices to optimize size and reduce complexity. There are a few more files you can remove if you don't need logging (nrf_printf, nrf_atomic.c, nrf_ringbuf.c, etc), but I would consider to keep them in so you can more easily re-enable logging if you ever need that. There is not much to gain with regards to flash usage, maybe a couple of KB. Of course, that may be significant if you're starting to run out of memory.
It would probably be ok to remove the Queued Writes module as the ios device should not have to request any queued writes. However, the module is only around 200 bytes with the default setting ('NRF_BLE_QWR_MAX_ATTR' == 0 - reject queued write request), and it will ensure that request is handled if it gets received.
iOS usually honors the preferred connection interval range requested by the peripheral if it follows the Apple recommendations (link - see section 25.6). The lowest interval you typically can get is 15 ms, and you should get that if you request Interval Min == Interval Max == 15 ms.
It should be sufficient to disable the NRF_LOG_ENABLED config option in your sdk_config.h header and recompile. This will exclude the nrf_log_* source files from the build and remove processing of the NRF_LOG_* macros.
I think the main point is to disable logging. Also make sure the app is compiled without DEBUG flag if you want the app to reset if an error occurs: Error module (note: does not include hard faults)
Thank you Vidar. All makes sense.
About disabling logging, in sdk_config.h I:
#define NRF_LOG_ENABLED 0
As expected, app does not log anything, but also does not behave properly. Normally the app reads some data from EEPROM via TWIM (sets some globals), then sets up BLE (ble_stack_init(), gap_params_init(), gatt_init(), services_init(), advertising_init(), conn_params_init()) and starts advertising (advertising_start()). It does not advertise. I've done a bit of tracing but can't make sense of it.
Also, how do I "compile without DEBUG flag"?
Hi Tim, disabling the logger may cause the timing of some of your functions to change, but in most cases, it isn't enough to change the behavior. Please try to place a breakpoint at the beginning of app_error_weak.c::app_error_fault_handler() to see if this function gets invoked when you disable logging (let me know if you have redefined it). Here you can also see if the DEBUG flag has been set or not.