///////////////////////////////////////////////////////////////////////////////////////////////////
bool ota_EraseSector(void)
{
nd_FlashUnlock();
FLASH_EraseInitTypeDef FLASH_EraseInitStruct;
FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
FLASH_EraseInitStruct.Sector = FLASH_SECTOR_6;
FLASH_EraseInitStruct.NbSectors = 1;
FLASH_EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
uint32_t SectorError = 0;
return (HAL_OK == HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &SectorError));
}
bool app_EraseSector(void)
{
nd_FlashUnlock();
FLASH_EraseInitTypeDef FLASH_EraseInitStruct;
FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
FLASH_EraseInitStruct.Sector = FLASH_SECTOR_5;
FLASH_EraseInitStruct.NbSectors = 1;
FLASH_EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
uint32_t SectorError = 0;
return (HAL_OK == HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &SectorError));
}
bool config_EraseSector(void)
{
nd_FlashUnlock();
FLASH_EraseInitTypeDef FLASH_EraseInitStruct;
FLASH_EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
FLASH_EraseInitStruct.Sector = FLASH_SECTOR_1;
FLASH_EraseInitStruct.NbSectors = 1;
FLASH_EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
uint32_t SectorError = 0;
return (HAL_OK == HAL_FLASHEx_Erase(&FLASH_EraseInitStruct, &SectorError));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
nd_ota_config_t g_ota_conf = {0};
void load_factory_config(void)
{
nd_flash_read(NDADDR_INFO, (uint8_t *)&g_ota_conf, sizeof(nd_ota_config_t));
}
void save_factory_config(void)
{
nd_FlashUnlock();
nd_flash_write(NDADDR_INFO, (uint8_t *)&g_ota_conf, sizeof(nd_ota_config_t));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
4. 引导代码.
static void exec_application(void) { uint32_t JumpAddress; pFunction Jump_To_Application;
if ((((*(__IO uint32_t *) NDADDR_FW_APP) & 0x2FFE0000) == 0x20000000) /* 检查栈顶地址是否合法 */ || (((*(__IO uint32_t *) NDADDR_FW_APP) & 0xFF000000) == 0x10000000)) { /* Jump to user application */ JumpAddress = *(__IO uint32_t *) (NDADDR_FW_APP + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t *) NDADDR_FW_APP); Jump_To_Application(); } } static void update_app_from_ota(void) { app_EraseSector();
nd_FlashUnlock(); //g_ota_conf.page_cnt * 2K 的 数据从 OTA区 转移到 App区. uint32_t idx_pages, idx_oft; uint32_t src_addr = NDADDR_FW_OTA; uint32_t dst_addr = NDADDR_FW_APP;
for (idx_pages = 0; idx_pages < g_ota_conf.page_cnt; idx_pages++) { nd_flash_write(dst_addr, (uint8_t *)src_addr, FW_PAGE_SIZE); dst_addr += FW_PAGE_SIZE; src_addr += FW_PAGE_SIZE; } } int main(void) { //首先读取 g_ota_conf, 确定是否需要升级. memset(&g_ota_conf, 0, sizeof(g_ota_conf)); load_factory_config();
if (NDADDR_FW_OTA == g_ota_conf.fw_addr) { //不需要升级. //从OTA更新到APP. update_app_from_ota();
//改写配置. if (config_EraseSector()) { g_ota_conf.fw_addr = NDADDR_FW_APP; g_ota_conf.page_cnt = 0; //g_ota_conf.sn = 0x8010191120A90200; save_factory_config(); } }
exec_application(); //升级完毕后, 调用应用端. while (1) { } } |
5. App区
在 main.c 中开始位置写入SCB->VTOR = NDADDR_FW_APP; 即可. 最好的是写在 system_stm32f7xx.c 的 SystemInit的第一行 |
同时设置
同样主要是起始地址 和大小
下面就是实现协议从主机下载固件并更新到 OTA区即可.
发现的问题, IAP到了App时候启动比较慢.
上一篇:Stm32空指令使用
下一篇:STM32 UART/USART 的差别
推荐阅读最新更新时间:2024-11-13 14:23
设计资源 培训 开发板 精华推荐
- STEVAL-ISA185V1,基于 A6985F3V3、38V、0.5A 同步降压开关稳压器的评估板
- 具有直流恢复输出的 ADA4858-3ACPZ-R7 交流耦合视频输入的典型应用电路
- AD9219-65EBZ,用于评估 AD9219 四通道、10 位、65 MSPS 串行 LVDS ADC 的评估板
- LTC1550LCS8 1mVP-P 纹波、-2V 输出 GaAs FET 偏置发生器的典型应用电路
- 用于计算机/外围设备的 DC 到 DC 单路输出电源
- 温湿度计
- 带放大器的R1293K多电源IC的典型应用
- 使用 LTC4162EUFD-L40 1-8 节、3.2A 降压型开关电池充电器和 PowerPath 的典型应用
- 基于VL160的U3转换接头
- AM1/4S-1224SZ 24V 0.25 瓦 DC-DC 转换器的典型应用