Question
STM32WB15CC + FreeRTOS: BLE connection drops when writing configuration to internal Flash
Hardware: STM32 NUCLEO-WB15CC (STM32WB15CCUX)
RTOS: FreeRTOS
BLE stack: STM32WB WPAN / BLE via CPU2 (M0+)
Hi,
When writing a small configuration block (~48 bytes) to the internal Flash from CPU1 (M4 FreeRTOS task), the BLE connection drops immediately. The disconnect event is received on the host side with no prior warning, and the firmware logs a HCI_DISCONNECTION_COMPLETE_EVT shortly after the Flash erase/write sequence begins.
The Flash region used is a dedicated 2 KB NVM page at address 0x0801B000 (defined in the linker script as FLASH_NVM):
FLASH_NVM (rx) : ORIGIN = 0x0801B000, LENGTH = 2K
--- Data Written ---
The payload written is 48 bytes (already 8-byte aligned), structured as:
[magic: uint32_t (4 B)] [Config_t (40 B)] [checksum: uint32_t (4 B)]
The Config_t struct:
typedef struct {
uint16_t volume_shown;
uint16_t client_timeout_ms;
uint16_t cup_detection_threshold;
uint16_t flow_timeout_forward_ms;
uint16_t flow_timeout_backward_ms;
uint16_t foam_ms;
uint16_t foam_decay_minutes;
uint16_t foam_ms_after_decay;
uint16_t steps_forward;
uint16_t steps_backward;
uint16_t step_increment;
uint16_t tick;
uint8_t use_hall_positioning;
uint8_t offline_operation;
uint8_t com_mode;
uint8_t integration_zig;
float adjust;
char serial_number[4];
RGB_Color_t led_color; // 3 bytes (r, g, b)
} Config_t; // sizeof = 40 bytes
--- Flash Write Code (CPU1 / M4, FreeRTOS task) ---
Erase (FlashStorage_Erase):
FlashStorage_Status_t FlashStorage_Erase(void)
{
FLASH_EraseInitTypeDef erase_config;
uint32_t page_error = 0U;
uint32_t base = storage_base_addr(); // 0x0801B000
uint32_t page = (base - FLASH_BASE) / FLASH_PAGE_SIZE;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
erase_config.TypeErase = FLASH_TYPEERASE_PAGES;
erase_config.Page = page;
erase_config.NbPages = 1U;
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase_config, &page_error);
HAL_FLASH_Lock();
return (status == HAL_OK) ? FLASH_STORAGE_OK : FLASH_STORAGE_ERROR_ERASE;
}
Write (FlashStorage_Write):
FlashStorage_Status_t FlashStorage_Write(uint32_t offset, const void *data, uint32_t size)
{
uint32_t address = storage_base_addr() + offset; // 0x0801B000 + 0
const uint64_t *src=(const uint64_t *)data;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
for (uint32_t i = 0U; i < (size / 8U); i++) {
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, src[i]);
address += 8U;
}
HAL_FLASH_Lock();
return FLASH_STORAGE_OK;
}
Call site (Config_SaveToFlash):
void Config_SaveToFlash(void)
{
uint8_t buf[128];
uint32_t magic = CONFIG_FLASH_MAGIC;
uint32_t new_checksum = compute_config_checksum(&config, sizeof(Config_t));
if (new_checksum == last_saved_checksum) return;
memset(buf, 0xFF, sizeof(buf));
memcpy(buf, &magic, 4);
memcpy(buf + 4, &config, sizeof(Config_t));
memcpy(buf + 4 + sizeof(Config_t), &new_checksum, 4);
FlashStorage_Erase();
FlashStorage_Write(0, buf, 48);
last_saved_checksum = new_checksum;
}
--- Deferred Save Strategy ---
Config_SaveToFlash() is called from a FreeRTOS task via a deferred mechanism: when a configuration command is received over BLE (GATT write on a custom NUS-style RX characteristic), a pending flag is set and the actual write is delayed by 3000 ms. The task polls Config_ProcessPendingSave() periodically:
void Config_RequestSaveToFlash(void) {
save_pending = true;
save_request_tick = xTaskGetTickCount();
}
void Config_ProcessPendingSave(void) {
if (!save_pending) return;
if ((xTaskGetTickCount() - save_request_tick) < pdMS_TO_TICKS(3000)) return;
save_pending = false;
Config_SaveToFlash();
}
Even with this 3-second delay, the BLE connection still drops at the moment HAL_FLASHEx_Erase() is called.
--- Questions ---
1. On STM32WB15CC, does a Flash erase/write from CPU1 stall CPU2 (M0+) long enough to cause a supervision timeout or HCI timeout? Is the FLASH_NVM page at 0x0801B000 in a region shared with the BLE stack firmware?
2. Should SHCI_C2_FLASH_EraseActivity() be called before/after the erase to notify CPU2? Is this function available and applicable on the WB15?
3. Is there a recommended pattern for safely writing to internal Flash while maintaining an active BLE connection on STM32WB15, using FreeRTOS?
Any guidance is appreciated. Thank you.