EEPROM
EEPROM是一种带电可擦的可编程只读存储器,相较于FLASH来说,EEPROM的寿命更长,写入数据之前不需要先进行擦写操作。目前市面上常见的eeprom的型号多为at24cxx,其中有02,04,08,16,32等等。
在多功能调试器上加入EEPROM的目的:主要是起一个学习作用,因为在多功能调试器硬件上其实已经有一颗EMMC了,需要保存什么配置或者日志都可以通过这颗EMMC进行,且速度更快。之所以加入EEPROM,是因为之前在网上看过一遍通过文件系统操作EEPROM的文章,当然这里的文件系统并非真正意义上的文件系统,只是通过索引加内容的方式来访问EEPROM。
当然这种方式在我看来更适用于容量稍微大一点的EEPROM,且更适用于自己学习使用,真正到项目里边感觉这种方式访问的效率与价值都不如通过其他方式来访问的高。容量小了自然不用说,比如at24c02,总的容量为:2 * 1024 / 8 = 256 (byte),如果还使用这种文件系统,那除了文件系统的索引区,剩下实际能用于存储数据的数据区将大大缩减,这样反而得不偿失了,反而通过在mcu内使用一个结构体保存相应的访问地址来访问EEPROM内的数据更加高效。
EEPROM文件系统
多功能调试器使用了两片EEPROM,型号为at24c512。这里不使用一片at24c1024的原因单纯是两篇at24c512的价格更便宜。
文件系统思路
整体来说就是将EEPROM的内存空间分为两片区域:索引区 + 数据区。
索引区分为目录区 + 地址区,目录区主要用于保存文件名、文件创建时间、文件大小以及地址区索引(用于保存指向地址区的第一个地址),地址区用于保存需要访问的数据区索引(为了实现这个操作,意味着数据区的数据块大小需要对应上地址区可存储的索引值的上限,比如说,有1KB的数据区,在使用时将每个数据块分16 byte,则整个数据区有64个块,则在地址区需要能保存0 - 63 的索引值,就当前情况而言,每个索引需要用至少6位,因为最大值为63,但是为了方便操作,每个索引占一个字节,则需要64字节的空间保存索引值)不难看出分块越大,需要的地址区越小,反之亦然。虽然分块越大可以得到更小的地址区占用,但是这样会带来一个空间利用率低的问题。所以在使用时需要合理分配。
目录区,文件名占用大小 + 文件时间占用大小 + 文件大小存储占用大小 + 地址区索引占用大小,比如32(文件名占用大小) + 14(时间用BCD码保存) + 2(最大保存 2^16 byte) + 1(0 - 63) = 49 byte。
在使用时通过文件名去遍历目录区,寻找匹配的文件。
文件系统伪代码
1. 文件系统初始化
(1)对整个目录区进行初始化操作,赋值0xFF
(2)对整个地址区进行初始化操作,赋值0xEE /* 0xEE表示当前地址区可用,0xFF表示某一个文件的结束标志 */
2. 创建文件
(1)判断剩余空间是否足够(索引区)
(2)空间足够,写入文件名、文件时间、文件大小等值,然后遍历地址区,寻找起始地址区索引值
(3)在地址区继续遍历寻找可用地址区索引,直到最后一个地址区,写入结束标志
(4)按照地址索引在数据区写入文件数据
3. 删除文件
(1)遍历目录区,找到文件信息所处位置
(2)读取文件目录区的地址索引值,通过该索引读取到下一个索引值,同时对上一个索引值做清除操作(在地址区时才进行),写入0xEE,直到在地址区找到0xFF的文件结束标志,此时同时对结束标志清除,写入0xEE
(3)清除文件信息位置,写入0xFF
4. 读取文件
(1)遍历目录区,找到文件信息所处位置
(2)按照索引读取数据区的数据,直到找到文件结束标志
5. 修改文件
(1)在文件末尾追加数据1.通过追加数据大小更新地址索引
(2)覆写文件1.计算新文件大小,更新地址区。若新文件更大,只需增加索引,但新文件更小,则需先对原文件多出新文件的索引做清除操作2.覆写文件
(3)其他写入操作对其他写入操作不做考虑,主要由于EEPROM本身的写入速度就很慢,对诸如文件中的插入写操作还需先暂存相应数据,然后在写入要插入的数据,最后还要回复原始数据,操作起来较为繁琐,所以除文件末尾追加数据与覆写文件外,其他写入操作不做考虑,下方的代码采用覆写操作