想要使用片內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 />
