news 2026/5/10 7:42:12

嵌入式从零开始(第七篇):存储与地址 —— 大小端、内存映射、4GB 空间之谜

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
嵌入式从零开始(第七篇):存储与地址 —— 大小端、内存映射、4GB 空间之谜

前言:两个“内存”概念的冲突

初学 STM32 时,我们一定会遇到两个矛盾的说法:

  • 数据手册说:Flash 64KB,RAM 20KB
  • 教程里讲:32 位单片机可以寻址 4GB 空间

到底哪个是对的? ——两个都对,但说的是不同维度

  • 64KB Flash / 20KB RAM是芯片内部实际存在的物理存储器大小。
  • 4GB 寻址空间是 CPU 能访问的地址范围(地址总线的能力),并不代表真有 4GB 的存储器。

就像你家有一个 100 平米的房子(实际存储),但你手里的钥匙可以打开整栋楼 1000 户的门(寻址能力)——只不过其中 990 户是空的(保留地址),你不能随便闯进去。


一、存储器映射:一张 4GB 的“地址地图”

存储器映射(Memory Map)是芯片设计者预先定义的一张表,规定了 4GB 地址空间里每一块区域用来干什么。

ARM Cortex-M 内核规定了一个统一的 4GB 地址布局,而芯片厂商(如 ST)在这个框架内填充自己的具体内容。

以 STM32F103 为例(地址从低到高):

起始地址结束地址大小用途说明
0x000000000x1FFFFFFF512MB代码区(Code)通常映射到 Flash,存放程序
0x200000000x3FFFFFFF512MBSRAM 区实际只有 20KB 在这里
0x400000000x5FFFFFFF512MB外设寄存器区GPIO、USART、定时器等寄存器
0x600000000xDFFFFFFF2GB外部存储器区FSMC 连接外部 SRAM/NOR
0xE00000000xFFFFFFFF512MB内核私有区NVIC、SysTick、调试等

注意:大部分区域标注的是“保留”(Reserved),访问它们会导致 HardFault 或读出随机数据。

关键点统一编址—— 无论是 Flash、RAM 还是外设寄存器,都被分配了独一无二的地址。CPU 不需要特殊的 I/O 指令,直接用ldr/str就能操作外设。这正是 C 语言指针可以操控寄存器的根本原因。


二、实际物理存储器在哪里?

虽然地图有 4GB 大,但芯片里真正焊接的“仓库”只有这几处:

  • Flash:从0x08000000开始(通过映射,也可从0x00000000访问)。大小通常 16KB~2MB。
  • SRAM:从0x20000000开始。大小通常 6KB~512KB。
  • 外设寄存器:从0x40000000开始,每个寄存器占 1~4 字节。

访问其他地址(比如0x30000000)会导致总线错误(HardFault)。所以,4GB 是理论寻址范围,不是物理存储容量


三、什么是大小端模式?

大小端(Endianness)是指多字节数据在内存中的存储顺序

假设有一个 32 位整数0x12345678,它在内存中的存放方式有两种:

大端模式(Big-Endian)

  • 高字节存低地址,低字节存高地址
  • 地址 0x1000:0x12,0x1001:0x34,0x1002:0x56,0x1003:0x78
  • 符合我们的阅读顺序(如:1234:1-千位,2-百位,3-十位,4-个位,从左到右读,但是左边代表的是最大的数)。

小端模式(Little-Endian)

  • 低字节存低地址,高字节存高地址
  • 地址 0x1000:0x78,0x1001:0x56,0x1002:0x34,0x1003:0x12
  • 这是 x86、ARM(默认)采用的方式。

为什么会有大小端
主要是历史原因和 CPU 设计哲学差异。网络协议规定使用大端(称为网络字节序),而 PC 和大多数嵌入式处理器使用小端。因此跨平台通信时必须转换字节序。


四、如何判断你的系统是大端还是小端?

下面这段经典代码,利用了联合体(union)共享内存的特性:

#include<stdio.h>intmain(){union{uint32_tword;uint8_tbytes[4];}test;test.word=0x12345678;if(test.bytes[0]==0x78)printf("Little-endian\n");elseprintf("Big-endian\n");return0;}
  • 如果bytes[0]0x78,说明低地址存低位 → 小端。
  • 如果bytes[0]0x12,说明低地址存高位 → 大端。

STM32(ARM Cortex-M)默认是小端模式,但有些 ARM 核心可以配置为大端(需要硬件支持)。


五、大小端对嵌入式开发的实际影响

1. 数据解析(串口、I2C、SPI 接收)

假设你通过串口收到两个字节0x120x34,协议规定这是大端的一个 16 位整数。
正确拼装:value = (buf[0] << 8) | buf[1];
如果协议是小端:value = (buf[1] << 8) | buf[0];
搞反了就会得到错误数值。

2. 寄存器访问

当你用 32 位指针访问一个 8 位寄存器数组时,大小端影响哪个字节对应哪个地址。不过外设寄存器通常按小端设计,直接赋值即可。

3. 网络通信

TCP/IP 协议规定使用大端。所以发送多字节整数前要用htonl/htons转换,接收后用ntohl/ntohs还原。

4. 文件存储

如果直接保存内存中的结构体到 SD 卡,换个不同端序的设备读取就会乱码。解决办法:统一使用小端或大端存储,或使用文本格式(如 JSON)。


六、一个容易混淆的概念:地址 vs 数据

很多新手会问:“地址 0x20000000 里存的是大端还是小端?”
大小端是针对多字节数据的存储顺序,地址本身没有端序。地址0x20000000是一个数值,它在指令中是以字节序列存在的,但 CPU 会自动处理。


七、STM32 的实际内存布局(以 F103C8T6 为例)

  • Flash0x08000000~0x0800FFFF(64KB)
  • SRAM0x20000000~0x20004FFF(20KB)
  • 外设
    • GPIOA:0x40010800~0x40010BFF
    • USART1:0x40013800~0x40013BFF
    • TIM2:0x40000000~0x400003FF

我们可以在参考手册的“Memory Map”章节找到完整列表。


八、常见误区与注意事项

  1. “STM32 有 4GB 内存”
    没有,只有几十 KB 到几 MB 的物理 RAM,但可以外扩。

  2. “指针可以随便指向任何地址”⚠️
    指向保留地址会触发 HardFault。除非你确定该地址有有效设备。

  3. “大小端只在跨平台时重要”⚠️
    即使本地开发,如果你通过 DMA 将数据从外设搬到 RAM,也要了解外设的端序(大多数与 CPU 一致)。

  4. “联合体判断大小端不通用”⚠️
    在某些 DSP 或特殊架构上可能因对齐问题失效,但嵌入式 Cortex-M 上没问题。


九、总结

  • 存储器映射:4GB 地址空间的分配表,包括代码、SRAM、外设、保留区。
  • 实际物理存储:Flash 和 SRAM 只占地图的一小部分,其余地址访问会出错。
  • 大小端:多字节数据的存储顺序(大端:高字节在低地址;小端:低字节在低地址)。
  • STM32 默认为小端,但网络协议使用大端,通信时需要转换。
  • 影响场景:数据解析、寄存器访问、网络通信、文件存储。

理解了存储映射,我们就知道*(uint32_t *)0x40010800 = 0x55;为什么能点亮 LED(因为那是 GPIO 寄存器的地址)。掌握了大小端,你就能轻松应对各种协议解析,不再被乱码困扰。


系列导航

  • 第一篇:嵌入式到底是什么?(含 ARM/C51/STM32 关系)
  • 第二篇:串口江湖 —— UART、RS-232、RS-485
  • 番外篇:波特率解析
  • 第三篇:两线走天下 —— I2C 总线精讲
  • 第四篇:极速先锋 —— SPI 总线精讲
  • 第五篇:嵌入式大脑 —— 中断与事件驱动
  • 第六篇:时间管理大师 —— 定时器与系统滴答
  • 第七篇:存储与地址 —— 大小端、内存映射、4GB 空间之谜(本文)
  • 第八篇:从裸机到 RTOS —— 任务、调度、FreeRTOS(预告)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/13 9:00:00

微信对接OpenClaw的常见问题和解决方案懊

AI Agent 时代的沙箱需求 从 Copilot 到 Agent&#xff1a;执行能力的质变 在生成式 AI 的早期阶段&#xff0c;应用主要以“Copilot”形式存在&#xff0c;AI 仅作为辅助生成建议。然而&#xff0c;随着 AutoGPT、BabyAGI 以及 OpenAI Code Interpreter&#xff08;现为 Advan…

作者头像 李华
网站建设 2026/4/13 14:28:32

AI开发-python-langchain框架(--并行流程 )厥

如果有多个供应商&#xff0c;你也可以使用 [[CC-Switch]] 来可视化管理这些API key&#xff0c;以及claude code 的skills。 # 多平台安装指令 curl -fsSL https://claude.ai/install.sh | bash ## Claude Code 配置 GLM Coding Plan curl -O "https://cdn.bigmodel.cn/i…

作者头像 李华
网站建设 2026/4/17 17:36:57

河北双迹美业系统源码开发

河北双迹美业系统源码开发涉及美容行业管理软件的定制化开发&#xff0c;通常包括会员管理、预约管理、库存管理、财务管理等功能模块。以下是开发此类系统的关键要点&#xff1a;功能模块设计 会员管理模块需支持会员信息录入、消费记录查询、积分管理等功能。预约管理模块应实…

作者头像 李华
网站建设 2026/4/13 4:26:02

STM32F407 USART3驱动详解:从零构建RS485通信链路

1. RS485通信与STM32F407 USART3的硬件连接 在工业环境中&#xff0c;RS485通信因其抗干扰能力强、传输距离远等优势被广泛应用。STM32F407的USART3外设通过简单的转换芯片即可实现RS485通信功能。这里我们以MAX485芯片为例&#xff0c;讲解硬件连接的关键点。 MAX485芯片的RO引…

作者头像 李华