FAL移植

概述

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

  • 支持静态可配置的分区表,并可关联多个 Flash 设备;
  • 分区表支持 自动装载 。避免在多固件项目,分区表被多次定义的问题;
  • 代码精简,对操作系统 无依赖 ,可运行于裸机平台,比如对资源有一定要求的 Bootloader;
  • 统一的操作接口。保证了文件系统、OTA、NVM等对 Flash 有一定依赖的组件,底层 Flash 驱动的可重用性;
  • 自带基于 Finsh/MSH 的测试命令,可以通过 Shell 按字节寻址的方式操作(读写擦) Flash 或分区,方便开发者进行调试、测试;
    在这里插入图片描述

正文

第一步:下载源文件

链接

第二步:准备好一个工程
第三步:将源文件添加进工程,并包含好头文件路径

在这里插入图片描述

在这里插入图片描述

第四步:修改工程文件

修改fal_flash_sfud_port.c

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

#include <fal.h>
#include <sfud.h>
#include "include.h"


#define FAL_USING_SFUD_PORT

#ifdef FAL_USING_SFUD_PORT
#ifdef RT_USING_SFUD
#include <spi_flash_sfud.h>
#endif

#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define FAL_USING_NOR_FLASH_DEV_NAME             "norflash0"
#endif

static char log_buf[256];

static int init(void);
static int read(long offset, uint8_t *buf, size_t size);
static int write(long offset, const uint8_t *buf, size_t size);
static int erase(long offset, size_t size);

static sfud_flash_t sfud_dev = NULL;
struct fal_flash_dev nor_flash0 =
{
    .name       = FAL_USING_NOR_FLASH_DEV_NAME,
    .addr       = 0,
    .len        = 8 * 1024 * 1024,
    .blk_size   = 4096,
    .ops        = {init, read, write, erase},
    .write_gran = 1
};

static int init(void)
{

#ifdef RT_USING_SFUD
    /* RT-Thread RTOS platform */
    sfud_dev = rt_sfud_flash_find_by_dev_name(FAL_USING_NOR_FLASH_DEV_NAME);
#else
    /* bare metal platform */
//  extern sfud_flash sfud_norflash0;
//	sfud_dev = &sfud_norflash0;
	sfud_flash *flash = NULL;
	flash = sfud_get_device(0);
    sfud_dev = flash;
#endif

    if (NULL == sfud_dev)
    {
        return -1;
    }

    /* update the flash chip information */
    nor_flash0.blk_size = sfud_dev->chip.erase_gran;
    nor_flash0.len = sfud_dev->chip.capacity;

    return 0;
}

static int read(long offset, uint8_t *buf, size_t size)
{
    assert(sfud_dev);
    assert(sfud_dev->init_ok);
    sfud_read(sfud_dev, nor_flash0.addr + offset, size, buf);

    return size;
}

static int write(long offset, const uint8_t *buf, size_t size)
{
    assert(sfud_dev);
    assert(sfud_dev->init_ok);
    if (sfud_write(sfud_dev, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS)
    {
        return -1;
    }

    return size;
}

static int erase(long offset, size_t size)
{
    assert(sfud_dev);
    assert(sfud_dev->init_ok);
    if (sfud_erase(sfud_dev, nor_flash0.addr + offset, size) != SFUD_SUCCESS)
    {
        return -1;
    }

    return size;
}

/**
 * This function is print flash non-package info.
 *
 * @param format output format
 * @param ... args
 */
void fal_print(const char *format, ...) {
    va_list args;

    /* args point to the first variable parameter */
    va_start(args, format);
    /* must use vprintf to print */
    rt_vsprintf(log_buf, format, args);
    uart_write(DEV_UART1,(uint8_t *)log_buf, strlen(log_buf));
    va_end(args);
}


#endif /* FAL_USING_SFUD_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 FAL_PART_HAS_TABLE_CFG

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

/* flash device table */
#define FAL_FLASH_DEV_TABLE                                          \
{                                                                    \
    &nor_flash0,                                                     \
    &stm32f1_onchip_flash,											 \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE                                                               \
{                                                                                    \
    {FAL_PART_MAGIC_WORD, "easyflash", 	      "norflash0",   	 0, 		 1024*1024, 0}, \
    {FAL_PART_MAGIC_WORD, "download", 	      "norflash0", 	 	 1024*1024,  1024*1024, 0}, \
    {FAL_PART_MAGIC_WORD, "bl",	   			  "onchipflash",	 0,			 10*1024,  0}, \
    {FAL_PART_MAGIC_WORD, "app",   			  "onchipflash",	 10*1024,	 50*1024,  0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */

#endif /* _FAL_CFG_H_ */

修改fal_flash_stm32f1_port.c

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

#include "include.h"

#define PAGE_SIZE_ONCHIP	2*1024

static int init(void)
{
    /* do nothing now */

    return 0;
}

static int read(long offset, uint8_t *buf, size_t size)
{
    size_t i;
    uint32_t addr = stm32f1_onchip_flash.addr + offset;
    for (i = 0; i < size; i++, addr++, buf++)
    {
        *buf = *(uint8_t *) addr;
    }

    return size;
}

static int write(long offset, const uint8_t *buf, size_t size)
{
    size_t i;
    uint32_t addr = stm32f1_onchip_flash.addr + offset;
    uint32_t read_data;
    uint32_t *buf_32 = (uint32_t *)buf;
    
    FLASH_Unlock();
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
    for (i = 0; i < size; i += 4, buf_32++, addr += 4) {
        /* write data */
        FLASH_ProgramWord(addr, *buf_32);
        read_data = *(uint32_t *)addr;
        /* check data */
        if (read_data != *buf_32) {
            return -1;
        }
    }
    FLASH_Lock();

    return size;
}

static int erase(long offset, size_t size)
{
	size_t i;
    FLASH_Status flash_status;
    size_t erase_pages;
    uint32_t addr = stm32f1_onchip_flash.addr + offset;

    /* calculate pages */
    erase_pages = size / PAGE_SIZE_ONCHIP;
    if (size % PAGE_SIZE_ONCHIP != 0) {
        erase_pages++;
    }

    /* start erase */
    FLASH_Unlock();
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
    for (i = 0; i < erase_pages; i++) {
        flash_status = FLASH_ErasePage(addr + (PAGE_SIZE_ONCHIP * i));
        if (flash_status != FLASH_COMPLETE) {
            return -1;
        }
    }
    FLASH_Lock();

    return size;
}

const struct fal_flash_dev stm32f1_onchip_flash =
{
    .name       = "onchipflash",
    .addr       = 0x0800C200,
    .len        = 256*1024,
    .blk_size   = 2*1024,
    .ops        = {init, read, write, erase},
    .write_gran = 32
};

如果是使用rtthread-nano移植的话,还要修改fal_def.h

extern void fal_print(const char *format, ...);

#ifndef FAL_MALLOC
#define FAL_MALLOC                     malloc
#endif

#ifndef FAL_CALLOC
#define FAL_CALLOC                     calloc
#endif

#ifndef FAL_REALLOC
#define FAL_REALLOC                    realloc
#endif

#ifndef FAL_FREE
#define FAL_FREE                       free
#endif

#ifndef FAL_PRINTF
#define FAL_PRINTF                     fal_print	//printf
#endif

#ifndef FAL_DEBUG
#define FAL_DEBUG                      0
#endif
第五步:调试接

根据fal.h提供的接口使用即可,这里不作过多解释。效果展示如下:
在这里插入图片描述

总结

这样就完成了FAL的简单移植,实际项目中可以结合其他模块联合使用,效果还是很不错的。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值