生活随笔
收集整理的這篇文章主要介紹了
SPIFFS文件系统移植–基于STM32F407
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=616126&highlight=%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F
?
本帖最后由 huangxuejia-29212 于 2018-6-3 22:47 編輯
?
SPIFFS文件系統(tǒng),有什么特別呢?
從名字就可知,這是一個用于SPI FLASH的file system。
現(xiàn)在好像在ESP8266上用的很多,感覺慢慢有的人氣了。
從特性上說,這個文件系統(tǒng)用很少的RAM資源。
但是,我最后會吐槽吐槽這個特性的。
網(wǎng)絡(luò)上資源不多,好在github上說明文檔挺全。
?
github
地址:https://github.com/pellepl/spiffs
最新版本是0.3.7.
目錄結(jié)構(gòu)如下:
添加到工程的文件如下:
在github上有wiki說明如何移植
https://github.com/pellepl/spiffs/wiki
認(rèn)真讀完這個wiki,基本就知道如何使用spiffs。
對于spiffs的設(shè)計,有一個網(wǎng)站可做參考, spiffs技術(shù)手冊。
https://blog.csdn.net/zhangjinxing_2006/article/details/75050611
移植概述
下面我們說說移植的過程。
1. 配置
spiffs-0.3.7\src\default下有一個默認(rèn)的配置文件,spiffs_config.h。
為了方便,拷貝一個到spiffs-0.3.7\src。
在工程中,頭文件搜索路徑,只包含src路徑,不要包含\src\default。
spiffs_config.h頭部包含的頭文件修改如下。
在這里也定義了變量名。
//#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stddef.h>#include "stm32f4xx.h"?typedef u32??u32_t;typedef u16 u16_t;typedef u8??u8_t;?typedef s32??s32_t;typedef s16 s16_t;typedef s8??s8_t;
復(fù)制代碼
?
修改幾個宏定義
#ifndef SPIFFS_USE_MAGIC#define SPIFFS_USE_MAGIC? ?? ?? ?? ?? ? (1)#endif?#ifndef SPIFFS_USE_MAGIC_LENGTH#define SPIFFS_USE_MAGIC_LENGTH? ?? ?? ?(1)#endif#endif
復(fù)制代碼
?
在spiffs-0.3.7\src\spiffs_nucleus.h文件中定義的聯(lián)合用了一個gcc特性,在MDK編譯會報錯。
在聯(lián)合前增加一句代碼#pragma anon_unions 即可。
????#pragma anon_unions???union {? ? // type read cache? ? struct {? ?? ?// read cache page index? ?? ?spiffs_page_ix pix;? ? };#if SPIFFS_CACHE_WR? ? // type write cache? ? struct {? ?? ?// write cache? ?? ?spiffs_obj_id obj_id;? ?? ?// offset in cache page? ?? ?u32_t offset;? ?? ?// size of cache page? ?? ?u16_t size;? ? };#endif??};} spiffs_cache_page;
復(fù)制代碼
?
2 應(yīng)用
首先,
要實現(xiàn)SPI FLASH操作函數(shù),SPIFFS需要的函數(shù)格式如下
s32_t core_spiflash_spiffs_read(u32_t addr, u32_t size, u8_t *dst);static s32_t core_spiflash_spiffs_write(u32_t addr, u32_t size, u8_t *src);static s32_t core_spiflash_spiffs_erase(u32_t addr, u32_t size);
復(fù)制代碼
?
第二,
定義文件系統(tǒng)相關(guān)參數(shù)
/*? ? ? ? 文件系統(tǒng)配置? ? ? ??? ? ? ? #define SPIFFS_SINGLETON (0) 這個宏配置為0,也就是支持多個spiffs*/spiffs_config cfg=? ? ? ? {? ? ? ??? ? ? ? ? ? ? ? /* 分配給SPIFFS的空間 要是邏輯扇區(qū)的整數(shù)倍*/? ? ? ? ? ? ? ? .phys_size = 1024*4*4*128,? ? ? ? ? ? ? ? /* 起始地址 */? ? ? ? ? ? ? ? .phys_addr = 0,? ? ? ? ? ? ? ? /*? ? ? ? ? ? ? ? ? ? ? ? 物理扇區(qū),也就是一次擦除的大小,要跟hal_erase_f函數(shù)擦除的一致? ? ? ? ? ? ? ? */? ? ? ? ? ? ? ? .phys_erase_block = 1024*4,?? ? ? ? ? ? ? ? /* 邏輯扇區(qū),必須是物理扇區(qū)的整數(shù)倍? ? ? ? ? ? ? ? ? ? ? ? 最好是: log_block_size/log_page_size = (32-512)? ? ? ? ? ? ? ? */? ? ? ? ? ? ? ? .log_block_size = 1024*4*4,? ? ? ? ? ? ? ? /*邏輯頁,通常是256*/? ? ? ? ? ? ? ? .log_page_size = LOG_PAGE_SIZE,?? ? ? ? ? ? ? ??? ? ? ? ? ? ? ? .hal_read_f = core_spiflash_spiffs_read,? ? ? ? ? ? ? ? .hal_write_f = core_spiflash_spiffs_write,? ? ? ? ? ? ? ? .hal_erase_f = core_spiflash_spiffs_erase,? ? ? ??? ? ? ? };
復(fù)制代碼
?
第三,
掛載文件系統(tǒng),如果是第一次掛載會失敗,需要卸載文件系統(tǒng)再格式化文件系統(tǒng),最后重新掛載即可。
/*文件系統(tǒng)結(jié)構(gòu)體*/static spiffs fs;?/*頁定義*/#define LOG_PAGE_SIZE? ? ? ? ? ? ? ? 256?static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];static u8_t spiffs_fds[32*4];static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE+32)*4];?/***@brief:? ???*@details: 格式化文件系統(tǒng)*@param[in]? ??*@param[out]??*@retval:? ???*/void sys_spiffs_format(void){?? ? ? ? wjq_log(LOG_INFO, ">---format spiffs coreflash\r\n");?? ? ? ? /* 格式化之前要先unmount */? ? ? ? SPIFFS_unmount(&fs);? ? ? ? ? ? ? ? ? ? ? ??? ? ? ? SPIFFS_format(&fs);?? ? ? ? int res = SPIFFS_mount(&fs,? ? ? ?? ?&cfg,? ? ? ?? ?spiffs_work_buf,? ? ? ?? ?spiffs_fds,? ? ? ?? ?sizeof(spiffs_fds),? ? ? ?? ?spiffs_cache_buf,? ? ? ?? ?sizeof(spiffs_cache_buf),? ? ? ?? ?0);? ? ? ? wjq_log(LOG_INFO, "mount res: %i\r\n", res);? ? ? ??? ? ? ? wjq_log(LOG_INFO, ">---format spiffs coreflash finish\r\n");?}/***@brief:? ???*@details: 掛載spiffs文件系統(tǒng)*@param[in]? ??*@param[out]??*@retval:? ???*/void sys_spiffs_mount_coreflash(void)?{?? ? int res = SPIFFS_mount(&fs,? ?? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &cfg,? ?? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? spiffs_work_buf,? ?? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? spiffs_fds,? ?? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sizeof(spiffs_fds),? ?? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? spiffs_cache_buf,? ???? ? ? ? ? ? ? ???? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sizeof(spiffs_cache_buf),? ?? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0);? ? wjq_log(LOG_INFO, "mount res: %i\r\n", res);?? ? ? ? if(SPIFFS_ERR_NOT_A_FS == res )? ? ? ? {? ? ? ? ? ? ? ? sys_spiffs_format();? ? ? ??? ? ? ? }}
復(fù)制代碼
?
然后,就可以進(jìn)行基本讀寫測試?yán)病?/span>
?
吐槽
1
如果要好好用這個文件系統(tǒng),需要多次測試找一個設(shè)置平衡點。
什么意思呢?也就是你這個文件系統(tǒng)如何配置。
也就是spiffs_config中的:邏輯塊多大,頁設(shè)置多大。不同的設(shè)置會嚴(yán)重影響性能。
因為這個文件系統(tǒng)為了省內(nèi)存,沒有任何索引。
具體細(xì)節(jié)大家自己分析,我就說一個事實:
打開一個文件,很可能要輪詢所有BLOCK的第一頁。
當(dāng)你BLOCK跟頁設(shè)置小,數(shù)量就多,操作文件就會很慢很慢,,,,。
為什么這么慢?作者在WIKI上有說明。
2
目前還沒有認(rèn)真使用這個文件系統(tǒng),但是總感覺它有點上不成下不就的感覺。
是的,嵌入式RAM緊張,但是嵌入式對速度也敏感啊!
想起以前公司用的文件系統(tǒng),速度不慢,RAM用得也不算多。
怎么做到呢?
限制其他性能,例如,最多只能創(chuàng)建100個文件,文件系統(tǒng)最大只能到1M。
這樣的限制對于單片機系統(tǒng)來說,其實是能用的。
(帶這個文件系統(tǒng)的產(chǎn)品估計出貨也1000萬臺了吧)
?
移植源碼
在開源STM32代碼上有這個文件系統(tǒng)的移植,需要請參觀:
https://github.com/wujique/stm32f407/tree/sw_arch
這個倉庫是個人寫的一些代碼,主要是按照經(jīng)驗進(jìn)行了一些程序設(shè)計,自認(rèn)為比大部分教程的例程代碼要好。
后續(xù)會慢慢添加各種外設(shè)驅(qū)動。大家拿來用即可。
歡迎商用,后果自負(fù)
總結(jié)
以上是生活随笔為你收集整理的SPIFFS文件系统移植–基于STM32F407的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。