C/单片机内存管理,仿真keii

发布于:2025-08-18 ⋅ 阅读:(19) ⋅ 点赞:(0)

技术术语 全称 核心定义 主要特点 典型应用场景 技术优势 局限性 数据断电 / 上电保存性
Flash Memory(闪存) Flash Memory 非易失性存储芯片,可电擦除和重写,兼具 ROM 的非易失性和一定的可改写性 1. 非易失性,断电数据不丢失
2. 可多次擦写(数万至数百万次)
3. 读写速度快于传统 ROM
4. 分 NOR Flash(随机访问)和 NAND Flash(块访问)
1. U 盘、SD 卡、固态硬盘(SSD)
2. 智能手机、平板电脑的存储芯片
3. 嵌入式系统程序存储(路由器、智能手表)
1. 无需电池维持数据
2. 擦写速度和耐用性优于早期存储介质
3. 体积小、功耗低,容量可做大
1. 擦写次数有限,长期使用可能老化
2. 单字节写入速度较慢(尤其 NAND 类型)
3. 成本高于传统 ROM
非易失性:断电后数据永久保存,上电后可正常读取,无上电丢失问题
ARM Advanced RISC Machine(进阶精简指令集机器) 基于 RISC 架构的处理器设计方案,提供高效低功耗的计算能力 1. 采用精简指令集,执行效率高
2. 功耗低,散热性能好
3. 架构可授权定制,支持 32/64 位运算
4. 兼容性强,支持多操作系统
1. 智能手机、平板处理器(高通骁龙、华为麒麟)
2. 嵌入式设备(智能家居、物联网传感器)
3. 移动终端(笔记本、智能手表)、汽车电子
1. 低功耗适合移动设备
2. 架构灵活,可按需定制
3. 生态成熟,应用广泛
1. 高性能计算领域(如服务器)略逊于 x86
2. 高端型号成本较高
本身不存储数据:ARM 是处理器,负责数据运算,不直接存储数据,数据存储依赖外部介质(如 Flash、RAM 等),因此不存在 “上电丢失数据” 的问题。
ROM Read-Only Memory(只读存储器) 早期非易失性存储介质,数据通常出厂前写入,正常使用中不可修改 1. 非易失性,断电数据永久保存
2. 结构简单,制造成本低
3. 读取速度快,稳定性高
1. 早期计算机 BIOS 芯片
2. 家电固定程序(洗衣机、微波炉控制逻辑)
3. 游戏卡带、光盘等一次性写入介质
1. 数据稳定性极高,不易受干扰
2. 制造成本低,适合大规模生产
1. 数据一旦写入难以修改(需特殊设备)
2. 灵活性差,无法适应程序更新
非易失性:数据由工厂预先写入,断电后永久保存,上电后可直接读取,无上电丢失问题
EEPROM Electrically Erasable Programmable Read-Only Memory(电可擦除可编程只读存储器) 可通过电信号多次擦除和改写的非易失性存储,ROM 的升级类型 1. 非易失性,断电数据不丢失
2. 可字节级擦写(无需整块擦除)
3. 擦写无需特殊设备,仅需电信号
4. 擦写次数约 10 万次
1. 主板 BIOS 设置存储
2. 智能卡、IC 卡数据存储
3. 工业设备参数配置(传感器校准值)
4. 汽车电子故障码、用户设置
1. 可局部修改数据,灵活性高
2. 擦写操作简单,无需额外设备
3. 数据保存时间长(可达 10 年以上)
1. 存储容量小(几 KB 到几 MB)
2. 擦写速度较慢,不适合大量写入
3. 成本高于普通 ROM
非易失性:数据通过电信号写入后,断电不丢失,上电后可正常读取,无上电丢失问题
RAM Random Access Memory(随机存取存储器) 易失性存储介质,用于临时存放处理器正在使用的数据和程序,读写速度极快 1. 易失性,断电后数据立即丢失
2. 读写速度极快(纳秒级),远高于 Flash/EEPROM
3. 支持随机访问(任意地址直接读写)
4. 按技术分 DRAM(动态)和 SRAM(静态)
1. 计算机内存(DDR4/DDR5)
2. 手机运行内存(LPDDR5)
3. 处理器缓存(SRAM,如 CPU 三级缓存)
4. 嵌入式设备临时数据缓冲区
1. 读写速度极快,匹配处理器运算需求
2. 支持高频随机访问,适合临时数据处理
1. 易失性,断电数据丢失(需依赖外部存储持久化)
2. 容量成本高于 Flash(同等容量价格更高)
3. DRAM 需定期刷新,消耗额外功耗
易失性:依赖持续供电维持数据,断电后数据立即丢失,上电后需重新从外部存储(如 Flash)加载数据,存在 “上电丢失数据” 的特性。

 

1. pflash 分区(非易失性,断电数据保留)

存放程序代码、只读数据,特点是只读 / 少写、断电不丢失,是程序的 “静态基础”:

分区名称 作用说明 核心特性
.text(函数) 存放编译后的机器指令(程序的执行逻辑,如函数体、算法流程的二进制代码) - 程序启动后,CPU 从这里取指令执行
- 只读,运行时不可修改
.rodata 存放只读数据(全局 const 常量、字符串字面量,如 const int a = 10; - 只读,防止程序意外篡改数据
- 直接存储在 pflash,节省 RAM 空间

2. ram 分区(易失性,断电数据丢失)

存放动态数据、运行时临时空间,特点是可读写、断电清空,是程序的 “动态工作区”:

分区名称 作用说明 核心特性
.bss 存放未显式初始化的全局 / 静态变量(默认值为 0,如 int global_var; - 程序加载时,系统自动清零
- 仅占内存 “地址空间”,不占可执行文件体积
.data 存放显式初始化的全局 / 静态变量(如 int global_var = 10; - 程序加载时,从可执行文件中加载初始值
- 运行时可修改,属于 “动态数据”
.Stack(栈区) 存放函数调用的临时数据(局部变量、函数参数、返回地址等) - 自动管理:函数调用时分配,返回时释放
- 空间小、速度快,遵循 “后进先出(LIFO)”
.Heap(堆区) 存放动态分配的内存(如 C malloc、C++ new 申请的内存) - 手动管理:程序员控制分配(malloc)和释放(free
- 空间灵活,按需扩容(但需注意内存泄漏)
.Reg(寄存器区域) 处理器最核心的临时存储(存放运算中间值、指令指针、函数调用上下文) - 速度极快(比 RAM 快数倍)
- 数量少(几十个通用寄存器),硬件 / 编译器自动调度

3. 程序运行流程(pflash ↔ ram 协同)

  1. 启动阶段:程序从 pflash 的 .text 段开始执行(CPU 读取指令),rodata 提供只读常量支持。
  2. 运行阶段
    • 全局变量(.bss/.data )、局部变量(.Stack )、动态内存(.Heap )在 ram 中动态分配 / 使用;
    • 寄存器(.Reg )作为 “高速中转站”,衔接 CPU 运算与内存数据,加速程序执行。

4. 关键设计逻辑

  • “静态存储(pflash) + 动态存储(ram)” 分离:既保证程序 / 常量的 “持久化”(断电不丢),又满足运行时数据的 “灵活性”(可读写、动态分配)。
  • 不同分区的 “管理方式” 差异.Stack 自动管理(简单但空间有限)、.Heap 手动管理(灵活但需警惕泄漏)、.bss/.data 关联全局变量生命周期。


 

F1 

1.产品介绍

我们使用stm32f103c8t6系列测试

Commercial Product Code(商用产品型号) Core(内核) Frequency (MHz)(频率) Flash (Kbytes)(闪存容量) RAM (Kbytes)(随机存取存储器容量) Package(封装)
STM32F103C8T6 Cortex - M3 72 64 20 LQFP48

 

Flash 存储器(ROM)

        STM32F103C8T6 的 Flash 存储器起始地址为 0x08000000,大小为 0x10000(16 进制),即 65536 字节(10 进制),也就是 64KB。Flash 存储器用于存储程序代码和常量数据。

        65536/1024=64KB

SRAM(RAM)

        STM32F103C8T6 的 SRAM 起始地址为 0x20000000,大小为 0x5000(16 进制),即 20480 字节(10 进制),也就是 20KB。SRAM 用于存储运行时的数据和变量。

        20480/1024=20kb

BOOT1 BOOT0 启动模式 说明 0x00000000 映射地址 0x00000004 映射地址
X 0 主闪存存储器 主闪存存储器被选为启动区域(最常使用) 0x08000000 0x08000004
0 1 系统存储器 系统存储器被选为启动区域 0x1FFFF000 0x1FFFF004
1 1 内置 SRAM 内置 SRAM 被选为启动区域 0x20000000 0x20000004

 我们下面只介绍主闪存存储器启动方式

  1. 内核类型:M3/M4/M7
  2. 复位后第一步:从地址 0x00000000 取出 堆栈指针 MSP 初始值(栈顶地址 )
  3. 复位后第二步:从地址 0x00000004 取出 程序计数器 PC 初始值(复位向量 )
  4. 流程走向:Reset → 获取 MSP 值(0x00000000 )→ 获取 PC 值(0x00000004 )→ Reset_Handler
  1. 初始化 MSP:从 0X0800 0000 获取初始主堆栈指针值,为系统运行准备栈空间
  2. 初始化 PC:从 0X0800 0004 获取复位向量,指向程序执行起点
  3. 设置堆栈大小:通过 Heap_Size(堆)、Stack_Size(栈)定义堆和栈的内存分配
  4. 初始化中断向量表:基于 __Vectors 定义,建立中断服务程序映射关系
  5. 调用初始化函数:可选执行如 SystemInit,完成系统时钟、总线等基础配置
  6. 调用 __main:借助标准 C 库函数,完成全局变量初始化等准备工作,最终进入 main 函数,是 STM32 程序执行前的 “启动引导” 逻辑 ,参考资料为《STM32 启动文件浅析.pdf》 ,用于理解 STM32 程序从复位到 main 执行的底层流程 。

2.仿真

定时器

定时器3  PSC:7200-1     ARR:10000-1     CCR=ARR/2=5000

定时器定时时间:T=(7200*10000) / 72000 000=1s

PWM占空比:Duty=5000/10000=50%

PWM频率:F=72000 000 /7200 / 10000 =1HZ      或者     F=1/T=1/1=1HZ

A.时钟配置

B.寄存器

查看寄存器的值,可以看到寄存器的值和我们设置的值一样。

定时器从0开始,所以寄存器差看出来差一;

C.逻辑分析仪

 这里使用 GPIOx_IDR.y 语法,其中 x 表示 A~G 端口,y 表示 0~15 号引脚,点击 Enter 后,Keil 会自动帮我们完成引脚地址设置:

仿真设置


        在图中,选择:Use Simulator,即使用软件仿真。选择:Run to main(),即跳过汇编代码,直接跳转到 main 函数开始仿真。设置下方的:Dialog DLL分别为:DARMSTM.DLL和 TARMSTM.DLL,Parameter 均为:-pSTM32F103C8,用于设置支持 STM32F103C8 的软硬件仿真(即可以通过 Peripherals 选择对应外设的对话框观察仿真结果)。最后点击 OK,完成设置

 配置好的图:

开始我尝试使用了软件仿真,但是一直不能显示出来,(如果有大佬的话,可以指点一下,解决了少打了一个L,上面图片已经更新),我们最后选择了硬件仿真。

注意:硬件仿真,需要我们连接上我们的板子,并把程序下载进去。

A:找型号

填写如我们的上面的表中就欧克了。

可以参考我的:

01:HAL库---时钟_hal库时钟配置-CSDN博客

3.内存

 在startup_stm32f103xb.s文件里:

Stack_Size      EQU     0x00000400--》1024MB=1kB--》栈

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000200 --》500MB堆

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

stm32cubeide仿真


网站公告

今日签到

点亮在社区的每一天
去签到