因為單片機的存儲比較小,所以我們經(jīng)常會用到外置FLASH來存儲一些文件、數(shù)據(jù)或者OTA等。如果一個FLASH只用來做單一的功能,那只需要把所有內(nèi)存都分配到這個功能上就行了,但是如果要用一個FLASH同時做多個功能,比如我用一部分內(nèi)存來做文件系統(tǒng),一部分用來存OTA升級固件,那在操作內(nèi)存的時候就要注意地址的分配了,為了方便內(nèi)存管理,我們通常會進行分區(qū)處理。
RT-thread系統(tǒng)就有分區(qū)和內(nèi)存管理相關(guān)的軟件包,這一點還是很方便的。
FAL軟件包:http://packages.rt-thread.org/detail.html?package=fal
FAL軟件包可以用于片內(nèi)flash也可以用于片外flash,我這一講主要介紹片外flash的使用。
一、掛載FLASH
首先我們要把這個片外flash掛載上。這個我之前的教程已經(jīng)介紹過了,不知道的同學可以先看下我之前的博客:RT-thread應(yīng)用講解——norflash
二、ENV配置
1、打開on-chip flash
2、打開FAL軟件包
3、重新生成工程
設(shè)置完之后保存退出,然后重新生成工程即可。
在env輸入下面的命令,重新生成新的工程。
提示:會使用env的話應(yīng)該都知道這個操作,不多說了。
scons --target=mdk5
三、分區(qū)處理
1、定義flash設(shè)備表
打開fal_cfg.h文件(在boardports文件夾里面),找到flash設(shè)備的定義,增加片外flash的定義。
注意:fal軟件包里面也會有一個fal_cfg.h文件,這個只是demo,默認是不加入到工程里面的,也不會起作用。
定義flash設(shè)備表示例代碼如下:
extern const struct fal_flash_dev stm32_onchip_flash_16k;
extern const struct fal_flash_dev stm32_onchip_flash_64k;
extern const struct fal_flash_dev stm32_onchip_flash_128k;
extern struct fal_flash_dev nor_flash0;
/* flash device table */
#define FAL_FLASH_DEV_TABLE
{
&stm32_onchip_flash_16k,
&stm32_onchip_flash_64k,
&stm32_onchip_flash_128k,
&nor_flash0,
}
2、定義flash分區(qū)表
同樣是在fal_cfg.h文件里面,根據(jù)自己的需要定義分區(qū)表。
示例代碼如下:
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE
{
{FAL_PART_MAGIC_WROD, "bootload", "onchip_flash_16k", 0 * 1024, 128 * 1024, 0},
{FAL_PART_MAGIC_WROD, "app", "onchip_flash_128k", 0 * 1024, 384 * 1024, 0},
{FAL_PART_MAGIC_WROD, "download", "norflash0", 0 * 1024, 256 * 1024, 0},
{FAL_PART_MAGIC_WROD, "factory", "norflash0", 256 * 1024, 384 * 1024, 0},
{FAL_PART_MAGIC_WROD, "easyflash", "norflash0", 640 * 1024, 128 * 1024, 0},
{FAL_PART_MAGIC_WROD, "cmb_log", "norflash0", 768* 1024, 128 * 1024, 0},
{FAL_PART_MAGIC_WROD, "filesystem", "norflash0", 896 * 1024, 15488 * 1024, 0},
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
上面這個分區(qū)表詳細描述信息如下:
分區(qū)名 | FLASH設(shè)備名 | 偏移地址 | 內(nèi)存大小 | 說明 |
---|---|---|---|---|
“bootload” | “onchip_flash_16k” | 0 | 128 * 1024 字節(jié) | bootload引導程序 |
“app” | “onchip_flash_128k” | 0 | 384 * 1024 字節(jié) | 應(yīng)用程序 |
“download” | “norflash0” | 0 | 256 * 1024 字節(jié) | OTA升級固件 |
“factory” | “norflash0” | 256 * 1024 | 384 * 1024 字節(jié) | 恢復出廠固件 |
“cmb_log” | “norflash0” | 640 * 1024 | 128 * 1024 字節(jié) | 運行日志 |
“filesystem” | “norflash0” | 896 * 1024 | 15488 * 1024 字節(jié) | 文件系統(tǒng) |
提示:FLASH設(shè)備名要根據(jù)實際情況來寫,比如onchip_flash_16k和onchip_flash_128k是默認的一個定義(在drv_flash_f4.c文件),stm32_onchip_flash_16k指定的起始地址就是stm32f4系列rom的起始地址,onchip_flash_128k則是從128k偏移開始的,如果這幾個定義不滿足你的需求可以自己在drv_flash_f4.c文件再定義一個。
最后貼一個fal_cfg.h文件完整的代碼:
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-5 SummerGift first version
*/
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtthread.h>
#include <board.h>
#define FLASH_SIZE_GRANULARITY_16K (4 * 16 * 1024)
#define FLASH_SIZE_GRANULARITY_64K (64 * 1024)
#define FLASH_SIZE_GRANULARITY_128K (7 * 128 * 1024)
#define STM32_FLASH_START_ADRESS_16K STM32_FLASH_START_ADRESS
#define STM32_FLASH_START_ADRESS_64K (STM32_FLASH_START_ADRESS_16K + FLASH_SIZE_GRANULARITY_16K)
#define STM32_FLASH_START_ADRESS_128K (STM32_FLASH_START_ADRESS_64K + FLASH_SIZE_GRANULARITY_64K)
extern const struct fal_flash_dev stm32_onchip_flash_16k;
extern const struct fal_flash_dev stm32_onchip_flash_64k;
extern const struct fal_flash_dev stm32_onchip_flash_128k;
extern struct fal_flash_dev nor_flash0;
/* flash device table */
#define FAL_FLASH_DEV_TABLE
{
&stm32_onchip_flash_16k,
&stm32_onchip_flash_64k,
&stm32_onchip_flash_128k,
&nor_flash0,
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE
{
{FAL_PART_MAGIC_WROD, "bootload", "onchip_flash_16k", 0 * 1024, 128 * 1024, 0},
{FAL_PART_MAGIC_WROD, "app", "onchip_flash_128k", 0 * 1024, 384 * 1024, 0},
{FAL_PART_MAGIC_WROD, "download", "norflash0", 0 * 1024, 256 * 1024, 0},
{FAL_PART_MAGIC_WROD, "factory", "norflash0", 256 * 1024, 384 * 1024, 0},
{FAL_PART_MAGIC_WROD, "easyflash", "norflash0", 640 * 1024, 128 * 1024, 0},
{FAL_PART_MAGIC_WROD, "cmb_log", "norflash0", 768* 1024, 128 * 1024, 0},
{FAL_PART_MAGIC_WROD, "filesystem", "norflash0", 896 * 1024, 15488 * 1024, 0},
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
3、FAL初始化
在你的工程里面調(diào)用fal_init()函數(shù),比如我這里是在main函數(shù)里面調(diào)用的(放其他位置也是可以的,只要調(diào)用了就行)。
提示:調(diào)用fal_init()函數(shù)之前要先包含fal.h這個頭文件,不然就找不到這個函數(shù)了。
四、運行測試
正常運行的日志如下:
可以通過輸出的日志再次核對你的分區(qū)是否有誤。
fal本身就提供了一些測試命令,可以通過msh命令完成測試。
具體的命令可以輸入fal查看。
關(guān)于這些測試的命令,我這里就簡單地列一下,F(xiàn)AL軟件包官方的介紹里面已經(jīng)有詳細的解析了,可以自行查閱。
FAL軟件包:http://packages.rt-thread.org/detail.html?package=fal
1、指定待操作的Flash設(shè)備或Flash分區(qū)
示例如下:
fal probe download
2、擦除數(shù)據(jù)
示例如下:
fal erase 0 4096
3、寫入數(shù)據(jù)
示例如下:
fal write 0 00 01 02 03 04
4、讀取數(shù)據(jù)
示例如下:
fal read 0 5
5、性能測試
性能測試將會測試Flash的擦除、寫入及讀取速度,同時將會測試寫入及讀取數(shù)據(jù)的準確性,保證整個 Flash 或整個分區(qū)的 寫入與讀取數(shù)據(jù)的一致性。
示例如下:
fal bench 4096 yes
最后貼一個完整的測試示例:
五、結(jié)束語
好了,關(guān)于FLASH分區(qū)的介紹就到這里,如果還有什么問題,歡迎在評論區(qū)留言。如果這篇文章能夠幫到你,就給我點個贊吧,如果想了解更多RT-thread和單片機的內(nèi)容,可以關(guān)注一下博主,后續(xù)我還會繼續(xù)分享更多的經(jīng)驗給大家。
教程相關(guān)源碼:https://pan.baidu.com/s/1N2D8dM31deKIqNqaIQfPiA
提取碼:7nsx