将LittleFS Porting到STM32 G431RB板子上
想在STM32 G431RB板子上实现一个小的Log系统。G431RB的板子只有128KB的Flash. 加上代码段,留给Log系统的空间就不多了。
如果使用FATFS系统,系统开销有些大,很难搞一个20KB的文件系统。选择了开销比较小的LittleFS 文件系统。
G431RB板子的Page size = 2KB,也就意味着文件系统中的Block Size需要设置为2KB, Flash的写(Prog)最小是64bit。
我从100KB的地方开始创建LittleFS文件系统,Block Count = 14 (28KB)。
代码实现参考Github (https://github.com/magicduan/STM_LittleFS_Log)
实现起来还是比较简单的,配置好LittleFS configuration struct,实现好四个Interface Function(read, prog, erase, sync)就可以了。
// configuration of the filesystem is provided by this struct const struct lfs_config cfg = { // block device operations .read = stm32_interl_flash_block_read, .prog = stm32_interl_flash_block_prog, .erase = stm32_interl_flash_block_erase, .sync = stm32_interl_flash_block_sync, // block device configuration .read_size = STM32_G431RB_READ_SIZE, //16 .prog_size = STM32_G431RB_PROG_SIZE, //64 .block_size = STM32_G431RB_BLOCK_SIZE, //2K = 2048 .block_count = STM32_G431RB_BLOCK_COUNT, //14 .cache_size = 128, .lookahead_size = 8, .block_cycles = 500, };
四个Interface Function:
int stm32_interl_flash_block_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { uint32_t src_addr = FS_BASE_ADDR + c->block_size*block +off; uint32_t read_size = 0; uint16_t* pDest = (uint16_t*)buffer; uint16_t* pSrc = (uint16_t*)src_addr; while(read_size < size){ *pDest = *(pSrc); pDest++; pSrc++; read_size += 2; } return 0; } int stm32_interl_flash_block_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { HAL_FLASH_Unlock(); uint32_t dest_addr = FS_BASE_ADDR + c->block_size*block +off; uint64_t *pSrc = (uint64_t*)buffer; uint32_t write_size = 0; while(write_size < size){ if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,dest_addr,*(pSrc)) != HAL_OK){ HAL_FLASH_Lock(); return HAL_FLASH_GetError(); } pSrc++; dest_addr += 8; write_size += 8; } HAL_FLASH_Lock(); return 0; } int stm32_interl_flash_block_erase(const struct lfs_config *c, lfs_block_t block) { static FLASH_EraseInitTypeDef EraseInitStruct; uint32_t PageError; HAL_FLASH_Unlock(); EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.Banks = FLASH_BANK_1; EraseInitStruct.Page = FS_BASE_PAGE_START + block; EraseInitStruct.NbPages = 1; if (HAL_FLASHEx_Erase(&EraseInitStruct,&PageError)!= HAL_OK){ return HAL_FLASH_GetError(); } HAL_FLASH_Lock(); return 0; } int stm32_interl_flash_block_sync(const struct lfs_config *c) { return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)