前言
芯片:STM32F103C8T6
通讯协议:TCP
上位机:自己写的一个上位机,后面会分享
可下载APP大小:最大44K
之前的博客讲了几个硬件的方法解决下载大数据量APP的方法,今天讲一下如何使用软件下载大数据量的APP。
Bootloader连接:https://download.csdn.net/download/weixin_42148920/12982217
方法
我们把接收到的文件数据,分批下载到Flash里面,之后释放数组等待下一次接收数据,这样我们就实现了边下边收的效果,不占用太大的RAM,APP可下载量只与你Flash的大小有关,下面讲解一下我是如何做的
1.分包接受数据
if(USART1->SR&(1<<5))//½ÓÊÕµ½Êý¾Ý
{
res=USART1->DR;
Rec_Flag=1;
if(res==0xAA)
{
shujutou=1;
}
if(shujutou2==1)
{
if(USART_RX_CNT<USART_REC_LEN)
{
USART_RX_BUF[USART_RX_CNT]=res;
USART_RX_CNT++;
}
}
if(res==0x55&&shujutou==1)
{
shujutou2=1;
}
}
else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
if(USART_RX_CNT==USART_REC_LEN)
{
OverFlow_CNT++;
USART_RX_CNT=0;
iap_write_appbin(FLASH_APP1_ADDR_CHANGE,USART_RX_BUF,USART_REC_LEN);
printf("µØÖ·£º%x\r\n",FLASH_APP1_ADDR_CHANGE);
FLASH_APP1_ADDR_CHANGE+=FLASH_APP1_ADDR_ADD;
if(OverFlow_CNT==File_FullByte)
{
USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
}
}
}
可以看到我用到了一个空闲中断,来接收文件数据,我这里是每接收到5K数据之后,存到Flash里面,释放数组,等待接受,为什么会串口空闲,是因为上位机是自己写的,发送5k会有一个空闲时间,按照这个思路我们就可以把文件分批接收到Flash里面了,剩下的就是跳转了。
千万注意我是参考的正点原子IAP的方法,里面有一句
if((((vu32)(0X20001000+4))&0xFF000000)==0x20000000)
要判断是不是0x20000000,这个判断我理解是判断0X20001000+4这个地址存储的是不是中断向量表,因为我们这个程序是分批接收的文件数据,所以除了第一包数据剩下的这个地址存储的肯定是错的,所以我直接就删掉了。里面加了一个0XAA55的数据头,是因为我上位机用TCP协议发送的,会发一些无关紧要的一些数据所以加了一个数据头在前面
main函数变成了下面的
//接受数据
if(Rec_Flag)
{
delay_ms(1000);
if(oldcount==(OverFlow_CNT*5120+USART_RX_CNT))
{
Rec_Flag=0;
applenth_remain=USART_RX_CNT;
applenth=(OverFlow_CNT*5120+USART_RX_CNT);
oldcount=0;
USART_RX_CNT=0;
printf("Óû§³ÌÐò½ÓÊÕÕû¶ÎÍê³É!\r\n");
printf("×Ü´úÂ볤¶È:%dBytes\r\n",applenth);
printf("ÒÑ»º´æ´úÂ볤¶È:%d\r\n",OverFlow_CNT*5120);
printf("Ê£Óà´úÂ볤¶È:%d\r\n",applenth_remain);
updata_flag=1;
}else oldcount=(OverFlow_CNT*5120+USART_RX_CNT);
}
t++;
delay_ms(10);
if(t==30)
{
t=0;
if(clearflag)
{
clearflag--;
}
}
/*************更新数据***************/
if(updata_flag==1)
{
loaddata_flag=1;
updata_flag=0;
USART_RX_CNT=0;
if(applenth_remain)
{
printf("¿ªÊ¼¸üÐÂÊ£Óà¹Ì¼þ...\r\n");
iap_write_appbin(FLASH_APP1_ADDR_CHANGE,USART_RX_BUF,applenth_remain);//¸üÐÂFLASH´úÂë
printf("FLASH_APP1_ADDR_CHANGE:%X\r\n",FLASH_APP1_ADDR_CHANGE);
printf("¹Ì¼þ¸üÐÂÍê³É!\r\n");
}else
{
printf("ûÓпÉÒÔ¸üеĹ̼þ!\r\n");
}
}
//执行数据
if(loaddata_flag==1)
{
loaddata_flag=0;
printf("¿ªÊ¼Ö´ÐÐFLASHÓû§´úÂë%x!!\r\n",(*(vu32*)(FLASH_APP1_ADDR+4)));
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//ÅжÏÊÇ·ñΪ0X08XXXXXX.
{
iap_load_app(FLASH_APP1_ADDR);//Ö´ÐÐFLASH APP´úÂë
}else
{
printf("·ÇFLASHÓ¦ÓóÌÐò,ÎÞ·¨Ö´ÐÐ!\r\n");
}
}
printf里面的东西可以不用管我是为了调试输出的相关信息。
main函数里面是自动跳转的
大家可以看一下,有问题我可以评论告诉我,我改进。
文件下载链接我放到了文章开始的位置。