Skip to main content
RGali.1
Visitor II
March 17, 2021
Question

How to correctly access flash memory to erase sectors (operation triggered by a BLE notification) before notifying the operation status through BLE.

  • March 17, 2021
  • 1 reply
  • 680 views

Dear,

My goal is to erase some flash sectors after the receipt of a specific BLE notification ( ChardId = OTAS_STM_BASE_ADDR_ID / Command = OTAS_STM_APPLICATION_UPLOAD) (line 17 in the first code sample). Once the operation done, I should notify the initiator via BLE using the method OTAS_STM_UpdateChar().

The issue is that the notification is correctly read by the initiator if I do not perform the erase operation, and is NOT read by the initiator if I perform the erase operation. Therefore, I suspect this flash erase operation to disturb the BLE protocol.

Here the code dealing with the received notification from the initiator :

switch(p_notification->ChardId)
 {
 	 case OTAS_STM_BASE_ADDR_ID:
 	 {
 		 switch( ((OTA_STM_Base_Addr_Event_Format_t*)(p_notification->pPayload))->Command )
 		 {
 		 	 case OTAS_STM_STOP_ALL_UPLOAD:
 		 		 break;
 
 		 	 case OTAS_STM_WIRELESS_FW_UPLOAD:
 		 		 OTAS_APP_Context.file_type = Wireless_Fw;
 		 		 OTAS_APP_Context.base_address = FLASH_BASE;
 		 		 memcpy( (uint8_t*)&OTAS_APP_Context.base_address, ((OTA_STM_Base_Addr_Event_Format_t*)(p_notification->pPayload))->Base_Addr, p_notification->ValueLength -1 );
 		 		 OTAS_APP_Context.write_value_index = 0;
 		 		 break;
 
 		 	 case OTAS_STM_APPLICATION_UPLOAD:
 		 		 (void)vBOOT_eraseAppSectors();
 
 		 		 OTAS_APP_Context.file_type = Fw_App;
 		 		 OTAS_APP_Context.base_address = MEMORY_MAP_APP_ADDR;
 		 		 OTAS_APP_Context.write_value_index = 0;
 		 		 OTAS_STM_UpdateChar(OTAS_STM_CONF_ID, fw_start_upload_ind);
 
 		 		 IHM_setStateFlag(IHM_STATE_BLE_UPLOADING_NEW_FIRMWARE, true);
 
 		 		 break;
 
 		 	 case OTAS_STM_UPLOAD_FINISHED:
 		 		 OTAS_STM_UpdateChar(OTAS_STM_CONF_ID, fw_received_ok_ind);
 		 		 break;
 
 		 	 case OTAS_STM_CANCEL_UPLOAD:
 		 		 break;
 
 		 	 default:
 		 		 break;
 		 }
 }
 break;

Here the code of the method used to erase flash sectors :

int vBOOT_eraseAppSectors()
{
 int rc;
 
 uint32_t primask_bit;
 
 uint32_t cpu1_sem_status;
 uint32_t cpu2_sem_status = 0;
 
 rc = SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
 if (rc != SHCI_Success)
 return rc;
 
 for(uint8_t i = 0; i < (MEMORY_MAP_APP_SIZE & 0xFF000) >> 12; i++)
 {
 while( LL_HSEM_1StepLock( HSEM, CFG_HW_FLASH_SEMID ) );
 
 rc = HAL_FLASH_Unlock();
 if (rc != HAL_OK)
 return rc;
 
 /* Wait for the BSY bit */
 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0U)
 {
 }
 
 do
 {
 while(LL_FLASH_IsActiveFlag_OperationSuspended());
 
 /* Enter critical section */
 primask_bit = __get_PRIMASK();
 __disable_irq();
 
 cpu1_sem_status = LL_HSEM_GetStatus( HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID );
 
if(cpu1_sem_status == 0)
 {
 cpu2_sem_status = LL_HSEM_1StepLock( HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID );
 
 if(cpu2_sem_status == 0)
 {
 FLASH_PageErase(((MEMORY_MAP_APP_ADDR + (0x1000 * i)) & 0xFF000) >> 12);
 
 LL_HSEM_ReleaseLock( HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, 0 );
 }
 }
 
 /* Exit critical section */
 __set_PRIMASK(primask_bit);
 
 }while(cpu2_sem_status || cpu1_sem_status);
 
 /* Wait for the BSY bit */
 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0U)
 {
 }
 
 rc = HAL_FLASH_Lock();
 if (rc != HAL_OK)
 return rc;
 
 LL_HSEM_ReleaseLock( HSEM, CFG_HW_FLASH_SEMID, 0 );
 
 }
 
 rc = SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
 if (rc != SHCI_Success)
 return rc;
 
 //hci_resume_flow(); ??
 
 return rc;
 
}

Any big mistakes ? Thank you very much for your help !!

Best regards,

Robin

This topic has been closed for replies.

1 reply

ST Employee
April 6, 2021

Hello,

I can read you implemented your own code to erase/write the flash. As I don't see anything specific to your application, I would recommend to switch to the flash driver provided in the BLE_RfWithFlash project.

Regards.