SPIFFS: Update example, README.md
Separate method to initialize SPIFFS memory buffers. REDME.md for spiffs component. Simplify spiffs example.
This commit is contained in:
		
							parent
							
								
									66610c56cb
								
							
						
					
					
						commit
						924860a78f
					
				
					 6 changed files with 277 additions and 171 deletions
				
			
		
							
								
								
									
										153
									
								
								extras/spiffs/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								extras/spiffs/README.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,153 @@ | |||
| # SPIFFS ESP8266 File system | ||||
| 
 | ||||
| This component adds file system support for ESP8266. File system of choice | ||||
| for ESP8266 is [SPIFFS](https://github.com/pellepl/spiffs).  | ||||
| It was specifically designed to use with SPI NOR flash on embedded systems. | ||||
| The main advantage of SPIFFS is wear leveling, which prolongs life time  | ||||
| of a flash memory. | ||||
| 
 | ||||
| ## Features | ||||
| 
 | ||||
|  * SPIFFS - embedded file system for NOR flash memory. | ||||
|  * POSIX file operations. | ||||
|  * Static files upload to ESP8266 file system within build process. | ||||
|  * SPIFFS singleton configuration. Only one instance of FS on a device. | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| In order to use file system in a project the following steps should be made: | ||||
|  * Add SPIFFS component in a project Makefile `EXTRA_COMPONENTS = extras/spiffs` | ||||
|  * Specify your flash size in the Makefile `FLASH_SIZE = 32` | ||||
|  * Specify the start address of file system region on the flash memory | ||||
| `SPIFFS_BASE_ADDR = 0x200000` | ||||
|  * If you want to upload files to a file system during flash process specify | ||||
| the directory with files `$(eval $(call make_spiffs_image,files))` | ||||
| 
 | ||||
| In the end the Makefile should look like: | ||||
| 
 | ||||
| ``` | ||||
| PROGRAM=spiffs_example | ||||
| EXTRA_COMPONENTS = extras/spiffs | ||||
| FLASH_SIZE = 32 | ||||
| 
 | ||||
| SPIFFS_BASE_ADDR = 0x200000 | ||||
| SPIFFS_SIZE = 0x100000 | ||||
| 
 | ||||
| include ../../common.mk | ||||
| 
 | ||||
| $(eval $(call make_spiffs_image,files)) | ||||
| ``` | ||||
| 
 | ||||
| Note: Macro call to prepare SPIFFS image for flashing should go after | ||||
| `include common.mk` | ||||
| 
 | ||||
| ### Files upload | ||||
| 
 | ||||
| To upload files to a file system during flash process the following macro is | ||||
| used: | ||||
| 
 | ||||
| ``` | ||||
| $(eval $(call make_spiffs_image,files)) | ||||
| ``` | ||||
| 
 | ||||
| It enables the build of a helper utility **mkspiffs**. This utility creates | ||||
| an SPIFFS image with files in the specified directory. | ||||
| 
 | ||||
| The SPIFFS image is created during build stage, after `make` is run. | ||||
| The image is flashed into the device along with firmware during flash stage, | ||||
| after `make flash` is run. | ||||
| 
 | ||||
| **mkspiffs** utility uses the same SPIFFS source code and the same | ||||
| configuration as ESP8266. So the created image should always be compatible | ||||
| with SPIFFS on a device. | ||||
| 
 | ||||
| The build process will catch any changes in files directory and rebuild the | ||||
| image each time `make` is run. | ||||
| The build process will handle SPIFFS_SIZE change and rebuild **mkspiffs** | ||||
| utility and the image. | ||||
| 
 | ||||
| ## Example | ||||
| 
 | ||||
| ### Mount | ||||
| 
 | ||||
| ``` | ||||
| esp_spiffs_init();   // allocate memory buffers | ||||
| if (esp_spiffs_mount() != SPIFFS_OK) { | ||||
|     printf("Error mounting SPIFFS\n"); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ### Format | ||||
| 
 | ||||
| Formatting SPIFFS is a little bit awkward. Before formatting SPIFFS must be | ||||
| mounted and unmounted. | ||||
| ``` | ||||
| esp_spiffs_init(); | ||||
| if (esp_spiffs_mount() != SPIFFS_OK) { | ||||
|     printf("Error mount SPIFFS\n"); | ||||
| } | ||||
| SPIFFS_unmount(&fs);  // FS must be unmounted before formating | ||||
| if (SPIFFS_format(&fs) == SPIFFS_OK) { | ||||
|     printf("Format complete\n"); | ||||
| } else { | ||||
|     printf("Format failed\n"); | ||||
| } | ||||
| esp_spiffs_mount(); | ||||
| ``` | ||||
| 
 | ||||
| ### POSIX read | ||||
| 
 | ||||
| Nothing special here. | ||||
| 
 | ||||
| ``` | ||||
| const int buf_size = 0xFF; | ||||
| uint8_t buf[buf_size]; | ||||
| 
 | ||||
| int fd = open("test.txt", O_RDONLY); | ||||
| if (fd < 0) { | ||||
|     printf("Error opening file\n"); | ||||
| } | ||||
| 
 | ||||
| read(fd, buf, buf_size); | ||||
| printf("Data: %s\n", buf); | ||||
| 
 | ||||
| close(fd); | ||||
| ``` | ||||
| 
 | ||||
| ### SPIFFS read | ||||
| 
 | ||||
| SPIFFS interface is intended to be as close to POSIX as possible. | ||||
| 
 | ||||
| ``` | ||||
| const int buf_size = 0xFF; | ||||
| uint8_t buf[buf_size]; | ||||
| 
 | ||||
| spiffs_file fd = SPIFFS_open(&fs, "other.txt", SPIFFS_RDONLY, 0); | ||||
| if (fd < 0) { | ||||
|     printf("Error opening file\n"); | ||||
| } | ||||
| 
 | ||||
| SPIFFS_read(&fs, fd, buf, buf_size); | ||||
| printf("Data: %s\n", buf); | ||||
| 
 | ||||
| SPIFFS_close(&fs, fd); | ||||
| ``` | ||||
| 
 | ||||
| ### POSIX write | ||||
| 
 | ||||
| ``` | ||||
| uint8_t buf[] = "Example data, written by ESP8266"; | ||||
| 
 | ||||
| int fd = open("other.txt", O_WRONLY|O_CREAT, 0); | ||||
| if (fd < 0) { | ||||
|     printf("Error opening file\n"); | ||||
| } | ||||
| 
 | ||||
| write(fd, buf, sizeof(buf)); | ||||
| 
 | ||||
| close(fd); | ||||
| ``` | ||||
| 
 | ||||
| ## Resources | ||||
| 
 | ||||
| [SPIFFS](https://github.com/pellepl/spiffs) | ||||
|  | @ -14,9 +14,21 @@ | |||
| 
 | ||||
| spiffs fs; | ||||
| 
 | ||||
| static void *work_buf = 0; | ||||
| static void *fds_buf = 0; | ||||
| static void *cache_buf = 0; | ||||
| typedef struct { | ||||
|     void *buf; | ||||
|     uint32_t size; | ||||
| } fs_buf_t; | ||||
| 
 | ||||
| static fs_buf_t work_buf = {0}; | ||||
| static fs_buf_t fds_buf = {0}; | ||||
| static fs_buf_t cache_buf = {0}; | ||||
| 
 | ||||
| /**
 | ||||
|  * Number of file descriptors opened at the same time | ||||
|  */ | ||||
| #define ESP_SPIFFS_FD_NUMBER       5 | ||||
| 
 | ||||
| #define ESP_SPIFFS_CACHE_PAGES     5 | ||||
| 
 | ||||
| /*
 | ||||
|  * Flash addresses and size alignment is a rip-off of Arduino implementation. | ||||
|  | @ -147,6 +159,29 @@ static s32_t esp_spiffs_erase(u32_t addr, u32_t size) | |||
|     return SPIFFS_OK; | ||||
| } | ||||
| 
 | ||||
| void esp_spiffs_init() | ||||
| { | ||||
|     work_buf.size = 2 * SPIFFS_CFG_LOG_PAGE_SZ(); | ||||
|     fds_buf.size = SPIFFS_buffer_bytes_for_filedescs(&fs, ESP_SPIFFS_FD_NUMBER); | ||||
|     cache_buf.size= SPIFFS_buffer_bytes_for_cache(&fs, ESP_SPIFFS_CACHE_PAGES); | ||||
| 
 | ||||
|     work_buf.buf = malloc(work_buf.size); | ||||
|     fds_buf.buf = malloc(fds_buf.size); | ||||
|     cache_buf.buf = malloc(cache_buf.size); | ||||
| } | ||||
| 
 | ||||
| void esp_spiffs_deinit() | ||||
| { | ||||
|     free(work_buf.buf); | ||||
|     work_buf.buf = 0; | ||||
| 
 | ||||
|     free(fds_buf.buf); | ||||
|     fds_buf.buf = 0; | ||||
| 
 | ||||
|     free(cache_buf.buf); | ||||
|     cache_buf.buf = 0; | ||||
| } | ||||
| 
 | ||||
| int32_t esp_spiffs_mount() | ||||
| { | ||||
|     spiffs_config config = {0}; | ||||
|  | @ -155,18 +190,13 @@ int32_t esp_spiffs_mount() | |||
|     config.hal_write_f = esp_spiffs_write; | ||||
|     config.hal_erase_f = esp_spiffs_erase; | ||||
| 
 | ||||
|     size_t workBufSize = 2 * SPIFFS_CFG_LOG_PAGE_SZ(); | ||||
|     size_t fdsBufSize = SPIFFS_buffer_bytes_for_filedescs(&fs, 5); | ||||
|     size_t cacheBufSize = SPIFFS_buffer_bytes_for_cache(&fs, 5); | ||||
|     printf("SPIFFS size: %d\n", SPIFFS_SIZE); | ||||
|     printf("SPIFFS memory, work_buf_size=%d, fds_buf_size=%d, cache_buf_size=%d\n", | ||||
|             work_buf.size, fds_buf.size, cache_buf.size); | ||||
| 
 | ||||
|     work_buf = malloc(workBufSize); | ||||
|     fds_buf = malloc(fdsBufSize); | ||||
|     cache_buf = malloc(cacheBufSize); | ||||
|     printf("spiffs memory, work_buf_size=%d, fds_buf_size=%d, cache_buf_size=%d\n", | ||||
|             workBufSize, fdsBufSize, cacheBufSize); | ||||
| 
 | ||||
|     int32_t err = SPIFFS_mount(&fs, &config, work_buf, fds_buf, fdsBufSize, | ||||
|             cache_buf, cacheBufSize, 0); | ||||
|     int32_t err = SPIFFS_mount(&fs, &config, (uint8_t*)work_buf.buf,  | ||||
|             (uint8_t*)fds_buf.buf, fds_buf.size,  | ||||
|             cache_buf.buf, cache_buf.size, 0); | ||||
| 
 | ||||
|     if (err != SPIFFS_OK) { | ||||
|         printf("Error spiffs mount: %d\n", err); | ||||
|  | @ -175,19 +205,6 @@ int32_t esp_spiffs_mount() | |||
|     return err; | ||||
| } | ||||
| 
 | ||||
| void esp_spiffs_unmount() | ||||
| { | ||||
|     SPIFFS_unmount(&fs); | ||||
| 
 | ||||
|     free(work_buf); | ||||
|     free(fds_buf); | ||||
|     free(cache_buf); | ||||
| 
 | ||||
|     work_buf = 0; | ||||
|     fds_buf = 0; | ||||
|     cache_buf = 0; | ||||
| } | ||||
| 
 | ||||
| #define FD_OFFSET 3 | ||||
| 
 | ||||
| // This implementation replaces implementation in core/newlib_syscals.c
 | ||||
|  |  | |||
|  | @ -13,16 +13,27 @@ | |||
| extern spiffs fs; | ||||
| 
 | ||||
| /**
 | ||||
|  * Provide SPIFFS with all necessary configuration, allocate memory buffers | ||||
|  * and mount SPIFFS. | ||||
|  * Prepare for SPIFFS mount. | ||||
|  *  | ||||
|  * The function allocates all the necessary buffers. | ||||
|  */ | ||||
| void esp_spiffs_init(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Free all memory buffers that were used by SPIFFS. | ||||
|  * | ||||
|  * The function should be called after SPIFFS unmount if the file system is not | ||||
|  * going to need any more. | ||||
|  */ | ||||
| void esp_spiffs_deinit(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Mount SPIFFS. | ||||
|  * | ||||
|  * esp_spiffs_init must be called first. | ||||
|  * | ||||
|  * Return SPIFFS return code. | ||||
|  */ | ||||
| int32_t esp_spiffs_mount(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Unmount SPIFFS and free all allocated buffers. | ||||
|  */ | ||||
| void esp_spiffs_unmount(); | ||||
| 
 | ||||
| #endif  // __ESP_SPIFFS_H__
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue