www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]本程序編寫(xiě)基于秉火霸道STM32F103ZET6運(yùn)行環(huán)境。 最近疫情期間,特地將自己大部分硬件資源全部用熱膠搶焊到了一起,以便以后自己復(fù)習(xí)和學(xué)習(xí),當(dāng)然還有很多,弄不上來(lái)了,只能等以后有機(jī)會(huì)再重新搞一塊!我還是非常舍得花錢(qián)買(mǎi)設(shè)備的!哈哈!這是一個(gè)STM32+Linu














本程序編寫(xiě)基于秉火霸道STM32F103ZET6運(yùn)行環(huán)境。

最近疫情期間,特地將自己大部分硬件資源全部用熱膠搶焊到了一起,以便以后自己復(fù)習(xí)和學(xué)習(xí),當(dāng)然還有很多,弄不上來(lái)了,只能等以后有機(jī)會(huì)再重新搞一塊!我還是非常舍得花錢(qián)買(mǎi)設(shè)備的!哈哈!這是一個(gè)STM32+Linux+51的大雜燴開(kāi)發(fā)平臺(tái)!

1、產(chǎn)生問(wèn)題

公司的產(chǎn)品,每次生產(chǎn)燒寫(xiě)程序都得把機(jī)器拆開(kāi),然后插上串行線或者ST-Link進(jìn)行燒寫(xiě),產(chǎn)品量產(chǎn)的情況下數(shù)量很多,所以生產(chǎn)每次都需要花費(fèi)很長(zhǎng)去時(shí)間去給機(jī)器燒程序(這里我們用野火的開(kāi)發(fā)板來(lái)模擬)。

2、現(xiàn)有的硬件接口

現(xiàn)在的產(chǎn)品(野火的STM32F103ZET6開(kāi)發(fā)板)有一個(gè)USB接口,硬件連接圖如下:

如上圖所示,當(dāng)PD3為低電平的時(shí)候,USB接口供電,即可用,這一點(diǎn)在上一篇文章已經(jīng)講解了,我們?cè)赟TM32CubeMX把這個(gè)管腳默認(rèn)拉低即可。

3、分析問(wèn)題

STM32CubeMX支持了與USB相關(guān)的諸多配置功能,請(qǐng)看如下:

于我們需要使用USB接口來(lái)更新程序,所以我們需要在配置USB設(shè)備模式的時(shí)候給它選擇Download Firmware Update Class(DFU)。

1、USB燒寫(xiě)原理及流程分析

1.1 燒寫(xiě)原理

這點(diǎn)與IAP升級(jí)是大同小異的,只不過(guò)這里我們使用了USB來(lái)燒寫(xiě),之前寫(xiě)過(guò)類似的一篇文章:帶串口屏顯示的BootLoader程序開(kāi)發(fā) 在這篇文章里面也介紹了相應(yīng)的原理,這里就不再重復(fù)描述,我們負(fù)責(zé)把這篇文章里提到的幾點(diǎn)實(shí)現(xiàn)就可以了。

1.2 程序存儲(chǔ)分區(qū)

STM32F103ZET6的FLASH容量一共有512KB。所以,我給BootLoader的大小是64K,也就是0x10000,具體是怎么算的呢?

0x10000轉(zhuǎn)十進(jìn)制為65536,65536/1024 = 64K

把剩下的空間全部分配給APP,也就是0x70000,具體是怎么算的呢?

0x70000轉(zhuǎn)十進(jìn)制為458752,458752/1024 = 448K

4、解決問(wèn)題

4.1 配置編寫(xiě)B(tài)ootLoader程序的CubeMX工程

4.1.1 配置RCC時(shí)鐘

4.1.2 配置串行調(diào)試接口

4.1.3 配置按鍵、調(diào)試燈、調(diào)試串口、USB使能管腳

調(diào)試燈選擇的是PB1,低電平點(diǎn)亮,具體可以看原理圖:

USB使能管腳默認(rèn)為低電平。

選用USART2作為調(diào)試打印輸出。

4.1.4 配置USB相關(guān)的選項(xiàng)

配置的基本參數(shù)默認(rèn)即可,不需要改變。

在中斷設(shè)置這里,將USB優(yōu)先級(jí)調(diào)低,可以避免一些默認(rèn)其妙不穩(wěn)定的現(xiàn)象。接下來(lái)配置USB設(shè)備相關(guān)的選項(xiàng)。

類參數(shù)有一個(gè)字段比較重要:

@Internal Flash   /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg,04*016Kg,01*064Kg,07*128Kg

這個(gè)參數(shù)的具體含義描述如下:

  • @:檢測(cè)到這是一個(gè)特殊的映射描述符(避免解碼標(biāo)準(zhǔn)描述符)

  • /:用于區(qū)域之間的分隔符

  • 每個(gè)地址以“ 0x”開(kāi)頭的最大8位數(shù)字

  • /:用于區(qū)域之間的分隔符

  • 扇區(qū)數(shù)的最大2位數(shù)字

  • *:用于扇區(qū)數(shù)和扇區(qū)大小之間的分隔符

  • 扇區(qū)大小在0到999之間的最大3位

  • 扇區(qū)大小乘數(shù)的1位數(shù)字。有效條目為:B(字節(jié)),K(千),M(兆)

  • 扇區(qū)類型的1位數(shù)字,如下所示:

– a(0x41):可讀
– b(0x42):可擦除
– c(0x43):可讀和可擦除
(0x44):可寫(xiě)
– e(0x45):可讀寫(xiě)
–f(0x46):可擦除和可寫(xiě)
–g(0x47):可讀寫(xiě),可寫(xiě)

4.1.5 生成工程

這里默認(rèn)不讓它自動(dòng)生成main函數(shù),main函數(shù)我們自己寫(xiě)。在配置USB設(shè)備參數(shù)里,USBD_DFU_XFER_SIZE參數(shù):USB數(shù)據(jù)pack大小,越大配置速度越快。默認(rèn)配置1024Bytes. 1024Bytes使用的是堆空間,故堆空間要大于1024Bytes. 原因:代碼如下。

#define USBD_malloc         malloc
/* Allocate Audio structure */
pdev->pClassData = USBD_malloc(sizeof (USBD_DFU_HandleTypeDef));

所以這里的堆我把它配置成0x1000。(個(gè)人習(xí)慣)

4.2 編寫(xiě)B(tài)ootLoader程序

4.2.1 實(shí)現(xiàn)usbd_dfu_if.c中相關(guān)的接口

宏定義一些參數(shù)

//FLASH的擦寫(xiě)實(shí)現(xiàn)
#define FLASH_ERASE_TIME (uint16_t)50
#define FLASH_PROGRAM_TIME (uint16_t)50
//APP存放的結(jié)束地址
#define USBD_DFU_APP_END_ADD 0x08080000
//FLASH頁(yè)大小
#define FLASH_PAGE_SIZE 0x800U //2K

實(shí)現(xiàn)如下接口:

MEM_If_Init_FS,       閃存初始化,解鎖內(nèi)部flash。
MEM_If_DeInit_FS, 閃存反(取消)初始化,上鎖內(nèi)部flash。
MEM_If_Erase_FS, 閃存擦除。
MEM_If_Write_FS, 閃存寫(xiě)入。
MEM_If_Read_FS, 閃存讀取。
MEM_If_GetStatus_FS 獲取閃存狀態(tài),返回寫(xiě)入或擦除操作所需的時(shí)間。

閃存初始化,解鎖內(nèi)部flash。

uint16_t MEM_If_Init_FS(void)
{
/* USER CODE BEGIN 0 */
//解鎖內(nèi)部FLASH
HAL_FLASH_Unlock();
//清除FLASH的一些標(biāo)志,可以避免一些莫名其妙的問(wèn)題
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
return (USBD_OK);
/* USER CODE END 0 */
}

閃存反(取消)初始化,上鎖內(nèi)部flash。

uint16_t MEM_If_DeInit_FS(void)
{
/* USER CODE BEGIN 1 */
//給FLASH上鎖
HAL_FLASH_Lock();
return (USBD_OK);
/* USER CODE END 1 */
}

閃存擦除。

uint16_t MEM_If_Erase_FS(uint32_t Add)
{
/* USER CODE BEGIN 2 */
/*擦除整個(gè)APP程序存放的空間,即是0x08080000-0x08010000*/
/*
因?yàn)槠鹗嫉刂肥?x8000000,而Size是0x80000,所以MCU存放代碼的最后一個(gè)區(qū)域的地址為0x8080000。
而DFU占了其中的0x10000的空間。
*/
uint32_t NbOfPages = 0 ;
uint32_t PageError = 0 ;
FLASH_EraseInitTypeDef pEraseInit ;
NbOfPages = (USBD_DFU_APP_END_ADD - USBD_DFU_APP_DEFAULT_ADD)/FLASH_PAGE_SIZE ;
pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
pEraseInit.PageAddress = USBD_DFU_APP_DEFAULT_ADD;
pEraseInit.NbPages = NbOfPages; //erase all pages of APP
if(HAL_FLASHEx_Erase(&pEraseInit,&PageError)!= HAL_OK)
return USBD_FAIL ;
return (USBD_OK);
/* USER CODE END 2 */
}

閃存寫(xiě)入。

uint16_t MEM_If_Write_FS(uint8_t *src, uint8_t *dest, uint32_t Len)
{
/* USER CODE BEGIN 3 */
uint32_t i =0;

for(i=0;i<Len;i+=4)
{
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(uint32_t)(dest+i),*(uint32_t*)(src+i))== HAL_OK)
{
if(*(uint32_t*)(src+i) != *(uint32_t*)(dest+i))
return USBD_FAIL;
}
else
{
return USBD_FAIL;
}
}
return (USBD_OK);
/* USER CODE END 3 */
}

閃存讀取

uint8_t *MEM_If_Read_FS(uint8_t *src, uint8_t *dest, uint32_t Len)
{
/* Return a valid address to avoid HardFault */
/* USER CODE BEGIN 4 */
uint32_t i = 0;
uint8_t *psrc = src;

for (i = 0; i < Len; i++)
{
dest[i] = *psrc++;
}

return (uint8_t*) (dest);
/* USER CODE END 4 */
}

獲取閃存狀態(tài),返回寫(xiě)入或擦除操作所需的時(shí)間。

uint16_t MEM_If_GetStatus_FS(uint32_t Add, uint8_t Cmd, uint8_t *buffer)
{
/* USER CODE BEGIN 5 */
switch (Cmd)
{
case DFU_MEDIA_PROGRAM:
buffer[1] = (uint8_t)FLASH_PROGRAM_TIME;
buffer[2] = (uint8_t)(FLASH_PROGRAM_TIME << 8);
buffer[3] = 0;
break;

case DFU_MEDIA_ERASE:
buffer[1] = (uint8_t)FLASH_ERASE_TIME;
buffer[2] = (uint8_t)(FLASH_ERASE_TIME << 8);
buffer[3] = 0;
break ;
default:

break;
}

return (USBD_OK);
/* USER CODE END 5 */
}

4.2.1 實(shí)現(xiàn)main.c

定義調(diào)試打印接口,這里我用的是USART2

int fputc(int ch, FILE* FILE)
{
HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
return ch;
}

跳轉(zhuǎn)到APP的代碼實(shí)現(xiàn):

static void JumpToApp(void)
{
typedef void (*pFunction)(void);
static pFunction JumpToApplication;
static uint32_t JumpAddress;

/* Test if user code is programmed starting from USBD_DFU_APP_DEFAULT_ADD * address */
if (((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD) & 0x2FFE0000) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t *) (USBD_DFU_APP_DEFAULT_ADD + 4);
JumpToApplication = (pFunction) JumpAddress;

/* Initialize user application's Stack Pointer */
__set_MSP((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD));
JumpToApplication();
}
}

在正常啟動(dòng)過(guò)程中,如果APP區(qū)域存放有數(shù)據(jù),我們不希望去啟動(dòng)USB,在剛開(kāi)始的時(shí)候我們可以把USB的功能給失能掉,如果檢測(cè)到APP區(qū)域沒(méi)有數(shù)據(jù),則再初始化USB功能,所以在這里編寫(xiě)一個(gè)USB的失能函數(shù)。

static void USB_GPIO_DeInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11 | GPIO_PIN_12, GPIO_PIN_RESET);

/*Configure GPIO pin*/
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_Delay(500);
}

main函數(shù)實(shí)現(xiàn)

int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
USB_GPIO_DeInit();
MX_USART2_UART_Init();
/*如果沒(méi)有按下按鍵,則自動(dòng)跳轉(zhuǎn)到APP區(qū),如果跳轉(zhuǎn)不過(guò)去,則代表區(qū)域無(wú)APP*/
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) != GPIO_PIN_SET)
{
JumpToApp();
printf("跳轉(zhuǎn)失敗,開(kāi)始進(jìn)入DFU模式\r\n");
}
//進(jìn)入DFU模式
MX_USB_DEVICE_Init();
printf("Bruce.Yang DFU\n");
//調(diào)試燈常亮,代表此時(shí)在DFU模式
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin,GPIO_PIN_RESET);
while(1)
{
HAL_Delay(1000);
}
}

實(shí)現(xiàn)完畢,接下來(lái)可以編譯程序,下載到開(kāi)發(fā)板,由于沒(méi)有APP,所以開(kāi)發(fā)板上PB1的燈常亮。

4.2.2 編寫(xiě)APP程序

APP程序很簡(jiǎn)單,就讓PB1燈以500ms的頻率進(jìn)行翻轉(zhuǎn)吧。

配置過(guò)程(略)太簡(jiǎn)單了,應(yīng)用APP的核心代碼如下:

 while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(BLUE_LED_GPIO_Port,BLUE_LED_Pin);
HAL_Delay(500);
/* USER CODE BEGIN 3 */
}

接下來(lái)主要是在工程里做一些設(shè)置。

1、點(diǎn)擊魔術(shù)棒設(shè)置APP啟動(dòng)的地址

2、更改中斷向量表偏移

接下來(lái)編譯生成APP_TEST.hex文件,我們用一個(gè)工具來(lái)將它燒寫(xiě)到板子上。

安裝DFU燒錄軟件:DfuSe_Demo

官網(wǎng)下載鏈接:

https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stsw-stm32080.html#resource

默認(rèn)安裝即可。

安裝成功后得到兩個(gè)軟件。


Dfu file manager是把bin文件或者h(yuǎn)ex文件生成 .dfu后綴的文件, .dfu后綴的文件就是我們的固件。DfuSe_Demo是燒錄 文件后綴 .dfu 軟件。

燒錄步驟:

1、將.hex文件轉(zhuǎn)化成.dfu后綴的文件

生成后可以看到效果:

2、連接USB到開(kāi)發(fā)板的設(shè)備端口到PC

看到?jīng)]有識(shí)別DFU

我們需要手動(dòng)給它更新下驅(qū)動(dòng)程序,直接就是剛剛下載的DfuSe安裝的目錄下找對(duì)應(yīng)系統(tǒng)版本的驅(qū)動(dòng)就好了。

最后可以看到該模式被識(shí)別了:

接下來(lái)打開(kāi)DfuSeDemo這個(gè)軟件,可以看到開(kāi)發(fā)板現(xiàn)在已經(jīng)被識(shí)別了。

接下來(lái)將剛剛生成的APP_TEST1.dfu加載進(jìn)來(lái)。

點(diǎn)擊Upgrade進(jìn)行升級(jí)。

升級(jí)成功!接下來(lái)點(diǎn)擊Leave DFU mode,程序則會(huì)自動(dòng)開(kāi)始執(zhí)行。


這時(shí)候APP已經(jīng)跑起來(lái)了,燈在以500ms的頻率不斷閃爍。

至此USB DFU固件成功!

Bootloader代碼以及APP代碼在這里下載:

鏈接:https://pan.baidu.com/s/1zRv7j4E8SXgCV5F6RbSo1Q
提取碼:5539

如果有興趣的話,還可以把我之前寫(xiě)的串口屏BootLoader那個(gè)程序繼續(xù)升級(jí)一下!

帶串口屏顯示的Bootloader

往期精彩


帶串口屏顯示的Bootloader

為L(zhǎng)inux應(yīng)用構(gòu)造有限狀態(tài)機(jī)

編程修養(yǎng)(精品文,建議認(rèn)真品讀并實(shí)踐)

嵌入式C語(yǔ)言代碼優(yōu)化方案(深度好文,建議花時(shí)間研讀并收藏)

若覺(jué)得本次分享的文章對(duì)您有幫助,隨手點(diǎn)[在看]并轉(zhuǎn)發(fā)分享,也是對(duì)我的支持。

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉