該筆記類別主要是在自己學(xué)習(xí)時(shí)做的一些記錄,方便自己很久不用忘掉時(shí)進(jìn)行快速回憶
1 使用
1.1 導(dǎo)入文件
文件名 | 位置 |
---|---|
fal.c | ./src/ |
fal_flash.c | ./src/ |
fal_partition.c | ./src/ |
fal_rtt.c | ./src/ |
fal_flash_stm32l1_port.c(移植文件) | ./samples/porting |
然后導(dǎo)入頭文件地址
目錄 |
---|
./samples/porting |
./inc |
1.2 添加宏定義
在rtconfig.h文件中添加宏定義
// fal
#define PKG_USING_FAL
#define FAL_PART_HAS_TABLE_CFG
1.3建立分區(qū)表
根據(jù)在移植文件中定義的存儲(chǔ)空間名字來(lái)分區(qū)尚揣,例如在fal_flash_stm32l1_port.c中定義了
const struct fal_flash_dev stm32l_eeprom = { "stm32l_eeprom", 0, 2*1024, 2048, {NULL, read, write, erase} };
則在fla_cfg.h中可用如下劃分區(qū)域
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WROD, "eeprom", "stm32l_eeprom", 0, 1024+512, 0}, \
{FAL_PART_MAGIC_WROD, "eeprom2", "stm32l_eeprom", 1024+512,512 , 0}, \
}
注意的是頭文件中必須使用宏(FAL_PART_HAS_TABLE_CFG)赐写,才會(huì)使用這里定義的分區(qū)方式
1.3 例程
- 添加頭文件
#include "fal.h"
- 初始化fla組件
fal_init();
- 打印分區(qū)表
fal_show_part_table();
輸出結(jié)果:
- 選擇一個(gè)操作分區(qū)
const struct fal_partition * bli = fal_partition_find("eeprom2") ;
if (bli ==RT_NULL)
{
rt_kprintf("flash not find\n");
}
- 讀寫測(cè)試
static uint8_t reg[3] ={0,0,0};
static uint8_t data[3] ={1,2,3};
fal_partition_read(bli,0,reg,3);
rt_kprintf("##%d %d %d",reg[0],reg[1],reg[2]);
rt_thread_mdelay(1000);
fal_partition_erase(bli,0,3);
fal_partition_write(bli,0,data,3);
fal_partition_read(bli,0,reg,3);
rt_kprintf("##%d %d %d",reg[0],reg[1],reg[2]);
先讀取3個(gè)寄存器鸭栖,然后寫入新數(shù)據(jù)1,2,3袜漩,再次讀取顯示出來(lái)。串口打印結(jié)果在第一次讀取時(shí)輸出為零舶掖,在擦除寫入后讀取出來(lái)便是數(shù)據(jù)1,2,3. 復(fù)位模塊后第一次讀取出的數(shù)據(jù)也為1,2,3. 表示掉電保存成功了卑硫。
2 通用API
2.1查找 Flash 設(shè)備
失敗返回NULL
const struct fal_flash_dev *fal_flash_device_find(const char *name)
2.2 查找 Flash 分區(qū)
const struct fal_partition *fal_partition_find(const char *name)
2.3 獲取分區(qū)表
led:分區(qū)表長(zhǎng)度
const struct fal_partition *fal_get_partition_table(size_t *len)
2.4 臨時(shí)設(shè)置分區(qū)表
FAL 初始化時(shí)會(huì)自動(dòng)裝載默認(rèn)分區(qū)表徒恋。使用該設(shè)置將臨時(shí)修改分區(qū)表,重啟后會(huì) 丟失 該設(shè)置
void fal_set_partition_table_temp(struct fal_partition *table, size_t len)
2.5 從分區(qū)讀取數(shù)據(jù)
返回實(shí)際讀取大小
int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size)
2.6 往分區(qū)寫入數(shù)據(jù)
int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size)
2.7 擦除分區(qū)數(shù)據(jù)
int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size)
2.8 擦除整個(gè)分區(qū)數(shù)據(jù)
int fal_partition_erase_all(const struct fal_partition *part)
2.9 打印分區(qū)表
void fal_show_part_table(void)
2.10 根據(jù)分區(qū)名稱欢伏,創(chuàng)建對(duì)應(yīng)的塊設(shè)備
該函數(shù)可以根據(jù)指定的分區(qū)名稱入挣,創(chuàng)建對(duì)應(yīng)的塊設(shè)備,以便于在指定的分區(qū)上掛載文件系統(tǒng)
struct rt_device *fal_blk_device_create(const char *parition_name)
參數(shù) | 描述 |
---|---|
parition_name | 分區(qū)名稱 |
return | 創(chuàng)建成功硝拧,則返回對(duì)應(yīng)的塊設(shè)備径筏,失敗返回空 |
2.11 根據(jù)分區(qū)名稱,創(chuàng)建對(duì)應(yīng)的 MTD Nor Flash 設(shè)備
該函數(shù)可以根據(jù)指定的分區(qū)名稱障陶,創(chuàng)建對(duì)應(yīng)的 MTD Nor Flash 設(shè)備滋恬,以便于在指定的分區(qū)上掛載文件系統(tǒng)
struct rt_device *fal_mtd_nor_device_create(const char *parition_name)
參數(shù) | 描述 |
---|---|
parition_name | 分區(qū)名稱 |
return | 創(chuàng)建成功,則返回對(duì)應(yīng)的 MTD Nor Flash 設(shè)備抱究,失敗返回空 |
2.12 根據(jù)分區(qū)名稱恢氯,創(chuàng)建對(duì)應(yīng)的字符設(shè)備
該函數(shù)可以根據(jù)指定的分區(qū)名稱,創(chuàng)建對(duì)應(yīng)的字符設(shè)備鼓寺,以便于通過(guò) deivice 接口或 devfs 接口操作分區(qū)勋拟,開(kāi)啟了 POSIX 后,還可以通過(guò) oepn/read/write 函數(shù)操作分區(qū)
struct rt_device *fal_char_device_create(const char *parition_name)
參數(shù) | 描述 |
---|---|
parition_name | 分區(qū)名稱 |
return | 創(chuàng)建成功妈候,則返回對(duì)應(yīng)的塊設(shè)備敢靡,失敗返回空 |
3 MSH命令
命令 | 說(shuō)明 |
---|---|
fal | 顯示fal的相關(guān)命令 |
fal probe | 顯示并用于指定分區(qū) |
fal read addr size | 例如 fal read 0 64 |
fal write addr data1 ... dataN | 例如fal write 8 1 2 3 4 5 |
fal erase addr size | 例如 fal erase 0 4096 |
fal bench <blk_size> | 例如 fal bench 4096 yes |
4 移植
使用一節(jié)中提到的samples\porting目下便是移植需要修改的文件,例如源碼只提供了fal_flash_sfud_port.c和fal_flash_stm32f2_port.c兩個(gè)文件州丹,我想在芯片stm32L151上使用它的eeprom醋安,則自己新建立一個(gè)文件,實(shí)現(xiàn)初始化墓毒、讀吓揪、寫、擦即可所计,最后在同目錄下的fal_cfg.h中進(jìn)行分區(qū)柠辞,就想下面這樣
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WROD, "eeprom", "stm32l_eeprom", 0, 1024+512, 0}, \
{FAL_PART_MAGIC_WROD, "eeprom2", "stm32l_eeprom", 1024+512,512 , 0}, \
}
fal_flash_stm32l1_port.c
#include <fal.h>
#include "rtthread.h"
#define EEPROM_BASE_ADDR 0x08080000
static int read(long offset, uint8_t *buf, size_t size)
{
uint8_t *wAddr;
size_t i;
wAddr=(uint8_t *)(EEPROM_BASE_ADDR+offset);
for (i = 0; i < size; i++, wAddr++, buf++)
{
*buf = *(uint8_t *) wAddr;
}
// while(size--){
// *buf++=*wAddr++;
// }
return size;
}
static int write(long offset, const uint8_t *buf, size_t size)
{
size_t i;
uint32_t read_data;
uint32_t addr = EEPROM_BASE_ADDR + offset;
HAL_FLASHEx_DATAEEPROM_Unlock();
for (i = 0; i < size; i++, buf++, addr++)
{
// HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_BYTE,addr);
HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE , addr, *buf);
read_data = *(uint8_t *) addr;
/* check data */
if (read_data != *buf)
{
return -1;
}
}
HAL_FLASHEx_DATAEEPROM_Lock();
return size;
}
static int erase(long offset, size_t size)
{
size_t i;
uint32_t addr = EEPROM_BASE_ADDR + offset;
HAL_FLASHEx_DATAEEPROM_Unlock();
for(i=0;i<size;i++ , addr++)
{
HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_BYTE,addr);
}
HAL_FLASHEx_DATAEEPROM_Lock();
return size;
}
const struct fal_flash_dev stm32l_eeprom = { "stm32l_eeprom", 0, 2*1024, 2048, {NULL, read, write, erase} };
同理無(wú)論任何存儲(chǔ),只需要實(shí)現(xiàn)對(duì)于接口后主胧,上層使用便沒(méi)有任何區(qū)別