因?yàn)?a class="article-link" target="_blank" href="/tag/%E5%8D%95%E7%89%87%E6%9C%BA/">單片機(jī)的存儲(chǔ)比較小,所以我們經(jīng)常會(huì)用到外置FLASH來(lái)存儲(chǔ)一些文件、數(shù)據(jù)或者OTA等。如果一個(gè)FLASH只用來(lái)做單一的功能,那只需要把所有內(nèi)存都分配到這個(gè)功能上就行了,但是如果要用一個(gè)FLASH同時(shí)做多個(gè)功能,比如我用一部分內(nèi)存來(lái)做文件系統(tǒng),一部分用來(lái)存OTA升級(jí)固件,那在操作內(nèi)存的時(shí)候就要注意地址的分配了,為了方便內(nèi)存管理,我們通常會(huì)進(jìn)行分區(qū)處理。
RT-thread系統(tǒng)就有分區(qū)和內(nèi)存管理相關(guān)的軟件包,這一點(diǎn)還是很方便的。
FAL軟件包:http://packages.rt-thread.org/detail.html?package=fal
FAL軟件包可以用于片內(nèi)flash也可以用于片外flash,我這一講主要介紹片外flash的使用。
一、掛載FLASH
首先我們要把這個(gè)片外flash掛載上。這個(gè)我之前的教程已經(jīng)介紹過(guò)了,不知道的同學(xué)可以先看下我之前的博客:RT-thread應(yīng)用講解——norflash
二、ENV配置
1、打開(kāi)on-chip flash
2、打開(kāi)FAL軟件包
3、重新生成工程
設(shè)置完之后保存退出,然后重新生成工程即可。
在env輸入下面的命令,重新生成新的工程。
提示:會(huì)使用env的話應(yīng)該都知道這個(gè)操作,不多說(shuō)了。
scons --target=mdk5
三、分區(qū)處理
1、定義flash設(shè)備表
打開(kāi)fal_cfg.h文件(在boardports文件夾里面),找到flash設(shè)備的定義,增加片外flash的定義。
注意:fal軟件包里面也會(huì)有一個(gè)fal_cfg.h文件,這個(gè)只是demo,默認(rèn)是不加入到工程里面的,也不會(huì)起作用。
定義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_ */
上面這個(gè)分區(qū)表詳細(xì)描述信息如下:
分區(qū)名 | FLASH設(shè)備名 | 偏移地址 | 內(nèi)存大小 | 說(shuō)明 |
---|---|---|---|---|
“bootload” | “onchip_flash_16k” | 0 | 128 * 1024 字節(jié) | bootload引導(dǎo)程序 |
“app” | “onchip_flash_128k” | 0 | 384 * 1024 字節(jié) | 應(yīng)用程序 |
“download” | “norflash0” | 0 | 256 * 1024 字節(jié) | OTA升級(jí)固件 |
“factory” | “norflash0” | 256 * 1024 | 384 * 1024 字節(jié) | 恢復(fù)出廠固件 |
“cmb_log” | “norflash0” | 640 * 1024 | 128 * 1024 字節(jié) | 運(yùn)行日志 |
“filesystem” | “norflash0” | 896 * 1024 | 15488 * 1024 字節(jié) | 文件系統(tǒng) |
提示:FLASH設(shè)備名要根據(jù)實(shí)際情況來(lái)寫(xiě),比如onchip_flash_16k和onchip_flash_128k是默認(rèn)的一個(gè)定義(在drv_flash_f4.c文件),stm32_onchip_flash_16k指定的起始地址就是stm32f4系列rom的起始地址,onchip_flash_128k則是從128k偏移開(kāi)始的,如果這幾個(gè)定義不滿足你的需求可以自己在drv_flash_f4.c文件再定義一個(gè)。
最后貼一個(gè)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這個(gè)頭文件,不然就找不到這個(gè)函數(shù)了。
四、運(yùn)行測(cè)試
正常運(yùn)行的日志如下:
可以通過(guò)輸出的日志再次核對(duì)你的分區(qū)是否有誤。
fal本身就提供了一些測(cè)試命令,可以通過(guò)msh命令完成測(cè)試。
具體的命令可以輸入fal查看。
關(guān)于這些測(cè)試的命令,我這里就簡(jiǎn)單地列一下,F(xiàn)AL軟件包官方的介紹里面已經(jīng)有詳細(xì)的解析了,可以自行查閱。
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、寫(xiě)入數(shù)據(jù)
示例如下:
fal write 0 00 01 02 03 04
4、讀取數(shù)據(jù)
示例如下:
fal read 0 5
5、性能測(cè)試
性能測(cè)試將會(huì)測(cè)試Flash的擦除、寫(xiě)入及讀取速度,同時(shí)將會(huì)測(cè)試寫(xiě)入及讀取數(shù)據(jù)的準(zhǔn)確性,保證整個(gè) Flash 或整個(gè)分區(qū)的 寫(xiě)入與讀取數(shù)據(jù)的一致性。
示例如下:
fal bench 4096 yes
最后貼一個(gè)完整的測(cè)試示例:
五、結(jié)束語(yǔ)
好了,關(guān)于FLASH分區(qū)的介紹就到這里,如果還有什么問(wèn)題,歡迎在評(píng)論區(qū)留言。如果這篇文章能夠幫到你,就給我點(diǎn)個(gè)贊吧,如果想了解更多RT-thread和單片機(jī)的內(nèi)容,可以關(guān)注一下博主,后續(xù)我還會(huì)繼續(xù)分享更多的經(jīng)驗(yàn)給大家。
教程相關(guān)源碼:https://pan.baidu.com/s/1N2D8dM31deKIqNqaIQfPiA
提取碼:7nsx