一、什么是SPIFFS?
spifs是专门为spi flash编写的文件系统,支持均匀摩擦算法。
SPIFFS不需要Heap堆内存的能力,只需要一定的工作RAM缓冲区即可。
文件系统下载链接https://github.com/pellepl/spiffs
二、SPIFFS移植
1、下载SPIFS源代码,把src他加入到自己的工程里,test文件夹可以删除,default文件夹里面的配置文件拷贝到最外层目录,最后文件结构下图
2、配置SPI FLASH的相关信息
此配置要根据自己的SPI FLASH硬件信息做相应的修改,下面是我的配置
#ifndef SPIFFS_CFG_PHYS_SZ
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*1024*4) /*flash容量*/
#endif
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536) /*擦除单位,我使用的可以配置4k,或者64k,这里配置的64k*/
#endif
#ifndef SPIFFS_CFG_PHYS_ADDR
#define SPIFFS_CFG_PHYS_ADDR(ignore) (0)/* 开始地址*/
#endif
#ifndef SPIFFS_CFG_LOG_PAGE_SZ
#define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256)/*页:写数据的单位,都是256整数倍*/
#endif
#ifndef SPIFFS_CFG_LOG_BLOCK_SZ
#define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536)/*块大小,一般和擦除的大小相同*/
#endif
3、配置FLASH的读写接口函数
#include "stm32f10x.h"
#include "stdio.h"
#include "spi_flash.h"
#include "usart.h"
spiffs SPIFlashFS;
static u8_t FS_Work_Buf[SPIFLASH_CFG_LOG_PAGE_SZ*2];
static u8_t FS_FDS[32*4];
static u8_t FS_Cache_Buf[(SPIFLASH_CFG_LOG_PAGE_SZ+32)*4];
/***********************************************
* 加载SPI FLASH文件系统
*/
void Mount_SPI_Flash_File_System(void)
{
spiffs_config SPIFlashCfg;
SPIFlashCfg.phys_size = SPIFLASH_CFG_PHYS_SZ; // SPI Flash的总容量
SPIFlashCfg.phys_addr = SPIFLASH_CFG_PHYS_ADDR; // 起始地址
// FLASH最大可擦除的块大小(W25X64可以按扇区擦除(4K)或者按块擦除(64K))
SPIFlashCfg.phys_erase_block = SPIFLASH_CFG_PHYS_ERASE_SZ;
// 块的大小(W25X64每块包含16个扇区,每个扇区4K字节,每块的总容量为:16X4=64K=65535字节)
SPIFlashCfg.log_block_size = SPIFLASH_CFG_LOG_BLOCK_SZ;
// (W25X64每页包含256个字节,16个页构成一个扇区)
SPIFlashCfg.log_page_size = SPIFLASH_CFG_LOG_PAGE_SZ;
SPIFlashCfg.hal_read_f = SPI_Flash_Read; //读
SPIFlashCfg.hal_write_f = SPI_Flash_Write; //写
SPIFlashCfg.hal_erase_f = SPI_Flash_Erase; //擦除 ,参数为地址,大小
//挂载SPIFS
int res = SPIFFS_mount(&SPIFlashFS,
&SPIFlashCfg,
FS_Work_Buf,
FS_FDS,
sizeof(FS_FDS),
FS_Cache_Buf,
sizeof(FS_Cache_Buf),
0);
}
4、测试程序
char WriteBuf[]={"Hi,Budy! if you get this Message......Congratulations!You have succeeded!!"};
char ReadBuf[80];
int main(void)
{
SPI_FLASH_Init(); //FLASH存储器初始化
Mount_SPI_Flash_File_System( );//spi flash文件系统初始化
USART_Configuration(USART1,115200,EN_IT); //初始化USART1,开接收中断
//打开文件,如果文件不存在,自动创建
spiffs_file fd = SPIFFS_open(&SPIFlashFS, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
//写文件
if (SPIFFS_write(&SPIFlashFS, fd, WriteBuf, sizeof(WriteBuf)) < 0)
printf("errno %i\n", SPIFFS_errno(&SPIFlashFS));
SPIFFS_close(&SPIFlashFS, fd);
//读文件
fd = SPIFFS_open(&SPIFlashFS, "my_file", SPIFFS_RDWR, 0);
if (SPIFFS_read(&SPIFlashFS, fd, ReadBuf, sizeof(WriteBuf)) < 0)
printf("errno %i\n", SPIFFS_errno(&SPIFlashFS));
SPIFFS_close(&SPIFlashFS, fd);
//打印输出文件内容
printf("%s\n", ReadBuf);
while(1)
{
//Nothing to do..........
}
}
4 :对回调函数的说明
SPI_Flash_Read; //读 ,参数是地址,大小
SPIFlashCfg.hal_write_f = SPI_Flash_Write; //写,页对齐,不能超过256
SPIFlashCfg.hal_erase_f = SPI_Flash_Erase; //擦除 ,参数为地址,需要擦除的大小
5 参考项目链接链接:https://pan.baidu.com/s/1WxZwqEzLLLU16ZWVl_KrkQ 密码:87ps
6可能存在的问题 :
是否s32_t SPI_Flash_Erase(u32_t Addr,u32_t Num) 函数接口有问题
应该改为 SPI_Flash_Erase2,希望有人可以验证
/*************************************************************************************
* 擦除多个扇区 (文件系统接口函数)
* Addr :擦除起始地址
* size: 要擦除的空间大小
*/
s32_t SPI_Flash_Erase2(u32_t Addr,u32_t size)
{
u32_t i,Num;
Num=size/4096;
for(i=0;i<Num;i++) {
SPI_FLASH_Write_Enable(); //SET WEL
SPI_Flash_Wait_Busy();
SPI_FLASH_CS_LOW(); //使能器件
SPIx_ReadWriteByte(W25X_SectorErase); //发送扇区擦除指令
SPIx_ReadWriteByte((u8_t)((Addr)>>16)); //发送24bit地址
SPIx_ReadWriteByte((u8_t)((Addr)>>8));
SPIx_ReadWriteByte((u8_t)Addr);
SPI_FLASH_CS_HIGH(); //取消片选
SPI_Flash_Wait_Busy(); //等待擦除完成
Addr+=4096;
}
return 0;
}