cancel
Showing results for 
Search instead for 
Did you mean: 

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

RGali.1
Associate

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

1 REPLY 1
Christophe Arnal
ST Employee

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.