精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何使用CubeMx生成一個DFU工程

技術讓夢想更偉大 ? 來源:CSDN技術社區 ? 作者:flydream0 ? 2022-10-26 09:31 ? 次閱讀

1 前言

DFU用來做IAP是很方便的,可以直接通過USB來對APP進行升級,因此,掌握DFU的制作還是挺有好處,特別是使用CubeMx工具可以快速制作,本文將基于STM3240G-EVL評估板來一步一步實現一個DFU的IAP工程。

2 制作CubeMx工程

新建一個STM32F407IGHx工程:Pinout:

Peripherals:RCC->High Speed Clock(HSE):Crystal/Ceramic ResonatorSYS->Debug:Serial WireUSB_OTG_FS->Mode:Device_Only

MiddleWaresUSB_DEVICE->Class For FS IP:Download Firmware Update Class(DFU)

再配置PG15腳為GPIO_Input模式。

Clock Configuration:

17fd57a4-5474-11ed-a3b6-dac502259ad0.png

圖1 時鐘樹設置

如上圖,STM3240G-EVAL評估板使用的是25M HSE。Configuration:NVIC中將USB中斷優先級調為5,PG15的標簽設置為USER_BTN,此外還需要設置中間件USB DFU參數,如下圖:

183e14d8-5474-11ed-a3b6-dac502259ad0.png

圖2 USB DFU參數設置

如上圖,紅色框內為需要修改的代碼,0x0800C000為需要為用戶程序APP燒錄的起始地址,字符串“@Internal Flash /0x08000000/03016Ka,01016Kg,01064Kg,07128Kg”實際為USB DFU類的interface字符串描述符,在USB DFU標準文件中有提到可選接口可以使用一個對應的接口字符串來表示此可選接口對應的目標設備的存儲塊信息,但如何具體規定的,DFU標準(DFU_1.1)并沒有要求,是開放的,如下:

1860a408-5474-11ed-a3b6-dac502259ad0.png

圖3 DFU標準對接口字符串定義的描述

由此可見,接口字符串定義是可以自由定義的,那么在這里,由于使用到ST工具軟件DfuSe Demo(v3.0.5),那么這個工具與USB DFU設備就有一個自定義的接口字符串定義,用來表示當前MCU內部的FLASH組織結構。

接下來我們來看看MCU內部FLASH的組織,由于這里的MCU是STM32F407IGHx,找到其參考文檔,并查看其內部FLASH組織結構:

188778da-5474-11ed-a3b6-dac502259ad0.png

圖4 STM32F407內部FLASH的組織結構

如上圖,STM32F407內部FLASH包含4個16K扇區+1個64K扇區+7個128K扇區,并且起始地址為0x0800 0000,所以它對應的接口字符串表示為: “@Internal Flash /0x08000000/03016Ka,01016Kg,01064Kg,07128Kg”, Internal Flash為在工具軟件顯示的名稱,0x08000000為起始地址,03016Ka表示3個16K大小只讀的扇區,01064Kg表示1個64K大小的可讀寫扇區,07*128Kg表示7個128K大小的可讀寫扇區,后綴a表示只讀,后綴g表示可讀寫。這個就是工具軟件DfuSe Demo(v3.0.5)與DFU設備之間的約定。如下:

18c09070-5474-11ed-a3b6-dac502259ad0.png

圖5 DfuSeDemo軟件中所顯示的內部FLASH的可讀寫屬性

知道了這些信息后,我們再回過頭來看APP的起始地址0x0800C000,那么APP的起始地址該如何得來的?有什么要求?與這個接口字符串之間是否有關系?

到目前為止,我們可以確定地是,APP_DEFAULT_ADD的地址必須是位于接口字符串表示的可讀寫的地址范圍內,也就是第4個扇區起(前3個扇區都是只讀的),不然是燒錄不進去的。其他問題我們先暫且放一放,后續我們回過頭來會回答這個問題。

Project Setting :堆設置為0x500,棧大小設置為0x2000。

18deb550-5474-11ed-a3b6-dac502259ad0.png

圖6 堆棧設置

另外,在高級設置中,設置先不調用對USB DFU的初始化:

19047dc6-5474-11ed-a3b6-dac502259ad0.png

圖7 高級設置

最后生成代碼。

3 代碼完善

對生成后的代碼是可以直接編譯通過的,我們這里使用的是IAR,當然你也可以使用MDK,由于不同編譯器編譯的最終文件大小有所差異,而APP的偏移地址在一定程度上也是有考慮到這個DFU本身代碼大小的,接下來我們都將以IAR為例。

打開usbd_duf_if.c文件,這個文件就是USB DFU CLASS與本地對接的接口實現文件,我們需要對這個源文件內沒有接口填充其具體實現內容,當然,我們主要的目的是想借助DFU這個IAP來實現對APP的升級和跳轉,而這些接口就是實現對FLASH讀寫的操作。

uint16_tMEM_If_Init_FS(void)
{
/*USERCODEBEGIN0*/
HAL_FLASH_Unlock();
return(USBD_OK);
/*USERCODEEND0*/
}

如上,初始化實現對FALSH的解鎖。

uint16_tMEM_If_DeInit_FS(void)
{
/*USERCODEBEGIN1*/
HAL_FLASH_Lock();
return(USBD_OK);
/*USERCODEEND1*/
}

對應地,反初始化時,實現對FALSH的上鎖。

uint16_tMEM_If_Erase_FS(uint32_tAdd)
{
/*USERCODEBEGIN2*/
uint32_tstartsector=0;
uint32_tsectornb=0;
/*VariablecontainsFlashoperationstatus*/
HAL_StatusTypeDefstatus;
FLASH_EraseInitTypeDeferaseinitstruct;

/*Getthenumberofsector*/
startsector=GetSector(Add);

eraseinitstruct.TypeErase=FLASH_TYPEERASE_SECTORS;
eraseinitstruct.VoltageRange=FLASH_VOLTAGE_RANGE_3;
eraseinitstruct.Sector=startsector;
eraseinitstruct.NbSectors=1;
status=HAL_FLASHEx_Erase(&eraseinitstruct,§ornb);

if(status!=HAL_OK)
{
return1;
}
return0;
/*USERCODEEND2*/
}

如上,實現對FLASH擦除操作。對應的GetSector函數實現如下:

staticuint32_tGetSector(uint32_tAddress)
{
uint32_tsector=0;

if((Address=ADDR_FLASH_SECTOR_0))
{
sector=FLASH_SECTOR_0;
}
elseif((Address=ADDR_FLASH_SECTOR_1))
{
sector=FLASH_SECTOR_1;
}
elseif((Address=ADDR_FLASH_SECTOR_2))
{
sector=FLASH_SECTOR_2;
}
elseif((Address=ADDR_FLASH_SECTOR_3))
{
sector=FLASH_SECTOR_3;
}
elseif((Address=ADDR_FLASH_SECTOR_4))
{
sector=FLASH_SECTOR_4;
}
elseif((Address=ADDR_FLASH_SECTOR_5))
{
sector=FLASH_SECTOR_5;
}
elseif((Address=ADDR_FLASH_SECTOR_6))
{
sector=FLASH_SECTOR_6;
}
elseif((Address=ADDR_FLASH_SECTOR_7))
{
sector=FLASH_SECTOR_7;
}
elseif((Address=ADDR_FLASH_SECTOR_8))
{
sector=FLASH_SECTOR_8;
}
elseif((Address=ADDR_FLASH_SECTOR_9))
{
sector=FLASH_SECTOR_9;
}
elseif((Address=ADDR_FLASH_SECTOR_10))
{
sector=FLASH_SECTOR_10;
}
else
{
sector=FLASH_SECTOR_11;
}
returnsector;
}

寫操作:

uint16_tMEM_If_Write_FS(uint8_t*src,uint8_t*dest,uint32_tLen)
{
/*USERCODEBEGIN3*/
uint32_ti=0;

for(i=0;i

如上,實現對FLASH的寫操作。

uint8_t*MEM_If_Read_FS(uint8_t*src,uint8_t*dest,uint32_tLen)
{
/*ReturnavalidaddresstoavoidHardFault*/
/*USERCODEBEGIN4*/
uint32_ti=0;
uint8_t*psrc=src;

for(i=0;i

讀FLASH接口實現。

uint16_tMEM_If_GetStatus_FS(uint32_tAdd,uint8_tCmd,uint8_t*buffer)
{
/*USERCODEBEGIN5*/
switch(Cmd)
{
caseDFU_MEDIA_PROGRAM:
buffer[1]=(uint8_t)FLASH_PROGRAM_TIME;
buffer[2]=(uint8_t)(FLASH_PROGRAM_TIME<

獲取狀態接口實現。

接下來實現從DFU跳轉到APP的功能,在main函數中 :

/*USERCODEBEGIN2*/
if(HAL_GPIO_ReadPin(USER_BTN_GPIO_Port,USER_BTN_Pin)==GPIO_PIN_SET)
{
/*Testifusercodeisprogrammedstartingfromaddress0x0800C000*/
if(((*(__IOuint32_t*)USBD_DFU_APP_DEFAULT_ADD)&0x2FFE0000)==0x20000000)
{
/*Jumptouserapplication*/
JumpAddress=*(__IOuint32_t*)(USBD_DFU_APP_DEFAULT_ADD+4);
JumpToApplication=(pFunction)JumpAddress;

/*Initializeuserapplication'sStackPointer*/
__set_MSP(*(__IOuint32_t*)USBD_DFU_APP_DEFAULT_ADD);
JumpToApplication();
}
}
MX_USB_DEVICE_Init();
/*USERCODEEND2*/

這樣代碼就大體修改完了,再次編譯下,生成最終可執行文件。我們得到IAR如下編譯信息:

18170bytesofreadonlycodememory
290bytesofreadonlydatamemory
12517bytesofreadwritedatamemory

那么DFU這個IAP本身所占ROM大小為(18170+290 )/1024 =18.02K,從圖4中我們可以得知,它需要占用兩個扇區(扇區0和1都是16K大小),那么APP至少應該是從扇區2開始。

此時,我們回過頭去看之前提到的APP偏移地址的問題,此處結合之前說到的APP必須是第4個扇區起,那么最終APP的地址應該設置在第4個扇區的起始位置,也就是扇區3的位置,從圖4可知,扇區3的起始位置為0x0800C000,這樣我們回到CubeMx中將其設置,這也就是為什么APP地址設置為0x0800C000的原因。

重新編譯并燒錄進MCU,接下來連接USB到PC,接可是識別這個DFU設備,并通過DfuSeDemo這個軟件升級APP了。

4 制作APP工程需要注意事項

不同編譯器設置方式略有不同,在IAR中:首先將system_stm32f4xx.c文件中找到VECT_TAB_OFFSET宏定義 :

#defineVECT_TAB_OFFSET0xC000
1

即將中斷向量表的偏移位置相應偏移0xC000.接下來修改連接選項 :

191c68c8-5474-11ed-a3b6-dac502259ad0.png1930c296-5474-11ed-a3b6-dac502259ad0.png

圖8 IAR鏈接設置

MDK中:?首先也是修改system_stm32f4xx.c文件中的VECT_TAB_OFFSET宏定義.接著 :

194738d2-5474-11ed-a3b6-dac502259ad0.png

圖9 Target設置

相應設置好了接可以了。

5 測試

最后就是通過ST的軟件Dfu File Manager這個軟件將APP的HEX文件或BIN文件轉化成dfu文件,然后通過DfuSeDemo這個軟件導入dfu文件,最終燒錄APP到0x0800C000這個地址了,最終驗證是可以運行的。

6 總結

APP的起始地址應該設置為扇區的起始地址,且即使沒有重疊,也不能放在IAP的所在扇區。

APP的起始地址必須在USB DFU CLASS接口字符串所描述的可讀寫扇區范圍內。

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • APP
    APP
    +關注

    關注

    33

    文章

    1569

    瀏覽量

    72384
  • IAP
    IAP
    +關注

    關注

    2

    文章

    163

    瀏覽量

    24253
  • CubeMx
    +關注

    關注

    0

    文章

    30

    瀏覽量

    1327

原文標題:如何使用CubeMx生成一個DFU工程

文章出處:【微信號:技術讓夢想更偉大,微信公眾號:技術讓夢想更偉大】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    【CANNON試用體驗】STM32 DFU下載與 DFU生成工具

    方法,都是使用dfufile manager進行轉換,偶然接觸開源項目發現有python的工具可以將 bin轉成dfu。dfu.py,
    發表于 04-23 22:19

    cubemx生成工程有問題

    cubemx自己生成工程就有問題。。為什么啊。。
    發表于 10-11 09:04

    使用CubeMX自動生成工程編譯出錯

    使用CubeMX 自動生成工程編譯出錯 ??工程文件包括 sd卡,網絡,sdram,等,在編譯時提示 HAL_SD_TransferStateTypedef 等找不到,但是我看看
    發表于 11-27 09:01

    修改cubemx,重新生成工程,原有工程自己的代碼有些被刪

    cubemx我最近才開始使用。 現在碰到這樣問題:之前已經有人使用cubemx生成
    發表于 12-27 09:08

    使用CubeMX生成工程文件

    ,使用CubeMX生成工程文件1,配置串口引腳2,時鐘配置3,打開中斷(此圖還不太懂,先記下來,待研究)4,生成代碼備注:此處選為自己所用
    發表于 08-13 06:00

    基于STM32CUBEMX生成工程些步驟

    ,害,上圖做實驗的話是夠用的了2.生成工程因為之前用原子的例程寫了,但是對于我這種懶人來說,還是STM32CUBEMX比較方便,后期開發
    發表于 08-19 07:08

    如何使用stm32 cubeMX配置生成工程?

    如何使用stm32 cubeMX配置生成工程?
    發表于 12-06 06:56

    如何用CubeMX生成工程文件?

    CubeMX移植野火ILI9341觸摸畫板筆記前言前期準備CubeMX配置移植代碼調試感言前言本次移植使用CubeMX和Keil5,大致流程為用CubeMX
    發表于 01-21 07:37

    如何使用STM32CUBEMX生成工程

    使用STM32CUBEMX生成工程IAR+J-LINK調試準備工作CUBEMX生成的代碼問題所在如何改變文本的樣式插入鏈接與圖片如何插入
    發表于 01-27 07:29

    STM32Cubemx生成USB DFU固件升級程序

    STM32Cubemx 生成USB DFU 固件升級程序生成代碼如圖,新建項目工程2. 修改關鍵代碼keil軟件打開
    發表于 02-22 07:03

    使用CubeMX生成TCPEchoServer程序

    使用CubeMX生成TCPEchoServer程序
    發表于 12-08 11:45 ?0次下載

    STM32CubeMX生成SD卡讀寫程序

    本文檔內容介紹了STM32CubeMX生成SD卡讀寫程序,由于本程序是直接操作SD卡的物
    發表于 01-08 11:23 ?57次下載

    STM32CubeMX HAL庫串口+DMA數據發送不定長度數據接收,解決第筆數據無法收發問題

    具:STM32CubeMX 6.01 生成代碼DfuSe V3.0.6 DFU驅動STM32虛擬COM端口驅動程序 在App端需要用到USB虛擬串口來發送進入DFU的指令編譯工具
    發表于 12-20 19:36 ?2次下載
    STM32<b class='flag-5'>CubeMX</b> HAL庫串口+DMA數據發送不定長度數據接收,解決第<b class='flag-5'>一</b>筆數據無法收發問題

    STM32Cube 生成 USB DFU

    STM32Cubemx 生成USB DFU 固件升級程序生成代碼如圖,新建項目工程2. 修改關鍵代碼keil軟件打開
    發表于 12-28 19:45 ?6次下載
    STM32Cube <b class='flag-5'>生成</b> USB <b class='flag-5'>DFU</b>

    使用DFU方案實現STM32單片機的高級開發

    boot引腳來啟動。(具體可參照ST文檔:AN2606)。不過內置DFU的芯片大部分型號都比較新,如果你用的型號沒有內置DFU程序,沒關系我們也可以通過CubeMX來快速生成和移植
    的頭像 發表于 11-28 09:33 ?2633次閱讀