历史上的今天
今天是:2025年08月21日(星期四)
2018年08月21日 | STM32 IAP程序升级
2018-08-21 来源:eefocus
硬件平台:STM32F103ZET6的最小系统,512K Flash 64KRAM
Bootloader区:0x08000000 ----- 0x08010000 64K
APP区: 0x080010000 ----- 0x08080000 448K
1.Bootloader部分
#define ApplicationAddress 0x08010000 //app存放的起始地址
#define ApplicationPages 224
#define App1Address 0x20001000 //app程序中接收的更新程序存放在RAM中,起始地址为0x20001000,试验的程序代码比较小
#ifdef iap
if(((*(__IO uint32_t*)(App1Address+4))& 0x2FFE0000 ) == 0x20000000 && (*(__IO uint32_t*)App1Address)!=0)
{
printf("There is a new app program,now preapring to update the fermware.");
printf("Erasing flash¡¡");
FLASH_Unlock();
for(i=0;i
status=FLASH_ErasePage(ApplicationAddress+i*0x400);
}
FLASH_Lock();
printf("Erase flash ok!!!");
printf("Programing flash¡¡");
FlashProgram(ApplicationAddress,(*(__IO uint32_t*)App1Address),(uint8_t *)(App1Address+4));
printf("Programe flash ok!!!");
printf("Jump to app_main!!!");
*(__IO uint32_t*)App1Address = 0;
JumpAddress = (iapfun)*(__IO uint32_t*) (ApplicationAddress+4);
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
JumpAddress();
}
else if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
printf("Jump to app_main!!!");
JumpAddress = (iapfun)*(__IO uint32_t*) (ApplicationAddress+4);
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
JumpAddress();
}
else
{
printf("Jump to app_main failed!\n\r");
}
#endif
(1)上电时检测有无更新文件,有更新文件时,根据指定的App长度将新程序拷贝到App的Flash区
(2)跳转到APP的FLASH区执行app程序
2.APP程序的串口接收程序
struct
{
uint32_t length;
uint8_t ReceiveDatebuff1[RecvLength];
}app_program __attribute__ ((at(0X20001000)));
void USART1_IRQHandler()
{
uint8_t ReceiveData;
if(!(USART_GetITStatus(USART1,USART_IT_RXNE)));
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
if(recievestatus==0)
{
ReceiveData=USART_ReceiveData(USART1);
if(ReceiveData==0x55)recievestatus=1;
printf("prepared for recieve a new app program!");
}
else if(recievestatus==1)
{
ReceiveData=USART_ReceiveData(USART1);
if(recievelength < RecvLength)
{
app_program.ReceiveDatebuff1[recievelength++]=ReceiveData;
}
if(app_program.ReceiveDatebuff1[recievelength-1]==0x55
&&app_program.ReceiveDatebuff1[recievelength-2]==0x55)
{
recievelength-=2;
app_program.length=recievelength;
recievestatus=2;
printf("Recieved a new app program!");
printf("please press enter to update the new program");
}
}
else if(recievestatus==2)
{
ReceiveData=USART_ReceiveData(USART1);
if(ReceiveData==0x13)
{
NVIC_SystemReset();
}
}
}
}
(1)接收0x55,指示准备接收更新程序
(2)发送app.bin文件,APP程序接收后存放在RAM中指定的地址0X20001000处,并记录app长度
(3)接收0x5555,指示接收APP更新程序结束,准备好更新操作
(4)接收0x13,启动更新操作,软复位,跳转至Bootloader处重启
实现的功能很简单,在APP中接收更新程序,再跳转到Bootloader中去更新;这里没有做任何的出错检验,只是简单的演示下IAP的过程。
(1)BIN文件在通过串口接收时,速率过快可能会出错,可以将波特率调低些做实验
(2)接收APP更新程序可以在APP中也可以在Bootloader中,获取更新文件的途径可以为串口、USB、SD卡、can等
(3)更新文件的存放可以是任何的存储设备,只要足够大的空间即可;
(4)为了更新的准确性和可操作性,无线方式应考虑BIN的分包断点续传;更新前旧APP程序的备份;数据的校验;
史海拾趣
|
上周举办的北京车展无疑是中国汽车圈最受瞩目的盛事,不过在车展揭幕以前,首先碰到的却是一家汽车零件业巨头——美国江森自控公司。该公司宣布在中国推出瓦尔塔品牌的汽车蓄电池,同时更加引起我注意的是,有关人员还透露说,该公司在混合动力轿车 ...… 查看全部问答> |
|
我对LPC2148定时器的捕获功能很糊涂, 哪位可以帮忙解释一下?当我把一个管脚设置成捕获功能后, 如果我把这个管脚和一个外置时钟连接, 我能否对这个时钟的上升, 下降沿进行捕获? 计数控制寄存器(CTCR) 和捕获控制寄存器(CCR)有什么区别? 谢 ...… 查看全部问答> |
|
外部晶振选用的4.096MHz,电容C1和C2都是20pF,电阻RF是1M。 觉得外部晶振没有起振呢,测晶振两脚的电压,各是0.37V,0.47V。 ICS的工作模式是使用FLL的外部模式FEE。 不知道原因出在哪了? 还请高手指点,谢谢~… 查看全部问答> |
|
各位大虾: 我用ST-LINK和J-LINK通过JTAG或者SWD方式都可以给目标板下载程序,但是换另外一块板子,只引出VDD GND JTMS JCLK 对其无论使用JLINK还是STLINK都无法下载,已确认用3v电池供电,求助!!!… 查看全部问答> |




