一直在想设计OTA方案,使用开源的软件工具实现OTA,因为涉及较多,暂未完成。。。

关于OTA设计,可以先参考IAP:【IAP】IAP在线升级流程,涉及对芯片BootLoader和flash操作;升级数据下发又涉及使用哪种网络协议等,还有等等。。。言归正传。

对不同芯片的flash的操作不太相同,也有类似的地方。STM32L43xx系列:每页2k数据,单bank。

STM32G4系列:双bank ,每个bank 128页。

所以在设计时要对内部flash(暂时不说外部flash)正确划分、操作, 认真查看手册,官方例程。他们才是最熟悉芯片。

 擦除结构体:

参数1:选择哪种擦除方式

参数2:擦除所在bank区

参数3:擦除页(从多少页开始擦除)

参数4:擦除多少页

typedef struct
{
  uint32_t TypeErase;   /*!< Mass erase or page erase.
                             This parameter can be a value of @ref FLASH_Type_Erase */
  uint32_t Banks;       /*!< Select bank to erase.
                             This parameter must be a value of @ref FLASH_Banks
                             (FLASH_BANK_BOTH should be used only for mass erase) */
  uint32_t Page;        /*!< Initial Flash page to erase when page erase is disabled.
                             This parameter must be a value between 0 and (max number of pages in the bank - 1)
                             (eg : 127 for 512KB dual bank) */
  uint32_t NbPages;     /*!< Number of pages to be erased.
                             This parameter must be a value between 1 and (max number of pages in the bank - value of initial page)*/
} FLASH_EraseInitTypeDef;

这两个函数很重要。。。获得地址所在页,获得地址所在bank 。

static uint32_t GetPage(uint32_t Addr)
{
  uint32_t page = 0;

  if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
  {
    /* Bank 1 */
    page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
  }
  else
  {
    /* Bank 2 */
    page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
  }

  return page;
}

/**
  * @brief  Gets the bank of a given address
  * @param  Addr: Address of the FLASH Memory
  * @retval The bank of a given address
  */
static uint32_t GetBank(uint32_t Addr)
{
  return FLASH_BANK_1;
}

擦数据函数: 

if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
  {


}

向flash中写入数据:双字写64位数据。

if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, DATA_64) == HAL_OK)
    {
      Address = Address + 8;  /* increment to next double word*/
1地址,1字节数据
    }

flash中数据: 

 

while (Address < FLASH_USER_END_ADDR)
  {
    data32 = *(__IO uint32_t *)Address;

    if (data32 != DATA_32)
    {
      MemoryProgramStatus++;
    }
    Address = Address + 4;
  }
单字读数据

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐