使用说明
每次开发新项目时候, 都要移植常用的几个软件包,打开每个软件包的readme.md, 设置参数, 设置, 保存, 编译,很容易漏掉好多操作, 所以写了一个围绕flash 的常用的三个软件包, 以及使用步骤 基于 rt-thread studio。
1 软件包简述
1.1 fal
flash 管理中间层, 用来管理片内flash 与 外部 nor flash ,为上层软件提供统一接口,具体使用方法参考软件包 readme.md , 简易移植方法参考本文
1.2 easyflash
easyflash 可以直接操作flash , 也可以基于fal 操作 flash ( 建议此方法 ), 提供了 ENV 小型数据库, 日志备份接口, 擦写均衡等功能
1.3 ulog_easyflash
ulog 的后台写入到flash的软件包。
2 添加spi 功能
2.1 按照board.h 中, 配置spi 总线即可
3 添加flash 驱动
3.1 添加必须的软件包和驱动
1: settings 文件中, 打开sfud 驱动支持
2: 软件包中, 添加 fal 软件包
备注:
//1 fal 为 flash 抽象层驱动, 必须
//2 easyflash , 统一管理内外flash 提供小型数据库功能
//3 ulog_flash, 基于easyflash 的日志存储组件, 可选选项
/* 熟练操作后, 可一次性添加 以上三个软件包 并打开ulog 组件*/
3:右键fal 软件包 勾选使用 SFUD 驱动程序
完成上述操作后, 保存
4 把fal_cfg.h 从文件目录\packages\fal-v0.5.0\samples\porting移动到fal软件包的inc 文件夹, 或者用户驱动文件夹
5 把fal_flash_sfud_port.c 文件从目录\packages\fal-v0.5.0\samples\porting移动到 fal软件包所在的src 文件夹, 或者用户文件夹
3.2 片上flash 支持
1 在board.h 中, 按照 #define BSP_USING_ON_CHIP_FLASH 的两步, 实现片上flash 驱动
2 对接 drv_flash_l4.c 与 fal_cfg.h 的对接接口
2.1 fal_cfg.h 中 stm32 f2_onchip_flash 修改为 stm32f4_onchip_flash
2.2 添加内部ops 驱动函数 , 如果drv_flash_l4.c 存在如下代码, 改至统一即可, 不存在, 则自行添加
#if defined(PKG_USING_FAL)
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_erase(long offset, size_t size);
const struct fal_flash_dev stm32l4_onchip_flash = { "onchip_flash", STM32_FLASH_START_ADRESS, STM32_FLASH_SIZE,
FLASH_PAGE_SIZE, { NULL, fal_flash_read, fal_flash_write, fal_flash_erase } };
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
{
return stm32_flash_read(stm32l4_onchip_flash.addr + offset, buf, size);
}
static int fal_flash_write(long offset, const rt_uint8_t buf, size_t size)
{
return stm32_flash_write(stm32l4_onchip_flash.addr + offset, buf, size);
}
static int fal_flash_erase(long offset, size_t size)
{
return stm32_flash_erase(stm32l4_onchip_flash.addr + offset, size);
}
#endif
3.3 片外flash 支持
1 注册spi flash 设备到系统中去 添加如下代码到fal_flash_sfud_port.c
修改对应的spi 总线 和片选引脚
/ 如下初始化函数 /
#include "spi_flash_sfud.h"
#include "drv_spi.h"
#define NOR_FLASH_SPI_DEV_NAME "spi10"
/ 如下初始化函数 */
int sfud_nor_flash_init(void)
{
__HAL_RCC_GPIOB_CLK_ENABLE();// 片选引脚的时钟打开
rt_hw_spi_device_attach("spi1", NOR_FLASH_SPI_DEV_NAME, GPIOB, GPIO_PIN_6);// 在总线上添加flash 设备
if (rt_sfud_flash_probe(FAL_USING_NOR_FLASH_DEV_NAME, NOR_FLASH_SPI_DEV_NAME) == RT_NULL)
{
return -RT_ERROR;
}
return RT_EOK;
return -RT_ERROR;
}
INIT_DEVICE_EXPORT(sfud_nor_flash_init);
完成此操作后, 可以使用 list_device , 查看是否正常注册flash 设备
4 添加/配置easyflash 驱动
前置条件 fal 驱动正常
4.1 添加软件包/ 添加驱动文件
1 添加 easyflash 软件包
2 复制\EasyFlash-v4.1.0\ports 下 ef_fal_port.c 到 src文件夹/ 用户文件夹参与编译
3 在ef_fal_port.c 中, 修改 FAL_EF_PART_NAME 为 设置的分区名 "easyflash"
4 在ef_cfg.h 中, 95行左右 修改ENV_AREA_SIZE 为扇区大小, 是最小擦除大小的N倍
4.2 定义配置分区表
分区表在 fal_cfg.h 中, 根据需求, 调整名字和分区大小 easyfash 分区 = env + ulog
5 添加easylog 功能使用说明
1 软件包添加 ulog_easyflash , 组件打开ulog
2 easy_flash 软件包右键设置 LOG:在flash上保存日志, 并设置保存日志的大小 自行计算为easyflash 分区大小 - env 大小
6 flash 启动及使用
1 在用户函数中 添加如下代码
#include "fal.h"
#include "easyflash.h"
fal_init();
if(easyflash_init() == EF_NO_ERR)
{
rt_uint32_t i_boot_times = 0;
char *c_old_boot_times, c_new_boot_times[11] = {0};
c_old_boot_times = ef_get_env("boot_times");
if (c_old_boot_times == RT_NULL)
{
c_old_boot_times[0] = '0';
}
i_boot_times = atol(c_old_boot_times);
i_boot_times ++;
rt_kprintf("===============================================\n");
rt_kprintf("The system now boot %d times\n", i_boot_times);
rt_kprintf("===============================================\n");
sprintf(c_new_boot_times, "%d", i_boot_times);
ef_set_env("boot_times", c_new_boot_times);
ef_save_env();
LOG_D("Hello RT-Thread!");
}
完成以上步骤, 即可实现存日志, 小型键值对数据库等功能
1 每次开机之后, 会显示开机次数增加一次
2 使用 ulog_flash read 可以读取存在flash 上的日志 , 程序中使用 LOD_X 的代码, 都会存到flash 上,日志写满后, 会自动循环擦除,env 数据如果只是固定的几个键值对, 反复修改理论上没问题 , 也会在env 所处的扇区循环擦除。
3 使用 flash DB , fatfs 等文件系统之类的软件包, 只需要在 fal 层上, 在一个分区使用函数抽象出来一个flash 设备, 对接文件系统的驱动即可。与之前功能不会冲突。
原作者:kid