06-STM32+ESP8266+AIR202遠程升級方案-移植STM32+ESP8266實現利用http或https遠程更新STM32程序到自己的項目(定時訪問升級,備份升級)


<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_B/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

 

移植BootLoader

1.凡是和ESP8266類似,通過串口配置通信的模塊都可參照此節移植.

如果做項目,請大家必須使用STM32F103CBT6 及其以上的Flash>=128KB的單片機.

2.用戶移植的時候首先保證自己的程序已經可以控制模塊實現TCP通信(模塊作為客戶端)

3.我准備了一份空模板

該模板只有一個定時器,延時,串口

因為每個人寫的程序都不一樣,我假設我的模板也實現了控制模塊實現TCP通信.

然后現在我就想移植我寫的程序到一個新的工程里面作為BootLoader引導程序.

 

 

 

 

 

 

 

 4.我復制出來一份空模板作為BootLoader

 

 

 

 

5.把BootLoader移植文件里面的BootLoader和mem文件夾復制到自己的工程

 

 

 

6.把文件添加到工程,並包涵下.h路徑

 

 

 

 

7.需要添加操作 flash的庫

 

 

 

補充:(鑒於用戶可能使用的其它單片機,庫可能不一樣,Flash操作不一樣)

注意:用戶可以先把里面的實際操作程序屏蔽,只留一個空函數.

待整體編譯沒有錯誤以后再來根據自己的庫實現這部分!

 

補充1:Flash寫函數 void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)

升級程序會調用此函數存儲相關數據.

 

 

 

 

補充2:Flash寫函數  char WriteFlashHalfWord(uint32_t WriteAddress,u16 data)

該函數用於將程序數據寫入Flash

 

 

 

 

補充3: Flash讀函數  void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead) 

該函數用於從Flash里面讀取數據

 

 

 

補充4: Flash擦除函數 char FlashErasePage(uint32_t EraseAddress,u16 PageCnt)

注意:假設需要擦除20KB,BootLoader會傳進來20.

BootLoader里面只是傳進來需要擦除的KB數.

 

如果自己的單片機是以1024字節一頁,那么此函數直接控制擦除20頁即可.

如果自己的單片機是以2048作為一頁,那么此函數就應該擦除10頁!

所以源碼里面有一句 if(STM_SECTOR_SIZE==2048){PageCnt=PageCnt/2;}

 

 

 

 

 

8.編譯工程,打開第一個錯誤

 

 

 

 

 

9.添加上自己的延時1ms函數

 

 

 

 

 

 

10,接着看下面兩個錯誤

下面兩個地方是向模塊發送get指令

 

 

 

 

11,我的8266模塊配置上TCP連接Web服務器以后如果是透傳模式下我直接往串口發送數據

數據就會被8266轉發出去

如果不是透傳模式下,https的時候模塊就不支持透傳,我需要先發送AT+CIPSEND=數據個數

然后等模塊返回 < 以后我再發送數據

所以我的修改如下(假設我是用串口1和wifi模塊通訊)

 

 

 

 

 

12,把 IAPTimerOut(); 函數放到1ms定時器中斷函數里面

 

 

 

 

 

13, 在主程序里面寫上以下程序

 

 

 

注:AutoConnectTCP()函數是控制模塊連接web服務器的函數,客戶需要根據自己的程序實現此功能

連接的IP地址為: IAPStructValue.IP(字符串形式)   連接的端口號為:IAPStructValue.Port

連接成功以后返回 1

上面的IP地址和端口號是根據固件程序地址解析出來的

還有一個參數 IAPStructValue.SSLEN ; 0:http  1:https

如果客戶使用的也是8266,可以參考測試升級源碼中的例子.

 

 

 

如果客戶需要把字符串形式的IP地址轉換為數組形式,可使用下面的轉化函數

/**
*@brief        檢查字符串地址是IP還是域名
*@param        str 要轉換的數據
*@param        ip  轉換后存儲的位置
*@return     0:轉換失敗,可能是域名   1:轉換成功
*@example  UTILS_StrToIP("192.168.0.1", &ip) ip[0]=192;ip[1]=168;ip[2]=0;ip[3]=1;
*/ 
uint8 UTILS_StrToIP(const char* str, void *ip)
{
        /* The count of the number of bytes processed. */
        int i;
        /* A pointer to the next digit to process. */
        const char * start;

        start = str;
        for (i = 0; i < 4; i++) {
            /* The digit being processed. */
            char c;
            /* The value of this byte. */
            int n = 0;
            while (1) {
                c = * start;
                start++;
                if (c >= '0' && c <= '9') {
                    n *= 10;
                    n += c - '0';
                }
                /* We insist on stopping at "." if we are still parsing
                   the first, second, or third numbers. If we have reached
                   the end of the numbers, we will allow any character. */
                else if ((i < 3 && c == '.') || i == 3) {
                    break;
                }
                else {
                    return 0;
                }
            }
            if (n >= 256) {
                return 0;
            }
            ((uint8_t*)ip)[i] = n;
        }
        return 1;

}

 

13.如果使用的是DTU,因為DTU本身就自動連接和透傳

可以屏蔽掉判斷

 

 

 

 

 

14,把 IAPPutDataToLoopList(char Res); IAPHttpHead(char Res);

函數放到和模塊通信的串口中斷里面

 

 

15,如果模塊不是透傳模式,還需要修改接收數據部分

一般不是透傳模式,模塊接收每一條數據的開頭都會攜帶着其它自己添加的信息

假設ESP8266在非透傳模式下接收到123個數據,返回給單片機的數據為:

\r\n+IPD,123:真實數據

用戶可以參考下面的剔除程序,修改為自己的剔除程序.

客戶修改做的就是把真實數據寫入環形隊列.

 

 

 

16,設置下默認的固件程序下載地址(根據自己的服務器修改)

 

 

17,建議在BootLoader程序里面打開看門狗

可直接把我提供的升級源碼中的看門狗復制過來

 

 

 

 

18,屏蔽掉BootLoader程序里面使用的中斷

用戶需要把自己的中斷函數放到此處關閉!

 

 

 

 

19,關於日志打印口(必須有,便於查看Flash分配情況和更新過程)

所有的日志都是使用的printf函數打印

printf打印不得和控制網絡模塊的串口沖突!

printf打印最好加上緩存,中斷發送方式(建議環形隊列+中斷)

如果用戶用 USART_SendData(其它串口,c); 等類似的阻塞型的函數實現printf

請屏蔽以下部分

 

 

 

 

 

 

 

20,設置工程生成bin文件,然后編譯下工程.

 

 

 

 

21,根據bin文件大小在 stmflash.h中調整下flash分配

STM32_FLASH_SIZE  根據自己的單片機容量調整

 

如果使用的是128KB Flash的單片機:

FLASH_IAP_SIZE XX   根據BootLoader生成的bin文件大小設置(該值需要大於生成的bin文件大小)

FLASH_UPDATE_SIZE 1  //存儲更新相關數據所有FLASH大小,不需要改動.

FLASH_USERDATA_SIZE XX  如果用戶存儲的數據量比較大,增加該值即可

 

如果使用的是256KB及其以上 Flash的單片機:

FLASH_IAP_SIZE XX   根據BootLoader生成的bin文件大小設置(該值需要大於生成的bin文件大小,設置為4的倍數)

FLASH_UPDATE_SIZE 4  //存儲更新相關數據所有FLASH大小,設置為4

FLASH_USERDATA_SIZE XX  如果用戶存儲的數據量比較大,增加該值即可(設置為4的倍數)

 

 

 

 

22,當前BootLoader程序已經移植完成

為防止意外情況,我提供的遠程升級源碼中增加了崩潰處理程序.

客戶根據自己的情況參考移植使用!

重新設置URL

 

 

 

配置模塊連接路由器

 

 

 

APUConfig配網

 

 

 

 

 

移植用戶程序

1.我復制了一份空模板假設作為了用戶程序

 

 

 

2.把BootLoader移植文件里面的BootLoader和mem文件夾復制到自己的工程

 

 

 

 

3.把文件添加到工程,並包涵下.h路徑

 

 

 

 

4.需要添加操作 flash的庫

 

5.打開 IAP.h文件 設置 IAPProgramSelect 為 IAPUserProgram

 

 

 

 

6.屏蔽掉下面部分

 

 

 

 

7.去掉屏蔽

 

 

 

 

8.修改型號和info.txt文件的下載地址(根據自己的情況修改)

 

 

 

 

9.編譯下工程,打開下面的錯誤

 

 

 

10.把自己的延時函數放到此處

 

 

 

 

 

 

 

11.調整用戶程序stmflash.h文件里面的配置

和BootLoader程序里面的保持一致

和BootLoader程序里面的保持一致!

和BootLoader程序里面的保持一致!

 

 

 

 

12.把BootLoader程序編譯下,下載到單片機,根據打印的信息調整用戶程序配置

SCB->VTOR = FLASH_BASE | 0xXXXX;

 

 

 

 

 

 

 

13,在主函數里面添加以下函數

 

 

 

 

14,自行增加使用get指令訪問info.txt文件命令

連接的服務器的IP地址 IAPStructValue.IP(字符串)   端口號 IAPStructValue.Port

文件路徑 IAPStructValue.Path

以上信息是由 IAPInfoPathInit();函數解析而來

連接訪問參考原用戶程序:

 

 

 

15,解析獲取的文件信息

info.txt文件內容:

{"version":"0.0.1","size":15990,"url":"http://mnif.cn/ota/hardware/STM32ESP8266BK/user_crc.bin","info":"1.解決了部分BUG
2.優化了部分程序"}

 

判斷版本號,本地版本號存儲在 FirmwareVersion

 

 

 

如果版本還不一致,把固件程序大小和固件程序下載地址調用相應的函數存儲

void IAPSetUpdateUrl(char* ch)  //存儲url

void IAPSetFileSize(u32 data)    //存儲size

 

然后設置更新標志,重啟即可

IAPSetUpdateFlage();

IAPResetMCU();

 

16,至此用戶程序也移植完成!

移植完成以后,用戶按照我先前提供的測試流程測試.

由於我本人是當局者,可能會忽略到一些細節,

如果客戶遇到什么問題,請聯系我,我將根據客戶的反饋完善此節文章.

 


免責聲明!

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



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