STM32如何下载大数据量APP程
- 前言
- 方法
前言
芯片:STM32F103C8T6
通讯协议:TCP
上位机:自己写的一个上位机,后面会分享
可下载APP大小:最大44K
之前的博客讲了几个硬件的方法解决下载大数据量APP的方法,今天讲一下如何使用软件下载大数据量的APP。
方法
我们把接收到的文件数据,分批下载到Flash里面,之后释放数组等待下一次接收数据,这样我们就实现了边下边收的效果,不占用太大的RAM,APP可下载量只与你Flash的大小有关,下面讲解一下我是如何做的
1.分包接受数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | if(USART1->SR&(1<<5))//?óê?μ?êy?Y {<!-- --> 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("μ??·£o%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函数变成了下面的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | //接受数据 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("ó??§3ìDò?óê?????íê3é!\r\n"); printf("×ü′ú??3¤?è:%dBytes\r\n",applenth); printf("ò??o′?′ú??3¤?è:%d\r\n",OverFlow_CNT*5120); printf("ê£óà′ú??3¤?è:%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("?aê??üD?ê£óà1ì?t...\r\n"); iap_write_appbin(FLASH_APP1_ADDR_CHANGE,USART_RX_BUF,applenth_remain);//?üD?FLASH′ú?? printf("FLASH_APP1_ADDR_CHANGE:%X\r\n",FLASH_APP1_ADDR_CHANGE); printf("1ì?t?üD?íê3é!\r\n"); }else {<!-- --> printf("??óD?éò??üD?μ?1ì?t!\r\n"); } } //执行数据 if(loaddata_flag==1) {<!-- --> loaddata_flag=0; printf("?aê??′DDFLASHó??§′ú??%x!!\r\n",(*(vu32*)(FLASH_APP1_ADDR+4))); if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//?D??ê?·??a0X08XXXXXX. {<!-- --> iap_load_app(FLASH_APP1_ADDR);//?′DDFLASH APP′ú?? }else {<!-- --> printf("·?FLASHó|ó?3ìDò,?T·¨?′DD!\r\n"); } } |
printf里面的东西可以不用管我是为了调试输出的相关信息。
main函数里面是自动跳转的
大家可以看一下,有问题我可以评论告诉我,我改进。
文件下载链接我放到了文章开始的位置。