前言 在STM32 的系列產(chǎn)品中,很多型號(hào)都帶有USB 接口,為使用USB 來(lái)進(jìn)行代碼升級(jí)提供了便利。這些型號(hào)中又有很大一部分可以通過(guò)芯片內(nèi)部SystemMemory 中的Bootloader 直接進(jìn)行USB DFU 升級(jí),具體哪些型號(hào)支持USB DFU,可參考應(yīng)用筆記AN2606《STM32 微控制器系統(tǒng)存儲(chǔ)器自舉模式》。 不過(guò),有些型號(hào)雖然有USB,但是SystemMemory中的Bootloader 并不支持USB DFU,比如STM32F102 /STM32F103、或者Bootloader V2.x 的STM32F2xxx、STM32F303等等,或者用戶希 望通過(guò)不同的觸發(fā)方式進(jìn)入bootloader 來(lái)進(jìn)行USB 下載,比如接收一串編制好的數(shù)據(jù)來(lái)觸發(fā)。那么,就要使用USB DFU IAP 了。 關(guān)于如何使用USB DFU IAP 的簡(jiǎn)要說(shuō)明,可參考另一份文檔《利用USB DFU 實(shí)現(xiàn)IAP 功能》。在這里,主要介紹在利用USB DFU IAP 例程進(jìn)行移植時(shí),需要注意的兩個(gè)地方。 問(wèn)題一 某客戶在其產(chǎn)品的設(shè)計(jì)中,使用了STM32L073RBT6。客戶在開發(fā)過(guò)程中,使用STM32L0Cube庫(kù)中的STM32L073Z_EVAL的DFU_Standalone 進(jìn)行代碼移植,完成后在使用DfuseDemo 軟件燒寫用戶代碼時(shí)發(fā)生了錯(cuò)誤。 調(diào)研 1.1.了解問(wèn)題 客戶在開發(fā)中使用了STM32L0Cube 庫(kù)STM32Cube_FW_L0_V1.7.0,對(duì)里邊的 \Projects\STM32L073Z_EVAL\Applications\USB_Device\DFU_Standalone例程進(jìn)行修改,以應(yīng)用于用戶板??蛻粢呀?jīng)根據(jù)硬件上的區(qū)別,對(duì)LED 燈和按鍵的I/O 口配置做了相應(yīng)的修改,并在main.h 中使能了USE_USB_CLKSOURCE_CRSHSI48,因?yàn)槠涫褂肧TM32L073 內(nèi)部的48MHz振蕩作為USB 時(shí)鐘源??蛻艟幾g通過(guò)后,使用ST-Link 將其下載到STM32L073RBT6中。然后斷開ST-Link,使用USB 進(jìn)行連接,PC 可以認(rèn)到“STM Devicein DFU Mode”。打開Dfuse Demo 軟件,也可發(fā)現(xiàn)已經(jīng)識(shí)別到STM32L073 處于DFU Mode。 ![]() 但是,當(dāng)用戶選擇了“Verify after download”,并點(diǎn)擊“Choose”按鍵選擇用戶代碼.dfu文件后,并點(diǎn)擊“Upgrade”進(jìn)行燒寫,發(fā)現(xiàn)彈出了提示發(fā)生錯(cuò)誤的對(duì)話框,如下: ![]() 1.2.問(wèn)題分析 STM32L073Z_EVAL 開發(fā)板使用的芯片型號(hào)為STM32L073VZT6,其Flash 容量為192KB,地址從0x08000000 到0x0802FFFF。而客戶所使用的STM32L073RBT6,其Flash 容量為128KB,地址從0x08000000 到0x0801FFFF。檢查項(xiàng)目中的usbd_conf.h文件中的代碼,客戶并未作任何修改,也就是說(shuō),以下兩個(gè)定義沒(méi)有根據(jù)實(shí)際的型號(hào)進(jìn)行修改: /* Startuser code address:ADDR_FLASH_PAGE_120 */ #defineUSBD_DFU_APP_DEFAULT_ADD 0x08003C00 /*Startaddress of latest flash page: ADDR_FLASH_PAGE_1535*/ #define USBD_DFU_APP_END_ADD0x0802FF80 USBD_DFU_APP_DEFAULT_ADD 和USBD_DFU_APP_END_ADD定義了用戶代碼空間的開始頁(yè)和結(jié)束頁(yè)。從這可以看出,用戶代碼是從0x08003C00 開始的,也就是第120 頁(yè),而結(jié)束于第1535 頁(yè)。STM32L073VZT6從第0 頁(yè)到第1535 頁(yè)共1536 頁(yè),每頁(yè)128 Bytes??蛻羰褂玫氖荢TM32L073RBT6,總共才1024 頁(yè)。顯然,這里對(duì)USBD_DFU_APP_END_ADD的定義并不對(duì),需要修改為第1023 頁(yè)的地址。 1.3.問(wèn)題解決 將usbd_conf.h 中的USBD_DFU_APP_END_ADD修改為第1023 頁(yè)的地址: /* Startaddress of latest flash page: ADDR_FLASH_PAGE_1023 */ #defineUSBD_DFU_APP_END_ADD 0x0801FF80 問(wèn)題解決,USB DFU 可以下載代碼了。別急,接著往下看第二個(gè)話題。 問(wèn)題二 在上面問(wèn)題的解決過(guò)程中,有沒(méi)有注意到Dfuse Demo 界面中顯示“1536 sectors”?這明顯不對(duì),來(lái)看看怎么修改。 調(diào)研 2.1.了解問(wèn)題 在Dfuse Demo 界面中,雙擊“1536 sectors”,可以看到Internal Flash 的詳細(xì)信息,如下: ![]() 2.2.問(wèn)題分析 從上圖可以了解到,實(shí)際上這里所定義的Sector的大小為128Bytes,也就是STM32L073 的Page,所以這里的Sector定義與STM32L073 的參考手冊(cè)定義的Sector 是不一樣的,不要造成誤解。在RM0367 中,每128Bytes 為1 個(gè)Page,每32 個(gè)Page 才是1 個(gè)Sector。所以不要誤會(huì)了。在這個(gè)Mapping 窗口中,也可以看到地址0x08003C00之前的空間為Read only,也就是Bootloader 所處的空間為只讀,以避免對(duì)這部分代碼的重寫。而后面的空間,也就是用戶代碼所處的空間為Read/Write/Erase。 這些信息是從哪里來(lái)的呢?其實(shí)它來(lái)自于usbd_dfu_flash.c 里邊定義的描述符FLASH_DESC_STR,如下: #define FLASH_DESC_STR "@Internal Flash /0x08000000/120*128 a,1416*128g" 來(lái)解釋一下這個(gè)描述符的內(nèi)容: 0x08000000 為起始地址?!癮”代表的是Read-only,“g”代表Read/Write/Erase。也就是說(shuō),“a”所指明的區(qū)域?yàn)锽ootloader 的空間,“g”所指明的區(qū)別為用戶代碼空間。大小由前面的數(shù)字決定,星號(hào)“*”前面的為Sector 的個(gè)數(shù),后面的為Sector 的大小,這里的意思就是從0x08000000 開始,前面120 個(gè)Sector(每個(gè)Sector 為128 字節(jié))為Read-only,后面1416 個(gè)Sector(每個(gè)Sector 為128 字節(jié))為Read/Write/Erase。 再舉另外一個(gè)例子,在\Projects\STM32L053C8-Discovery\Applications\USB_Device\DFU_Standalone\Src下的 usbd_dfu_flash.c 是這樣定義的: #define FLASH_DESC_STR "@Internal Flash/0x08000000/28*01Ka,36*01Kg" 它的意思就是前面28 個(gè)Sector(每個(gè)Sector 為1KB)為Read-only,后面36 個(gè)Sector(每個(gè)Sector 為1KB)為Read/Write/Erase。因?yàn)樵谶@個(gè)例子中,用戶代碼起始地址為0x08007000。在Dfuse Demo 的界面中,你也將看到只有64個(gè)Sector,雙擊打開后能看到每個(gè)Sector 為1KB。 搞明白了這個(gè)事,就知道如何去修改這個(gè)描述符FLASH_DESC_STR,讓它符合STM32L073RBT6的大小。 3.3.問(wèn)題解決 STM32L073RBT6 有1024 頁(yè),每頁(yè)128 字節(jié),所以需要修改描述符FLASH_DESC_STR 定義如下: #define FLASH_DESC_STR "@Internal Flash/0x08000000/120*128B a,904*128B g" 話題延伸: 如果用戶代碼空間的定義是這樣的: /* Start user code address:ADDR_FLASH_PAGE_120 */ #define USBD_DFU_APP_DEFAULT_ADD 0x08003C00 /* Start address of latest flash page: ADDR_FLASH_PAGE_1023 */ #define USBD_DFU_APP_END_ADD 0x0801FF80 但是描述符FLASH_DESC_STR 的定義修改為: #define FLASH_DESC_STR "@Internal Flash /0x08000000/28*01K a,100*01K g" 那會(huì)發(fā)生什么情況呢? 將Bootloader程序編譯后燒寫到STM32L073 中,然后使用USB 接口進(jìn)行連接,打開Dfuse Demo。首先,可以看到界面中顯示的就是128 Sectors,雙擊打開,每個(gè)Secotor 大小為1KB。 接下來(lái),來(lái)燒寫一個(gè)用戶代碼,從0x08003c00 地址開始的。在Verify 時(shí),就會(huì)彈出錯(cuò)誤的對(duì)話框: 驗(yàn)證在0x08003C00 的地址就已經(jīng)發(fā)生了錯(cuò)誤:燒錄文件該地址的數(shù)據(jù)為0x58,但是讀回來(lái)的是0x00。這是因?yàn)槲覀儼衙枋龇鸉LASH_DESC_STR錯(cuò)誤地定義成了前面28KB 為Read-only,也就是從0x08007000 開始才是可讀/可寫/可擦除的。所以,在0x08007000 之前的空間是不可擦除和寫入的,也就導(dǎo)致了這樣的情況。 這個(gè)延伸話題也只是為了強(qiáng)調(diào)這個(gè)描述符FLASH_DESC_STR 的重要性。 結(jié)論 使用USB DFU IAP 參考例程進(jìn)行移植的時(shí)候,Bootloader 的空間以及用戶代碼的空間的定義都需要根據(jù)具體的STM32芯片型號(hào)進(jìn)行調(diào)整修改。 文章來(lái)源于網(wǎng)絡(luò) |
|