rtt使用littleFS片内flash 文件系统问题


想要使用片内flash挂载文件系统需要如下操作

1.添加fal和littlefs软件包

2.打开DFS组件

3.打开MTD Nor flash设备驱动程序

4.board.h中打开 #define BSP_USING_ON_CHIP_FLASH

5.添加drv_flash_l4.c

6.fal_cfg.h中添加/修改FAL_FLASH_DEV_TABLE,对应drv_flash_l4.c中的stm32_onchip_flash

7.修改FAL_PART_TABLE,配置空间区域和区域名,通常app是应用程序占空,剩下的可作为文件系统使用,实测32k以上是可行的

//-------------fal_cfg.h-----------------------------

extern const struct fal_flash_dev stm32_onchip_flash; extern struct fal_flash_dev nor_flash0; /* flash device table */ #define FAL_FLASH_DEV_TABLE \ { \ &stm32_onchip_flash, \ } /* ====================== Partition Configuration ========================== */ #ifdef FAL_PART_HAS_TABLE_CFG /* partition table */ #define FAL_PART_TABLE \ { \ {FAL_PART_MAGIC_WORD, "app", "onchip_flash", 0, 480*1024, 0}, \ {FAL_PART_MAGIC_WORD, "fs", "onchip_flash", 480*1024, 32*1024, 0}, \ } #endif /* FAL_PART_HAS_TABLE_CFG */

 

littlefs和fal软件包配置如下

 

 

 遇到的问题

格式化扇区是提示擦除失败,如下

[E/FAL] (fal_partition_erase:476) Partition erase error! Flash device(onchip_flash) erase error!

问题在drv_flash_l4.c中的stm32_flash_erase函数返回错误导致

最后发现是在进行flash erase操作是单片机发生PGSERR错误,原因暂不清楚,通过擦除的重试操作解决了此问题,代码如下

int stm32_flash_erase(rt_uint32_t addr, size_t size)
{
    rt_err_t result = RT_EOK;
    uint8_t err;
    uint32_t FirstPage = 0, NbOfPages = 0, BankNumber = 0;
    uint32_t PAGEError = 0;

    if ((addr + size) > STM32_FLASH_END_ADDRESS)
    {
        LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(addr + size));
        return -RT_EINVAL;
    }

    /*Variable used for Erase procedure*/
    FLASH_EraseInitTypeDef EraseInitStruct;
    /* Unlock the Flash to enable the flash control register access *************/
    HAL_FLASH_Unlock();

    /* Clear OPTVERR bit set on virgin samples */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
    /* Get the 1st page to erase */
    FirstPage = GetPage(addr);
    /* Get the number of pages to erase from 1st page */
    NbOfPages = GetPage(addr + size - 1) - FirstPage + 1;
    /* Get the bank */
    BankNumber = GetBank(addr);
    /* Fill EraseInit structure*/
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Banks       = BankNumber;
    EraseInitStruct.Page        = FirstPage;
    EraseInitStruct.NbPages     = NbOfPages;



    err = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError); if (err != HAL_OK)//retry { err = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError); }
    if (err != HAL_OK)
    {

        result = -RT_ERROR;
        goto __exit;
    }

__exit:
    HAL_FLASH_Lock();

    if (result != RT_EOK)
    {
//        LOG_D("erase :size:%d",size);
//        LOG_E("erase err: size=%d,%d(%d)", size,result,err);
        return result;
    }

    LOG_D("erase done: addr (0x%p), size %d", (void*)addr, size);
    return size;
}

  

文件系统初始化代码如下

#define FS_PARTITION_NAME              "fs"
void littlefs_sample(void)
{
    struct rt_device *mtd_dev = RT_NULL;

    // 初始化 fal
    fal_init();
    // 创建 mtd 设备
    mtd_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);
    if (!mtd_dev)
    {
        LOG_E("Can't create a mtd device on '%s' partition.", FS_PARTITION_NAME);
    }
    else
    {
        // 挂载littlefs
        // 参数: 块设备名、文件系统挂载点路径,挂载文件系统类型,读写标志位,文件系统的私有数据
        if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == 0)
        {
            LOG_I("para initialized!");
            //readwrite_sample();
        }
        else // dfs_mkfs("elm", "AT45");
        {
            LOG_E("dfs_mount Failed ");
            /* 格式化文件系统 */
            dfs_mkfs("lfs", FS_PARTITION_NAME);
            /* 挂载 littlefs */
            if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == 0)
            {
                LOG_I("para initialized!");
            }
            else
            {
                LOG_E("Failed to initialize filesystem!");
            }
        }


    }
}

  

测试成功

msh />ls
Directory /:
msh />df
disk free: 28.0 KB [ 14 block, 2048 bytes per block ]
msh />

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM