STM32 HAL OTA 小白教程
1. OTA基础知识 2. 手把手教你写Boot Loader(引导程序) 3. OTA理论基础
提示:这一系列文章还没有更新完... ...
前言
感谢这些前辈分享的资料, 在此我只是整理了前辈们的资料,然后使用通俗易懂的方法再介绍给大家,方便大家学习
一、OTA基础知识
我是懒得再写了,这里有个很完整的 OTA基础知识链接
二、创建Boot Loader(引导程序)
1.ota_bootloader.h
代码如下(示例):
#ifndef __OTA_BOOTLOADER_H
#define __OTA_BOOTLOADER_H
#include "main.h"
#include <stdbool.h>
#define BLOCK_BOOTLOADER_START ((uint32_t)0x08000000)
#define BLCOK_SYS_PARAM_START ((uint32_t)0x08004000)
#define UPDATE_FLASH_FLAG 0x08004000
#define BLOCK_APP1_START ((uint32_t)0x08008000)
#define BLOCK_APP2_START ((uint32_t)0x08040000)
#define BLCOK_APP2_SPACE ((uint32_t)224*1024)
typedef void (*pFunction)(void);
void FlashErase(uint32_t StartAddress);
void FlashWrite(uint32_t StartAddress,uint32_t data);
uint32_t FlashRead(uint32_t StartAddress);
void jump_to_app(uint32_t app_addr);
bool check_update_flag(void);
void FlashErases(uint32_t StartAddress,uint8_t num);
void updateInterface_CopyCode_FromApp2ToApp1(void);
#endif
2.ota_bootloader.c
代码如下(示例):
#include "ota_bootloader.h"
uint32_t sectStartAddr[8]=
{
0x08000000,
0x08004000,
0x08008000,
0x0800c000,
0x08010000,
0x08020000,
0x08040000,
0x08060000
};
int GetSectorFromAddress(uint32_t address)
{
int sect;
if( address < 0x08000000 || address > 0x0807FFFF )
return -1;
for( int i=0; i<8; i++ )
{
if( address >= sectStartAddr[i] && address < sectStartAddr[i+1] )
{
sect = i;
break;
}
}
return sect;
}
void FlashErase(uint32_t StartAddress)
{
int sect = 0;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
sect = GetSectorFromAddress(StartAddress);
FLASH_Erase_Sector(sect,FLASH_VOLTAGE_RANGE_3);
HAL_FLASH_Lock();
}
void FlashErases(uint32_t StartAddress,uint8_t num)
{
int sect = 0;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
sect = GetSectorFromAddress(StartAddress);
for(uint8_t i = 0;i<num;i++)
{
FLASH_Erase_Sector(sect+i,FLASH_VOLTAGE_RANGE_3);
FLASH_WaitForLastOperation(1000);
}
HAL_FLASH_Lock();
}
void FlashWrite(uint32_t StartAddress,uint32_t data)
{
HAL_FLASH_Unlock();
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,StartAddress,data);
HAL_FLASH_Lock();
}
uint32_t FlashRead(uint32_t StartAddress)
{
return *(uint32_t *)StartAddress;
}
bool check_update_flag(void)
{
bool status = false;
if (FlashRead(UPDATE_FLASH_FLAG) == 0x55555555)
{
status = true;
}
return status;
}
void updateInterface_CopyCode_FromApp2ToApp1(void)
{
uint32_t i = 0;
for (i = 0; i < BLCOK_APP2_SPACE; i += 4)
{
FlashWrite(BLOCK_APP1_START + i, *(uint32_t *)(BLOCK_APP2_START + i));
}
}
void jump_to_app(uint32_t app_addr)
{
pFunction jump_to_application;
if (((*(__IO uint32_t*)app_addr) & 0x2FFE0000 ) == 0x20000000)
{
jump_to_application = (pFunction)*(__IO uint32_t*) (app_addr + 4);
__set_MSP(*(__IO uint32_t*) app_addr);
jump_to_application();
}
}
3. 查看引导程序的大小
生成 bin 文件
总结
结合视频看更加详细 下一篇介绍怎么写APP程序
|