在實際的應用中,我們經(jīng)常需要使用片外flash來保存一些數(shù)據(jù),比如設(shè)備的一些配置參數(shù),但是如果每個數(shù)據(jù)都按固定地址和長度讀寫,就要先把所有數(shù)據(jù)的地址和長度都分配好,數(shù)據(jù)量大的話使用起來就很不方便,所以我們需要一個內(nèi)存管理的應用。
easyflash是一款開源的輕量級嵌入式flash存儲器庫,方便開發(fā)者更加輕松的實現(xiàn)基于flash存儲器的常見應用開發(fā)。
EasyFlash軟件包:http://packages.rt-thread.org/detail.html?package=EasyFlash
一、掛載FLASH
首先我們要把這個片外flash掛載上。這個我之前的教程已經(jīng)介紹過了,不知道的同學可以先看下我之前的博客:RT-thread應用講解——norflash
二、配置分區(qū)
我們在實際的應用中片外flash可能會同時使用多個功能,比如OTA,easyflash、文件系統(tǒng)等,這個時候為了避免數(shù)據(jù)沖突,我們就要先把flash分成幾個區(qū)域。
關(guān)于FLASH分區(qū)的內(nèi)容,請參考我另外一篇博客。
RT-thread應用講解——FLASH分區(qū)
提示:如果要把整個外置flash都作為easyflash的話可以不分區(qū)。
三、下載軟件包
env的使用我就不多說了,已經(jīng)說過很多次了,可以翻一下我之前的博客。
RT-thread官網(wǎng)上也有很詳細的說明。
env使用方法:https://www.rt-thread.org/document/site/programming-manual/env/env/#bsp-menuconfig
打開easyflash軟件包。
配置說明:
四、接口驅(qū)動移植
easyflash軟件包不會直接把接口驅(qū)動加入到你的工程,因為考慮到每個人的使用情況可能不同,所以只給了一些demo作為參考。我們要把這個demo加到我們的工程里面,這樣才是完整的。
1、移植驅(qū)動
驅(qū)動移植常用的方法有兩種。
1:基于fal,有分區(qū)。
2:基于SFUD,不分區(qū)。
如果你的Flash驅(qū)動使用的是上面的其中一種,那么移植EasyFlash將會非常簡單。
如果沒有使用上面的驅(qū)動,請參考 EasyFlash 的 移植文檔 進行移植。在 EasyFlash 官方倉庫 下有很多 demo,也可以參考。
我這里舉的例子的是第1種,基于fal分區(qū),分區(qū)方法前面第二點已經(jīng)講過了,現(xiàn)在只要移植驅(qū)動即可。
第一步:在項目工程文件里面找到EasyFlash軟件包下的ports文件夾,復制ef_fal_port.c文件。
第二步:把復制的ef_fal_port.c文件拷貝到EasyFlash軟件包下的src文件夾。
提示:如果用第2種方法(基于SFUD),可以參考ports文件夾里面的README.md介紹的方法。
2、修改分區(qū)名
移植完驅(qū)動之后還要根據(jù)實際情況修改easyflash使用的分區(qū)名稱。
打開src目錄下的ef_fal_port.c文件,修改分區(qū)名。
示例如下:
/* EasyFlash partition name on FAL partition table */
#define FAL_EF_PART_NAME "easyflash" // 分區(qū)名為easyflash
提示:分區(qū)名必須是有效的分區(qū),分區(qū)表在fal_cfg.h文件里面FAL_PART_TABLE定義。
3、重新生成工程
在env輸入下面的命令,重新生成新的工程。
提示:會使用env的話應該都知道這個操作,不多說了。
scons --target=mdk5
五、測試用例
驅(qū)動移植好之后就可以正常運行easyflash了,這個時候可以寫一個簡單的測試用例來測試數(shù)據(jù)是否可以正常讀寫。
參考示例如下:
#include <rtdevice.h>
#include <rtthread.h>
#include <easyflash.h>
#define DBG_TAG "env"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
uint32_t i_boot_times = NULL;
static void env_boot(void);
int env_init(void)
{
fal_init();
if(easyflash_init() == EF_NO_ERR)
{
/* 演示環(huán)境變量功能 */
env_boot();
}
}
INIT_ENV_EXPORT(env_init);
static void env_boot(void)
{
char *c_old_boot_times, c_new_boot_times[11] = {0};
/* 從環(huán)境變量中獲取啟動次數(shù) */
c_old_boot_times = ef_get_env("boot_times");
/* 獲取啟動次數(shù)是否失敗 */
if(c_old_boot_times == RT_NULL)
c_old_boot_times[0] = '0';
i_boot_times = atol(c_old_boot_times);
/* 啟動次數(shù)加 1 */
i_boot_times++;
LOG_D("===============================================");
LOG_D("The system now boot %d times", i_boot_times);
LOG_D("===============================================");
/* 數(shù)字轉(zhuǎn)字符串 */
sprintf(c_new_boot_times, "%d", i_boot_times);
/* 保存開機次數(shù)的值 */
ef_set_env("boot_times", c_new_boot_times);
ef_save_env();
}
這個示例記錄了設(shè)備的重啟次數(shù),每次啟動的時候會先讀取上一次啟動的記錄,并加1,然后再把啟動次數(shù)保存到easyflash里面。
六、運行
正常運行的日志如下:
可以輸入以下命令來查看已保存的環(huán)境變量。
printenv
可以輸入以下命令來清除已保存的環(huán)境變量。
resetenv
七、結(jié)束語
好了,關(guān)于easyflash的介紹就到這里,如果還有什么問題,歡迎在評論區(qū)留言。如果這篇文章能夠幫到你,就給我點個贊吧,如果想了解更多RT-thread和單片機的內(nèi)容,可以關(guān)注一下博主,后續(xù)我還會繼續(xù)分享更多的經(jīng)驗給大家。
教程相關(guān)源碼:https://pan.baidu.com/s/1N2D8dM31deKIqNqaIQfPiA
提取碼:7nsx