那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何使用CubeMx生成一個(gè)DFU工程

技術(shù)讓夢(mèng)想更偉大 ? 來源:CSDN技術(shù)社區(qū) ? 作者:flydream0 ? 2022-10-26 09:31 ? 次閱讀

1 前言

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

2 制作CubeMx工程

新建一個(gè)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 時(shí)鐘樹設(shè)置

如上圖,STM3240G-EVAL評(píng)估板使用的是25M HSE。Configuration:NVIC中將USB中斷優(yōu)先級(jí)調(diào)為5,PG15的標(biāo)簽設(shè)置為USER_BTN,此外還需要設(shè)置中間件USB DFU參數(shù),如下圖:

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

圖2 USB DFU參數(shù)設(shè)置

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

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

圖3 DFU標(biāo)準(zhǔn)對(duì)接口字符串定義的描述

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

接下來我們來看看MCU內(nèi)部FLASH的組織,由于這里的MCU是STM32F407IGHx,找到其參考文檔,并查看其內(nèi)部FLASH組織結(jié)構(gòu):

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

圖4 STM32F407內(nèi)部FLASH的組織結(jié)構(gòu)

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

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

圖5 DfuSeDemo軟件中所顯示的內(nèi)部FLASH的可讀寫屬性

知道了這些信息后,我們?cè)倩剡^頭來看APP的起始地址0x0800C000,那么APP的起始地址該如何得來的?有什么要求?與這個(gè)接口字符串之間是否有關(guān)系?

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

Project Setting :堆設(shè)置為0x500,棧大小設(shè)置為0x2000。

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

圖6 堆棧設(shè)置

另外,在高級(jí)設(shè)置中,設(shè)置先不調(diào)用對(duì)USB DFU的初始化:

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

圖7 高級(jí)設(shè)置

最后生成代碼。

3 代碼完善

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

打開usbd_duf_if.c文件,這個(gè)文件就是USB DFU CLASS與本地對(duì)接的接口實(shí)現(xiàn)文件,我們需要對(duì)這個(gè)源文件內(nèi)沒有接口填充其具體實(shí)現(xiàn)內(nèi)容,當(dāng)然,我們主要的目的是想借助DFU這個(gè)IAP來實(shí)現(xiàn)對(duì)APP的升級(jí)和跳轉(zhuǎn),而這些接口就是實(shí)現(xiàn)對(duì)FLASH讀寫的操作。

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

如上,初始化實(shí)現(xiàn)對(duì)FALSH的解鎖。

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

對(duì)應(yīng)地,反初始化時(shí),實(shí)現(xiàn)對(duì)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*/
}

如上,實(shí)現(xiàn)對(duì)FLASH擦除操作。對(duì)應(yīng)的GetSector函數(shù)實(shí)現(xiàn)如下:

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

如上,實(shí)現(xiàn)對(duì)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接口實(shí)現(xiàn)。

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<

獲取狀態(tài)接口實(shí)現(xiàn)。

接下來實(shí)現(xiàn)從DFU跳轉(zhuǎn)到APP的功能,在main函數(shù)中 :

/*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*/

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

18170bytesofreadonlycodememory
290bytesofreadonlydatamemory
12517bytesofreadwritedatamemory

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

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

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

4 制作APP工程需要注意事項(xiàng)

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

#defineVECT_TAB_OFFSET0xC000
1

即將中斷向量表的偏移位置相應(yīng)偏移0xC000.接下來修改連接選項(xiàng) :

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

圖8 IAR鏈接設(shè)置

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

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

圖9 Target設(shè)置

相應(yīng)設(shè)置好了接可以了。

5 測試

最后就是通過ST的軟件Dfu File Manager這個(gè)軟件將APP的HEX文件或BIN文件轉(zhuǎn)化成dfu文件,然后通過DfuSeDemo這個(gè)軟件導(dǎo)入dfu文件,最終燒錄APP到0x0800C000這個(gè)地址了,最終驗(yàn)證是可以運(yùn)行的。

6 總結(jié)

APP的起始地址應(yīng)該設(shè)置為扇區(qū)的起始地址,且即使沒有重疊,也不能放在IAP的所在扇區(qū)。

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

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • APP
    APP
    +關(guān)注

    關(guān)注

    33

    文章

    1577

    瀏覽量

    72774
  • IAP
    IAP
    +關(guān)注

    關(guān)注

    2

    文章

    164

    瀏覽量

    24388
  • CubeMx
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    1378

原文標(biāo)題:如何使用CubeMx生成一個(gè)DFU工程

文章出處:【微信號(hào):技術(shù)讓夢(mèng)想更偉大,微信公眾號(hào):技術(shù)讓夢(mèng)想更偉大】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用stm32cubeMX無法生成mdk工程文件?

    幾年前使用過cubemx,可以生成keil的工程文件。最近有個(gè)工程使用cubemx創(chuàng)建,結(jié)果只能
    發(fā)表于 01-04 20:03

    【CANNON試用體驗(yàn)】STM32 DFU下載與 DFU生成工具

    方法,都是使用dfufile manager進(jìn)行轉(zhuǎn)換,偶然接觸個(gè)開源項(xiàng)目發(fā)現(xiàn)有個(gè)python的工具可以將 bin轉(zhuǎn)成dfudfu.py,
    發(fā)表于 04-23 22:19

    cubemx生成工程有問題

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

    使用CubeMX自動(dòng)生成工程編譯出錯(cuò)

    使用CubeMX 自動(dòng)生成工程編譯出錯(cuò) ??工程文件包括 sd卡,網(wǎng)絡(luò),sdram,等,在編譯時(shí)提示 HAL_SD_TransferStateTypedef 等找不到,但是我看看
    發(fā)表于 11-27 09:01

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

    cubemx我最近才開始使用。 現(xiàn)在碰到這樣個(gè)問題:之前已經(jīng)有人使用cubemx生成
    發(fā)表于 12-27 09:08

    使用CubeMX生成工程文件

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

    基于STM32CUBEMX生成工程些步驟

    ,害,上圖做實(shí)驗(yàn)的話是夠用的了2.生成工程因?yàn)橹坝迷拥睦虒懥?b class='flag-5'>一個(gè),但是對(duì)于我這種懶人來說,還是STM32CUBEMX比較方便,后期開發(fā)
    發(fā)表于 08-19 07:08

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

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

    如何用CubeMX生成個(gè)工程文件?

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

    如何使用STM32CUBEMX生成工程

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

    STM32Cubemx生成USB DFU固件升級(jí)程序

    STM32Cubemx 生成USB DFU 固件升級(jí)程序生成代碼如圖,新建項(xiàng)目工程2. 修改關(guān)鍵代碼keil軟件打開
    發(fā)表于 02-22 07:03

    使用CubeMX生成TCPEchoServer程序

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

    STM32CubeMX生成個(gè)SD卡讀寫程序

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

    STM32Cube 生成 USB DFU

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

    使用DFU方案實(shí)現(xiàn)STM32單片機(jī)的高級(jí)開發(fā)

    boot引腳來啟動(dòng)。(具體可參照ST文檔:AN2606)。不過內(nèi)置DFU的芯片大部分型號(hào)都比較新,如果你用的型號(hào)沒有內(nèi)置DFU程序,沒關(guān)系我們也可以通過CubeMX來快速生成和移植
    的頭像 發(fā)表于 11-28 09:33 ?2890次閱讀
    万龙百家乐官网的玩法技巧和规则 | 网上百家乐官网能作弊吗| 百家乐官网最常见的路子| 百家乐vshow| 博发百家乐官网游戏| 百家乐开户代理| bet365备用主页器| 大西洋百家乐官网的玩法技巧和规则 | 百家乐官网网站加盟| 豪博百家乐娱乐城| 百家乐官网博彩博彩网| 百家乐最新分析仪| 香港六合彩码报| 线上百家乐官网手机版| 百家乐庄闲必胜手段| 贵南县| 澳门百家乐怎赌才能赚钱| 赌博娱乐场| 百家乐赌博筹码大不大| 百家乐官网网上投注作弊| 百家乐注码技术打法| 澳门百家乐官网职业| 大发888娱乐场118| 百家乐官网制胜软件| 新葡京百家乐的玩法技巧和规则 | 百家乐关键词| 利来国际网上娱乐| 万达百家乐官网娱乐城| 尉氏县| 菲彩百家乐官网的玩法技巧和规则| 威尼斯人娱乐城线路lm0| 易胜博百家乐官网娱乐城| 大发888投注网| 百家乐游戏资料网| 水城县| 百家乐六手变化混合赢家打法| 百家乐官网娱乐求指点呀| 大发888娱乐场1888| 百家乐注册下注平台| 百家乐官网陷阱| 威尼斯人娱乐城官方网站|