HAL-STM32-USB内部Flash虚拟U盘更新程序

2023-10-27

1.IAP部分

 

添加fat32文件(修改Flash擦除代码,F401ccu6按扇区删除,F103按页删除)

static bool _fat32_write_firmware(const uint8_t *b, uint32_t addr)
{
    bool return_status = true;
  
    HAL_StatusTypeDef status;
    
    HAL_FLASH_Unlock();
    
    uint32_t offset = addr - fw_addr_range.begin;
    uint32_t phy_addr = APP_ADDR + offset;
    uint32_t prog_size = MIN(FAT32_SECTOR_SIZE, fw_addr_range.end - fw_addr_range.begin);
  
    if(prog_size & 0x03)
    {
        prog_size += 4;
    }
  
    if(addr == fw_addr_range.begin)
    {
        // Erase the APPCODE area
		//stm32f401ccu6 256k Flash ,0~5个扇区 0,1,2,3:16K  4:64K  5:128K
		//前面32K预留为BootLoader 删除后两个扇区64K+128K备用烧录程序
        uint32_t PageError = 0;
        FLASH_EraseInitTypeDef eraseinitstruct;
        
        eraseinitstruct.TypeErase = FLASH_TYPEERASE_SECTORS;
        eraseinitstruct.Sector = FLASH_SECTOR_2;
        eraseinitstruct.NbSectors = 4;
        status = HAL_FLASHEx_Erase(&eraseinitstruct, &PageError);
        
        if(status != HAL_OK)
        {
            return_status = false;
            goto EXIT;
        }
    }
    
    
    if((phy_addr >= APP_ADDR) && (phy_addr < (APP_ADDR + APP_SIZE)) )
    {
        uint32_t i = 0;
      
        for(i=0; i<prog_size; i+=4)
        {
            const uint8_t *wbuf = b + i;
            status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, phy_addr + i, *((uint32_t*)wbuf));
            if(status != HAL_OK)
            {
                return_status = false;
                goto EXIT;
            }
        }
				
    }
    
    if(addr == (fw_addr_range.end - FAT32_SECTOR_SIZE))
    {
//			 HAL_FLASH_Lock();
       DownloadComplete();
       return_status = true;
    }
EXIT:
    HAL_FLASH_Lock();
    return return_status;
}

IAP跳转函数

#include "stdio.h"
#include <stdint.h>
#include <stdbool.h>
#include "btldr_config.h"

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

bool is_appcode_exist()
{
  uint32_t *mem = (uint32_t*)APP_ADDR;
  
  if ((mem[0] == 0x00000000 || mem[0] == 0xFFFFFFFF) && \
      (mem[1] == 0x00000000 || mem[1] == 0xFFFFFFFF) && \
      (mem[2] == 0x00000000 || mem[2] == 0xFFFFFFFF) && \
      (mem[3] == 0x00000000 || mem[3] == 0xFFFFFFFF))
  {
    return false;
  }
  else
  {
    return true;
  }
}


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 *) APP_ADDR) & 0x2FFE0000) == 0x20000000)
    {
        /* Jump to user application */
        JumpAddress = *(__IO uint32_t *) (APP_ADDR + 4u);
			  //HAL_DeInit();
        JumpToApplication = (pFunction) JumpAddress;

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

bool is_button_down()
{
  return (HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET);
}


int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
 // MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */
	printf("STM32F4 USB-IAP TEST !!!\r\n");
	
	if(!is_appcode_exist() || is_button_down())
  {
    MX_USB_DEVICE_Init();
		printf("Jump failed, USB firmware upgrade mode!!!\r\n");
    while(1)
    {
    }
  }
  else
  {
		printf("Jump succeed!!!\r\n");
    JumpToApp();
  }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

 跳转位置以生成的bin大小为准

 因为F401以扇区擦除,说英语0x5000修改为0x8000,前面2个扇区作为BootLoader

2.APP篇

int fputc(int ch, FILE* FILE)
{
    HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
    return ch;
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
	SCB->VTOR = FLASH_BASE | 0x8000;
  __ASM("CPSIE I");//
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  printf("STM32F4 USB-IAP-APP TEST !!!\r\n");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
	printf("Succeed!!!\r\n");
		HAL_Delay(500);
  }
  /* USER CODE END 3 */
}

设置生成bin文件(fromelf --bin -o "$L@L.bin" "#L")

 设置跳转

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HAL-STM32-USB内部Flash虚拟U盘更新程序 的相关文章

  • 初始化 ST-Link 设备时出错 - 无法连接到设备

    我目前正在使用 ST Link 调试器对我的 STM32F3 Discovery 板进行编程 我使用的IDE是Atollic TrueStudio 5 5 2 现在我面临一个非常奇怪的问题 那就是我不断收到消息 初始化 ST Link 设备
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • 138-基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真+源程序

    资料编号 138 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 LED灯 蜂鸣器 电位器 制作一个基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真 2 通过DHT1
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • 匹配 STM32F0 和 zlib 中的 CRC32

    我正在研究运行 Linux 的计算机和 STM32F0 之间的通信链路 我想对我的数据包使用某种错误检测 并且由于 STM32F0 有 CRC32 硬件 并且我在 Linux 上有带有 CRC32 的 zlib 所以我认为在我的项目中使用
  • STM32超声波——HC_SR04

    文章目录 一 超声波图片 二 时序图 三 超声波流程 四 单位换算 五 取余计算 六 换算距离 七 超声波代码 一 超声波图片 测量距离 2cm 400cm 二 时序图 1 以下时序图要先提供一个至少10us的脉冲触发信号 告诉单片机我准备
  • 物联网网关

    物联网网关是 连接物联网设备和互联网的重要桥梁 它负责将物联网设备采集到的数据进行处理 存储和转发 使其能够与云端或其它设备进行通信 物联网网关的作用是实现物联网设备与云端的无缝连接和数据交互 物联网网关功能 数据采集 物联网网关可以从物联
  • 硬件基础-电容

    电容 本质 电容两端电压不能激变 所以可以起到稳定电压作用 充放电 电容量的大小 想使电容容量大 使用介电常数高的介质 增大极板间的面积 减小极板间的距离 品牌 国外 村田 muRata 松下 PANASONIC 三星 SAMSUNG 太诱
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • 嵌入式开发--STM32G4系列片上FLASH的读写

    这个玩意吧 说起来很简单 就是几行代码的事 但楞是折腾了我大半天时间才搞定 原因后面说 先看代码吧 读操作 读操作很简单 以32位方式读取的时候是这样的 data IO uint32 t 0x0800F000 需要注意的是 当以32位方式读
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • 特殊寄存器

    特殊寄存器 文章目录 前言 一 背景 二 2 1 2 2 总结 前言 前期疑问 STM32特殊寄存器到底是什么 特殊寄存器怎么查看和调试代码 本文目标 记录和理解特殊寄存器 一 背景 最近在看ucosIII文章是 里面提到特殊寄存器 这就进
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • 在 Contiki 程序中使用 malloc

    考虑以下 Contiki 程序 include
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐

  • 2022 年 MathorCup 高校数学建模挑战赛——大数据竞赛(北京移动用户体验影响因素研究全套代码)

    赛道 B 北京移动用户体验影响因素研究 移动通信技术飞速发展 给人们带来了极大便利 人们也越来越离不开移动通信技术带来的各种便捷 随着网络不断的建设 网络覆盖越来越完善 各个移动运营商 越来越重视客户的网络使用体验 从而进一步提升网络服务质
  • HDU1096(最大递增子序列的变形)

    http acm hdu edu cn showproblem php pid 1069 输入几种方块 当方块的长宽小于下面那个时可以放在上面 求最大方块的高度 方块可以无限 每个方块有6种不同的状态 比如 10 20 30 10 30 2
  • PE盘和系统启动盘制作

    摘要 自己多两把刷子还是很重要滴 学会自己做PE盘就可以及时抢救数据啦 学会自己装系统就不用求别人帮忙啦 进度条掌握在自己手中 开篇前先简单介绍下PE盘和系统启动盘的作用 PE盘呢其实是用来做一个很小的微PE系统 可以类比成Windows系
  • 学习率Learn_rate是什么(深度学习)

    学习率是指在训练神经网络时用于调整参数的步进大小 它决定了每次梯度更新时参数的调整程度 学习率的选择直接关系到模型的性能和训练过程的效果 学习率变化可能带来的影响 收敛速度 较高的学习率可以加快模型的收敛速度 因为参数更新更大 模型能够更快
  • sublime text3设置快捷键在浏览器中打开

    Sublime Text3自带在浏览器中打开的功能 不需要另外安装插件 右键就可以选择open in browser 为了方便 设置快捷键来使用这个功能 Preferences Key Bindings User 将以下代码粘贴进去 我没有
  • 可编程led灯带原理_88张图搞定层板灯带的设计、安装、收口及检修!

    dop设计 ID dopdesign 原创 作者丨泽顺 编辑丨那兰 光之于空间 犹如空气之于生命 光的存在赋予了空间生命和灵魂 无论是建筑空间还是室内装饰设计 光都是设计当中必不可少的元素 越来越多的设计师更加重视和倾向于利用灯光来点缀空间
  • maven的环境配置问题:出现无法解析插件

    在配置maven环境的过程中 我首先出现了通过maven archetype webapp创建web项目时始终没有src包 然后开始了反复安装maven的过程 结果反正环境很乱 问题也没有解决 最后通过重新配置环境变量的方式 src包就莫名
  • Windows下JetBrains GoLand环境配置记录

    闲来无事 go go go 这篇文章不是最简单的配置方法 相对简单的配置方法见文末引用 本文记录了我遇见的一些问题以及解决方案与解释 Go编译环境配置 首先得前往谷歌的网站下载go语言的镜像文件 Downloads The Go Progr
  • 05-07章

    第5章 if 语句 1 True False 2 gt gt lt lt 3 and or not 4 判断某个值是否已包含在列表中 可用关键字in 判断某个值是否未包含在列表中 可用关键字not in 5 if else if elif
  • 用SVR模型完成对Boston房价的回归预测

    用SVR模型完成对Boston房价的回归预测 文章目录 用SVR模型完成对Boston房价的回归预测 实验说明 实验代码 参数优化 实验说明 实验要求 使用SVR模型实现对波士顿房价的预测 load boston 并使用r2 score 对
  • 山海经2服务器维护时间,山海经异兽录多久出一次新服

    发布时间 2016 07 14 梦幻西游手游魔王寨多久出 梦幻西游手游魔王寨怎么样 在梦幻西游手游嘉年华公布了官方消息 魔王寨将成为梦幻西游手游的第七个门派 相信大家已经迫不及待的想要尝试新门派了 那么魔王寨门派怎么样 今天蚕豆网小编就为大
  • bandgap电路设计与仿真

    1 电路图 带隙基准电路主要由具有负温度特性的三极管 以电流镜做负载的5管OTA和启动电路构成 工艺采用的是0 18um工艺 具体电路也可参考拉扎维模拟coms集成电路第十一章带隙基准 2 直流仿真 扫描温度 40 105 进行直流DC仿真
  • python 使用bottle搭建网页,如何在后台获取数据

    想利用python的bottle设计一个调查问卷 第一次接触网页 想了好久才想明白应该如何进行数据的交互操作 我们可以设置参数method GET POST 实际上我们也可以将这两部分分开 一个method GET 另一个method PO
  • 如何学习Redis

    掌握数据结构和缓存的基本使用方法 要想会用一种系统 我们首先要会一些基本操作 我们平时在开发业务系统时 或多或少地会把 Redis 当作数据库或缓存使用 Redis 也提供了非常丰富的数据结构 这也给我们的开发提供了极大的便利 所以 要想快
  • HTML表单标签及其具体使用

    HTML表单标签 文章目录 HTML表单标签 一 form标签 解析 具体使用 二 input标签 解析 具体使用 运行结果 三 textarea标签 解析 包含属性 具体使用 运行结果 四 select标签 解析 包含属性 五 optio
  • 基于JSP的毕业设计选题系统的设计与实现(源代码+论文)

    随着全球信息化技术的兴起 特别是Internet的日益普及 我国各大中专院校都建立了自己的校园网 毕业生以班级为单位的原始手工报送的选题方式已经不能适应时代发展的需求 所以基与互联网的毕业设计选题系统也就孕育而生了 毕业设计选题系统就是能够
  • 安全防御——IDS(入侵检测系统)

    安全防御 IDS 入侵检测系统 IDS介绍 为什么需要IDS IDS的工作原理 IDS的工作过程 第一步 信息收集 第二步 数据分析 IDS的主要检测方法 1 模式匹配 误用检测 2 统计分析 异常检测 3 完整性分析 异常检测 4 融合使
  • Docker镜像保存为文件及从本地文件导入镜像的方法

    1 概述 我们制作好镜像后 有时需要将镜像复制到另一台服务器使用 能达到以上目的有两种方式 一种是上传镜像到仓库中 本地或公共仓库 但是另一台服务器很肯能只是与当前服务器局域网想通而没有公网的 所以如果使用仓库的方式 只能自己搭建私有仓库
  • Linux:监控GPU状态【nvidia-smi】【watch -n 1 nvidia-smi】【pip install gpustat;gpustat -i】

    一台服务器毕竟很多人都在用 这个时候查看GPU状态显得尤为重要 查看剩余显存大小 以便自己能否使用这块卡 后来查找发现有2种方式 最开始我用的就是第一种 但是显然不是很好用 最后发现gpustat超级好用 下面分别介绍两种用法 一 nvid
  • HAL-STM32-USB内部Flash虚拟U盘更新程序

    1 IAP部分 添加fat32文件 修改Flash擦除代码 F401ccu6按扇区删除 F103按页删除 static bool fat32 write firmware const uint8 t b uint32 t addr bool