STM32F1与STM32CubeIDE编程实例-W25Q-SPI-Flash与SPIFFS移植 W25Q-SPI-Flash与SPIFFS移植 SPIFFS 是用于嵌入式目标上的 SPI NOR 闪存设备的文件系统。 它支持磨损均衡、文件系统一致性检查等。本文将详细介绍如何将SPIFFS移植到STM32F1中。通过前面的文章,我们成功驱动了W25Q SPI Flash,请参考:
在这个基础上,移植SPIFFS就变得很简单了。
1、SPIFFS移植 关于STM32CubeIDE工程创建、配置请参考前面文章:
第一步,下载SPIFFS源码:https://github.com/pellepl/spiffs
第二步,将SPIFFS源码的src目录复制到STM32CubeIDE工程中。
第三步,添加SPIFFS移植文件,实现SPIFFS适合接口移植。
在src文件中,添加spiffs_port.h和spiffs_port.c文件。其内容分别如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /\* \* spiffs\_port.h \* \* Created on: Jun 14, 2022 \* Author: jenson \*/ #ifndef SPIFFS\_SRC\_SPIFFS\_PORT\_H\_ #define SPIFFS\_SRC\_SPIFFS\_PORT\_H\_ #include "spiffs.h" extern spiffs spiffs_fs; int spiffs\_port\_init(void); #endif /\* SPIFFS\_SRC\_SPIFFS\_PORT\_H\_ \*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 /\* \* spiffs\_port.c \* \* Created on: Jun 14, 2022 \* Author: jenson \*/ #include "spiffs.h" #include "w25qxx/w25qxx\_drv.h" #include "main.h" #include "spi.h" #include <stm32f1xx\_hal.h> #include <stdio.h> w25qxx\_t __spiffs_w25qxx; static int32\_t \_spiffs\_erase(uint32\_t addr, uint32\_t len) { w25qxx\_erase\_sector(&__spiffs_w25qxx, addr); return 0; } static int32\_t \_spiffs\_read(uint32\_t addr, uint32\_t size, uint8\_t \*dst) { w25qxx\_read(&__spiffs_w25qxx, dst, addr, size); return 0; } static int32\_t \_spiffs\_write(uint32\_t addr, uint32\_t size, uint8\_t \*dst) { w25qxx\_write(&__spiffs_w25qxx, dst, addr, size); return 0; } uint8\_t FS_Work_Buf[256 \* 2]; uint8\_t FS_FDS[32 \* 4]; uint8\_t FS_Cache_Buf[(256 + 32) \* 4]; spiffs_config spiffs_cfg; spiffs spiffs_fs; int spiffs\_port\_init(void) { // SPIFFS接口注册 spiffs_cfg.hal_erase_f = _spiffs_erase; spiffs_cfg.hal_read_f = _spiffs_read; spiffs_cfg.hal_write_f = _spiffs_write; // W25Q SPI Flash驱动实现 __spiffs_w25qxx.SPI_CS_Pin = FLASH_CS_Pin; __spiffs_w25qxx.SPI_CS_Port = FLASH_CS_GPIO_Port; __spiffs_w25qxx.SPI_Handle = &hspi1; if (!w25qxx\_init(&__spiffs_w25qxx)) { return SPIFFS_ERR_NOT_CONFIGURED; } // 打印W25Q信息 w25qxx\_display\_info(&__spiffs_w25qxx); int res = -1; // 挂载SPIFFS,如果没有找到文件系统,则格式化W25Q和格式化SPIFFS文件系统 if ((res = SPIFFS\_mount(&spiffs_fs, &spiffs_cfg, FS_Work_Buf, FS_FDS, sizeof(FS_FDS), FS_Cache_Buf, sizeof(FS_Cache_Buf), NULL)) != SPIFFS_OK && SPIFFS\_errno(&spiffs_fs) == SPIFFS_ERR_NOT_A_FS) { printf("not found SPIFFS ...\n"); printf("erase chip...\r\n"); w25qxx\_erase\_chip(&__spiffs_w25qxx); // 擦除芯片 printf("erase chip done\r\n"); printf("SPIFFS start format ...\r\n"); if (SPIFFS\_format(&spiffs_fs) != SPIFFS_OK) { // 格式化文件系统 printf("SPIFFS format failed: %d\n", SPIFFS\_errno(&spiffs_fs)); return SPIFFS\_errno(&spiffs_fs); } printf("SPIFFS format ok\n"); printf("SPIFFS mounting...\n"); // 重新挂载SPIFFS文件系统 res = SPIFFS\_mount(&spiffs_fs, &spiffs_cfg, FS_Work_Buf, FS_FDS, sizeof(FS_FDS), FS_Cache_Buf, sizeof(FS_Cache_Buf), NULL); if (res != SPIFFS_OK) { printf("SPIFFS mount failed: %d\n", SPIFFS\_errno(&spiffs_fs)); return SPIFFS\_errno(&spiffs_fs); } } printf("SPIFFS mounted\n"); return SPIFFS_OK; }
实现SPIFFS移植主要步骤如下:
1 2 3 4 5 // SPIFFS接口注册 spiffs_cfg.hal_erase_f = _spiffs_erase; spiffs_cfg.hal_read_f = _spiffs_read; spiffs_cfg.hal_write_f = _spiffs_write;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // 挂载SPIFFS,如果没有找到文件系统,则格式化W25Q和格式化SPIFFS文件系统 if ((res = SPIFFS\_mount(&spiffs_fs, &spiffs_cfg, FS_Work_Buf, FS_FDS, sizeof(FS_FDS), FS_Cache_Buf, sizeof(FS_Cache_Buf), NULL)) != SPIFFS_OK && SPIFFS\_errno(&spiffs_fs) == SPIFFS_ERR_NOT_A_FS) { printf("not found SPIFFS ...\n"); printf("erase chip...\r\n"); w25qxx\_erase\_chip(&__spiffs_w25qxx); // 擦除芯片 printf("erase chip done\r\n"); printf("SPIFFS start format ...\r\n"); if (SPIFFS\_format(&spiffs_fs) != SPIFFS_OK) { // 格式化文件系统 printf("SPIFFS format failed: %d\n", SPIFFS\_errno(&spiffs_fs)); return SPIFFS\_errno(&spiffs_fs); } printf("SPIFFS format ok\n"); printf("SPIFFS mounting...\n"); // 重新挂载SPIFFS文件系统 res = SPIFFS\_mount(&spiffs_fs, &spiffs_cfg, FS_Work_Buf, FS_FDS, sizeof(FS_FDS), FS_Cache_Buf, sizeof(FS_Cache_Buf), NULL); if (res != SPIFFS_OK) { printf("SPIFFS mount failed: %d\n", SPIFFS\_errno(&spiffs_fs)); return SPIFFS\_errno(&spiffs_fs); } }
2、SPIFFS调用 在STM32CubeIDE工程和Application目录中,分为添加如下文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /\* \* spiffs\_demo.h \* \* Created on: Jul 12, 2022 \* Author: jenson \*/ #ifndef SPIFFS\_DEMO\_H\_ #define SPIFFS\_DEMO\_H\_ #include "SPIFFS/src/spiffs.h" #include "SPIFFS/src/spiffs\_port.h" void spiffs\_demo(void); #endif /\* SPIFFS\_DEMO\_H\_ \*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 /\* \* spiffs\_demo.c \* \* Created on: Jul 12, 2022 \* Author: jenson \*/ #include "spiffs\_demo.h" #include <stdio.h> //#ifdef DEMO\_SPIFFS #define SPIFFS\_FILE\_SIZE 512 uint8\_t spiffs_tx_buffer[SPIFFS_FILE_SIZE]; uint8\_t spiffs_rx_buffer[SPIFFS_FILE_SIZE]; #define FILE\_NAME "hello.txt" extern spiffs spiffs_fs; void spiffs\_read\_test(void) { uint32\_t total = 0; uint32\_t used_space = 0; spiffs_file fd = SPIFFS\_open(&spiffs_fs, FILE_NAME, SPIFFS_RDWR, 0); if (SPIFFS\_read(&spiffs_fs, fd, spiffs_rx_buffer, SPIFFS_FILE_SIZE) < 0) { printf("spiffs read\_test errno %d\n", SPIFFS\_errno(&spiffs_fs)); } else { printf("spiffs read\_test:\r\n%s\r\n", spiffs_rx_buffer); } SPIFFS\_close(&spiffs_fs, fd); SPIFFS\_info(&spiffs_fs, &total, &used_space); printf("spiffs info:\r\ntotal size = %d,used space = %d\r\n", total, used_space); } void spiffs\_write\_test(void) { memset(spiffs_tx_buffer, 'A', SPIFFS_FILE_SIZE); spiffs_file fd = SPIFFS\_open(&spiffs_fs, FILE_NAME, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); printf("spiffs write\_test errno %d\n", SPIFFS\_errno(&spiffs_fs)); if (SPIFFS\_write(&spiffs_fs, fd, spiffs_tx_buffer, SPIFFS_FILE_SIZE) < 0) { printf("spiffs write\_test %d\n", SPIFFS\_errno(&spiffs_fs)); } SPIFFS\_close(&spiffs_fs, fd); } void spiffs\_demo(void) { int res = spiffs\_port\_init(); if (res != SPIFFS_OK) { printf("spiffs init faled:(%d)\r\n", res); while (1) ; } spiffs\_write\_test(); spiffs\_read\_test(); } //#endif
在main.c文件中添加如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 /\* Private includes ----------------------------------------------------------\*/ /\* USER CODE BEGIN Includes \*/ #include<stdio.h> #include "w25qxx/w25qxx.h" #include "spiffs\_demo.h" /\* USER CODE END Includes \*/ int main(void) { /\* USER CODE BEGIN 1 \*/ /\* USER CODE END 1 \*/ /\* MCU Configuration--------------------------------------------------------\*/ /\* Reset of all peripherals, Initializes the Flash interface and the Systick. \*/ HAL\_Init(); /\* USER CODE BEGIN Init \*/ /\* USER CODE END Init \*/ /\* Configure the system clock \*/ SystemClock\_Config(); /\* USER CODE BEGIN SysInit \*/ /\* USER CODE END SysInit \*/ /\* Initialize all configured peripherals \*/ MX\_GPIO\_Init(); MX\_USART1\_UART\_Init(); MX\_SPI1\_Init(); /\* USER CODE BEGIN 2 \*/ spiffs\_demo(); /\* USER CODE END 2 \*/ /\* Infinite loop \*/ /\* USER CODE BEGIN WHILE \*/ while (1) { /\* USER CODE END WHILE \*/ /\* USER CODE BEGIN 3 \*/ } /\* USER CODE END 3 \*/ }
运行结果如下:
文章来源: https://iotsmart.blog.csdn.net/article/details/125822926
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!