stm32f103rc片内Flash使用FAL库配置说明

1.参考文件

https://github.com/RT-Thread-packages/fal
https://github.com/RT-Thread-packages/fal/blob/master/samples/porting/README.md
https://blog.csdn.net/m0_37621078/article/details/102689903

2.ENV配置

(1)配置使用片内Flash,修改./board/Kconfig文件增加使用内部Flash选项。
①增加的内容如下:

menu "On-chip Peripheral Drivers"   
...     
    config BSP_USING_ON_CHIP_FLASH
        bool "Enable on-chip FLASH"
        default y

② ENV配置如下图
选择该选项后,MDK工程中会增加 stm32f1xx_hal_flash_ex.c和stm32f1xx_hal_flash.c另个与片内Flash相关的文件。
stm32f103rc片内Flash使用FAL库配置说明_第1张图片

(2)ENV配置使用fal包,配置内容如下:
选择使用fal_cfg.h配置Flash的分区表,配置路径为:

RT-Thread online packages
    system packages --->
        --- fal: Flash Abstraction Layer implement. Manage flash device and partition.

stm32f103rc片内Flash使用FAL库配置说明_第2张图片

3.重写底层Flash驱动函数

(1)创建设备底层驱动需要的c文件,根据实际芯片改写内存配置,包括设备名,起始地址,内存总大小,山区大小,注册函数名,如下图所示。
stm32f103rc片内Flash使用FAL库配置说明_第3张图片

4.配置Flash分区表

(1)目前只使用片内Flash,故FAL_FLASH_DEV_TABLE结构只配置一个Flash
(2)配置分区表结构FAL_PART_TABLE,包括:分区名, flash设备名, 起始地址, 空间大小等内容,如下图所示:

注意: 分区表的flash设备名要和fal_flash_dev中定义的名称一致!!!起始地址为相对于fal_flash_dev中扇区
首地址的偏移地址(STM32F4xx系列需要格外注意)!!!
stm32f103rc片内Flash使用FAL库配置说明_第4张图片

5.配置完成,测试读写

使用之前,必须首先调用fal_init()函数进行初始化。

附录1:测试读写

// 测试代码来源于参考文件中的网址
#include "rtthread.h"
#include "rtdevice.h"
#include "board.h"
#include "fal.h"

#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!\n");
        return -1;
    }

    partition = fal_partition_find(partiton_name);
    if (partition == RT_NULL)
    {
        rt_kprintf("Find partition (%s) failed!\n", 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!\n", partition->flash_name);
        ret = -1;
        return ret;
    }

    rt_kprintf("Flash device : %s   "
               "Flash size : %dK   \n"
               "Partition : %s   "
               "Partition size: %dK\n", 
                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!\n", partition->name);
        ret = -1;
        return ret;
    }
    rt_kprintf("Erase (%s) partition finish!\n", 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!\n", 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!\n");
                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!\n", partition->name);
            ret = -1;
            return ret;
        }

        i += len;
    }
    rt_kprintf("Write (%s) partition finish! Write size %d(%dK).\n", 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!\n", 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!\n");
                ret = -1;
                return ret;
            }
        }

        i += len;
    }

    ret = 0;
    return ret;
}

void fal_sample(void)
{
    fal_init(); //抽象层初始化

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

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

MSH_CMD_EXPORT(fal_sample, fal sample);

你可能感兴趣的:(RT-Thread)