FLASH全名叫做Flash Memory,属于非易失性存储设备(Non-volatile MemoryDevice)。FLASH分层结构为块(Block)>扇区(Sector)>页(Page)。一个FLASH设备可以有多个块(Block),每个块可以对应多个扇区(Sector),每个扇区可以对应多个页(Page)。举个例子,可以将一个块(Block)看作一个存储货物的货仓,那么每个扇区(Sector)可以看作货仓里的一个集装箱,每个页(Page)看作集装箱里的一个货箱,将数据看作货箱里的货物,管理员根据实际情况去调整货物存储位置以及分配方式,即用户可以根据实际情况调整数据在FLASH中的存储位置以及分配方式。
以LPC55S69-EVK为例,其包含一个块(Block),块大小为640K,每个块包含20个扇区(Sector),扇区大小为32K,每个扇区包含64个页(Page),页大小为512B。
FLASH基本操作为读、写、擦除等。片上FLASH擦除与写操作的最小单元是页(Page),读操作最小单元为字节(Byte)。
以MCUXpresso SDK中的/boards/lpcxpresso55s69/driver_examples/flashiap为例,先熟悉FLASH基本操作的API。打开fsl_iap.h,查看如下结构体与函数。 Demo的流程为: 1. 初始化 初始化flash_config_t,并通过FLASH_GetProperty函数获取片上FLASH属性,调试得到如下结果: 通过数据手册可知: 片上FLASH为640K,其中预留了10K,故可用FLASH为630K。FLASH总大小为640K,Block数量为1,每个Block有20个32K的Sector,每个sector有64个512B的Page。
2. 擦除操作 最后一页首地址=FLASH偏移地址+FLASH总大小-页大小,使用FLASH_Erase函数对最后一页(Page)进行擦除操作,并使用FLASH_VerifyErase验证擦除,擦除操作的最小单元为页(page,512bytes)。
3. 写操作 使用FLASH_Program对最后一页(Page)进行写操作,并使用FLASH_VerifyProgram验证写入,写操作的最小单元为页(page,512bytes)。
4. 读操作 利用*(volatile uint32_t *)(地址如0x0009DC00)进行强制类型转换读取地址中的值,或使用FLASH_Read函数进行读操作,读操作的最小单元为字节(byte)。
对于片上FLASH来说,写与擦除操作最小单元是页(Page),所以写数组大小应为页大小(512bytes)或其整数倍,当然读写擦除的单元也可以是扇区(Sector),只需将数组大小更改为扇区大小(32K),并在读写擦除函数传参时修改长度参数即可。LPC55S69为32位单片机,每一个地址对应的数据为一个字节也就是8位,本例中使用的读写数组为32位,写与擦除操作单元为页(Page),故数组长度应为页大小/4。同样,在进行读操作时,每读取一个32位数据应跨过四个地址,即data01 = *(volatile uint32_t*)(0x00000000),则data02 = *(volatile uint32_t *)(0x00000004);
有些用户在对FLASH进行读操作时会出现Hard_Fault_Handler()异常中断,这是因为LPC55S69的机制是必须对FLASH ECC进行校验才可以读取,擦除FLSAH无法执行校验,而写FLASH会对ECC自动校验。故如果Flash的某个扇区处于被擦除的状态,我们只需要在通过AHB总线读取内存区域之前对该区域执行写操作,这样ECC校验更新正确后,就可以正常读Flash。详情见如下:
|