MM32F3273G8P火龙果开发板MindSDK开发教程19 - littlefs文件系统的移植

本文介绍了如何在MM32F3273G8P火龙果开发板上移植littlefs文件系统,该系统由ARM发布,适用于微控制器和Flash存储,具有掉电恢复和擦写均衡功能。移植过程中,首先介绍了littlefs的特点,然后详细说明了移植步骤,包括拷贝必要的源码文件和实现特定的读写函数。最后,通过创建和修改文件来测试文件系统的功能。
摘要由CSDN通过智能技术生成

MM32F3273G8P火龙果开发板MindSDK开发教程19 - littlefs文件系统的移植

1、littlefs简介

LittleFS 由ARM官方发布,ARM mbedOS的官方推荐文件系统,具有轻量级,掉电安全的特性。主要用在微控制器和flash上,特点如下:
掉电恢复,在写入时即使复位或者掉电也可以恢复到上一个正确的状态。
擦写均衡,有效延长flash的使用寿命。例如W25QXX系列的spi接口的flash,擦写次数大概在10万次,如果是操作flash比较频繁那么这10万次很快就会到达上限从而导致芯片废掉。
有限的RAM/ROM,相对于FATFS节省ROM和RAM空间
github传送门

2、littlefs移植

上一节我们移植了sfud库,可以对spi flash进行读写操作。但是没有文件系统,就没有文件的概念。
这节,我们在上一节的基础上,再移植littlefs文件系统。
下载解压源码包,将如下几个文件拷贝到我们的工程。
在这里插入图片描述

并且增加ifs_port.c文件,工程视图如下:
在这里插入图片描述
ifs_port.c内容如下,里面的读写函数其实调用的是sfud中的读写函数。

/* lfs_port.c */
#include "lfs.h"
#include "sfud.h"

       int lfs_flash_init(      struct lfs_config *c);
static int lfs_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
static int lfs_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
static int lfs_flash_erase(const struct lfs_config *c, lfs_block_t block);
static int lfs_flash_sync(const struct lfs_config *c);

int lfs_flash_init(struct lfs_config *c)
{
    sfud_init(); /* init sfud. */
    const sfud_flash *flash = sfud_get_device(0u);

    c->read = lfs_flash_read;
    c->prog = lfs_flash_prog;
    c->erase = lfs_flash_erase;
    c->sync = lfs_flash_sync;

    c->read_size = 16;
    c->prog_size = 16;
    //c->block_size = LFS_FLASH_SECTOR_SIZE;
    c->block_size = flash->chip.erase_gran;
    c->block_count = 256;
    c->block_cycles = 500;
    c->cache_size = 16;
    c->lookahead_size = 16;

    //c->read_buffer = (void *)lfs_flash_read_buf;
    //c->prog_buffer = (void *)lfs_flash_prog_buf;
    //c->lookahead_buffer = (void *)lfs_flash_lookahead_buf;


    return LFS_ERR_OK;
}

static int lfs_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
{
    uint32_t addr = block * c->block_size + off;
    const sfud_flash *flash = sfud_get_device(0u);

    sfud_read(flash, addr, size, (uint8_t *)buffer);
    return LFS_ERR_OK;
}

static int
lfs_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
{
    uint32_t addr = block * c->block_size + off;
    const sfud_flash *flash = sfud_get_device(0u);

    sfud_write(flash, addr, size, (uint8_t *)buffer);
    return LFS_ERR_OK;
}

static int lfs_flash_erase(const struct lfs_config *c, lfs_block_t block)
{
    const sfud_flash *flash = sfud_get_device(0u);

    sfud_erase(flash, block * c->block_size, c->block_size);
    return LFS_ERR_OK;
}

static int lfs_flash_sync(const struct lfs_config *c)
{
    return LFS_ERR_OK;
}

/* EOF. */

3、调用与测试

创建一个文件,写入一个值,每次开机+1,然后看是否每次开机后的值会+1。

#include <stdint.h>
#include <stdio.h>
#include "clock_init.h"
#include "hal_rcc.h"
#include "hal_gpio.h"
#include "hal_uart.h"
#include "led.h"
#include "uart.h"
#include "systick.h"
#include "key.h"
#include "timer.h"
#include "multi_button.h"
#include "spi.h"
#include "sfud.h"
#include "lfs.h"

lfs_t app_lfs;
lfs_file_t app_lfs_file;
struct lfs_config app_lfs_config;

int lfs_flash_init(struct lfs_config *c);

struct Button btn1;

void BTN1_PRESS_DOWN_Handler(void* btn)
{
	//do something...
	printf("BTN1_PRESS_DOWN_Handler \r\n");
}

void BTN1_PRESS_UP_Handler(void* btn)
{
	//do something...
	printf("BTN1_PRESS_UP_Handler \r\n");
}

int main(void)
{
	BOARD_InitBootClocks();  // ³õʼ»¯Ê±ÖÓ
	BOARD_InitDebugConsole();
	BOARD_UserKeyInit();
	LED_Init();
	BOARD_TIM6_Init();

	// for mutilbutton init
	button_init(&btn1, read_button_GPIO, 0, btn1_id);
	button_attach(&btn1, PRESS_DOWN,       BTN1_PRESS_DOWN_Handler);
	button_attach(&btn1, PRESS_UP,         BTN1_PRESS_UP_Handler);
	button_start(&btn1);

	BOARD_TIM7_Init();

	BOARD_Delay1Ms(1000);
	
	printf("Board Init Success\r\n");

    printf("spi_lfs_sfud_spi example.\r\n");

    int err = lfs_flash_init(&app_lfs_config);
    if (err)
    {
        printf("lfs_flash_init() failed.\r\n");
        while (1);
    }

    err = lfs_mount(&app_lfs, &app_lfs_config);
    if (err)
    {
        printf("lfs_mount() failed.\r\n");
        lfs_format(&app_lfs, &app_lfs_config);
        printf("lfs_format() done.\r\n");
        lfs_mount(&app_lfs, &app_lfs_config);
        printf("lfs_mount() done.\r\n");
    }

    // read current count
    uint32_t boot_count = 0;
    lfs_file_open(&app_lfs, &app_lfs_file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
    lfs_file_read(&app_lfs, &app_lfs_file, &boot_count, sizeof(boot_count));

    // update boot count
    boot_count += 1;
    lfs_file_rewind(&app_lfs, &app_lfs_file);
    lfs_file_write(&app_lfs, &app_lfs_file, &boot_count, sizeof(boot_count));

    // remember the storage is not updated until the file is closed successfully
    lfs_file_close(&app_lfs, &app_lfs_file);

    // release any resources we were using
    lfs_unmount(&app_lfs);

    // print the boot count
    printf("boot_count: %u\r\n", (unsigned)boot_count);

	while(1)
	{
	}	
}

4、现象

在这里插入图片描述

代码

代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值