在 V4.1.0 中,將 fal 軟件包重新定義為 RT-Thread 內(nèi)部組件。
在使用方式上和以前有這些區(qū)別:原本使用 fal 需要在 RT-Thread 的包管理器中選擇并進行下載;現(xiàn)在只需要在組件中打開使用即可。以下做詳細介紹。
1、FAL介紹
FAL (Flash Abstraction Layer) Flash 抽象層,是對 Flash 及基于 Flash 的分區(qū)進行管理、操作的抽象層,對上層統(tǒng)一了 Flash 及 分區(qū)操作的 API (框架圖如下所示),并具有以下特性:
支持靜態(tài)可配置的分區(qū)表,并可關聯(lián)多個 Flash 設備;
分區(qū)表支持 自動裝載 。避免在多固件項目,分區(qū)表被多次定義的問題;
代碼精簡,對操作系統(tǒng) 無依賴 ,可運行于裸機平臺,比如對資源有一定要求的 Bootloader;
統(tǒng)一的操作接口。保證了文件系統(tǒng)、OTA、NVM(例如:EasyFlash) 等對 Flash 有一定依賴的組件,底層 Flash 驅動的可重用性;
自帶基于 Finsh/MSH 的測試命令,可以通過 Shell 按字節(jié)尋址的方式操作(讀寫擦) Flash 或分區(qū),方便開發(fā)者進行調試、測試;
1.1、打開 FAL
在組件中打開使用:
每個功能的配置說明如下:
開啟調試日志輸出(默認開啟);
分區(qū)表是否在 fal_cfg.h
中定義(默認開啟)。如果關閉此選項,fal 將會自動去指定 Flash 的指定位置去檢索并裝載分區(qū)表,具體配置詳見下面兩個選項;
存放分區(qū)表的 Flash 設備;
分區(qū)表的 結束地址 位于 Flash 設備上的偏移。fal 將從此地址開始往回進行檢索分區(qū)表,直接讀取到 Flash 頂部。如果不確定分區(qū)表具體位置,這里也可以配置為 Flash 的結束地址,fal 將會檢索整個 Flash,檢索時間可能會增加。
啟用 FAL 針對 SFUD 的移植文件(默認關閉);
應輸入調用 rt_sfud_flash_probe
函數(shù)時傳入的 FLASH 設備名稱(也可以通過 list_device 命令查看 Block Device 的名字獲取)。該名稱與分區(qū)表中的 Flash 名稱對應,只有正確設置設備名字,才能完成對 FLASH 的讀寫操作。
1.2、FAL 目錄
1.3、FAL API
FAL 相關的 API 如圖所示,點擊此處查看 API 參數(shù)詳解。(以下鏈接請復制至外部瀏覽器打開)
https://github.com/RT-Thread/rt-thread/blob/master/components/fal/docs/fal_api.md
2、使用 FAL
使用 FAL 的基本步驟如下所示:
1、打開 FAL:從 Env 中打開 fal 組件。
2、FAL 移植:定義 flash 設備、定義 flash 設備表、定義 flash 分區(qū)表。以下主要對步驟 2 展開講解。
3、調用 fal_init() 初始化該庫:移植完成后,可在應用層調用,如在 main 函數(shù)中調用。
2.1、定義 flash 設備
在定義 Flash 設備表前,需要先定義 Flash 設備。可以是片內(nèi) flash, 也可以是片外基于 SFUD 的 spi flash:
定義片內(nèi) flash 設備可以參考 fal_flash_stm32f2_port.c
定義片外 spi flash 設備可以參考 fal_flash_sfud_port.c
定義具體的 Flash 設備對象,用戶需要根據(jù)自己的 Flash 情況分別實現(xiàn) init
、 read
、 write
、 erase
這些操作函數(shù):
static int init(void)
:可選 的初始化操作。
static int read(long offset, uint8_t *buf, size_t size)
:讀取操作。
static int write(long offset, const uint8_t *buf, size_t size)
:寫入操作。
static int erase(long offset, size_t size)
:擦除操作。
用戶需要根據(jù)自己的 Flash 情況分別實現(xiàn)這些操作函數(shù)。在文件最底部定義了具體的 Flash 設備對象 ,如下示例定義了 stm32f2 片上 flash:stm32f2_onchip_flash
1const struct fal_flash_dev stm32f2_onchip_flash =2{3 .name = "stm32_onchip",4 .addr = 0x08000000,5 .len = 1024*1024,6 .blk_size = 128*1024,7 .ops = {init, read, write, erase},8 .write_gran = 89};
"stm32_onchip"
: Flash 設備的名字。
0x08000000
: 對 Flash 操作的起始地址。
1024*1024
:Flash 的總大小(1MB)。
128*1024
:Flash 塊/扇區(qū)大小(因為 STM32F2 各塊大小不均勻,所以擦除粒度為最大塊的大小:128K)。
{init, read, write, erase}
:Flash 的操作函數(shù)。如果沒有 init 初始化過程,第一個操作函數(shù)位置可以置空。
8
: 設置寫粒度,單位 bit, 0 表示未生效(默認值為 0 ),該成員是 fal 版本大于 0.4.0 的新增成員。各個 flash 寫入粒度不盡相同,可通過該成員進行設置,以下列舉幾種常見 Flash 寫粒度:
nor flash: 1 bit
stm32f2/f4: 8 bit
stm32f1: 32 bit
stm32l4: 64 bit
2.2、定義 flash 設備表
Flash 設備表定義在 fal_cfg.h
頭文件中,定義分區(qū)表前需 新建 fal_cfg.h
文件 ,請將該文件統(tǒng)一放在對應 BSP 或工程目錄的 port 文件夾下,并將該頭文件路徑加入到工程。fal_cfg.h 可以參考 示例文件 fal/samples/porting/fal_cfg.h 完成。
設備表示例:
1/* ===================== Flash device Configuration ========================= */ 2extern const struct fal_flash_dev stm32f2_onchip_flash; 3extern struct fal_flash_dev nor_flash0; 4 5/* flash device table */ 6#define FAL_FLASH_DEV_TABLE \ 7{ \ 8 &stm32f2_onchip_flash, \ 9 &nor_flash0, \10}
Flash 設備表中,有兩個 Flash 對象,一個為 STM32F2 的片內(nèi) Flash ,一個為片外的 Nor Flash。
2.3、定義 flash 分區(qū)表
分區(qū)表也定義在 fal_cfg.h
頭文件中。Flash 分區(qū)基于 Flash 設備,每個 Flash 設備又可以有 N 個分區(qū),這些分區(qū)的集合就是分區(qū)表。在配置分區(qū)表前,務必保證已定義好 Flash 設備 及 設備表。fal_cfg.h 可以參考 示例文件 fal/samples/porting/fal_cfg.h 完成。
分區(qū)表示例:
1#define NOR_FLASH_DEV_NAME "norflash0" 2/* ====================== Partition Configuration ========================== */ 3#ifdef FAL_PART_HAS_TABLE_CFG 4/* partition table */ 5#define FAL_PART_TABLE \ 6{ \ 7 {FAL_PART_MAGIC_WORD, "bl", "stm32_onchip", 0, 64*1024, 0}, \ 8 {FAL_PART_MAGIC_WORD, "app", "stm32_onchip", 64*1024, 704*1024, 0}, \ 9 {FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME, 0, 1024*1024, 0}, \10 {FAL_PART_MAGIC_WORD, "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \11}12#endif /* FAL_PART_HAS_TABLE_CFG */
上面這個分區(qū)表詳細描述信息如下:
用戶需要修改的分區(qū)參數(shù)包括:分區(qū)名稱、關聯(lián)的 Flash 設備名、偏移地址(相對 Flash 設備內(nèi)部)、大小,需要注意以下幾點:
分區(qū)名保證 不能重復;
關聯(lián)的 Flash 設備 務必已經(jīng)在 Flash 設備表中定義好 ,并且 名稱一致 ,否則會出現(xiàn)無法找到 Flash 設備的錯誤;
分區(qū)的起始地址和大小 不能超過 Flash 設備的地址范圍 ,否則會導致包初始化錯誤;
注意:每個分區(qū)定義時,除了填寫上面介紹的參數(shù)屬性外,需在前面增加
FAL_PART_MAGIC_WORD
屬性,末尾增加0
(目前用于保留功能)
3、Finsh/MSH 測試命令
fal 提供了豐富的測試命令,項目只要在 RT-Thread 上開啟 Finsh/MSH 功能即可。在做一些基于 Flash 的應用開發(fā)、調試時,這些命令會非常實用。它可以準確的寫入或者讀取指定位置的原始 Flash 數(shù)據(jù),快速的驗證 Flash 驅動的完整性,甚至可以對 Flash 進行性能測試。
具體功能如下:輸入 fal 可以看到完整的命令列表
1msh />fal2Usage:3fal probe [dev_name|part_name] - probe flash device or partition by given name4fal read addr size - read 'size' bytes starting at 'addr'5fal write addr data1 ... dataN - write some bytes 'data' starting at 'addr'6fal erase addr size - erase 'size' bytes starting at 'addr'7fal bench - benchmark test with per block size89msh />
3.1、指定待操作的 Flash 設備或 Flash 分區(qū)
當?shù)谝淮问褂?fal 命令時,直接輸入 fal probe
將會顯示分區(qū)表信息。可以指定待操作的對象為分區(qū)表里的某個分區(qū),或者某個 Flash 設備。
分區(qū)或者 Flash 被成功選中后,還將會顯示它的一些屬性情況。大致效果如下:
1msh />fal probe 2No flash device or partition was probed. 3Usage: fal probe [dev_name|part_name] - probe flash device or partition by given name. 4[I/FAL] ==================== FAL partition table ==================== 5[I/FAL] | name | flash_dev | offset | length | 6[I/FAL] ------------------------------------------------------------- 7[I/FAL] | bl | stm32_onchip | 0x00000000 | 0x00010000 | 8[I/FAL] | app | stm32_onchip | 0x00010000 | 0x000b0000 | 9[I/FAL] | ef | norflash0 | 0x00000000 | 0x00100000 |10[I/FAL] | download | norflash0 | 0x00100000 | 0x00100000 |11[I/FAL] =============================================================12msh />13msh />fal probe download14Probed a flash partition | download | flash_dev: norflash0 | offset: 1048576 | len: 1048576 |.15msh />16
3.2、擦除數(shù)據(jù)
先輸入 fal erase
,后面跟著待擦除數(shù)據(jù)的起始地址以及長度。以下命令為:從 0 地址(相對 Flash 或分區(qū))開始擦除 4096 字節(jié)數(shù)據(jù)
注意:根據(jù) Flash 特性,擦除動作將按扇區(qū)對齊進行處理。所以,如果擦除操作地址或長度未按照 Flash 的扇區(qū)對齊,將會擦除掉與其關聯(lián)的整個扇區(qū)數(shù)據(jù)。
1msh />fal erase 0 40962Erase data success. Start from 0x00000000, size is 4096.3msh />
3.3、寫入數(shù)據(jù)
先輸入 fal write
,后面跟著 N 個待寫入的數(shù)據(jù),并以空格隔開。以下命令為:從地址 8 的位置依次開始寫入 1、2、3、4 、 5 這 5 個字節(jié)數(shù)據(jù)
1msh />fal write 8 1 2 3 4 52Write data success. Start from 0x00000008, size is 5.3Write data: 1 2 3 4 5 .4msh />
3.4、讀取數(shù)據(jù)
先輸入 fal read
,后面跟著待讀取數(shù)據(jù)的起始地址以及長度。以下命令為:從 0 地址開始讀取 64 字節(jié)數(shù)據(jù)
1msh />fal read 0 642Read data success. Start from 0x00000000, size is 64. The data is:3Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F4[00000000] FF FF FF FF FF FF FF FF 01 02 03 04 05 FF FF FF 5[00000010] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6[00000020] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 7[00000030] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 89msh />
3.5、性能測試
性能測試將會測試 Flash 的擦除、寫入及讀取速度,同時將會測試寫入及讀取數(shù)據(jù)的準確性,保證整個 Flash 或整個分區(qū)的 寫入與讀取 數(shù)據(jù)的一致性。
先輸入 fal bench
,后面跟著待測試 Flash 的扇區(qū)大小(請查看對應的 Flash 手冊,SPI Nor Flash 一般為 4096)。由于性能測試將會讓整個 Flash 或者整個分區(qū)的數(shù)據(jù)丟失,所以命令最后必須跟 yes
。
1msh />fal bench 4096 yes2Erasing 1048576 bytes data, waiting...3Erase benchmark success, total time: 2.674S.4Writing 1048576 bytes data, waiting...5Write benchmark success, total time: 7.107S.6Reading 1048576 bytes data, waiting...7Read benchmark success, total time: 2.716S.8msh />
4、常見應用
基于 FAL 分區(qū)的 fatfs 文件系統(tǒng)例程
https://github.com/RT-Thread/IoT_Board/tree/master/examples/15_component_fs_flash
基于 FAL 分區(qū)的 littlefs 文件系統(tǒng)應用筆記
https://www.rt-thread.org/document/site/application-note/components/dfs/an0027-littlefs/
基于 FAL 分區(qū)的 EasyFlash 移植說明
https://github.com/armink-rtt-pkgs/EasyFlash/tree/master/ports
-
數(shù)據(jù)
+關注
關注
8文章
7030瀏覽量
89036 -
軟件
+關注
關注
69文章
4944瀏覽量
87492 -
RT-Thread
+關注
關注
31文章
1289瀏覽量
40131
發(fā)布評論請先 登錄
相關推薦
評論