cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB15CC + FreeRTOS: BLE connection drops when writing configuration to internal Flash

joaopaulob
Visitor

 

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.
0 REPLIES 0