0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【LPC55S69】使用FAL分区管理与easyflash变量管理(下集)

恩智浦MCU加油站 来源:未知 2023-06-29 09:05 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

上期带大家了解了FAL组件和DFS文件系统的功能特点和使用方法,本期将继续解读如何将EasyFlsh移植到FAL分区。

简述EasyFlash

关于EasyFlash的来源我们已经讲过,EasyFlash是一款开源的轻量级嵌入式Flash存储器库,方便开发者更加轻松的实现基于Flash存储器的常见应用开发。非常适合智能家居、可穿戴、工控、医疗、物联网等需要断电存储功能的产品,资源占用极低,支持各种 MCU 片上存储器。

EasyFlash不仅能够实现对产品的设定参数或运行日志等信息的掉电保存功能,还封装了简洁的增加、删除、修改及查询方法,降低了开发者对产品参数的处理难度,也保证了产品在后期升级时拥有更好的扩展性。让Flash变为NoSQL(非关系型数据库)模型的小型键值(Key-Value)存储数据库。

EasyFlash软件包使用

打开ENV进入路径:RT-Thread online packages → tools packages → EasyFlash: Lightweight embedded flash memory library.,选择软件包版本为最新版。配置后退出ENV,同时使用pkgs --update下载软件包,然后再使用scons-target=mdk5重新生成MDK5文件。

4936011e-1615-11ee-962d-dac502259ad0.png

移植EasyFlash

下载完easyflash软件包后,我们复制. t-threadsplpc55sxxlpc55s69_nxp_evkpackagesEasyFlash-latestportsef_fal_port.c到目录. t-threadsplpc55sxxlpc55s69_nxp_evkoardportseasyflashef_fal_port.c,双击打开该文件,完成以下修改:

// 修改 FAL_EF_PART_NAME 为 easyflash
#define FAL_EF_PART_NAME               "easyflash"

编写EasyFlash测试用例

/*
  * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2023-04-21     Wangyuqiang  the first version
  */


#include "rtthread.h"
#include "rtdevice.h"
#include "board.h"
#include "fal.h"


#include 


#include "easyflash.h"
#include 


#define FS_PARTITION_NAME  "filesystem"


#define BUF_SIZE 1024


static int fal_test(const char *partiton_name)
{
int ret;
int i, j, len;
uint8_t buf[BUF_SIZE];
const struct fal_flash_dev *flash_dev = RT_NULL;
const struct fal_partition *partition = RT_NULL;


if (!partiton_name)
     {
         rt_kprintf("Input param partition name is null!
");
return -1;
     }


     partition = fal_partition_find(partiton_name);
if (partition == RT_NULL)
     {
         rt_kprintf("Find partition (%s) failed!
", partiton_name);
         ret = -1;
return ret;
     }


     flash_dev = fal_flash_device_find(partition->flash_name);
if (flash_dev == RT_NULL)
     {
         rt_kprintf("Find flash device (%s) failed!
", partition->flash_name);
         ret = -1;
return ret;
     }


     rt_kprintf("Flash device : %s   "
"Flash size : %dK   
"
"Partition : %s   "
"Partition size: %dK
",
                 partition->flash_name,
                 flash_dev->len/1024,
                 partition->name,
                 partition->len/1024);


/* erase all partition */
     ret = fal_partition_erase_all(partition);
if (ret < 0)
     {
         rt_kprintf("Partition (%s) erase failed!
", partition->name);
         ret = -1;
return ret;
     }
     rt_kprintf("Erase (%s) partition finish!
", partiton_name);


/* read the specified partition and check data */
for (i = 0; i < partition->len;)
     {
         rt_memset(buf, 0x00, BUF_SIZE);


         len = (partition->len - i) > BUF_SIZE ? BUF_SIZE : (partition->len - i);


         ret = fal_partition_read(partition, i, buf, len);
if (ret < 0)
         {
             rt_kprintf("Partition (%s) read failed!
", partition->name);
             ret = -1;
return ret;
         }


for(j = 0; j < len; j++)
         {
if (buf[j] != 0xFF)
             {
                 rt_kprintf("The erase operation did not really succeed!
");
                 ret = -1;
return ret;
             }
         }
         i += len;
     }


/* write 0x00 to the specified partition */
for (i = 0; i < partition->len;)
     {
         rt_memset(buf, 0x00, BUF_SIZE);


         len = (partition->len - i) > BUF_SIZE ? BUF_SIZE : (partition->len - i);


         ret = fal_partition_write(partition, i, buf, len);
if (ret < 0)
         {
             rt_kprintf("Partition (%s) write failed!
", partition->name);
             ret = -1;
return ret;
         }


         i += len;
     }
     rt_kprintf("Write (%s) partition finish! Write size %d(%dK).
", partiton_name, i, i/1024);


/* read the specified partition and check data */
for (i = 0; i < partition->len;)
     {
         rt_memset(buf, 0xFF, BUF_SIZE);


         len = (partition->len - i) > BUF_SIZE ? BUF_SIZE : (partition->len - i);


         ret = fal_partition_read(partition, i, buf, len);
if (ret < 0)
         {
             rt_kprintf("Partition (%s) read failed!
", partition->name);
             ret = -1;
return ret;
         }


for(j = 0; j < len; j++)
         {
if (buf[j] != 0x00)
             {
                 rt_kprintf("The write operation did not really succeed!
");
                 ret = -1;
return ret;
             }
         }


         i += len;
     }


     ret = 0;
return ret;
}


static void fal_sample(void)
{
/* 1- init */
     fal_init();


if (fal_test("font") == 0)
     {
         rt_kprintf("Fal partition (%s) test success!
", "font");
     }
else
     {
         rt_kprintf("Fal partition (%s) test failed!
", "font");
     }


if (fal_test("download") == 0)
     {
         rt_kprintf("Fal partition (%s) test success!
", "download");
     }
else
     {
         rt_kprintf("Fal partition (%s) test failed!
", "download");
     }
}
MSH_CMD_EXPORT(fal_sample, fal sample);


static void fal_elmfat_sample(void)
{
int fd, size;
struct statfs elm_stat;
struct fal_blk_device *blk_dev;
char str[] = "elmfat mount to W25Q flash.", buf[80];


/* fal init */
     fal_init();


/* create block device */
     blk_dev = (struct fal_blk_device *)fal_blk_device_create(FS_PARTITION_NAME);
if(blk_dev == RT_NULL)
         rt_kprintf("Can't create a block device on '%s' partition.
", FS_PARTITION_NAME);
else
         rt_kprintf("Create a block device on the %s partition of flash successful.
", FS_PARTITION_NAME);


/* make a elmfat format filesystem */
if(dfs_mkfs("elm", FS_PARTITION_NAME) == 0)
         rt_kprintf("make elmfat filesystem success.
");


/* mount elmfat file system to FS_PARTITION_NAME */
if(dfs_mount(FS_PARTITION_NAME, "/", "elm", 0, 0) == 0)
         rt_kprintf("elmfat filesystem mount success.
");


/* Get elmfat file system statistics */
if(statfs("/", &elm_stat) == 0)
         rt_kprintf("elmfat filesystem block size: %d, total blocks: %d, free blocks: %d.
",
                     elm_stat.f_bsize, elm_stat.f_blocks, elm_stat.f_bfree);


if(mkdir("/user", 0x777) == 0)
         rt_kprintf("make a directory: '/user'.
");


     rt_kprintf("Write string '%s' to /user/test.txt.
", str);


/* Open the file in create and read-write mode, create the file if it does not exist*/
     fd = open("/user/test.txt", O_WRONLY | O_CREAT);
if (fd >= 0)
     {
if(write(fd, str, sizeof(str)) == sizeof(str))
             rt_kprintf("Write data done.
");


         close(fd);   
     }


/* Open file in read-only mode */
     fd = open("/user/test.txt", O_RDONLY);
if (fd >= 0)
     {
         size = read(fd, buf, sizeof(buf));


         close(fd);


if(size == sizeof(str))
             rt_kprintf("Read data from file test.txt(size: %d): %s 
", size, buf);
     }
}
MSH_CMD_EXPORT_ALIAS(fal_elmfat_sample, fal_elmfat,fal elmfat sample);


static void easyflash_sample(void)
{
/* fal init */
     fal_init();


/* easyflash init */
if(easyflash_init() == EF_NO_ERR)
     {
uint32_t i_boot_times = NULL;
char *c_old_boot_times, c_new_boot_times[11] = {0};


/* get the boot count number from Env */
         c_old_boot_times = ef_get_env("boot_times");
/* get the boot count number failed */
if (c_old_boot_times == RT_NULL)
             c_old_boot_times[0] = '0';


         i_boot_times = atol(c_old_boot_times);
/* boot count +1 */
         i_boot_times ++;
         rt_kprintf("===============================================
");
         rt_kprintf("The system now boot %d times
", i_boot_times);
         rt_kprintf("===============================================
");
/* interger to string */
sprintf(c_new_boot_times, "%d", i_boot_times);
/* set and store the boot count number to Env */
         ef_set_env("boot_times", c_new_boot_times);
         ef_save_env();
     }
}
MSH_CMD_EXPORT(easyflash_sample, easyflash sample);

EasyFlash测试结果

打开串口助手,输入命令:
  1. msh />easyflash_sample

复制代码

第一次命令调用:49613442-1615-11ee-962d-dac502259ad0.png第二次RESET开发板后调用:

498e3712-1615-11ee-962d-dac502259ad0.png

结语

至此,FAL分区管理EasyFlash变量管理已经全部介绍完毕了,经历从移植软件模拟SPI框架到LPC55S69,到移植过程中不断遇到的问题,解决问题并提供应用示例,并完成开发日记、开发笔记及应用教学,作者坦言整个过程还是受益良多的。希望大家怀揣着一颗求知及授学之心,共同建设好这个领域!

参考资料:

  • IOT-OS之RT-Thread(十一)--- FAL分区管理与easyflash变量管理

  • RT-Thread文档中心:FAL组件

本文转载自:

END

更多恩智浦AI-IoT市场和产品信息,邀您同时关注“NXP客栈”微信公众号

49c10750-1615-11ee-962d-dac502259ad0.jpg      

NXP客栈


恩智浦致力于打造安全的连接和基础设施解决方案,为智慧生活保驾护航。

长按二维码,关注我们

恩智浦MCU加油站


这是由恩智浦官方运营的公众号,着重为您推荐恩智浦MCU的产品信息、开发技巧、教程文档、培训课程等内容。

49d4e6b2-1615-11ee-962d-dac502259ad0.jpg  

长按二维码,关注我们


原文标题:【LPC55S69】使用FAL分区管理与easyflash变量管理(下集)

文章出处:【微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    147

    文章

    18613

    浏览量

    387194
  • 恩智浦
    +关注

    关注

    14

    文章

    6051

    浏览量

    134663

原文标题:【LPC55S69】使用FAL分区管理与easyflash变量管理(下集)

文章出处:【微信号:NXP_SMART_HARDWARE,微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    城市用水分区计量管理系统方案

    浪费,增加供水企业运营成本,也难以精准响应不同区域的用水需求,影响供水服务质量与居民用水体验。 为此,物通博联以工业数采网关为核心,构建城市用水分区计量管理系统,实现对城市各区域用水数据的实时采集、动态监控、
    的头像 发表于 09-09 10:37 384次阅读
    城市用水<b class='flag-5'>分区</b>计量<b class='flag-5'>管理</b>系统方案

    【PCA9958HN-ARD】GUI工具的使用

    :PCA9958HN-ARD评估板快速入门 | NXP 半导体),里面包含GUI上位机软件的安装包和LPC55S69开发板的固件。 然后,点击setup.exe,进行GUI上位机软件的安装,安装
    发表于 06-29 10:07

    Linux系统中磁盘分区与挂载详解

    磁盘分区是将物理硬盘划分为不同的逻辑部分,每个分区都可以被视为一个独立的存储设备。通过磁盘分区,我们可以更好地管理磁盘空间,实现数据的组织和隔离。
    的头像 发表于 06-17 15:08 2049次阅读
    Linux系统中磁盘<b class='flag-5'>分区</b>与挂载详解

    警用装备管理系统DW-S304,对警用装备的全生命周期追踪管理.

    管理系统
    jf_85364936
    发布于 :2025年06月15日 09:19:54

    战备器材管理系统DW-S301

    管理系统
    jf_72884372
    发布于 :2025年04月17日 16:28:57

    LPC55 USB端点rx数据无响应是哪里出了问题?

    我使用 LPC55S69 开发了一个 MIDI 键盘,USB MIDI 设备基于 SDK 的 USB 串行协议,我相应地对其进行了修改。 在 PC 上可以正确地枚举为 MIDI 设备,数据传输和接收
    发表于 04-09 08:09

    LPC55S69-EVK无法加载安全启动是怎么回事?

    我已按如下方式配置了我的 LPC55S69-EVK 板:   此外,我还配置了: TrustZone disabled image Authentication key: ROT1
    发表于 04-09 06:34

    SwdRead等待response_“LPC55s28” 超时了怎么解决?

    当我尝试锁定 MCU LPC55sXX 时,我遇到了以下问题。 我正在按照以下步骤锁定 MCU: 1.- 在 ISP 模式下配置 MCU。 2.- 将 bin 文件写入 CFPA。 3.- 将 bin 文件写入 CMPA。 4.- 验证 MCU 是否被锁定并预期出现以下结果: 此问题间歇性发生。
    发表于 04-08 06:52

    使用NXP控制器LPC55S69JBD100E,编程都需要SWD和JTAG吗?

    1. 在我们的项目中,我们使用 NXP 控制器LPC55S69JBD100E。编程都需要 SWD 和 JTAG 吗? 2. 您能解释一下 Flash 编程吗?
    发表于 03-27 07:23

    使用ConfigTools for USB创建新项目时遇到的问题求解

    使用 ConfigTools for USB 创建新项目时,存在缺少资源的问题,无法添加它: 该问题从 SDK 24.12.00 开始出现。适用于 macOS 的 MCUXpresso。经过 LPC55s69、MCX A153 和 MCX N947 测试。
    发表于 03-26 08:06

    LPC55S69JBD100通过SPI连接到WM02C时,是否支持通过bootloader进行OTA更新?

    该恩智浦-LPC55S69JBD100通过 SPI 连接到 WM02C (nRF7002) 时,是否支持通过 bootloader 进行 OTA 更新?请解释一下 OTA 更新过程。
    发表于 03-26 07:39

    EVK-LPC55S28的负载上限是多少?

    EVK-LPC55S28 使用晶CX3225GA16000D0PTVCC,在数据表中指定负载上限为 8pf。在 capbank appnote 中,它给出了一个示例,其中具有 8pF 值的 xtal
    发表于 03-26 06:25

    在ISP模式下无法在LPC55S69 EVK上升级应用程序怎么解决?

    我在使用 flash magic 工具升级 LPC55s69 evk 上的固件时看到问题。 在验证过程中,我看到失败。 请找到随附的快照作为参考, 有人可以告诉我,这是怎么回事吗? 一些其他信息
    发表于 03-26 06:00

    快速搞懂C语言程序内存分区

    在程序运行过程中,操作系统会根据程序的需要,将内存划分为多个功能不同的区段,以便更高效地管理内存资源和确保程序的稳定运行。不同的内存区段负责存储不同类型的数据和代码,涵盖了从程序指令、全局变量
    的头像 发表于 03-14 17:37 1340次阅读
    快速搞懂C语言程序内存<b class='flag-5'>分区</b>!