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

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

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