(本文主要是主要是对STM32IAP升级功能进行介绍、开放下位机源码、上位机EXE与脚本的使用)
hex格式解析(可参考自己的HEX程序进行验证):
<0x3a>[数据长度1Byte][数据地址2Byte][数据类型1Byte][数据nByte][校验1Byte]<0x0d><0x0a>
数据类型
'00' Data Record 数据
'01' End of File Record 文件结束标志
'02' Extended Segment Address Record 延伸段地址
'03' Start Segment Address Record 起始延伸地址
'04' Extended Linear Address Record 扩展线性地址 也就是基地址
'05' Start Linear Address Record 程序起始地址也就是程序入口地址(main)
IAP的作用与意义
作用:iap就是一个专门用来升级应用程序的程序,可以实现迭代升级程序,使客户能有更好的体验;
意义:一个产品给远在大洋客户,送样前没发现BUG,但客户发现了BUG,你进行修改后需要给客户升级,客户没有专门的烧录设备,这时你需要客户通过IAP升级,可进行IAP升级的方式有很多种(串口、蓝牙、网络);
下位机源码介绍(源码配合上位机包含多个功能,需自行验证)
主要实现的原理:把程序当作数据接收后写入FLASH,然后跳转到相应位置去执行此段写入FLASH的数据;本BL是上电等待一段时间直接跳转APP,如这段时间内有数据,则处理数据,所以升级程序只能在这段时间内发起;主要介绍BL的两个函数,具体代码,见文章结尾网盘(需关注);
协议格式:1Byte帧头(0xFF)+1Byte功能 +2Byte(1Byte现在传输到第几块(下位机+1)+1Byte共传输几块)+2Byte数据长度+1Byte数据异或校验码+1Byte帧尾(0xFE) + nByte发送数据(可有可无,参照数据长度)
注意:无数据错位校验,第一字节错了,整个接收数据都错了
//以下为BL更新FLASH主要部分
void Communication_Information(void)
{
if((USART_RX_CNT != USART_RX_LAST_CNT)&&(Receive_Time_Out >= 50)) //无新数据且在一定事件
{
if(USART_RX_CNT >= Frame_Cnt) //接收数据大于帧头
{
if((USART_RX_BUF[0] == Frame_Heard) && (USART_RX_BUF[7] == Frame_Tail)) //帧头帧尾符合
{
uint16_t len = (USART_RX_BUF[4]<<8) | (USART_RX_BUF[5]<<0); //帧数据长度
if((USART_RX_CNT - Frame_Cnt) >= len) //符合
{
USART_RX_CNT = 0;
uint8_t crc = Ckeck_CRC(&USART_RX_BUF[8],len);
if(crc == USART_RX_BUF[6]) //异或校验
{
if(USART_RX_BUF[1] == updete_software) //CMD
{
if((len > 0) && (USART_RX_BUF[3] > 0))
{
Decryption_Fun(len,(uint8_t*)&USART_RX_BUF[8]); //配合IAP脚本,其有加密功能(替换/异或)
if(USART_RX_BUF[2] == 0)
{
if(((*(vu32*)(0X20000100+(Frame_Cnt + 4))) & 0xFF000000) == 0x08000000)
{
Updata_Fw_True = 1;
Updata_block_cnt = 0;
}
}
if(Updata_Fw_True == 1)
{ //可更新FLASH
iap_write_appbin((FLASH_APP1_ADDR + (Updata_block_cnt* MCU_SECTOR_SIZE)),(uint8_t*)&USART_RX_BUF[8],len);
if(Updata_block_cnt == USART_RX_BUF[3])
{
Updata_Fw_True = 0;
Updata_block_cnt = 0;
Communication_Result_Report(OVER,(protocolCmd_t)USART_RX_BUF[1],USART_RX_BUF[2]);
Rst_Receive_Outtime();
}
else
{
Updata_block_cnt ++;
Communication_Result_Report(NEXT,(protocolCmd_t)USART_RX_BUF[1],USART_RX_BUF[2]); //块写完,可继续下一块
}
}
else
{
Communication_Result_Report(FAIL,(protocolCmd_t)USART_RX_BUF[1],USART_RX_BUF[2]);
#if (Encrypt_Flag == 1)
Encrypt_Cnt = 0;
#endif
}
}
else
{
Updata_Fw_True = 0;
#if (Encrypt_Flag == 1)
Encrypt_Cnt = 0;
#endif
Communication_Result_Report(NEXT,(protocolCmd_t)USART_RX_BUF[1],USART_RX_BUF[2]);
}
}
else
{
Updata_Fw_True = 0;
#if (Encrypt_Flag == 1)
Encrypt_Cnt = 0;
#endif
Choose_Menu((protocolCmd_t)USART_RX_BUF[1],USART_RX_BUF[2]);
}
}
else
{
Communication_Result_Report(CRCERR,(protocolCmd_t)USART_RX_BUF[1],USART_RX_BUF[2]);
Updata_Fw_True = 0;
#if (Encrypt_Flag == 1)
Encrypt_Cnt = 0;
#endif
}
}
}
else
{
Updata_Fw_True = 0;
USART_RX_CNT = 0;
}
}
Rst_Receive_Outtime();
USART_RX_LAST_CNT = USART_RX_CNT;
}
else
{
Receive_Time_Out++;
if(Receive_Time_Out > 240)
{
Receive_Time_Out = 0;
USART_RX_CNT=0;
Updata_Fw_True = 0;
#if (Encrypt_Flag == 1)
Encrypt_Cnt = 0;
#endif
}
}
}
//此信息是BL信息,定义的长度勿动
const usersReport_t Infor_data ={
"****",
"Bootload",
"V0.00.01",
__DATE__,
__TIME__,
"Design Farr Mei",
};
/*
//此信息是APP信息,定义的长度勿动
const usersReport_t Infor_data ={
"****",
"W111",
"V0.00.01_A1",
__DATE__,
__TIME__,
"Design Meijiayou",
};
*/
上位机介绍
将bl生成的bootloade.hex复制置APP工程目录下,FwEncrypt.exe为合并加密等脚本,客参考本人文章HEX合并(https://blog.csdn.net/weixin_43750820/article/details/108906556?spm=1001.2014.3001.5502),
MyConfig.ini一些主要配置介绍,具体还需自己验证,本人不想改了
bl与app的文件,文件名
打开APP工程文件,编译即可生成文件,对应的工程文件下会出现对应的文件;
以下为主要文件,HEX为出厂专业烧录器烧录文件,BIN为IAP烧录专用文件
上位机使用
1:本人使用的是战舰开发板,先将修改后的HEX通过STM32CubeProgrammer烧录进单片机,烧录成功会看到两个LED来回闪烁,打开IAP Updata.exe
其他功能可使用,需自己看,我也忘记了有什么用。。。。。
链接:https://pan.baidu.com/s/14mnzOHGDftmXUjcxrUKHnA
提取码:jglc