你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

SPIFFS文件系统移植–基于STM32F407

[复制链接]
huangxuejia-292 发布时间:2018-6-3 22:44
本帖最后由 huangxuejia-29212 于 2018-6-3 22:47 编辑

SPIFFS文件系统,有什么特别呢?
从名字就可知,这是一个用于SPI FLASH的file system。
现在好像在ESP8266上用的很多,感觉慢慢有的人气了。
从特性上说,这个文件系统用很少的RAM资源。
但是,我最后会吐槽吐槽这个特性的。
网络上资源不多,好在github上说明文档挺全。

github
地址:http://github.com/pellepl/spiffs
最新版本是0.3.7.
目录结构如下:

添加到工程的文件如下:
在github上有wiki说明如何移植
http://github.com/pellepl/spiffs/wiki
认真读完这个wiki,基本就知道如何使用spiffs。
对于spiffs的设计,有一个网站可做参考, spiffs技术手册。
http://blog.csdn.net/zhangjinxing_2006/article/details/75050611

移植概述

下面我们说说移植的过程。
1. 配置
spiffs-0.3.7\src\default下有一个默认的配置文件,spiffs_config.h。
为了方便,拷贝一个到spiffs-0.3.7\src。
在工程中,头文件搜索路径,只包含src路径,不要包含\src\default。
spiffs_config.h头部包含的头文件修改如下。
在这里也定义了变量名。
  1. //#include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stddef.h>
  5. #include "stm32f4xx.h"

  6. typedef u32  u32_t;
  7. typedef u16 u16_t;
  8. typedef u8  u8_t;

  9. typedef s32  s32_t;
  10. typedef s16 s16_t;
  11. typedef s8  s8_t;
复制代码

修改几个宏定义
  1. #ifndef SPIFFS_USE_MAGIC
  2. #define SPIFFS_USE_MAGIC                (1)
  3. #endif

  4. #ifndef SPIFFS_USE_MAGIC_LENGTH
  5. #define SPIFFS_USE_MAGIC_LENGTH         (1)
  6. #endif
  7. #endif
复制代码

在spiffs-0.3.7\src\spiffs_nucleus.h文件中定义的联合用了一个gcc特性,在MDK编译会报错。
在联合前增加一句代码#pragma anon_unions 即可。
  1.   
  2.   #pragma anon_unions
  3.   union {
  4.     // type read cache
  5.     struct {
  6.       // read cache page index
  7.       spiffs_page_ix pix;
  8.     };
  9. #if SPIFFS_CACHE_WR
  10.     // type write cache
  11.     struct {
  12.       // write cache
  13.       spiffs_obj_id obj_id;
  14.       // offset in cache page
  15.       u32_t offset;
  16.       // size of cache page
  17.       u16_t size;
  18.     };
  19. #endif
  20.   };
  21. } spiffs_cache_page;
复制代码

2 应用
首先,
要实现SPI FLASH操作函数,SPIFFS需要的函数格式如下
  1. s32_t core_spiflash_spiffs_read(u32_t addr, u32_t size, u8_t *dst);
  2. static s32_t core_spiflash_spiffs_write(u32_t addr, u32_t size, u8_t *src);
  3. static s32_t core_spiflash_spiffs_erase(u32_t addr, u32_t size);
复制代码

第二,
定义文件系统相关参数
  1. /*
  2.         文件系统配置
  3.        
  4.         #define SPIFFS_SINGLETON (0) 这个宏配置为0,也就是支持多个spiffs
  5. */
  6. spiffs_config cfg=
  7.         {       
  8.                 /* 分配给SPIFFS的空间 要是逻辑扇区的整数倍*/
  9.                 .phys_size = 1024*4*4*128,
  10.                 /* 起始地址 */
  11.                 .phys_addr = 0,
  12.                 /*
  13.                         物理扇区,也就是一次擦除的大小,要跟hal_erase_f函数擦除的一致
  14.                 */
  15.                 .phys_erase_block = 1024*4,
  16.                 /* 逻辑扇区,必须是物理扇区的整数倍
  17.                         最好是: log_block_size/log_page_size = (32-512)
  18.                 */
  19.                 .log_block_size = 1024*4*4,
  20.                 /*逻辑页,通常是256*/
  21.                 .log_page_size = LOG_PAGE_SIZE,
  22.                
  23.                 .hal_read_f = core_spiflash_spiffs_read,
  24.                 .hal_write_f = core_spiflash_spiffs_write,
  25.                 .hal_erase_f = core_spiflash_spiffs_erase,
  26.        
  27.         };
复制代码

第三,
挂载文件系统,如果是第一次挂载会失败,需要卸载文件系统再格式化文件系统,最后重新挂载即可。
  1. /*文件系统结构体*/
  2. static spiffs fs;

  3. /*页定义*/
  4. #define LOG_PAGE_SIZE                256

  5. static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
  6. static u8_t spiffs_fds[32*4];
  7. static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE+32)*4];

  8. /**
  9. *@brief:     
  10. *@details: 格式化文件系统
  11. *@param[in]   
  12. *@param[out]  
  13. *@retval:     
  14. */
  15. void sys_spiffs_format(void)
  16. {

  17.         wjq_log(LOG_INFO, ">---format spiffs coreflash\r\n");

  18.         /* 格式化之前要先unmount */
  19.         SPIFFS_unmount(&fs);
  20.                        
  21.         SPIFFS_format(&fs);

  22.         int res = SPIFFS_mount(&fs,
  23.           &cfg,
  24.           spiffs_work_buf,
  25.           spiffs_fds,
  26.           sizeof(spiffs_fds),
  27.           spiffs_cache_buf,
  28.           sizeof(spiffs_cache_buf),
  29.           0);
  30.         wjq_log(LOG_INFO, "mount res: %i\r\n", res);
  31.        
  32.         wjq_log(LOG_INFO, ">---format spiffs coreflash finish\r\n");

  33. }
  34. /**
  35. *@brief:     
  36. *@details: 挂载spiffs文件系统
  37. *@param[in]   
  38. *@param[out]  
  39. *@retval:     
  40. */
  41. void sys_spiffs_mount_coreflash(void)
  42. {
  43.     int res = SPIFFS_mount(&fs,
  44.                                                       &cfg,
  45.                                                       spiffs_work_buf,
  46.                                                       spiffs_fds,
  47.                                                       sizeof(spiffs_fds),
  48.                                                       spiffs_cache_buf,
  49.                                                       sizeof(spiffs_cache_buf),
  50.                                                       0);
  51.     wjq_log(LOG_INFO, "mount res: %i\r\n", res);

  52.         if(SPIFFS_ERR_NOT_A_FS == res )
  53.         {
  54.                 sys_spiffs_format();       
  55.         }
  56. }
复制代码

然后,就可以进行基本读写测试啦。

吐槽
1
如果要好好用这个文件系统,需要多次测试找一个设置平衡点。
什么意思呢?也就是你这个文件系统如何配置。
也就是spiffs_config中的:逻辑块多大,页设置多大。不同的设置会严重影响性能。
因为这个文件系统为了省内存,没有任何索引。
具体细节大家自己分析,我就说一个事实:
打开一个文件,很可能要轮询所有BLOCK的第一页。
当你BLOCK跟页设置小,数量就多,操作文件就会很慢很慢,,,,。
为什么这么慢?作者在WIKI上有说明。
2
目前还没有认真使用这个文件系统,但是总感觉它有点上不成下不就的感觉。
是的,嵌入式RAM紧张,但是嵌入式对速度也敏感啊!
想起以前公司用的文件系统,速度不慢,RAM用得也不算多。
怎么做到呢?
限制其他性能,例如,最多只能创建100个文件,文件系统最大只能到1M。
这样的限制对于单片机系统来说,其实是能用的。
(带这个文件系统的产品估计出货也1000万台了吧)

移植源码
在开源STM32代码上有这个文件系统的移植,需要请参观:
http://github.com/wujique/stm32f407/tree/sw_arch
这个仓库是个人写的一些代码,主要是按照经验进行了一些程序设计,自认为比大部分教程的例程代码要好。
后续会慢慢添加各种外设驱动。大家拿来用即可。
欢迎商用,后果自负


评分

参与人数 1 ST金币 +6 收起 理由
MrJiu + 6 很给力!

查看全部评分

收藏 4 评论6 发布时间:2018-6-3 22:44

举报

6个回答
MrJiu 回答时间:2018-6-4 09:49:03
很好啊!!!有时间阅读一下!!!看起来不错。。。
勿忘心安110 回答时间:2018-6-26 08:45:07
感谢楼主分享 有空去拜读一下代码
gaokai1992yy 回答时间:2018-9-26 09:41:06
谢谢,正好最近在看这个东西
streamlee 回答时间:2020-4-20 15:20:59
最近要上这个文件系统,参考
likang1202 回答时间:2020-4-23 08:49:20
谢谢分享
david69chen 回答时间:2020-5-14 04:12:31
very good!

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版