为什么访问一地址存16bits的存储芯片需要字节对齐?为什么访问外部Flash需要字节对齐?——深入理解STM32 FMC的地址映射机制

这篇文章来源于我发现的一个不解:为什么访问一地址存16bits的存储芯片需要字节对齐?我STM32G474VET6访问SST39 flash需要执行:

/* 将Flash字地址转换为STM32字节地址(字地址 × 2)*/ #define FLASH_WORD_TO_BYTE(addr_word) ((addr_word) << 1) /* 将Flash字节地址转换为字地址(字节地址 ÷ 2)*/ #define FLASH_BYTE_TO_WORD(addr_byte) ((addr_byte) >> 1)

核心是因为你的32中是8位,FMC他也觉得自己是八位,所以STM32映射到BANK的地址一个32 FMC以为8位实际代表16位,具体执行:

STM32 地址计算过程实际访问的 Flash 地址访问的数据
0x60000000(0x60000000 - 0x60000000) >> 1 =0x0000第 0 个 16 位字低字节 @0x60000000, 高字节 @0x60000001
0x60000001(0x60000001 - 0x60000000) >> 1 =0x0000(取整)第 0 个 16 位字只访问高字节(具体看字节使能信号)
0x60000002(0x60000002 - 0x60000000) >> 1 =0x0001第 1 个 16 位字低字节 @0x60000002, 高字节 @0x60000003

不是你不能访问奇数地址而是访问了也是错的,你访问

0x60000000
0x60000001

实际在fmc会输出访问同一个FLASH的地址但0x60000001的访问只访问高字节(具体看字节使能信号)访问了也没用所以执行:

/* 将Flash字地址转换为STM32字节地址(字地址 × 2)*/ #define FLASH_WORD_TO_BYTE(addr_word) ((addr_word) << 1) /* 将Flash字节地址转换为字地址(字节地址 ÷ 2)*/ #define FLASH_BYTE_TO_WORD(addr_byte) ((addr_byte) >> 1)

来消除奇数地址为偶地址达成以下效果:

STM32 地址计算过程实际访问的 Flash 地址访问的数据
0x60000000(0x60000000 - 0x60000000) >> 1 =0x0000第 0 个 16 位字低字节 @0x60000000, 高字节 @0x60000001
0x60000001(0x60000001 - 0x60000000) >> 1 =0x0000(取整)第 0 个 16 位字只访问高字节(具体看字节使能信号)
0x60000002(0x60000002 - 0x60000000) >> 1 =0x0001第 1 个 16 位字低字节 @0x60000002, 高字节 @0x60000003

引言:一个看似"异常"的访问现象

在STM32开发中,当我们通过FMC接口连接16位宽度的外部Flash时,经常会遇到一个看似奇怪的现象:访问地址0x600000000x60000001实际上访问的是Flash的同一个16位存储单元。这种"地址重叠"现象背后的原因,正是本文要深入探讨的字节对齐问题。

一、根本原因:数据宽度不匹配

1.1 两种不同的编址方式

  • STM32(CPU端):按字节(Byte)编址,每个地址对应1字节

  • 外部Flash(设备端):按字(Word,16位)编址,每个地址对应2字节

这种差异导致了地址映射的"缩放"关系。

1.2 地址总线连接

在硬件连接上,STM32的地址线A[0]通常不连接到16位Flash,因为Flash的A[0]引脚用于选择16位字内的低/高字节。STM32使用字节使能信号(NBL0/NBL1)来替代这一功能。

二、地址转换原理:右移一位的数学

2.1 转换公式

text

Flash字地址 = (STM32字节地址 - 0x60000000) >> 1
  • >> 1(右移一位)等效于除以2

  • 这是因为每个Flash地址包含2个字节

2.2 具体实例分析

STM32地址计算过程实际Flash地址访问的数据
0x60000000(0x60000000-0x60000000)>>1 = 0x0000第0个16位字低字节@0x60000000, 高字节@0x60000001
0x60000001(0x60000001-0x60000000)>>1 = 0x0000第0个16位字只访问高字节(字节使能NBL1=0, NBL0=1)
0x60000002(0x60000002-0x60000000)>>1 = 0x0001第1个16位字低字节@0x60000002, 高字节@0x60000003

关键发现0x600000000x60000001都映射到Flash的同一个16位字地址(0x0000)!差别仅在于访问的是该字的低字节还是高字节。

三、为什么需要字节对齐访问?

3.1 性能考量

非对齐访问的问题

c

// 非对齐访问示例(潜在问题) uint16_t *ptr = (uint16_t*)0x60000001; // 奇数地址! uint16_t value = *ptr; // 可能触发硬件异常或性能下降
  • 需要多个总线周期:非对齐的16位访问可能需要2次8位访问

  • 增加延迟:额外的时间开销影响实时性

  • 降低吞吐量:无法充分利用16位数据总线带宽

3.2 硬件限制

  • 某些Flash芯片:要求必须按字(16位)写入

  • 原子性保证:对齐访问确保操作的原子性

  • 时序一致性:简化时序控制逻辑

3.3 编程简化

对齐访问使得代码更易于理解和维护:

c

// 正确的对齐访问 #define FLASH_BASE ((volatile uint16_t*)0x60000000) // 按字访问,自然对齐 void write_flash(uint32_t word_index, uint16_t data) { FLASH_BASE[word_index] = data; // word_index对应Flash字地址 } // 按字节访问,明确处理高低字节 void write_flash_byte(uint32_t byte_addr, uint8_t data) { uint32_t word_addr = byte_addr >> 1; uint8_t byte_offset = byte_addr & 0x01; if (byte_offset == 0) { // 写低字节:保留高字节,更新低字节 uint16_t current = FLASH_BASE[word_addr]; current = (current & 0xFF00) | data; FLASH_BASE[word_addr] = current; } else { // 写高字节:保留低字节,更新高字节 uint16_t current = FLASH_BASE[word_addr]; current = (current & 0x00FF) | (data << 8); FLASH_BASE[word_addr] = current; } }

四、硬件实现细节:字节使能信号

FMC使用NBL[1:0](字节使能)信号来控制16位模式下的字节访问:

NBL1NBL0操作访问位置对应STM32地址
10写低字节字地址的低8位偶地址(如0x60000000)
01写高字节字地址的高8位奇地址(如0x60000001)
00写整个字整个16位字偶地址(16位对齐)

当访问0x60000001时:

  • FMC仍然向Flash发送地址0x0000

  • 但设置NBL[1:0] = 01,表示"只操作高字节"

  • Flash芯片根据此信号只更新对应字节

五、实际应用建议

5.1 地址转换宏的正确使用

c

/* Flash字地址 → STM32字节地址(字地址 × 2)*/ #define FLASH_WORD_TO_BYTE(addr_word) ((addr_word) << 1) /* Flash字节地址 → 字地址(字节地址 ÷ 2)*/ #define FLASH_BYTE_TO_WORD(addr_byte) ((addr_byte) >> 1) /* 实际使用示例 */ uint32_t flash_word_addr = 0x1000; // Flash的第0x1000个16位字 uint32_t stm32_byte_addr = 0x60000000 + FLASH_WORD_TO_BYTE(flash_word_addr); // 结果:0x60000000 + 0x2000 = 0x60002000

5.2 数据类型选择

c

// 推荐:使用对齐的16位指针 volatile uint16_t *flash_ptr = (volatile uint16_t*)0x60000000; // 不推荐:使用8位指针进行16位数据操作 volatile uint8_t *byte_ptr = (volatile uint8_t*)0x60000000; // byte_ptr[0]和byte_ptr[1]实际上属于同一个Flash字

5.3 内存布局规划

c

// 在链接脚本中确保Flash数据区对齐 .section .extflash, "aw", %progbits .align 2 // 2字节对齐(16位) .global _extflash_base _extflash_base: .space 0x100000 // 预留1MB外部Flash空间

六、特殊情况处理

6.1 混合字节/字访问策略

c

// 灵活处理对齐和非对齐访问 uint16_t read_flash_any(uint32_t stm32_addr, uint8_t size) { if (size == 2 && (stm32_addr & 0x01) == 0) { // 16位对齐访问:最优性能 return *(volatile uint16_t*)stm32_addr; } else { // 非对齐或8位访问:分解操作 volatile uint8_t *p = (volatile uint8_t*)stm32_addr; if (size == 1) return p[0]; else return (p[0] | (p[1] << 8)); // 注意:p[0]和p[1]可能跨字边界 } }

6.2 DMA传输的对齐要求

c

// DMA通常要求源/地址对齐 // 对于16位Flash访问,DMA地址必须是2的倍数 void setup_dma_for_flash(uint32_t flash_word_addr, uint32_t count) { uint32_t stm32_addr = 0x60000000 + (flash_word_addr << 1); // 检查地址对齐 if ((stm32_addr & 0x01) != 0) { // 处理非对齐:需要特殊处理或调整 handle_unaligned_dma(); } else { // 标准DMA配置 DMA1->CPAR = stm32_addr; // 外设地址(Flash) DMA1->CMAR = (uint32_t)buffer; // 内存地址 DMA1->CNDTR = count * 2; // 传输字节数(字数×2) } }

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

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

相关文章

嵌入式存储芯片驱动解析:标准化接口与STM32 FMC配置指南

一、不同存储芯片的驱动共性&#xff1a;标准化接口设计1.1 JEDEC标准&#xff1a;工业界的通用语言在嵌入式存储领域&#xff0c;虽然不同厂商生产的NOR Flash、PSRAM等存储芯片在性能、价格上有所差异&#xff0c;但它们都遵循一个共同的标准——JEDEC&#xff08;固态技术协…

2026年不锈钢黑棒厂商大比拼,哪些值得您信赖,2205不锈钢板/不锈钢酸洗板,不锈钢黑棒直营工厂哪个好 - 品牌推荐师

近年来,随着制造业升级与新兴领域需求释放,不锈钢黑棒作为关键基础材料,其市场呈现“需求多元化、品质高端化、交付高效化”的显著趋势。尤其在食品医疗、精密仪器、新能源装备等对材料耐腐蚀性、尺寸精度要求严苛的…

大二上英语期末

大二上英语期末 填词 module1:internet 1.maintain contact with their old 2.familiar with the scenario of people sitting next to each other 3.be immersed in social media module2:zhenghe module3:travel …

从模型训练到RKNN部署:YOLOv8姿态识别在RK3588上的高精度实时落地方案

文章目录 【YOLOv8-pose姿态识别部署至RK3588:模型训练到RKNN落地,让人体姿态分析精度与边缘推理速度双突破】 一、项目背景与技术选型:为何选择YOLOv8-pose+RK3588? 二、环境搭建:从代码仓库到硬件适配 1. 源码获取与工程结构 2. 依赖安装与硬件配置 三、YOLOv8-pose模型…

6.9 Elasticsearch-单元测试:ESSingleNodeTestCase ESIntegTestCase

6.9 Elasticsearch-单元测试&#xff1a;ESSingleNodeTestCase & ESIntegTestCase 6.9.1 为什么需要两类测试基类 Elasticsearch 的源码里&#xff0c;90 % 的“单元测试”其实都在和磁盘、网络、集群状态打交道。 如果你只想验证一个分词器、一个聚合器或者一个查询解析…

YOLOv13高性价比改进模块:轻量化设计下mAP提升6.556个百分点

绿色线条为优化后的模型,map50提升2.31个点!map50 文章目录 移植 创建ultralytics\cfg\models\v13\yolov13-GSConv.yaml 修改ultralytics\nn\tasks.py 修改ultralytics/nn/modules/__init__.py 修改ultralytics\nn\modules\block.py GSConv卷积架构深度原理解析 引言 设计背景…

YOLOv13实战进阶:手把手教你添加注意力机制,检测精度显著提升

文章目录 @[toc] 深度解析与实践:在YOLOv13中集成注意力机制 引言:YOLOv13与深度学习的焦点 第一章:理解注意力机制——为什么以及是什么? 1.1 为什么目标检测需要注意力机制? 1.2 注意力机制的分类与基本原理 第二章:精选注意力模块的原理与实现 2.1 模块一:Squeeze-an…

YOLOv8性能突破秘籍:融合HAttention,让目标检测精度飙升

文章目录 《YOLOv8融合HAttention:激活更多像素的注意力机制科研实践指南》 一、为什么HAttention是像素激活的“密钥”? 二、HAttention的原理深度解析 1. 核心设计:层级化像素激活与融合 2. 与传统注意力机制的对比 三、HAttention的代码实现与YOLOv8集成 1. HAttention核…

6.10 Elasticsearch-提 PR 规范:CLA 签署、issue 关联、Backport 流程、release note

6.10 Elasticsearch-提 PR 规范&#xff1a;CLA 签署、issue 关联、Backport 流程、release note 向 Elasticsearch 官方仓库提 PR 时&#xff0c;代码质量只是“入场券”&#xff0c;真正决定合并速度的是你对社区流程的熟悉度。本节把四个最容易被 maintainers 打回票的环节…

跨端Flutter × OpenHarmony调色板应用首页设计与实现—基于颜色分类枚举与数据模型的工程化实践

文章目录跨端Flutter OpenHarmony调色板应用首页设计与实现—基于颜色分类枚举与数据模型的工程化实践前言背景Flutter HarmonyOS 6.0 跨端开发介绍开发核心代码与解析一、首页入口组件&#xff1a;IntroPage设计说明二、颜色分类枚举&#xff08;ColorCategory&#xff09;为…

AI技术支持的论文平台测评与专业润色方案

AI论文工具对比分析 工具名称 处理速度 降重幅度 独特优势 aicheck 极快 高&#xff08;40%→7%&#xff09; 精准保留专业术语 askpaper 快 中高&#xff08;45%→8%&#xff09; 上下文逻辑完整 秒篇 较快 高&#xff08;38%→6%&#xff09; 简化操作界面 a…

智能学术写作:AI平台评测与文本润色服务优化

AI论文工具对比分析 工具名称 处理速度 降重幅度 独特优势 aicheck 极快 高&#xff08;40%→7%&#xff09; 精准保留专业术语 askpaper 快 中高&#xff08;45%→8%&#xff09; 上下文逻辑完整 秒篇 较快 高&#xff08;38%→6%&#xff09; 简化操作界面 a…

AI优化论文写作:7大专业平台支持格式规范与LaTeX适配

工具快速对比排名&#xff08;前7推荐&#xff09; 工具名称 核心功能亮点 处理时间 适配平台 aibiye 学生/编辑双模式降AIGC 1分钟 知网、万方等 aicheck AI痕迹精准弱化查重一体 ~20分钟 知网、格子达、维普 askpaper AIGC率个位数优化 ~20分钟 高校检测规则通…

【SpringBoot】SpringMVC 请求注解详解 响应注解详解 Lombok - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

智能学术助手:7个平台提供格式规范与LaTeX支持

工具快速对比排名&#xff08;前7推荐&#xff09; 工具名称 核心功能亮点 处理时间 适配平台 aibiye 学生/编辑双模式降AIGC 1分钟 知网、万方等 aicheck AI痕迹精准弱化查重一体 ~20分钟 知网、格子达、维普 askpaper AIGC率个位数优化 ~20分钟 高校检测规则通…

智慧农业树上猕猴桃检测数据集VOC+YOLO格式2810张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数)&#xff1a;2810标注数量(xml文件个数)&#xff1a;2810标注数量(txt文件个数)&#xff1a;2810标注类别…

用户 Token 到底该存哪?

🧑‍💻 写在开头 点赞 + 收藏 === 学会🤣🤣🤣面试官问:"用户 token 应该存在哪?" 很多人脱口而出:localStorage。 这个回答不能说错,但远称不上好答案。 一个好答案,至少要说清三件事:有哪些…

AI工具助力论文撰写:高效生成与降重,初稿轻松搞定

AI工具性能速览表 工具名称 核心功能 处理时间 AI生成率控制 适配检测平台 askpaper 降AIGC率降重同步 20分钟 个位数 知网/格子达/维普 秒篇 AI痕迹深度弱化 20分钟 个位数 知网/格子达/维普 aicheck 全学科初稿生成 20-30分钟 低水平 - aibiye 文献智能…

从原理到落地:Mamba-YOLOv8 全面实战指南(源码 + 训练 + 部署一次学会)

文章目录前言一、技术背景与动机1.1 传统架构的局限性1.2 Mamba的创新优势二、Mamba-YOLOv8架构详解2.1 整体架构设计2.2 核心模块&#xff1a;VSSblock2.3 SS2D模块工作原理三、完整实现流程3.1 环境配置3.2 代码集成步骤3.3 训练与微调四、性能分析与优化4.1 精度提升策略4.2…

vue3+python气象数据共享平台 天气预报数据共享系统

目录气象数据共享平台摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;气象数据共享平台摘要 该系统基于Vue3前端框架与Python后端技术构建&#xff0c;旨在实现高效、安全的气象数据共享…