第1章 基本知识
1.1 字节,页,扇区,块
本人在学习过程中,老是区分不了字节,页,扇区,块。今天就彻彻底底将这几个概念帮大家过目不忘的记住。

观察下面中学的作文本,可以知道。有14张纸,总共有28页。其中1页有11行,每1行有10个格子。

- 每1个格子表示1个字节。
- 物理存储上的页,就是作业本上的页。
- 14页纸张,就是1个扇区。一本作业本有28页,那就有2个扇区。
- 整个作业本就是1块。总共有2个扇区,28页。
在win10系统中还有一个重要的概率,簇。
定义:簇是文件系统中磁盘空间的分配单元。文件数据按照簇的大小被分割并存储在磁盘上。
在 Windows 10 中,一个 U 盘不是 一个簇(Cluster)。为了让你更容易理解,我们可以把 U 盘想象成一个大仓库 ,而簇 就是仓库里划分出的一个个标准储物箱。
1. 它们的核心区别
- U盘(整体):它是一个完整的物理存储设备,包含成千上万个甚至数以亿计的存储空间。
- 簇(局部) :它是操作系统在格式化 U 盘时,人为划分出来的最小存储单位。
2. 簇是如何工作的?
当你在 U 盘里保存文件时,系统并不是按"字节"来存放的,而是按"簇"来分配的。一个文件至少会占用一个簇。
- 大文件:如果一个文件很大,它就会被拆分成很多块,分别装进多个"簇(储物箱)"里。
- 小文件:如果一个文件非常小(比如只有 1KB),但系统设定的一个簇是 4KB,那么这个小文件依然会独占一个簇,剩下的 3KB 空间即使空着也不能放别的东西,这被称为"内部碎片"。
3. 簇的大小由什么决定?
簇的大小并不是固定的,它取决于你 U 盘的容量和格式化时选择的文件系统(如 FAT32、exFAT、NTFS)。
- 比如,对于 16GB 的 FAT32 U盘,系统默认的簇大小通常是 4KB。
- 对于 64GB 以上的 exFAT U盘,默认的簇大小可能是 8KB 或 16KB。
总结来说:U 盘是那个大仓库,而簇只是仓库里用来装文件的最小格子。一个 U 盘里包含了无数个簇。
1.2 Flash的写入和擦除
在嵌入式开发中(比如你之前提到的 SPI NOR Flash 芯片 GD25Q128),擦除和写入确实是按照"页(Page)"或"块(Block)"为单位进行的,而且它们对应的操作单位完全不同。
1.2.1 写入操作(Program / Write)
- 基本单位 :页(Page)。
- 具体规则 :数据只能以"页"为单位进行写入。例如,常见的页大小是 256 字节,这意味着你一次最多只能连续写入 256 个字节。
- 跨页限制:如果你要写入的数据超过了 256 字节,或者写入的起始地址加上数据长度超过了当前页的边界,就必须将这次写入操作拆分成多次"页编程"命令来执行。
1.2.2 擦除操作(Erase)
- 基本单位 :扇区(Sector) 或 块(Block)。
- 具体规则 :Flash 存储器绝对不能像普通内存那样直接覆盖或修改单个字节。如果你想改写某个地址的数据,必须先擦除它所在的整个区域。
- 擦除层级 :
- 扇区擦除 :这是最常用的最小擦除单位,通常大小为 4 KB(包含 16 个页)。
- 块擦除 :用于更大范围的数据删除,通常大小为 32 KB 或 64 KB(包含多个扇区)。
- 整片擦除(Chip Erase):一次性清空整个 Flash 芯片。
第2章 STM32的Flash
1.1 STM32的存储映射

1.2 STM32的Flash模块组织
可以看到的主存储器和信息块属于flash,闪存存储器不属于flash,相当于单独的外设。闪存存储器相当于上面信息块和主存储器的管理员,用于管理擦除和编程(读取flash直接进行指针读取即可,无需借用存储器)。
- STM32内部的flash只分成了页,起始地址为0x0800 0000,直到0x0801 FFFF,一共128K,每K一页,可以看到,以000、400、800、C00结尾的都是页起始地址。
- 系统存储区容量为2K,起始地址,存储系统Bootload内容。容量2K。
- 用户选项字节为16Byte,起始地址为0x1FFF F800 ,容量16Byte
- 用户选项字节和启动程序代码(系统存储区)也是flash,但是不计算在闪存容量中,闪存容量一般指程序存储区flash。
- 闪存存储器接口寄存器起始地址为0x4002 2000,属于外设,在外设存储区内



1.3 STM32的Flash的访问方式

1.4 数据的大小端格式
- Intel存储格式为小端存储:即低字节在低地址,高字节在高地址。即L_Byte(低地址) +H_Byte(高地址) ,例如0x482A = 18594。小端存储为 0x48 0x2A。

- Motorola存储格式为大端存储:即高字节在低地址,低字节在高地址。即H_Byte(低地址) +L_Byte(高地址) ,例如0x482A = 18594。大端存储为 0x2A 0x48。

1.5 keil使用技巧
为了区分程序存储空间和使用flash存储用户数据的空间大小,限制程序flash。

如果想写一个自定义的Bootload程序在尾部,也可以通过此处更改烧写程序的起始位置,但是要计算Bootload程序的大小、正式程序的大小,防止空间不足 。
右边是片上ram的内存 。
下载配置,根据需要配置下载时如何擦除程序。使用IAP选择页擦除(STM32为扇区擦除选项)



前三个数为程序占用闪存的大小,后面两个相加为占用SRAM的大小。
目前可以看到我这个程序占用flash的大小为5.03KB=5150.72B,flash地址为0x0800 0000,偏移5148B,实际存储空间到0x0800 141C左右。

使用软件核实程序的确存储到了0x0800141C左右。