STM32L152xx通过串⼝IAP在线升级(在程序中升级)固
件,Bootloader+app
新年好的祝福语我⽤的芯⽚是STM32L152RET6
IAP(在程序中升级)⼀般是需要写⼀个Bootloader引导程序,对程序进⾏引导。但因项⽬需要,不能单独烧写bootloader程序,所以采⽤在程序中升级,通过读写Flash,跳转的⽅法,省去了单独烧写bootloader。(其实只是把Bootloader加⼊app中,在程序中去引导)
IAP在线升级流程图:思路
APP1:
print(USART1, " APP1 is running! ");
while (1)
{
假期家长对孩子的评价if (UP_flag==1)
{
iap_start(0x8040000);  //写⼊Flash memory Bank 2
}
LL_mDelay(5000);
}
串⼝1输出:APP1 is runing!    main函数直接进⼊⼤循环,等待升级指令,当指令下发,进⼊串⼝中断,标志位置1
void USART1_IRQHandler(void)
{
uint8_t res;
if(LL_USART_IsActiveFlag_RXNE(USART1))
{
if(LL_USART_IsActiveFlag_RXNE(USART1))
{
if(U_RX_CNT<U_RECC_LEN)
{
res=LL_USART_ReceiveData8(USART1);
高尔基童年读书笔记U_RX_BUF[U_RX_CNT]=res;
U_RX_CNT++;
}
}
}
if(U_RX_BUF[0]==0x04)      //0x04表⽰升级指令
{
中国宜居城市UP_flag = 1;        //标志位置1新农村合作医疗
}
}
标志位置1后进⼊iap_start()函数,函数参数为要写⼊Flash地址即程序跳转执⾏地址。在这个函数⾥等待串⼝中断接收APP2升级程序⽂件,接收完成后写⼊Flash Bank 2,并将程序跳转到Flash Bank 2执⾏。
void iap_start(int FLASH_APP_ADDR)
{
u16 oldcount=0;    //原串⼝接收数据值
u16 applenth=0;    //接收到的APP代码长度
u16 page_num = 0;
print(USART1,"iapstart\r\n");
USART1_CLR_RecvBuf();
U_RX_CNT=0;
print(USART1,"等待接收完成\r\n");            //从这⾥进⼊⼤循环,等待串⼝中断接收待升级的APP2数据⽂件
while (1)
{
LL_mDelay(100);
if(U_RX_CNT)
{
if(oldcount==U_RX_CNT)//新周期内,没有收到任何数据,认为本次数据就收完成
{
applenth=U_RX_CNT;
oldcount=0;
U_RX_CNT=0;
print(USART1,"⽤户程序接收完成\r\n");
print(USART1,"开始更新固件库...\r\n");
/**************************擦除FLASH**************************/
HAL_FLASH_Unlock(); //解锁FLASH
page_num = applenth/256 + 1; //计算需要擦除的页数,L152RE每页256字节
FLASH_EraseInitTypeDef f;
f.TypeErase = FLASH_TYPEERASE_PAGES; // 擦除页
f.PageAddress = FLASH_APP_ADDR;  //擦除起始地址
f.NbPages = page_num;  // 擦除的页数
uint32_t PageError = 0;  // 接收错误返回值
王阳妻子
HAL_FLASHEx_Erase(&f, &PageError);  //擦除FLASH
HAL_FLASH_Lock(); //锁Flash
print(USART1,"等待更新...\r\n");
iap_write_appbin(FLASH_APP_ADDR,U_RX_BUF,applenth);
print(USART1,"更新固件完成...\r\n");
if(((*(volatile u32*)(FLASH_APP_ADDR+4))&0xFF000000)==0x08000000)  //判断是否为0x08xxxxxxx,程序开始地址(复位地址)    {
iap_load_app(FLASH_APP_ADDR);          //跳转到Flash Bank 2,执⾏APP2
}else
{
print(USART1,"⾮Flash应⽤程序,⽆法执⾏!\r\n");
}
}else oldcount=U_RX_CNT;
}
}
}
下发升级指令:    等待接收
发送APP2 bin⽂件:
bin⽂件传输完成后等待更新,并跳转执⾏APP2,从串⼝助⼿可以看到,程序已经跳转执⾏APP2了
现在我把掉电源,重新上电,看看是执⾏的哪个程序。  升级成功!