STM32F103C8T6串口IAP大数据量APP下载(不局限于RAM的大小)

it2023-02-23  94

STM32如何下载大数据量APP程

前言方法

前言

芯片: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函数里面是自动跳转的

大家可以看一下,有问题我可以评论告诉我,我改进。 文件下载链接我放到了文章开始的位置。

最新回复(0)