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

ARM-CortexM固件升级相关问题研究

STM32F4固件升级的核心原理

内存分区:划分IAPAPP区域,以及可能的备份区域。

启动机制:根据条件选择运行IAP还是APP

通信协议:接收新固件数据的方式。

Flash操作:擦除和编程Flash的方法,特别是STM32F4的Flash控制器操作。

校验与验证:确保固件完整性和正确性,如CRC、哈希或数字签名。

安全跳转:正确配置中断和外设,确保应用程序的环境干净。

错误恢复:防止升级失败导致系统无法启动的措施。

STM32F4,固件升级时,IAP的RAM空间和APP的RAM空间会不会重复?

STM32F4的RAM是统一编址的,也就是说无论是IAP还是APP,运行时都会使用相同的物理RAM。不过,问题在于它们是否会在同一时间使用RAM导致数据冲突。当IAP运行时,它需要使用RAM来执行自己的代码和处理数据,比如接收新的固件数据。一旦IAP完成它的任务并跳转到APP,APP会重新初始化RAM,覆盖掉IAP之前使用的部分。因此,从时间上来说,IAP和APP不会同时运行,它们的RAM使用是分时的,不会同时占用,所以理论上不会有重复的问题。

为什么下载到Flash的程序能让RAM存储数据?

当微控制器复位后,首先会执行启动代码(startup code),这部分代码通常由编译器或开发环境自动生成。启动代码的任务之一就是初始化RAM中的.data段和.bss段。.data段存储已初始化的全局变量和静态变量,而.bss段存储未初始化的全局变量和静态变量,这些变量在程序运行前需要被清零。具体来说,程序在编译链接时,链接脚本(linker script)会定义Flash和RAM的内存布局。初始化的变量值会被存储在Flash中,程序启动时,启动代码会将这些初始值从Flash复制到RAM的对应位置。例如,如果一个全局变量被初始化为5,这个值在Flash中有一个副本,启动时会被复制到RAM中的变量地址,这样程序运行时就可以从RAM中读取和修改变量的值。局部变量在函数调用时通过栈(Stack)动态分配在 RAM 中,函数返回后自动释放。动态内存(堆)​​通过 malloc/free 在堆(Heap)中分配和释放。

STM32F4 startup文件的作用?

初始化堆栈指针(Stack Pointer)和堆(Heap)​、设置中断向量表(Interrupt Vector Table)​、执行复位处理(Reset_Handler)​、调用SystemInit配置时钟、提供C语言运行环境​、异常和中断管理​

Program Size: Code=11832 RO-data=20048 RW-data=272 ZI-data=13008   分别是什么意思

Code:存放程序可执行代码,烧录到FLASH中

RO-data:存放只读常量、const变量,烧录到FLASH中

RW-data:存放已初始化且需要读写的全局变量或静态变量,初始值存放在FLASH中,程序启动时从 Flash 加载到 RAM

ZI-data:存放未初始化或初始化为零的全局变量/静态变量,仅在RAM中占用空间,程序启动时由运行时库(如 Startup Code)自动初始化为零

在keil中, fromelf --bin的作用

编译链接完成后,需要将生成的可执行文件(比如.axf或.elf)转换为二进制格式

fromelf --bin --output .\outputs\STM32F405_PROJ.bin ..\Output\Template.axf

将.uvprojx文件所在目录的上一级目录,下面的Output文件夹,下面的Template.axf文件,生产bin文件,bin文件存放在.uvprojx文件所在目录下的outputs文件夹,bin文件的名称是STM32F405_PROJ.bin

生成的bin文件,前8字节为 0x200033E0 和 0x0802019D,代表什么意思

STM32上电后,会从Flash的起始地址0x08000000读取前两个32位值。第一个是初始栈指针(SP),第二个是复位处理程序的地址,也就是程序开始执行的地方。所以,在bin文件的前8字节,前4字节是栈指针,后4字节是复位向量指向Flash中的Reset_Handler

固件头部信息需要什么内容,存放在哪里?大小选取多少合适?

通常,微控制器的Flash被分为多个扇区,Bootloader和应用程序各占不同的区域。头部信息应该放在应用程序固件的起始位置,这样Bootloader在启动时可以方便地读取。

​固件标识符

uint32_t

4

唯一标识固件类型(如 0xAA55A5A5),防止刷入错误设备

​固件版本号​

uint32_t

4

版本控制(格式:主版本.次版本,如 0x0102 → v1.2)

​固件大小​

uint32_t

4

固件总大小(不含头部),用于校验文件完整性

​CRC32 校验码​

uint32_t

4

固件数据(不含头部)的 CRC32 值,用于完整性验证

​预留字段​

uint8_t[]

7

未来扩展使用(建议初始化为 0xFF)

SCB->VTOR 的值必须满足 512字节对齐​​

VTOR全称是Vector Table Offset Register,属于系统控制块(SCB)中的一个寄存器,用于指定中断向量表在内存中的起始地址。在ARM Cortex-M处理器中,中断向量表包含了各个中断服务例程(ISR)的入口地址,处理器在发生中断时会根据中断号从向量表中查找对应的ISR地址。

IAP与APP相互跳转时 为什么像复位外设、复位时钟、关中断等这些操作是必要的

外设状态残留:当从IAP跳转到APP时,之前初始化的外设(如USB、DMA)可能保持原有配置,导致与新APP中的初始化冲突。例如,USB使用的DMA通道可能在跳转后未被释放,导致ADC-DMA无法正确初始化。

中断配置冲突:IAP中可能启用了某些中断,而APP中可能没有正确重新配置或清除这些中断,导致中断服务程序(ISR)指向错误的位置,或者中断使能位未被正确管理,引发意外中断。

时钟配置问题:IAP可能修改了时钟树(如PLL配置、分频系数),而APP假设时钟处于默认状态,未重新配置,导致外设时钟频率不正确,影响功能。

程序跳转的关键步骤与注意事项

1.禁用全局中断,跳转前关闭所有中断,防止在切换过程中触发未处理的中断,导致硬件错误(HardFault)。

2.复位并关闭所有IAP阶段使用的外设,确保外设寄存器状态、DMA占用、中断标志等完全释放,避免与APP冲突。

3.​​禁用外设相关中断,清除中断挂起标志,清除外设中断使能,避免残留中断触发。

4.设置需要跳转的程序(IAP/APP)的堆栈指针和复位向量,从向量表中获取初始堆栈指针(MSP)和复位处理函数地址。

5.程序跳转,设置主堆栈指针并执行跳转函数

如何把IAP、APP拼接起来,用烧录器生产烧录

以下演示单个APP区的情况

IAP:0x08000000-0x080FFFF,大小为0x10000

固件头部信息:0x08020000-0x080201FF,大小为0x200

APP:0x08020200-0x0802FFFF,大小为0x1FE00

IAP设置程序偏移地址及程序大小

APP设置程序偏移地址及程序大小

编译后生成bin文件

用软件将IAP和APP拼成bin文件

选用什么加密/校验方式?

在从U盘读取固件时,计算CRC并与预存校验值比对,确保数据完整性。相比SHA/MD5等哈希算法,CRC算法仅需简单位移和异或操作,适合资源受限的嵌入式环境。CRC查表法仅需256*4字节的RAM(用于存储预计算表),对STM32F4的Flash/RAM资源压力极小。CRC能识别固件传输或存储过程中因干扰、硬件故障导致的单比特翻转、多比特错误、突发性错误。使用标准多项式(如CRC-32)时,未检测到错误的概率极低。0xEDB88320 是 CRC-32 的反向多项式,专为 LSB-first 计算优化。平衡了错误检测能力和计算效率,成为以太网、压缩文件等领域的事实标准。

http://www.xdnf.cn/news/405973.html

相关文章:

  • 采用AI神经网络降噪算法的通信语音降噪(ENC)模组性能测试和应用
  • 学习笔记:Conda 环境共享
  • 2025年SDK游戏盾技术深度解析:AI赋能下的DDoS/CC攻击防御革命
  • Html5新特性_js 给元素自定义属性_json 详解_浅克隆与深克隆
  • 模型上下文协议(MCP):AI的“万能插座”
  • Halcon案例(一):C#联合Halcon识别路由器上的散热孔
  • 【Vue3】使用vite创建Vue3工程、Vue3基本语法讲解
  • Windows 添加 hosts 映射
  • 零碳园区能源系统-多能互补体系
  • 星海智算云平台部署GPT-SoVITS模型教程
  • 傲云源墅:以五傲价值重构北京主城别墅格局
  • Spring MVC 和 Spring Boot 是如何访问静态资源的?
  • MySQL数据库表的约束
  • 反弹shell再入门
  • MySQL查询优化100条军规
  • 深度解析RagFlow:本地大模型驱动的高效知识库应用搭建指南
  • Java MVC
  • nRF5_SDK_17.1.0_ddde560之ble_app_uart_c 出错
  • [Java实战]Spring Boot 整合 Session 共享(十七)
  • LintCode第42题-最大子数组 II
  • 《Vuejs设计与实现》第 5 章(非原始值响应式方案) 中
  • OpenCV 的 CUDA 模块中用于将一个多通道 GpuMat 图像拆分成多个单通道图像的函数split()
  • 【AI News | 20250512】每日AI进展
  • 一键生成达梦、Oracle、MySQL 数据库 ER 图!解锁高效数据库设计!
  • 【LeetCode】49.字母异位词分组
  • 典籍知识问答重新生成和消息修改Bug修改
  • 从零搭建AI工作站:Gemma3大模型本地部署+WebUI配置全套方案
  • sqlmap使用入门
  • Linux 系统中设置开机启动脚本
  • AAAI-2025 | 中科院无人机导航新突破!FELA:基于细粒度对齐的无人机视觉对话导航