<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,至此用戶程序也移植完成!
移植完成以后,用戶按照我先前提供的測試流程測試.
由於我本人是當局者,可能會忽略到一些細節,
如果客戶遇到什么問題,請聯系我,我將根據客戶的反饋完善此節文章.