当前位置: 首页 > news >正文

【stm32】【DFU】

学习DFU少不了dfu-util工具:dfu-util 是一个开源工具,用于通过 USB 接口对支持 DFU 协议的设备进行固件升级或下载操作。

Ubuntu上可以自己编译获得或者apt-get。window要自己找资源。

DFU实用工具dfu-util-0.9-win64在Windows平台上的应用-CSDN博客

ST官方提供DFU方案集成在内部系统存储器(ISP),唯独F103没有(写bootloader实现占用一部分flash)(IAP),子系列107还是有的。

STM32高级开发(17)-使用DFU方案_stm32 dfu-CSDN博客

自制17键数字机械键盘(3)——STM32F103 DFU功能实现 - 知乎

关键词:

USBd (USB Device)if (interface)DFU(Device firmware update)OB(option bytes)

fops(file operations)MSP(main stack point)

操作集模式

basic parameter(默认即可)

USBD_MAX_NUM_INTERFACES支持的最大接口数量 1

USBD_MAX_NUM_CONFIGURATION支持的最大配置数量 1

USBD_MAX_STR_DESC_SIZ字符串描述符的最大大小 512kb

USBD_SUPPORT_USER_STRING_DESC

usbd_dfu_if.c文件

USBD_DFU_fops_FS 结构体(full speed)

   (uint8_t*)FLASH_DESC_STR,
    MEM_If_Init_FS,
    MEM_If_DeInit_FS,
    MEM_If_Erase_FS,
    MEM_If_Write_FS,
    MEM_If_Read_FS,
    MEM_If_GetStatus_FS

#define FLASH_ERASE_TIME 	(uint16_t)50
#define FLASH_PROGRAM_TIME	(uint16_t)50
uint16_t MEM_If_Init_FS(void)
{/* USER CODE BEGIN 0 */HAL_FLASH_Unlock();return (USBD_OK);/* USER CODE END 0 */
}/*** @brief  De-Initializes Memory* @retval USBD_OK if operation is successful, MAL_FAIL else*/
uint16_t MEM_If_DeInit_FS(void)
{/* USER CODE BEGIN 1 */HAL_FLASH_Lock();return (USBD_OK);/* USER CODE END 1 */
}/*** @brief  Erase sector.* @param  Add: Address of sector to be erased.* @retval 0 if operation is successful, MAL_FAIL else.*/
uint16_t MEM_If_Erase_FS(uint32_t Add)
{/* USER CODE BEGIN 2 */uint32_t PageError;/* Variable contains Flash operation status */HAL_StatusTypeDef status;FLASH_EraseInitTypeDef eraseinitstruct;eraseinitstruct.TypeErase = FLASH_TYPEERASE_PAGES;eraseinitstruct.PageAddress = Add;eraseinitstruct.NbPages = 1U;status = HAL_FLASHEx_Erase(&eraseinitstruct, &PageError);if (status != HAL_OK){return (USBD_FAIL);}return (USBD_OK);/* USER CODE END 2 */
}
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){/* Device voltage range supposed to be [2.7V to 3.6V], the operation will* be done by byte */if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t) (dest + i),*(uint32_t *) (src + i)) == HAL_OK){/* Check the written value */if (*(uint32_t *) (src + i) != *(uint32_t *) (dest + i)){/* Flash content doesn't match SRAM content */return (USBD_FAIL);}}else{/* Error occurred while writing data in Flash memory */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 a valid address to avoid HardFault */return (uint8_t*)(USBD_OK);/* USER CODE END 4 */
}
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:default:buffer[1] = (uint8_t) FLASH_ERASE_TIME;buffer[2] = (uint8_t) (FLASH_ERASE_TIME << 8);buffer[3] = 0;break;}return (USBD_OK);/* USER CODE END 5 */
}

语法解析

__ALIGN_BEGIN 和 __ALIGN_END

// 确保结构体在内存中 4 字节对齐
__ALIGN_BEGIN                 // 开始对齐
USBD_DFU_MediaTypeDef USBD_DFU_fops_FS  // 结构体变量
__ALIGN_END                   // 结束对齐// 等价于:
USBD_DFU_MediaTypeDef USBD_DFU_fops_FS __attribute__((aligned(4)));

这个结构体中是要完善的函数,CubeMX生成的

程序更新失败软件重启

NVIC_SystemReset()函数软件复位失败的解决方法_nvicsystemreset没有复位-CSDN博客

__set_FAULTMASK(1); 和 __disable_irq(); 有什么不同_set faultmask(1)进去硬件错误-CSDN博客

__set_FAULTMASK(1); // 关闭所有中断
NVIC_SystemReset(); // 执行系统复位

main.c文件

思路就是MX_USB_DEVICE_Init()会开启USB功能,其中就有我们的DFU,这时候就会等待接上USB并更新代码,更新代码是程序在处理所有USB功能中断中进行,OTG_FS_IQRHandler中,因此我们在while(1){Hal_Delay(100);};。

但是我们不更新代码就要跳转程序,就写一些判断条件(按键按下),要是没按下就不进入while阻塞反而jumptoapp,跳转失败就打印失败并进入软件重启。

jumpto函数

jump_to_app函数,作用是一个程序跳转到另一个程序(app),更新固件程序跳转到app都是这样写,大差不差。noreturn属性自己去查。原理就是把msp主堆栈指针指向app的FLASH开头,程序的第一步是执行reset_handler的(可以看启动文件得知)。

因此,FLASH里应该分配bootloader(包含DFU)和app程序,首先执行bootloader决定是否执行程序更新和跳转。跳转后ram由app自动清理。跳转前建议关闭中断以免跳转后数据未清除前进入中断,敏感数据可以同时清理一下。

下面是两种跳转,实际功能一样。一个检查了程序首几位地址(stm32程序固定的)。

typedef void (*fctptr_t)(void);static __attribute__((noreturn)) void jumpTo(uint32_t addr)
{__disable_irq();__set_MSP(*(uint32_t*)addr);fctptr_t reset_handler = (fctptr_t)*(uint32_t*)(addr + 4);reset_handler();while(1){}    
}typedef  void (*pFunction)(void);
void jump_to_application(void)
{__disable_irq();pFunction JumpToApplication;uint32_t JumpAddress;if (((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD) & 0x2FFFB000) == 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();}
}

#define APP_START_ADDRESS               (uint32_t)(FIRMWARE_ADDRESS + BOOTLOADER_SIZE)
#define BOOTLOADER_SIZE                 0x8000//大小自己定,这里32kb = 8*4kb
#define FIRMWARE_ADDRESS                0x08000000

这里noreturn自己查吧。

main函数

int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();MX_USB_DEVICE_Init();  // DFUif (should_enter_dfu_mode()) {while (1) {printf("Entering DFU Mode - Waiting for USB connection...\n");HAL_Delay(200);}} else {if (!jumptoapp()) {printf("app-start falled..waiting for reboot\n");HAL_Delay(5000);__set_FAULTMASK(1);  // 关闭所有中断NVIC_SystemReset();  // 执行系统复位}}
}
http://www.dtcms.com/a/590052.html

相关文章:

  • 主流 AI IDE 之一的 Comate IDE 介绍
  • 学网站建设可以从事什么工作wordpress高仿都市头条主题
  • 完全自建网站钟山区生态文明建设局网站
  • OpenCV(二十三):透视变换
  • 十大网站黄页的免费免费推广策略
  • 网站怎么推广效果好一点呢上海做网站搜索一下马来西亚的
  • Kotlin实现全屏显示效果,挖空和刘海屏适配
  • 什么网站可以做护考题网址搜索器
  • 网站快照长期不更新怎样注册自己的网址
  • 哪些网站是用c语言做的wordpress主题基础
  • 建设网站首页应该采用浙江省建设厅执业资格注册中心网站
  • 【JAVA 进阶】SpringBoot框架核心原理与高级特性深度解析
  • 小游戏网站欣赏山东网站设计公司
  • 计算机网络自顶向下方法43——网络层 详解SDN控制平面
  • 数据结构——三十九、顺序查找(王道408)
  • 自己做电影资源网站wordpress升级php版本
  • 创建型设计模式2
  • Flutter与鸿蒙EventChannel事件流通信详解
  • 销售型网站设计如何自助建站
  • 11月9日星期天今日早报简报微语报早读
  • 在cmd通过代理安装包(from deepseek)
  • 新网站怎么做外链做外贸网站需要什么卡
  • 江阴企业网站建设哪家好wordpress数据库用户角色
  • 表格识别技术,通过目标检测、结构分析和文字识别三步骤,实现对纸质档案表格的智能解析
  • 一级站点和二级站点区别免费网站建设创意
  • 网站怎么做才可以做评价网站 展示板
  • 新手学做网站优化如何知道网站是否被k
  • 408超难页表大题精析(201320202024)
  • xcpc退役随笔
  • 从缓冲区到Stream:数据流机制与应用