STM32 IAP BootLoader總結(C#上位機+單片機程序)

本文章原創,不講解代碼,只幫助梳理思緒,幫助理解demo程序。

一、首先要清楚什麼是IAP?摘抄一段話,大家感受一下

       ISP:In System Programming (在系統中編程),通過芯片專用的串行編程接口對其內部的程序存儲器進行擦寫。

       IAP:In Application Programming( 在應用中編程),通過調用特定的bootloader程序,對程序存儲器的指定段進行讀/寫操作,從而實現對目標板的程序的修改。

        簡單來說ISP就是平時我們用JLINK之類的下載器通過專門的SWD接口來下載程序,IAP就是通過調用bootloader來充當下載器的功能實現更新程序的作用。

        bootloader是IAP不可缺少的,它存在於用戶APP程序(即我們真正具有實現某種功能的單片機程序)之前,單片機一上電後執行的程序。本質上bootloader的也是一個完整的程序,有main函數,中斷向量表,棧頂指針,它可以檢查有沒有新的固件,如果有,則將新的固件的數據寫入到我們指定的flash地址中,之後跳到新的程序中去就OK了。下圖爲bootloader和APP存儲於flash中的位置。

 

二、根據上述實現IAP的過程,有四個問題,程序從哪裏來,何時更新,如何更新,更新完成後呢?下面就這四點,簡單闡述。

  • 程序從哪裏來

         我的實驗是基於上位機,下位機是STM32F103RCT6的,通過PC的串口發送數據來升級下位機單片機程序。上位機用的是C#,通過調用函數讀取bin文件(STM32如何生成bin文件參考最下面資料或自行百度),並保存在緩存中,等待傳輸。

  • 什麼時候更新

        當然是收到指令的時候,指令從哪裏下達?上位機軟件通過PC串口下發給單片機。可以想象,當我們單擊上位機下載按鈕,就是讓上位機下發了指令傳給了單片機,單片機收到指令反饋給上位機(這個過程就叫“握手”)。然後開始執行更新程序。我定義的握手協議是上位機下發字符串“AABBCC”,當單片機接收後判斷一致後反饋給上位機字符串“DDEEFF”,此時表示握手成功,準備更新。

  • 如何更新

       更新的過程無非是把舊的程序擦除,把新的程序寫入進單片機。如何擦除flash,如何寫入flash並不難,demo程序裏有說明,重要的是這個過程需要上位機PC與下位機單片機之間定義一個協議。有了協議我們就能知道上位機何時下發的數據開始存入、何時下發的數據表示完成、一次發送了多少數據、還有多少數據沒有傳輸完、收發數據是否一致等等。demo程序中每次下發 2k Byte 數據,每次校驗一致再下發數據,否則重新發送。具體內容參見demo程序。

       包頭表示一幀數據的開始,當單片機收到0x5A時開始緩存上位機下發的數據,當單片機收到包尾0xAA表示上位機下發完一幀數據,當單片機收到包尾0xF5,0x5F兩個字節表示上位機下發完最後一幀數據。

幀協議如下:

上位機發送協議
包頭 幀序列 數據  包尾 校驗
0x5A 1 byte 2048 byte

0xAA

0xF5,0x5F(尾幀)

 1 byte
上位機接收協議(下位機發送)
包頭 幀序列 校驗 包尾
0x5A 1 byte 1byte

0xAA

0xF5,0x5F(尾幀)

 

  • 更新完成後

        前面說過了,bootloader程序是存在於用戶APP程序之前的,所以更新過後,我們需要跳轉到用戶APP程序中。具體如何跳轉參見最下方參考資料或者我的demo程序裏。

三、需要注意的點

1、keil工程設置

        需要準備兩個工程,一個爲bootloader,一個爲APP。bootloader通過ISP下載,APP編譯生成bin文件通過IAP下載。實驗中將flash分了幾個區域,bootloader存儲於0x08000000地址處,分配的大小爲0x5000字節,用戶APP存儲於0x08005000處,分配大小爲0x30000個字節。預留的容量多少根據單片機flash及程序大小而定,比如我選用的爲STM32F103RCT5, flash大小爲256KB = 256*1024 = 0x40000,我把前0x0~0x4FFF用於存儲bootloader,0x5000~0x34FFF用於存儲APP,其它爲預留。

        bootloader工程文件設置如下

         APP工程文件設置如下

2、中斷向量偏移地址

     

        理解了STM32它的運行流程就能明白爲什麼設置它。STM32F1中存在一箇中斷向量表,它存放在代碼起始後4個字節處(即0x08000004),代碼開始的4個字節存放的是堆棧棧頂地址,當發生中斷後,程序通過查找該表得到相應的中斷服務程序入口地址,再跳到相應的中斷服務程序中執行。

        流程:上電後從0x08000004處取出復位中斷向量的地址,再跳轉到復位中斷程序的入口(標號①所示),執行結束後跳轉到main函數中(標號②所示)。在執行main函數的過程中如果發生中斷,則強制將PC指針指回中斷向量表處(標號③所示),從中斷向量表中找到相應的中斷函數入口地址,跳轉到相應的中斷服務函數(標號④所示),執行完中斷函數後再返回到main函數中來(標號⑤所示)。

        bootloader和APP都是一樣的流程,只不過存放到flash的不同地址處,相當於單片機裏存放了兩個子程序。 由於bootloader程序從0x08000000地址處開始,用戶APP程序從0x08005000處開始,所以APP的中斷向量表偏移0x5000。

       bootloader程序main函數中需添加如下一段代碼

        APP程序main函數中需添加如下一段代碼

3、參考資料如下,參考如下內容能幫助你理解一些細節。

https://blog.csdn.net/jxgxlm2008/article/details/78677681

https://blog.csdn.net/tq384998430/article/details/81010002

https://www.cnblogs.com/ZzJan/p/11564060.html

https://blog.csdn.net/qq_23229787/article/details/84579567

https://www.cnblogs.com/wanjianjun777/p/10252303.html

https://wenku.baidu.com/view/e831d14728ea81c759f57842.html

四、實驗結果

發佈了2 篇原創文章 · 獲贊 8 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章