cuteftp-随播高清影视

bootloader模式
2023年4月5日发(作者:如何进入dos系统)

【STM32F429开发板⽤户⼿册】第29章STM32F429的系统

bootloader之。。。

第29章STM32F429的系统bootloader之USBDFU⽅式固件升

本章节为⼤家讲解使⽤系统bootloader做程序升级的⽅法,即使不依赖外部boot引脚也可以⽅便升级。

DFU的全称是DeviceFirmwareUpgrade,即设备固件升级

29.1初学者重要提⽰

29.2跳转到系统bootloader的程序设计

29.3STM32CubeProg的安装说明

29.3STM32CubeProg的程序下载说明

29.4USBDFU⽅式系统bootloader驱动移植和使⽤

29.6实验例程设计框架

29.7实验例程说明(MDK)

29.8实验例程说明(IAR)

29.9总结

29.1初学者重要提⽰

1.学习本章节前,务必优先学习第28章。

2.本章⽤到的相关软件和⽂档下载:。

3.软件STM32CubeProg和DfuSe都⽀持USBDFU,但是两个软件不能都安装使⽤,因为这两个软件的USB驱动不同,导致⼯作在系统

bootloader模式的板⼦通过USB线接到电脑端时,只有⼀个软件的驱动被识别。

是⽼版的USBDFU软件,不推荐⼤家使⽤了。建议使⽤STM32CubeProg,此软件实现了之前的DfuSe,STLINK⼩软件和

Flashloader三合⼀,并且⽀持外部EEPROM,NORFlash,SPIFlash,NANDFlash等烧写,也⽀持OTA编程。

5.本章节的USBDFU的下载软件采⽤STM32CubeProg,如果想使⽤DfuSe的话,此贴有详细说明:。

6.当芯⽚⼯作在系统bootLoader的USBDFU模式,更新完毕程序后,不会⾃动退出USBDFU,需要重新复位芯⽚后才会退出。由于

DFU模式会⽤到USB线,插拔USB线是难以避免的,所以是否⽀持⾃动退出,并不影响。

29.2跳转到系统bootLoader的程序设计

程序设计如下,基本是按照第28章3.2⼩节的⽅法进⾏设计

1./*

2.******************************************************************************************************

3.*函数名:JumpToBootloader

4.*功能说明:跳转到系统BootLoader

5.*形参:⽆

6.*返回值:⽆

7.******************************************************************************************************

8.*/

voidJumpToBootloader(void)

10.{

32_ti=0;

(*SysMemBootJump)(void);/*声明⼀个函数指针*/

13.__IOuint32_tBootAddr=0x1FFF0000;/*STM32F4的系统BootLoader地址*/

14.

15./*关闭全局中断*/

E_INT();

17.

18./*关闭滴答定时器,复位到默认值*/

k->CTRL=0;

k->LOAD=0;

k->VAL=0;

22.

23./*设置所有时钟到默认状态,使⽤HSI时钟*/

_RCC_DeInit();

25.

26./*关闭所有中断,清除所有中断挂起标志*/

(i=0;i<8;i++)

28.{

->ICER[i]=0xFFFFFFFF;

->ICPR[i]=0xFFFFFFFF;

31.}

32.

33./*使能全局中断*/

_INT();

35.

36./*设置重映射到系统Flash*/

37.__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();

38.

39./*跳转到系统BootLoader,⾸地址是MSP,地址+4是复位中断服务程序地址*/

BootJump=(void(*)(void))(*((uint32_t*)(BootAddr+4)));

41.

42./*设置朱堆栈指针*/

43.__set_MSP(*(uint32_t*)BootAddr);

44.

45./*在RTOS⼯程,这条语句很重要,设置为特权级模式,使⽤MSP指针*/

46.__set_CONTROL(0);

47.

48./*跳转到系统BootLoader*/

BootJump();

50.

51./*跳转成功的话,不会执⾏到这⾥,⽤户可以在这⾥添加代码*/

(1)

53.{

54.

55.}

56.}

这⾥把程序设计中的⼏个关键地⽅做个说明:

第12⾏,声明⼀个函数指针。

第13⾏,这个要特别注意,F4的系统bootloader地址。

第19到21⾏,设置滴答定时器到复位值。

第24⾏,此函数⽐较省事,可以⽅便的设置F4所有时钟到复位值,内部时钟使⽤HSI。

第27到31⾏,清除所有中断挂起标志并关闭中断,这⾥是直接通过⼀个for循环设置了NVIC所有配置位,共8组。

第37⾏,将系统bootloader的地址映射到0x00000000。这点⾮常重要,根本原因是F4的系统bootloader要从0x00000000地址读取中

断向量。

第40⾏,将系统bootLoader的中断复位服务程序的⼊⼝地址赋给第12⾏声明的函数,⽤户执⾏这个函数时,就会直接跳转过去。

第43⾏,设置主堆栈指针位置,即系统bootloader的⾸地址存储的就是栈地址。

第46⾏,这个设置在RTOS应⽤程序中⽐较重要,因为基于Cortex-M内核的RTOS任务堆栈基本都是使⽤线程堆栈指针PSP。但系统

BootLoader使⽤的是主堆栈指针MSP,所以务必要设置下,同时让M内核⼯作于特权级。此寄存器的作⽤如下:

第49⾏,跳转到系统bootLoader。

29.3STM32CubeProg的安装说明

STM32CubeProg的安装⽐较简单,如果⼤家的电脑中缺少JAVA环境,会提⽰安装,按照提⽰操作即可。

这⾥特别注意USBDFU驱动的安装,如果⼤家的电脑上安装了DfuSe软件,那边板⼦⼯作在系统bootLoader模式时,电脑端的设备管理器

识别出来的标识是这样的:

如果⽤STM32CubeProg的话,务必要将此驱动删掉,⿏标右击此标识,选择卸载,弹出如下对话框:

卸载完毕后,重启电脑,然后运⾏STM32CubeProg安装⽬录⾥⾯的即可,最后插上设备就可以正常识别了。识别后

的标识:

29.4STM32CubeProg的程序下载说明

这⾥把两种下载⽅式都做个说明,⼀种是设置外部boot引脚进⾏下载,另⼀种是设置程序跳转到系统bootloader进⾏下载。

29.4.1设置boot引脚跳转到系统bootLoader

第1步:此接⼝插上USB线:

第2步:板⼦上电前按住右下⾓的BOOT引脚。

第3步:板⼦上电3秒左右,松⼿。

在电脑端设备管理器就可以看到已经识别出来:

29.4.2应⽤程序跳转到系统bootloader

应⽤程序跳转到系统bootLoader⽐较⽅便,⽆需⽤户操作外置的boot引脚了,只需调⽤本章第2⼩节的程序就可以跳转。本章配套的例⼦是

⽤户按下按键K1后执⾏跳转程序,⼤家可以根据需要实现各种触发跳转的⽅式。跳转成功后,在电脑端设备管理器⾥⾯也会看到bootloader

标识:

29.4.3STM32CubeProg下载程序设置

识别成功后就可以下载程序了。

第1步,选择USB⽅式,点击Connect按钮。

识别成功后的效果如下:

这⾥要特别注意⼀点,如果⽤户没有关闭这个软件,多次插拔USB线时,记得点击这⾥的刷新按钮,因为有时候这个软件不会⾃动显⽰出

来,点击刷新按钮才⾏。

第2步,添加要下载的hex⽂件,勾选需要设置的选项,点击启动编程。

Startaddress选项不填的话,默认会下载到内部Flash的⾸地址,保险起见,⼤家也可以填上⾸地址0x08000000,或者其它要下载的

地址。

Runafterprogramming选项勾选或者不勾选均可,因为测试发现STM32CubeProg不⽀持USBDFU编程后运⾏。这样特别说⼀点,

如果勾上此选项后,下载完毕程序后,会⾃动断开连接,并弹出⼀些列窗⼝,最终弹出下⾯这个窗⼝:

弹出这个窗⼝并不是表⽰下载失败了,⽽是下载完成后退出了系统bootloader。

第3步,完成下载后的效果如下:

下载完成后板⼦重新上电就可以看到程序已经成功下载了。

29.5USBDFU⽅式系统Bootloader驱动移植和使⽤

系统bootloader的移植⽐较简单,仅需添加本章第2⼩节的程序到⾃⼰⼯程⾥⾯即可。⾥⾯有个开关中断API,是在bsp.h⽂件⾥⾯定义的:

/*开关全局中断的宏*/

#defineENABLE_INT()__set_PRIMASK(0)/*使能全局中断*/

#defineDISABLE_INT()__set_PRIMASK(1)/*禁⽌全局中断*/

29.6实验例程设计框架

通过程序设计框架,让⼤家先对配套例程有⼀个全⾯的认识,然后再理解细节,本次实验例程的设计框架如下:

第1阶段,上电启动阶段:

这部分在第14章进⾏了详细说明。

第2阶段,进⼊main函数:

第1部分,硬件初始化,主要是HAL库,系统时钟,滴答定时器和LED。

第2部分,应⽤程序设计部分,K1按键按下后跳转到系统bootloader。。

29.7实验例程说明(MDK)

配套例⼦:

V6-009_基于系统bootloader的USB接⼝⽅式IAP升级(USBDFU)

实验⽬的:

1.学习基于系统bootloader的USB接⼝⽅式IAP升级。

实验内容:

32的系统存储区⾃带bootLoader,可以⽅便的实现串⼝,I2C,CAN,SPI,USB等接⼝⽅式的程序升级。

2.如果使⽤系统bootLoader⽀持的接⼝升级⽅式,基本就不需要⽤户⾃⼰做bootLoader了。

3.除了通过boot引脚控制启动地址,也可以直接从应⽤程序⾥⾯跳转到系统存储区。

实验操作:

1.K1键按下,跳转到系统bootLoader。

上电后串⼝打印的信息:

波特率115200,数据位8,奇偶校验位⽆,停⽌位1。

程序设计:

系统栈⼤⼩分配:

硬件外设初始化

硬件外设的初始化是在bsp.c⽂件实现:

/*

*********************************************************************************************************

*函数名:bsp_Init

*功能说明:初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化⼀些全局变量。只需要调⽤⼀次

*形参:⽆0

*返回值:⽆

*********************************************************************************************************

*/

voidbsp_Init(void)

{

/*

STM32H429HAL库初始化,此时系统⽤的还是F429⾃带的16MHz,HSI时钟:

-调⽤函数HAL_InitTick,初始化滴答时钟中断1ms。

-设置NVIV优先级分组为4。

*/

HAL_Init();

/*

配置系统时钟到168MHz

-切换使⽤HSE。

-此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。

*/

SystemClock_Config();

/*

EventRecorder:

-可⽤于代码执⾏时间测量,MDK5.25及其以上版本才⽀持,IAR不⽀持。

-默认不开启,如果要使能此选项,务必看V5开发板⽤户⼿册第8章

*/

#ifEnable_EventRecorder==1

/*初始化EventRecorder并开启*/

EventRecorderInitialize(EventRecordAll,1U);

EventRecorderStart();

#endif

bsp_InitKey();/*按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描*/

bsp_InitTimer();/*初始化滴答定时器*/

bsp_InitUart();/*初始化串⼝*/

bsp_InitExtIO();/*初始化扩展IO*/

bsp_InitLed();/*初始化LED*/

BEEP_InitHard();/*初始化蜂鸣器*/

}

主功能:

主程序实现如下操作:

启动⼀个⾃动重装软件定时器,每100ms翻转⼀次LED2。

K1键按下,跳转到系统BootLoader。

/*

*********************************************************************************************************

*函数名:main

*功能说明:c程序⼊⼝

*形参:⽆

*返回值:错误代码(⽆需处理)

*********************************************************************************************************

*/

intmain(void)

{

uint8_tucKeyCode;/*按键代码*/

bsp_Init();/*硬件初始化*/

PrintfLogo();/*打印例程名称和版本等信息*/

PrintfHelp();/*打印操作提⽰*/

bsp_StartAutoTimer(0,100);/*启动1个100ms的⾃动重装的定时器*/

while(1)

{

bsp_Idle();/*这个函数在bsp.c⽂件。⽤户可以修改这个函数实现CPU休眠和喂狗*/

/*判断定时器超时时间*/

if(bsp_CheckTimer(0))

{

/*每隔100ms进来⼀次*/

bsp_LedToggle(2);

}

/*按键滤波和检测由后台systick中断服务程序实现,我们只需要调⽤bsp_GetKey读取键值即可。*/

ucKeyCode=bsp_GetKey();/*读取键值,⽆键按下时返回KEY_NONE=0*/

if(ucKeyCode!=KEY_NONE)

{

switch(ucKeyCode)

{

caseKEY_DOWN_K1:/*K1键按下,K1键按下,跳转到系统BootLoader*/

JumpToBootloader();

break;

default:

/*其它的键值不处理*/

break;

}

}

}

}

29.8实验例程说明(IAR)

配套例⼦:

V6-009_基于系统bootloader的USB接⼝⽅式IAP升级(USBDFU)

实验⽬的:

1.学习基于系统bootloader的USB接⼝⽅式IAP升级。

实验内容:

32的系统存储区⾃带bootLoader,可以⽅便的实现串⼝,I2C,CAN,SPI,USB等接⼝⽅式的程序升级。

2.如果使⽤系统bootLoader⽀持的接⼝升级⽅式,基本就不需要⽤户⾃⼰做bootLoader了。

3.除了通过boot引脚控制启动地址,也可以直接从应⽤程序⾥⾯跳转到系统存储区。

实验操作:

1.K1键按下,跳转到系统bootLoader。

上电后串⼝打印的信息:

波特率115200,数据位8,奇偶校验位⽆,停⽌位1。

程序设计:

系统栈⼤⼩分配:

硬件外设初始化

硬件外设的初始化是在bsp.c⽂件实现:

/*

*********************************************************************************************************

*函数名:bsp_Init

*功能说明:初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化⼀些全局变量。只需要调⽤⼀次

*形参:⽆0

*返回值:⽆

*********************************************************************************************************

*/

voidbsp_Init(void)

{

/*

STM32H429HAL库初始化,此时系统⽤的还是F429⾃带的16MHz,HSI时钟:

-调⽤函数HAL_InitTick,初始化滴答时钟中断1ms。

-设置NVIV优先级分组为4。

*/

HAL_Init();

/*

配置系统时钟到168MHz

-切换使⽤HSE。

-此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。

*/

SystemClock_Config();

/*

EventRecorder:

-可⽤于代码执⾏时间测量,MDK5.25及其以上版本才⽀持,IAR不⽀持。

-默认不开启,如果要使能此选项,务必看V5开发板⽤户⼿册第8章

*/

#ifEnable_EventRecorder==1

/*初始化EventRecorder并开启*/

EventRecorderInitialize(EventRecordAll,1U);

EventRecorderStart();

#endif

bsp_InitKey();/*按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描*/

bsp_InitTimer();/*初始化滴答定时器*/

bsp_InitUart();/*初始化串⼝*/

bsp_InitExtIO();/*初始化扩展IO*/

bsp_InitLed();/*初始化LED*/

BEEP_InitHard();/*初始化蜂鸣器*/

}

主功能:

主程序实现如下操作:

启动⼀个⾃动重装软件定时器,每100ms翻转⼀次LED2。

K1键按下,跳转到系统BootLoader。

/*

*********************************************************************************************************

*函数名:main

*功能说明:c程序⼊⼝

*形参:⽆

*返回值:错误代码(⽆需处理)

*********************************************************************************************************

*/

intmain(void)

{

uint8_tucKeyCode;/*按键代码*/

bsp_Init();/*硬件初始化*/

PrintfLogo();/*打印例程名称和版本等信息*/

PrintfHelp();/*打印操作提⽰*/

bsp_StartAutoTimer(0,100);/*启动1个100ms的⾃动重装的定时器*/

while(1)

{

bsp_Idle();/*这个函数在bsp.c⽂件。⽤户可以修改这个函数实现CPU休眠和喂狗*/

/*判断定时器超时时间*/

if(bsp_CheckTimer(0))

{

/*每隔100ms进来⼀次*/

bsp_LedToggle(2);

}

/*按键滤波和检测由后台systick中断服务程序实现,我们只需要调⽤bsp_GetKey读取键值即可。*/

ucKeyCode=bsp_GetKey();/*读取键值,⽆键按下时返回KEY_NONE=0*/

if(ucKeyCode!=KEY_NONE)

{

switch(ucKeyCode)

{

caseKEY_DOWN_K1:/*K1键按下,K1键按下,跳转到系统BootLoader*/

JumpToBootloader();

break;

default:

/*其它的键值不处理*/

break;

}

}

}

}

29.9总结

本章节为⼤家介绍的USBDFU⽅式还是⾮常实⽤的,特别是产品硬件不带boot引脚时。

更多推荐

bootloader模式