STM32Flash读写BUG,坑—————4字对齐

在 STM32 的 Flash 存储中,数据通常需要 4 字节对齐,这是由于其 Flash 存储的硬件设计和写入操作的限制决定的。
以下是更详细的原因与解释:

1. STM32 的 Flash 写入单位

STM32 的 Flash 通常以字(Word,4 字节 = 32 位)为基本操作单位。这意味着:

  • Flash 写操作是以 字(Word, 32 位)为最小单元进行的。
  • 即使你写入的数据小于 4 字节,底层的硬件仍然会以 4 字节为一组操作。
    因此,如果写入的数据没有 4 字节对齐,可能会导致:
  • 无法正确写入,或者写入错误(由于未对齐的数据会覆盖相邻的区域)。
  • 数据损坏,因为 Flash 的写入粒度为 4 字节,非对齐操作会导致其他区域被意外擦写。

2. 具体对齐要求的原因

以下是 STM32 Flash 对 4 字节对齐的需求来源:

  1. Flash 的最小写入单元
    • 对于许多 STM32 系列芯片,Flash 的最小写入单元是 4 字节(即 32 位)。
    • 例如:
      • STM32F1 系列:最小写入单元是 16 位(2 字节)。
      • STM32F4/F7/H7 系列:最小写入单元是 32 位(4 字节)。
      • 有些高端 STM32 芯片(如 H7 系列)甚至支持 64 位对齐。
    • 因此,Flash 写入时,数据地址通常必须满足 4 字节对齐
  2. Flash 擦除机制
    • Flash 的擦除是以扇区(Sector)或页(Page)为单位的。
    • 即使你只修改 1 个字节,底层硬件也需要先擦除整个扇区,然后重新写入。
    • 如果数据不对齐,可能会导致其他数据被意外覆盖。
  3. 总线访问限制
    • Cortex-M 内核(ARM 架构)的总线访问通常也要求数据地址对齐,尤其是对于 32 位数据,地址必须是 4 字节对齐的。
    • 如果不对齐,可能会触发硬件异常(如总线错误,BusFault)。

3. 如何保证数据对齐

在实际开发中,可以采取以下措施来保证数据对齐:

  1. 数据地址对齐
    使用编译器或语言提供的对齐属性。例如,在 C 语言中,可以使用 __attribute__((aligned(4))) 强制变量地址对齐:
    uint32_t flash_data __attribute__((aligned(4))) = 0x12345678;
    
  2. 写入时确保对齐
    • 如果需要写入非 4 字节对齐的数据,可以将数据填充(Padding)为 4 字节对齐后再写入。
    • 例如,使用数组或者结构体填充到 4 字节:
      uint8_t data[4] = {0x12, 0x34, 0x56, 0x78};
      HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *(uint32_t *)data);
      
  3. 结构体对齐
    如果使用结构体来存储数据,注意对齐方式,并设置合适的对齐规则。例如:
    typedef struct {uint32_t data1;uint32_t data2;
    } FlashData;
    
  4. Flash 写入函数约束
    STM32 的 HAL 库(或 LL 库)中通常会要求传入的数据是 32 位的,函数会强制你按照 4 字节对齐来传入数据。

4. 注意事项

  • 如果你尝试写入非对齐数据,STM32 的 Flash 控制器通常会拒绝操作或者抛出错误。
  • 还需注意的是,在 Flash 写入操作之前,必须先擦除相应的扇区或页,才能避免数据覆盖。
  • 对于需要频繁更新的数据,可以考虑将非对齐数据通过 RAM 或其他中间缓存调整对齐后,再写入 Flash。

总结

在 STM32 的 Flash 写入中,数据必须满足 4 字节对齐的要求,这是由硬件设计和写入机制决定的。如果你的数据不满足对齐要求,需要在写入之前手动对其进行填充或调整,确保写入操作的正确性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/66689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring-Cloud-Gateway-Samples,nacos为注册中心,负载均衡

背景:本想找个简单例子看下,无奈版本依赖太过复杂,花了点时间。记录下吧 使用Spring Cloud Gateway作为网关服务,Nacos作为注册中心,实现对子服务的负载均衡访问。简单例子。 一、gateway-main-nacos服务端&#xff…

LLM的实验平台有哪些:快速搭建测试大语言模型

LLM的实验平台有哪些:快速搭建测试大语言模型 目录 LLM的实验平台有哪些:快速搭建测试大语言模型低代码平台工程观测平台本地应用平台在线编程竞技场性能排名代码质量评估开源框架Hugging Face是一个机器学习和数据科学平台及社区主要功能开源工具与库应用场景优势低代码平台…

Springboot Rabbitmq + 线程池技术控制指定数量task执行

定义DataSyncTaskManager,作为线程池任务控制器 package org.demo.scheduletest.service;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueu…

51单片机 和 STM32 在硬件操作上的差异

51单片机 和 STM32 在硬件操作上的差异 1. 时钟系统的差异 STM32 的时钟系统 STM32 的时钟系统非常复杂,支持多种时钟源(如内部晶振、外部晶振、PLL 等),并且每个外设(如 GPIO、定时器、串口等)都有独立的…

T-SQL语言的编程范式

T-SQL编程范式探析 引言 随着信息技术的迅猛发展,数据库在各个行业的应用日益广泛。在众多数据库管理系统中,SQL Server以其高性能和易用性受到广泛欢迎。T-SQL(Transact-SQL)是SQL Server的扩展版本,是一种用于查询…

每日学习30分轻松掌握CursorAI:初识Cursor AI

初识Cursor AI 一、什么是Cursor AI? Cursor AI是一款革命性的AI驱动型代码编辑器,它将传统的代码编辑功能与先进的人工智能技术相结合。它不仅是一个编辑器,更是一个智能编程助手,能够帮助开发者提高编码效率,解决编…

小米路由器IPv6 功能使用指南

本文不限于多层路由使用IPv6 的情况,提供解决IPv6 无法获取的更硬核的方法,需要有ssh 工具。(无安卓设备,测试环境win、mac、ios) 首先明确一点,就是如果想让你的设备得到GUA 地址,即访问 6.i…

云商城--业务+架构学习和环境准备

云商城业务架构学习和环境准备 B2B:Business to Business,交易双方的身份都是商家,也就是商家将商品卖给商家,类似采购、批发类购物,国内代表性网站阿里巴巴批发网 C2C:Customer to Customer,…

vk-unicloud如何简单实现邮箱发送验证码?

以下代码是云函数发送验证码api,直接复制改个人参数: 其中"user"和"pass"使用自己的账号数据,如何拿到看以下步骤: 网易邮箱6.0版:登录--点击设置--点击POP3/SMTP/IMAP--点击开启服务&#xff1…

机器视觉系统中的重要配件--棱镜

在一套机器视觉系统中,人们一直比较注中工业相机、工业镜头及光源等重要的视觉器件,而小配件通常被忽视,虽然只是配角,但是却起着重要作用。以下以茉丽特镜头为例。 在构建视觉系统当中,遇到某个方向空间不足时&#x…

射频到底是什么

背景: 由于工作中wifi, gps 等等,经常使用到射频这个概念,一直很模糊,于是特此了解并记录一下。 概念理解: 射频可以理解为发射一个信号,该信号本质上是交流电所产生的电磁波, 一般通过这种方…

Flink-CDC 全面解析

Flink-CDC 全面解析 一、CDC 概述 (一)什么是 CDC CDC 即 Change Data Capture(变更数据获取),其核心要义在于严密监测并精准捕获数据库内发生的各种变动情况,像数据的插入、更新以及删除操作&#xff0…

PHP语言的字符串处理

PHP语言的字符串处理 引言 字符串是编程中最基本的数据类型之一,通常用于存储和操作文本数据。在PHP语言中,对字符串的处理非常灵活且强大。无论是简单的字符操作,还是复杂的模式匹配,PHP都提供了丰富的函数和工具来满足不同的需…

PHP的扩展Imagick的安装

windows下的安装 下载:Imagick扩展 PECL :: Package :: imagick 3.7.0 for Windows​​​​​​​ 下载:ghostscript(PDF提取图片时用到,不处理PDF可以不安装) Ghostscript : Downloads 安装扩展 Imagick解压后&…

THREE.js的VideoTexture以及CanvasTexture在部分浏览器以及小程序webview中纯黑不起作用的解决办法

黑色是因为video没有自动播放导致的。 而且video必须设置muted(静音)属性,否则视频都无法播放; 如果不设置muted,也可以用设置x5-video-player-type"h5" 替代(意为兼容qq浏览器,解决在小程序中黑…

【redis】ubuntu18安装redis7

在Ubuntu 18下安装Redis7可以通过以下两种方法实现:手动编译安装和使用APT进行安装。 Ubuntu 18系统的环境和版本: $ cat /proc/version Linux version 4.15.0-213-generic (builddlcy02-amd64-079) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)…

Java实现迭代器模式

一、简介 1、定义 迭代器模式(Iterator Pattern)是一种面向集合对象而生的行为设计模式。对于集合对象而言,会涉及对集合的添加和删除操作,也要支持遍历集合元素的操作。可以把遍历操作放在集合对象中,但这样做,集合对象就承担太…

uniapp中h5使用地图

export function loadTMap(key) {return new Promise(function(resolve, reject) {window.init function() {// resolve(qq) //注意这里resolve(TMap) //注意这里}var script document.createElement("script");script.type "text/javascript";// scrip…

获取地图文档中的图层列表

大多数情况下,获取地图文档中的图层列表是地理处理脚本中的首要工作之一.获取图层列表后,脚本可以循环遍历每个图层并执行某些类型的处理.制图模块中的ListLayers()函数提供获取图层列表的功能.本节将学习如何获得地图文档中的图层列表. 操作方法: 1.在arcgis中打开地图文件 …

软件系统安全逆向分析-混淆对抗

1. 概述 在一般的软件中,我们逆向分析时候通常都不能直接看到软件的明文源代码,或多或少存在着混淆对抗的操作。下面,我会实践操作一个例子从无从下手到攻破目标。 花指令对抗虚函数表RC4 2. 实战-donntyousee 题目载体为具有漏洞的小型软…