Hello!
I'll start by giving some context: custom bootloader created via modifications to the one provided in SDK6.1, then ported to SDK9.0. SD revision 0x0064, running on the 32K version of nrf51822.
We restart into the bootloader from the application, via a proprietary command that triggers the usual code from DFU examples:
/**@brief Function for preparing the reset, disabling SoftDevice and jump to the bootloader.
*/
void bootloader_start(void)
{
uint32_t err_code;
set_gpregret_bitmask(BOOTLOADER_DFU_START);
trace_log("GPREGRET=%08X\n", (unsigned int)get_gpregret());
nrf_delay_ms(100);
reset_prepare();
err_code = sd_softdevice_disable();
APP_ERROR_CHECK(err_code);
interrupts_disable();
err_code = sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR);
APP_ERROR_CHECK(err_code);
bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);
}
Randomly, after rebooting to BL, the SD will return a NRF_ERROR_NO_MEM error (0x004) to the call to sd_ble_enable().
This is the offending (or victim?) code:
// Enable BLE stack
ble_enable_params_t ble_enable_params;
memset(&ble_enable_params, 0, sizeof(ble_enable_params));
ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
// added in an attempt to fix a random NO_MEM error on sd_ble_enable
ble_enable_params.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_MIN*2;
err_code = sd_ble_enable(&ble_enable_params);
APP_ERROR_CHECK(err_code);
On this error from sd_ble_enable, the infocenter just says:
NRF_ERROR_NO_MEM The Attribute Table size is too large. Decrease size in ble_gatts_enable_params_t.
We tried both leaving the default (i.e. leave the ble_enable_params completely zeroed) or reducing the size to BLE_GATTS_ATTR_TAB_SIZE_MIN*2 as shown in the code snippet above, with the same random behaviour: once in a short while (25% of the times, more or less) we get the error, the rest of the times sd_ble_enable() is successful and everything works fine.
The hard part is how to explain the randomness of that: if the ATT table were actually too big, we would have this error each time, right? Right? =) Bring in mind that even when we don't specify the ATT table size, we still memset ble_enable_params to 0, which means "use the default of 0x700", so it shouldn't be a memory uninitialized problem. Also, we can use either Keil or GCC for our builds and we get the same problem in both builds.
Any guesses?
By default