利用stm32計算文件md5值校驗,實現OTA升級


最近做的一個項目需要做OTA升級,使用的芯片是stm32f103c8t6,從阿里雲獲取固件包,並寫入內部flash中,實現在線升級。

 

由於c8t6的內部flash只有64K,sram只有16K,沒辦法在從阿里雲接收數據的過程中同時進行md5值的校驗和寫入內部flash的操作,所以就使用了一個外部flash做緩存,即先將從阿里雲獲得的數據(包括bin文件,文件大小,md5校驗值)寫入外部flash中,然后再將外部flash里面的bin文件1K,1K的讀出來進行md5值的計算,最終與外部flash里的md5值進行比較,如果一致,說明數據沒錯,則將外部flash的bin文件寫入內部flash,再實現程序的跳轉;否則重新向阿里雲請求獲得數據包。以上即為我實現OTA升級的大致邏輯,如果哪位大佬覺得有更好的方案可以一起討論!下面介紹下實現md5值計算和程序跳轉的內容吧。

 

md5值計算

 

 

 以上代碼為md5運算過程的主要計算,全是數學方面的知識,鄙人才疏學淺,原理不是太懂,拿來能用就行啦,哈哈

 

 

 這串代碼的作用是將從外部flash里面讀出的bin文件以4個字節為一組,總共16組的方式填充進x里面,相當於C語言里面的函數fread(&x,4,16,fp),只不過這里的fp不是指向文件,而是讀出來的bin文件的首地址

 

 

 此函數即為實現從外部flash獲取數據進行計算的主要邏輯,首先是將外部flash的數據分別1K,1K的拿出來進行md5()計算,再將最后不足1K的進行計算,不過最后計算的時候需要補上10000000,以及文件長度的二進制,最終即得到文件的md5值,如果對計算出來的結果是否正確存在擔心時,可以利用notepad++計算該bin文件的md5值,進行對比即可

 

 

 

 

最后在簡單說說stm32的IAP是怎么做的

首先在上面計算出md5值之后,如果校驗成功,那么將該bin文件寫入內部flash的指定位置,我是寫到了0x8004000這個位置的,因為stm32的flash的起始地址是0x08000000,則我中間留出了16K的大小寫我的bootloader,在bin文件完全正確的寫入指定地址后,可以使用以下代碼進行程序跳轉

 

 

 

 

 

 不過怎樣去看自己的bin文件是否寫入正確呢?這里推薦使用軟件 ,通過stlink與stm32成功相連后,可以使用這個軟件查看內部flash的值,借此與bin文件進行比較,當然這款軟件不止這一個功能,比如全片flash擦除的等等功能啦

 

 

 

這里再講一個關於待升級的固件程序的配置問題,首先需要將設定為你程序需要跳轉的地方,其次是的將SystemInit()函數里的SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;進行修改,其中VECT_TAB_OFFSET代表了你固件程序中斷向量表的偏移地址;如果不修改,你固件程序中的中斷將無法使用,之前我就遇到過這個問題,對於一個串口接收和發送的程序,在程序跳轉后,能夠發送東西,但是無法收到我傳過去的東西,應該是串口接收中斷沒有起作用。

 

 

最后附上我工程里的一些關鍵性代碼

 

 

  1 #include "md5.h"
  2 
  3 unsigned int A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476,a,b,c,d,flen[2],x[16]; 
  4 u16 i = 0;
  5 u16 j = 0;
  6 u16 k = 0;
  7 
  8 u8 Temp_Ex_Flash[1025]  __attribute__((at(0X20001000)));//¶¨ÒåÔÝʱ´æ´¢1KÍⲿflashÄÚbinÎļþ
  9 
 10 void md5(void){                 //MD5Ö÷Òª¼ÆËã
 11 
 12   a=A,b=B,c=C,d=D;
 13 
 14   FF (a, b, c, d, x[ 0],  7, 0xd76aa478); 
 15   FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); 
 16   FF (c, d, a, b, x[ 2], 17, 0x242070db); 
 17   FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); 
 18   FF (a, b, c, d, x[ 4],  7, 0xf57c0faf); 
 19   FF (d, a, b, c, x[ 5], 12, 0x4787c62a); 
 20   FF (c, d, a, b, x[ 6], 17, 0xa8304613); 
 21   FF (b, c, d, a, x[ 7], 22, 0xfd469501); 
 22   FF (a, b, c, d, x[ 8],  7, 0x698098d8); 
 23   FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); 
 24   FF (c, d, a, b, x[10], 17, 0xffff5bb1); 
 25   FF (b, c, d, a, x[11], 22, 0x895cd7be); 
 26   FF (a, b, c, d, x[12],  7, 0x6b901122); 
 27   FF (d, a, b, c, x[13], 12, 0xfd987193); 
 28   FF (c, d, a, b, x[14], 17, 0xa679438e); 
 29   FF (b, c, d, a, x[15], 22, 0x49b40821); 
 30 
 31 
 32   GG (a, b, c, d, x[ 1],  5, 0xf61e2562); 
 33   GG (d, a, b, c, x[ 6],  9, 0xc040b340); 
 34   GG (c, d, a, b, x[11], 14, 0x265e5a51); 
 35   GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); 
 36   GG (a, b, c, d, x[ 5],  5, 0xd62f105d); 
 37   GG (d, a, b, c, x[10],  9, 0x02441453); 
 38   GG (c, d, a, b, x[15], 14, 0xd8a1e681); 
 39   GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); 
 40   GG (a, b, c, d, x[ 9],  5, 0x21e1cde6); 
 41   GG (d, a, b, c, x[14],  9, 0xc33707d6); 
 42   GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); 
 43   GG (b, c, d, a, x[ 8], 20, 0x455a14ed); 
 44   GG (a, b, c, d, x[13],  5, 0xa9e3e905); 
 45   GG (d, a, b, c, x[ 2],  9, 0xfcefa3f8); 
 46   GG (c, d, a, b, x[ 7], 14, 0x676f02d9); 
 47   GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); 
 48 
 49 
 50   HH (a, b, c, d, x[ 5],  4, 0xfffa3942); 
 51   HH (d, a, b, c, x[ 8], 11, 0x8771f681); 
 52   HH (c, d, a, b, x[11], 16, 0x6d9d6122); 
 53   HH (b, c, d, a, x[14], 23, 0xfde5380c); 
 54   HH (a, b, c, d, x[ 1],  4, 0xa4beea44); 
 55   HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); 
 56   HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); 
 57   HH (b, c, d, a, x[10], 23, 0xbebfbc70); 
 58   HH (a, b, c, d, x[13],  4, 0x289b7ec6); 
 59   HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); 
 60   HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); 
 61   HH (b, c, d, a, x[ 6], 23, 0x04881d05); 
 62   HH (a, b, c, d, x[ 9],  4, 0xd9d4d039); 
 63   HH (d, a, b, c, x[12], 11, 0xe6db99e5); 
 64   HH (c, d, a, b, x[15], 16, 0x1fa27cf8); 
 65   HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); 
 66 
 67 
 68   II (a, b, c, d, x[ 0],  6, 0xf4292244); 
 69   II (d, a, b, c, x[ 7], 10, 0x432aff97); 
 70   II (c, d, a, b, x[14], 15, 0xab9423a7); 
 71   II (b, c, d, a, x[ 5], 21, 0xfc93a039); 
 72   II (a, b, c, d, x[12],  6, 0x655b59c3); 
 73   II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); 
 74   II (c, d, a, b, x[10], 15, 0xffeff47d); 
 75   II (b, c, d, a, x[ 1], 21, 0x85845dd1); 
 76   II (a, b, c, d, x[ 8],  6, 0x6fa87e4f); 
 77   II (d, a, b, c, x[15], 10, 0xfe2ce6e0); 
 78   II (c, d, a, b, x[ 6], 15, 0xa3014314); 
 79   II (b, c, d, a, x[13], 21, 0x4e0811a1); 
 80   II (a, b, c, d, x[ 4],  6, 0xf7537e82); 
 81   II (d, a, b, c, x[11], 10, 0xbd3af235); 
 82   II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); 
 83   II (b, c, d, a, x[ 9], 21, 0xeb86d391); 
 84 
 85   A += a;
 86   B += b;
 87   C += c;
 88   D += d;
 89 
 90 }
 91 
 92 unsigned int sample_index = 0; //´ÓTEST_data²É¼¯64λ¸ö×Ö½Ú
 93 unsigned int data_index = 0;   //binÎļþ×Ö·ûË÷Òý,¹Ì¼þbinÎļþ´óС²»Òª³¬¹ý65K
 94 unsigned int read_times = 0;
 95 unsigned int BIN_location = 0;
 96 
 97 void Read_Group_TEMPBUF(void)
 98 {
 99     memset(x,0,64);    
100     sample_index = 0;
101     for(j = 0;j < 16;j++)//fread(&x,4,16,fp) ÒÔ4×Ö½ÚΪһ×飬¹²16×éÍùxдÈëÊý¾Ý
102     {
103         for(k = 0;k < 4;k++)
104         {
105             if((read_times >= BINLEN/1024)&&(data_index >= BINLEN%1024)) break;//µ±¶Ô×îºóÒ»²¿·ÖСÓÚ1KµÄbinÎļþ´¦Àí
106             
107             ((char*)x)[sample_index] = Temp_Ex_Flash[data_index];
108             data_index++;
109             sample_index++;
110         }
111     }
112 }
113 
114 
115 
116 void Get_Bin_Md5(void)
117 {
118     u16 i = 0;
119     
120     for(read_times = 0;read_times < BINLEN/1024;read_times++)//¶ÔÕûK½øÐÐmd5¼ÆËã
121     {
122         W25QXX_Read(Temp_Ex_Flash,EX_FLASH_SIZE-100*1024+BIN_location,1024);//ÿ´ÎÖ»¶ÁÈ¡1KµÄbinÎļþ
123         BIN_location += 1024;
124         
125         for(i = 0;i < 16;i++)//¸ÕºÃ¶Ô¶Á³öµÄ1KbinÎļþ½øÐÐmd5¼ÆËã 
126         {
127             Read_Group_TEMPBUF();
128             md5();    
129         }
130         data_index = 0;//×î´óÖ»µ½1023
131     }
132     memset(Temp_Ex_Flash,0,1025);
133     W25QXX_Read(Temp_Ex_Flash,EX_FLASH_SIZE-100*1024+BIN_location,BINLEN%1024);
134     
135     
136     Read_Group_TEMPBUF();
137     for(i = 0;i < (BINLEN%1024)/64;i++)
138     {
139         md5();
140         Read_Group_TEMPBUF();
141     }
142     ((char*)x)[BINLEN%64]=128;//Îļþ½áÊø²¹1,0²Ù×÷ 10000000
143     
144     flen[1]=BINLEN/0x20000000;   //ת»»¶þ½øÖÆÎļþ´óС£¨byte->bit£©
145     flen[0]=(BINLEN%0x20000000)*8;
146     
147     if(BINLEN%64>55) md5(),memset(x,0,64);
148     memcpy(x+14,flen,8);
149     md5();
150     printf("MD5 Code:%08x%08x%08x%08x\n",PP(A),PP(B),PP(C),PP(D));
151     
152 }
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
#include "md5.h"
#include "w25qxx.h"

iapfun jump2app; 
u16 iapbuf[1024];   
u8 iap_temp_buf[2048];

void iap_write_appbin(u32 appxaddr,u32 appsize)//³¯ÄÚ²¿flashÖ¸¶¨µØÖ·Ð´ÈëbinÎļþ
{
    u16 i = 0;
    u16 t = 0;
    u16 m = 0;
    u16 temp;
    u16 Binlocation;
    u32 fwaddr=appxaddr;//µ±Ç°Ð´ÈëµÄµØÖ·

    
    for(i = 0;i < appsize/2048;i++)
    {
        W25QXX_Read(iap_temp_buf,EX_FLASH_SIZE-100*1024+Binlocation,2048);//ÿ´ÎÖ»¶ÁÈ¡2KµÄbinÎļþ        
        for(t = 0;t < 2048;t = t+2)//×é³É1KµÄIAPBUF
        {
            temp = (u16)iap_temp_buf[t+1]<<8;
            temp += (u16)iap_temp_buf[t];
            iapbuf[m++] = temp;            
        }
        
        STMFLASH_Write(fwaddr,iapbuf,1024);
        Binlocation += 2048;
        fwaddr+=2048;
        m = 0;
    }
    
    memset(iap_temp_buf,255,2408);
    
    W25QXX_Read(iap_temp_buf,EX_FLASH_SIZE-100*1024+Binlocation,appsize%2048);
    for(t = 0;t < appsize%2048;t = t+2)
    {
        temp = (u16)iap_temp_buf[t+1]<<8;
        temp += (u16)iap_temp_buf[t];
        iapbuf[m++] = temp;    
    }
    STMFLASH_Write(fwaddr,iapbuf,m);    
}


//Ìø×ªµ½Ó¦ÓóÌÐò¶Î
//appxaddr:Óû§´úÂëÆðʼµØÖ·.
void iap_load_app(u32 appxaddr)
{
    if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)    
    { 
        jump2app=(iapfun)*(vu32*)(appxaddr+4);        
        MSR_MSP(*(vu32*)appxaddr);                 
        jump2app();                                    
    }
}         

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM