RT-Thread的 FAL 组件_使用笔记

RT-Thread的FAL分区表组件

1、FAL介绍

FAL (Flash Abstraction Layer) Flash 抽象层,是对 Flash 及基于 Flash 的分区进行管理、操作的抽象层,对上层统一了 Flash 及 分区操作的 API (框架图如下所示),并具有以下特性:

在这里插入图片描述

1.1 FAL目录

名称说明
inc头文件目录
src源代码目录
samples例程目录

1.2 FAL API

请添加图片描述

1.2.1 查找 Flash 设备
const struct fal_flash_dev *fal_flash_device_find(const char *name)
参数描述
nameFlash 设备名称
return如果查询成功,将返回 Flash 设备对象,查找失败==> NULL
1.2.2 查找 Flash 分区
const struct fal_partition *fal_partition_find(const char *name)
参数描述
nameFlash分区名称
return如果查询成功,将返回 Flash 分区对象, 查找失败==> NULL
1.2.3 获取分区表
const struct fal_partition *fal_get_partition_table(size_t *len)
参数描述
len分区表的长度
return分区表
1.2.4 临时设置分区表

FAL 初始化时会自动装载默认分区表。使用该设置将临时修改分区表,重启后会 丢失 该设置

void fal_set_partition_table_temp(struct fal_partition *table, size_t len)
参数描述
table分区表
len分区表的长度
1.2.5 从分区读取数据
int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size)
参数描述
part分区对象
addr相对分区的偏移地址
buf存放待读取数据的缓冲区
size待读取数据的大小
return返回实际读取的数据大小
1.2.6 从分区写入数据
int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size)
参数描述
part分区对象
addr相对分区的偏移地址
buf存放待写入数据的缓冲区
size待写入数据的大小
return返回实际写入的数据大小
1.2.7 擦除分区数据
int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size)
参数描述
part分区对象
addr相对分区的偏移地址
size擦除区域的大小
return返回实际擦除的区域大小
1.2.8 擦除整个分区数据
int fal_partition_erase_all(const struct fal_partition *part)
参数描述
part分区对象
return返回实际擦除的区域大小
1.2.9 打印分区表
void fal_show_part_table(void)
1.2.10 创建块设备

该函数可以根据指定的分区名称,创建对应的块设备,以便于在指定的分区上挂载文件系统

struct rt_device *fal_blk_device_create(const char *parition_name)
参数描述
parition_name分区名称
return创建成功,则返回对应的块设备,失败返回空
1.2.11 创建 MTD Nor Flash 设备

该函数可以根据指定的分区名称,创建对应的 MTD Nor Flash 设备,以便于在指定的分区上挂载文件系统

struct rt_device *fal_mtd_nor_device_create(const char *parition_name)
参数描述
parition_name分区名称
return创建成功,则返回对应的 MTD Nor Flash 设备,失败返回空
1.2.12 创建字符设备

该函数可以根据指定的分区名称,创建对应的字符设备,以便于通过 deivice 接口或 devfs 接口操作分区,开启了 POSIX 后,还可以通过 oepn/read/write 函数操作分区。

struct rt_device *fal_char_device_create(const char *parition_name)
参数描述
parition_name分区名称
return创建成功,则返回对应的字符设备,失败返回空

2、使用 定义 FAL

使用 FAL 的基本步骤如下所示:

  1. 打开 FAL:从 Env 中打开 fal 软件包并下载到工程。
  2. FAL 移植:定义 flash 设备、定义 flash 设备表、定义 flash 分区表。以下主要对步骤 2 展开讲解。
  3. 调用 fal_init() 初始化该库:移植完成后,可在应用层调用,如在 main 函数中调用。
    在这里插入图片描述

2.1 定义 flash 设备

在定义 Flash 设备表前,需要先定义 Flash 设备。可以是片内 flash, 也可以是片外基于 SFUD 的 spi flash:

片内 spi flash : fal_flash_sfud_port.c

片外flash : fal_flash_stm32f_port.c

  • 定义具体的 Flash 设备对象,用户需要根据自己的 Flash 情况分别实现 initreadwriteerase 这些操作函数:
2.1.1 初始化&读写&擦除
    • static int init(void)//可选 的初始化操作
      
    • static int read(long offset, uint8_t *buf, size_t size)//读取操作
      
      • 参数描述
        offset读取数据的 Flash 偏移地址
        buf存放待读取数据的缓冲区
        size待读取数据的大小
        return返回实际读取的数据大小
    • static int write(long offset, const uint8_t *buf, size_t size) //写入操作。
      
      • 参数描述
        offset写入数据的 Flash 偏移地址
        buf存放待写入数据的缓冲区
        size待写入数据的大小
        return返回实际写入的数据大小
    • static int erase(long offset, size_t size) :擦除操作。
      
      • 参数描述
        offset擦除区域的 Flash 偏移地址
        size擦除区域的大小
        return返回实际擦除的区域大小

用户需要根据自己的 Flash 情况分别实现这些操作函数。在文件最底部定义了具体的 Flash 设备对象 ,如下示例定义了 stm32f2 片上 flash:stm32f2_onchip_flash

const struct fal_flash_dev stm32f2_onchip_flash =
{
    .name       = "stm32_onchip",
    .addr       = 0x08000000,
    .len        = 1024*1024,
    .blk_size   = 128*1024,
    .ops        = {init, read, write, erase},
    .write_gran = 8
};
/*
"stm32_onchip":`	 Flash 设备的名字。
0x08000000: 		 对 Flash 操作的起始地址。
1024*1024:			Flash 的总大小(1MB)。
128*1024:			Flash 块/扇区大小(因为 STM32F2 各块大小不均匀,所以擦除粒度为最大块的大小:128K)。
{init, read, write, erase} :Flash 的操作函数。 如果没有 init 初始化过程,第一个操作函数位置可以置空。
8 : 				设置写粒度,单位 bit, 0 表示未生效(默认值为 0 ),该成员是 fal 版本大于 0.4.0 的新增成员。各个 flash 写入粒度不尽相同,可通过
*/

该成员进行设置,以下列举几种常见 Flash 写粒度:
nor flash: 1 bit
stm32f4: 8 bit
stm32f1: 32 bit
stm32l4: 64 bit

2.2 定义设备表

Flash 设备表定义在 fal_cfg.h 头文件中,定义分区表前需 新建 fal_cfg.h 文件 ,请将该文件统一放在对应 BSP 或工程目录的 port 文件夹下,并将该头文件路径加入到工程

参考 fal_cfg.h

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-05-17     armink       the first version
 */

#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_

#include <rtconfig.h>
#include <board.h>

#define NOR_FLASH_DEV_NAME             "norflash0"

/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev stm32f2_onchip_flash;
extern struct fal_flash_dev nor_flash0;

/* flash device table */
#define FAL_FLASH_DEV_TABLE                                          \
{                                                                    \
    &stm32f2_onchip_flash,                                           \
    &nor_flash0,                                                     \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE                                                               \
{                                                                                    \
    {FAL_PART_MAGIC_WORD,        "bl",     "stm32_onchip",         0,   64*1024, 0}, \
    {FAL_PART_MAGIC_WORD,       "app",     "stm32_onchip",   64*1024,  704*1024, 0}, \
    {FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME,         0, 1024*1024, 0}, \
    {FAL_PART_MAGIC_WORD,  "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */

#endif /* _FAL_CFG_H_ */

eg

/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev stm32f2_onchip_flash;
extern struct fal_flash_dev nor_flash0;

/* flash device table */
#define FAL_FLASH_DEV_TABLE                     
{                                               
    &stm32f2_onchip_flash,                   
    &nor_flash0,                               
}
  • Flash 设备表中,有两个 Flash 对象,一个为 STM32F2 的片内 Flash ,一个为片外的 Nor Flash。

2.3 定义flash分区表

分区表也定义在 fal_cfg.h 头文件中。Flash 分区基于 Flash 设备,每个 Flash 设备又可以有 N 个分区,这些分区的集合就是分区表。在配置分区表前,务必保证已定义好 Flash 设备设备表

eg

#define NOR_FLASH_DEV_NAME             "norflash0"
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE                                                               \
{                                                                                    \
    {FAL_PART_MAGIC_WORD,        "bl",     "stm32_onchip",         0,   64*1024, 0}, \
    {FAL_PART_MAGIC_WORD,       "app",     "stm32_onchip",   64*1024,  704*1024, 0}, \
    {FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME,         0, 1024*1024, 0}, \
    {FAL_PART_MAGIC_WORD,  "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
分区名Flash 设备名偏移地址大小说明
“bl”“stm32_onchip”064KB引导程序
“app”“stm32_onchip”64*1024704KB应用程序
“easyflash”“norflash0”01MBEasyFlash 参数存储
“download”“norflash0”1024*10241MBOTA 下载区

用户需要修改的分区参数包括:分区名称、关联的 Flash 设备名、偏移地址(相对 Flash 设备内部)、大小,需要注意以下几点:

  • 分区名保证 不能重复
  • 关联的 Flash 设备 务必已经在 Flash 设备表中定义好 ,并且 名称一致 ,否则会出现无法找到 Flash 设备的错误;
  • 分区的起始地址和大小 不能超过 Flash 设备的地址范围 ,否则会导致包初始化错误;

注意:每个分区定义时,除了填写上面介绍的参数属性外,需在前面增加 FAL_PART_MAGIC_WORD 属性,末尾增加 0 (目前用于保留功能)

3、MSH测试命令

fal 提供了丰富的测试命令,项目只要在 RT-Thread 上开启 MSH 功能即可。在做一些基于 Flash 的应用开发、调试时,这些命令会非常实用。它可以准确的写入或者读取指定位置的原始 Flash 数据,快速的验证 Flash 驱动的完整性,甚至可以对 Flash 进行性能测试。

在RT-Thread操作系统中,MSH是Finsh shell命令行工具的一部分,它允许用户通过命令行操作完成功能测试。MSH模式是Finsh shell的一种模式,用户可以通过启用特定的宏来使用MSH模式。在MSH模式下,用户可以导出自定义命令,这些命令可以直接在FinSH中执行

  • RT-Thread命令行中 msh
命令作用
fal看到完整的命令列表
fal probe指定待操作的Flash设备或Flash分区
fal erase擦除数据
fal write写入数据
fal read读取数据
fal bench性能测试

3.1完整的命令列表

msh />fal
Usage:
fal probe [dev_name|part_name]   - probe flash device or partition by given name
fal read addr size               - read 'size' bytes starting at 'addr'
fal write addr data1 ... dataN   - write some bytes 'data' starting at 'addr'
fal erase addr size              - erase 'size' bytes starting at 'addr'
fal bench <blk_size>             - benchmark test with per block size

msh />

3.2 指定待操作的Flash设备/Flash分区

当第一次使用 fal 命令时,直接输入 fal probe 将会显示分区表信息。可以指定待操作的对象为分区表里的某个分区,或者某个 Flash 设备

msh />fal probe    
No flash device or partition was probed.
Usage: fal probe [dev_name|part_name]   - probe flash device or partition by given name.
[I/FAL] ==================== FAL partition table ====================
[I/FAL] | name      | flash_dev    |   offset   |    length  |
[I/FAL] -------------------------------------------------------------
[I/FAL] | bl        | stm32_onchip | 0x00000000 | 0x00010000 |
[I/FAL] | app       | stm32_onchip | 0x00010000 | 0x000b0000 |
[I/FAL] | ef        | norflash0    | 0x00000000 | 0x00100000 |
[I/FAL] | download  | norflash0    | 0x00100000 | 0x00100000 |
[I/FAL] =============================================================
msh />
msh />fal probe download
Probed a flash partition | download | flash_dev: norflash0 | offset: 1048576 | len: 1048576 |.
msh />

3.3 擦除数据

  • 先输入 fal erase ,后面跟着待擦除数据的起始地址以及长度。以下命令为:从 0 地址(相对 Flash 或分区)开始擦除 4096 字节数据

注意:根据 Flash 特性,擦除动作将按扇区对齐进行处理。所以,如果擦除操作地址或长度未按照 Flash 的扇区对齐,将会擦除掉与其关联的整个扇区数据。

msh />fal erase 0 4096
Erase data success. Start from 0x00000000, size is 4096.
msh />

3.4 写入数据

  • 先输入 fal write ,后面跟着 N 个待写入的数据,并以空格隔开。以下命令为:从地址 8 的位置依次开始写入 1、2、3、4 、 5 这 5 个字节数据
msh />fal write 8 1 2 3 4 5
Write data success. Start from 0x00000008, size is 5.
Write data: 1 2 3 4 5 .
msh />

3.5 读取数据

  • 先输入 fal read ,后面跟着待读取数据的起始地址以及长度。以下命令为:从 0 地址开始读取 64 字节数据
msh />fal read 0 64
Read data success. Start from 0x00000000, size is 64. The data is:
Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
[00000000] FF FF FF FF FF FF FF FF 01 02 03 04 05 FF FF FF 
[00000010] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
[00000020] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
[00000030] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 

msh />

3.6 性能测试

  • 性能测试将会测试 Flash 的擦除、写入及读取速度,同时将会测试写入及读取数据的准确性,保证整个 Flash 或整个分区的 写入与读取 数据的一致性。

    先输入 fal bench ,后面跟着待测试 Flash 的扇区大小(请查看对应的 Flash 手册,SPI Nor Flash 一般为 4096)。由于性能测试将会让整个 Flash 或者整个分区的数据丢失,所以命令最后必须跟 yes

msh />fal bench 4096 yes
Erasing 1048576 bytes data, waiting...
Erase benchmark success, total time: 2.674S.
Writing 1048576 bytes data, waiting...
Write benchmark success, total time: 7.107S.
Reading 1048576 bytes data, waiting...
Read benchmark success, total time: 2.716S.
msh />

4、常见问题

  • 使用 FAL 时,无法找到 fal_cfg.h 头文件

fal_cfg.h 为 fal 软件包的配置文件,需要用户手动新建,并定义相关的分区表信息。请将该文件统一放在 BSP 的 port 文件夹下或工程目录的 port 文件夹下(若没有则新建 port 文件夹),并将该头文件路径加入到工程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/632049.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSP备考---2023大湾区比赛易错题

解析 9.D无向图公式&#xff1a;有向图公式&#xff1a;本题考察无向图&#xff0c;故 12.D公式&#xff1a; 14.B有三种情况&#xff1a;1男2女、2男1女、3女。 17.错 因为12300400000超过了int的范围 18.错 21.D 23.对 25.A 26.D代入程序 31.C 33.C 36.D 37.A …

四川古力未来科技抖音小店:科技赋能,购物新体验!

在当下这个数字化飞速发展的时代&#xff0c;电商行业早已成为了人们日常生活中不可或缺的一部分。而抖音小店作为电商领域的一匹黑马&#xff0c;正以其独特的优势和魅力&#xff0c;吸引着越来越多的消费者。今天&#xff0c;我们就来一起探讨一下四川古力未来科技抖音小店的…

2024 年 11 款顶级Android数据恢复软件的主要功能

Android 设备上的数据丢失可能是一种令人痛苦的体验&#xff0c;通常会导致不可替代的信息瞬间消失。 可能会发生意外删除、系统崩溃或格式错误&#xff0c;关键数据的丢失可能会扰乱日常工作并影响您的工作效率。 幸运的是&#xff0c;技术进步带来了几种恢复解决方案&#…

单片机烧录程序时“DTR的低电平复位,RTS高电平进入bootloader”有关的串口Modem联络信号

烧录程序时常见DTR和RTS引脚 参考&#xff0c;参考视频 因为常常使用的都是串口下载程序&#xff0c;常用的芯片CH340系列&#xff0c;下图中标红的引脚是MODEM联络信号&#xff0c;其中常见的DTR和RTS就是常见的串口Modem网络输出信号&#xff0c;也就是通过烧录软件控制的接…

网络地址转换(nat,easy ip,nat server)资源上传

实验概述 由内到外 nat&#xff0c;easy ip&#xff0c;转换的是源ip nat server 由外到内&#xff0c;转换的是目的IP 实验拓扑 结果验证 nat实验得到结果 1.ar1到ar3没有路由也可以访问 2.ar3配置telent后ar1也可以通过telnet远程配置 esay ip 如果ar2 g0/0/1接口ip非固…

智能边缘计算 | 2024高通边缘智能创新应用大赛赛道解读

随着物联网设备的普及和数据的井喷式增长&#xff0c;用户对数据处理的效率要求进一步提升&#xff0c;而边缘设备的计算能力日益增强&#xff0c;在边缘端完成复杂计算已经成为可能。 除降低时延与减少宽带资源占用外&#xff0c;边缘计算在离数据源更接近的地方完成数据处理…

cdn引入vue的项目嵌入vue组件——http-vue-loader 的使用——技能提升

最近在写MVC的后台&#xff0c;看到全是jq的写法&#xff0c;但是对于用惯了vue的我&#xff0c;真是让我无从下手。。。 vue的双向绑定真的很好用。。。 为了能够在cdn引入的项目中嵌入vue组件&#xff0c;则可以使用http-vue-loader了 步骤1&#xff1a;下载http-vue-loader…

MLM之GPT-4o:GPT-4o(多模态/高智能/2倍速/视觉改进/128K的大窗口)的简介、安装和使用方法、案例应用之详细攻略

MLM之GPT-4o&#xff1a;GPT-4o(多模态/高智能/2倍速/视觉改进/128K的大窗口)的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年5月13日&#xff0c;OpenAI重磅发布新旗舰模型GPT-4o&#xff0c;这是一个全新的旗舰模型&#xff0c;可以实时跨越音频、视觉和…

【算法】网络图中的dfs

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、单词搜索二、黄金矿工三、不同路径 |||四、图像渲染五、岛屿数量六、岛屿的最大面积七、被围绕的区域…

Flutter+Getx仿小米商城项目实战教程又新增了Flutter调用原生地图

FlutterGetx仿小米商城项目实战教程基于Flutter3.x录制&#xff0c;课程紧贴企业需求&#xff0c;目前已完结176讲。教程所讲内容支持Android、Ios、华为鸿蒙OS&#xff0c;教程更新于2024年4月09日新增 Flutter 调用百度地图、新增Flutter充电桩项目地图实战。支持2024年3月29…

【亚马逊云】注册APN账号及报考AWS认证考试说明演示

文章目录 1. 登录AWS网站2. 注册APN账号3. 更改APN账号密码&#xff08;选&#xff09;4. 修改APN账号信息&#xff08;选&#xff09;5. 查看AWS认证情况&#xff08;选&#xff09;6. AWS认证考试报名流程7. 修改报名控制台语言版本&#xff08;选&#xff09;8. 开始报名AWS…

抖音小店三大核心!掌握之后,做店岂不是手到捏来

大家好&#xff0c;我是电商喷火 做好一家抖音小店&#xff0c;并不需要太多的技术含量&#xff0c;做好这核心三点&#xff0c;起店并不难。 这三点分别是&#xff0c;选品、流量、售后 01.选品 首先&#xff0c;店铺的商品一定要和店铺的类目高度垂直&#xff0c;不要在大…

多联机常见各部件功能及常见机组制冷原理图

一、各部件名称和主要功能 1、压缩机 压缩机根据实际系统需要&#xff0c;调整其转速达到节能目的。 2、压缩机油温加热带 在待机状态下&#xff0c;保证压缩的油温确再启动可靠性。 3、压缩机 排气 感温包 检测压缩机的排气温度&#xff0c;达到控制和保护目的。 4、高压开…

关爱内向儿童:理解与支持助力成长

引言 每个孩子都是独特的&#xff0c;有些孩子天生性格外向&#xff0c;善于表达&#xff0c;而有些孩子则比较内向&#xff0c;喜欢独处。内向并不是缺点&#xff0c;而是一种性格特质。然而&#xff0c;内向的孩子在社交和学习过程中可能会面临一些挑战。本文将探讨内向儿童…

失而复得:揭秘删除照片恢复的技巧!

我们的生活与照片紧密相连。每一张照片都承载着一段独特的记忆&#xff0c;记录着我们的喜怒哀乐。然而&#xff0c;有时候我们会因为误操作、存储设备损坏或是文件管理不当而失去这些宝贵的照片。别担心&#xff01;现在&#xff0c;我们将揭示删除照片恢复的神秘面纱&#xf…

反激式开关电源-8利用AP法进行变压器设计

变压器AP的计算 在变压器设计中&#xff0c;主要有两种方法&#xff0c;一种称为Kc法&#xff0c;这种方法也称为磁芯几何参数法&#xff0c;如果用这个方法来进行设计&#xff0c;那么我们首先要计算出磁芯的几何参数Kc值&#xff0c;在这个参数上留有一定的裕度后选取和Kc值…

Github项目部署到自己的域名

天坑&#xff0c;买的是华为的域名&#xff0c;不过新用户才一块&#xff0c;就忍了 要买个域名&#xff0c;我买的是华为的&#xff08;此处是购买地址&#xff09; 购买后去控制台&#xff0c;点击“总览”进入域名页面 点击想要修改的域名后的“管理解析” 点击快速解析&…

HTML静态网页成品作业(HTML+CSS+JS)——在线购物商城网页设计制作(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;使用Javacsript代码实现图片轮播切换&#xff0c;共有4个页面。 二、…

力扣HOT100 - 300. 最长递增子序列

解题思路&#xff1a; 动态规划 class Solution {public int lengthOfLIS(int[] nums) {if (nums.length 0) return 0;int[] dp new int[nums.length];int max 0;Arrays.fill(dp, 1);for (int i 0; i < nums.length; i) {for (int j 0; j < i; j) {if (nums[j] <…