OTA简介:
OTA的全称是Over-The-Air,在嵌入式系统中指对某个嵌入式系统的软件在线升级。就MCU系统来说,是针对整个MCU的Firmware进行在线更新,所以也称之为FOTA。也有一种叫法是DFU,即Device firmware upgrade。都是相同的意思,这里统一使用OTA表达。
通用MCU一般是没有无线功能的,所以对MCU的OTA一般用于双芯片实现的系统,无线芯片接收MCU的ota文件,通过串口或USB传给MCU,实现MCU的ota功能。
独立的引导加载程序(Standlone Bootloader):
独立引导加载程序是使用外部通信接口(UART/USB)获取应用程序文件。固件更新是一个单阶段过程,将应用程序文件分批直接写入闪存,覆盖现有的应用程序,而无需应用程序本身的参与。独立引导加载程序和在闪存中运行的应用程序之间几乎没有交互。引导加载程序运行后,通过物理连接(UART/USB)接收包含新固件的固件更新数据包。当固件更新过程启动时,新代码会覆盖现有的堆栈和应用程序代码。如果在此过程中发生任何错误,则应用程序将无法恢复,必须重新开始该过程。
应用引导加载程序(Application Bootloader):
应用引导加载程序在运行的应用程序完全下载更新映像文件后才会开始固件更新过程。 应用引导加载程序期望镜像位于引导加载程序可访问的外部存储器中或主闪存的中。
应用引导加载程序依靠应用程序来获取新的固件镜像。 应用程序可以通过通信接口(UART/USB)下载此镜像,并将其存储在称为下载空间的区域(OTA storage)。 当新镜像下载完毕并存储后,将调用应用引导加载程序以验证新映像并将其从下载空间复制到应用程序的闪存地址(Application)。
软件实现方法:
独立的引导加载程序较多使用xmodem协议。无线模块和MCU都遵守xmodem协议(128 byte one time),无线模块遵循xmodem协议通过串口传输镜像文件,MCU构建一个支持xmodem协议的bootloader,将收到的镜像文件写入到相应的flash地址。
- 在Bootloader中获取固件
- 不需要存储升级固件
- 固件下载过程中,设备没有功能
- Bootloader接收到升级固件后直接覆盖掉现有应用程序
应用引导加载程序一般要把MCU需要将Flash划分为3部分:Bootloader, Application, OTA storage。应用程序从通信接口(UART/USB)接收无线模块发来的数据,每接收一包就放在存储区(OTA storage),当所有数据收完了应用软件就重启,运行权交给bootloader,bootloader把存储工的软件写到应用软件区,并跳转到应用软件运行。
- 在应用程序中或缺升级固件
- 升级固件存储在内部flash中
- 升级前可以校验升级固件的完整性和安全性
- Bootloader从内部闪存中读取升级固件
- 固件下载过程中,设备功能正常运行
MCU较常用的ota方式为Application bootloader
Application Bootloader软件运行流程:
Application Bootloader核心参考代码:
#define OFFSET_APPLICATION 0x2000
#define OFFSET_OTA_STORAGE 0x9000
uint8_t update_firmware(void)
{
uint32_t src,obj;
uint8_t t;
uint32_t offset;
src = OFFSET_OTA_STORAGE;
obj = OFFSET_APPLICATION;
//31 is the flash size value
for(t = 0; t < 31; t ++)
{
//1024 is the flash page size value, should change according with spicific chip type
offset = t * 1024;
if(Read_Flash(value,src + offset,1024) == ERROR)
{
return ERROR;
}
if(Earse_Flash(obj + offset) == ERROR)
{
return ERROR;
}
if(Write_Flash(obj + offset,value,1024) == ERROR)
{
return ERROR;
}
}
}
void main (void)
{
uint32_t OTA_status_flag;
uint32_t app_address;
Read_Flash((unsigned char *)&OTA_status_flag,OTA_FLAG_ADDR,4);
if(OTA_status_flag == FIREWARE_UPDATE_FLAG)
{
if(update_firmware() != SUCCESS)
{
Reset();
}
}
app_address = OFFSET_APPLICATION;
JumpToApp(app_address);
while(1)
{
}
}
应用程序接收OTA镜像的处理流程:
#define OFFSET_APPLICATION 0x2000
#define OFFSET_OTA_STORAGE 0x9000
#define FIREWARE_SPECIAL_FLAG 0x5555AAAA
unsigned char STM32_firm_update_handle(const unsigned char value[],unsigned long position)
{
unsigned long addr;
if(ota_Finish_Flag)
{
ota_finish_Data = FIREWARE_SPECIAL_FLAG;
if(Earse_Flash(OTA_FINISH_FLAG) == ERROR)
return ERROR;
if(Write_Flash(OTA_FINISH_FLAG,(unsigned char *)&ota_finish_Data,sizeof(ota_finish_Data)) == ERROR)
return ERROR;
Reset();
}
else
{
addr = OFFSET_OTA_STORAGE;
if(position % 1024 == 0)
{
if(Earse_Flash(addr + position) == ERROR)
return ERROR;
}
if(Write_Flash(addr + position,(unsigned char *)value,length) == ERROR)
return ERROR;
}
return SUCCESS;
}
优快云博客仅作为本人工作学习之余的笔记使用,无任何商业目的,如果侵犯了你的隐私或权益,请随时联系作者,本人将及时删除相关内容。