diff --git a/docs/INTEGRATION b/docs/INTEGRATION deleted file mode 100644 index 1eb49fd..0000000 --- a/docs/INTEGRATION +++ /dev/null @@ -1,306 +0,0 @@ -* QUICK AND DIRTY INTEGRATION EXAMPLE - -So, assume you're running a Cortex-M3 board with a 2 MB SPI flash on it. The -SPI flash has 64kB blocks. Your project is built using gnumake, and now you -want to try things out. - -First, you simply copy the files in src/ to your own source folder. Exclude -all files in test folder. Then you point out these files in your make script -for compilation. - -Also copy the spiffs_config.h over from the src/default/ folder. - -Try building. This fails, nagging about inclusions and u32_t and whatnot. Open -the spiffs_config.h and delete the bad inclusions. Also, add following -typedefs: - - typedef signed int s32_t; - typedef unsigned int u32_t; - typedef signed short s16_t; - typedef unsigned short u16_t; - typedef signed char s8_t; - typedef unsigned char u8_t; - -Now it should build. Over to the mounting business. Assume you already -implemented the read, write and erase functions to your SPI flash: - - void my_spi_read(int addr, int size, char *buf) - void my_spi_write(int addr, int size, char *buf) - void my_spi_erase(int addr, int size) - -In your main.c or similar, include the spiffs.h and do that spiffs struct: - - #include - - static spiffs fs; - -Also, toss up some of the needed buffers: - - #define LOG_PAGE_SIZE 256 - - static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2]; - static u8_t spiffs_fds[32*4]; - static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE+32)*4]; - -Now, write the my_spiffs_mount function: - - void my_spiffs_mount() { - spiffs_config cfg; - cfg.phys_size = 2*1024*1024; // use all spi flash - cfg.phys_addr = 0; // start spiffs at start of spi flash - cfg.phys_erase_block = 65536; // according to datasheet - cfg.log_block_size = 65536; // let us not complicate things - cfg.log_page_size = LOG_PAGE_SIZE; // as we said - - cfg.hal_read_f = my_spi_read; - cfg.hal_write_f = my_spi_write; - cfg.hal_erase_f = my_spi_erase; - - int res = SPIFFS_mount(&fs, - &cfg, - spiffs_work_buf, - spiffs_fds, - sizeof(spiffs_fds), - spiffs_cache_buf, - sizeof(spiffs_cache_buf), - 0); - printf("mount res: %i\n", res); - } - -Now, build warns about the my_spi_read, write and erase functions. Wrong -signatures, so go wrap them: - - static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst) { - my_spi_read(addr, size, dst); - return SPIFFS_OK; - } - - static s32_t my_spiffs_write(u32_t addr, u32_t size, u8_t *src) { - my_spi_write(addr, size, src); - return SPIFFS_OK; - } - - static s32_t my_spiffs_erase(u32_t addr, u32_t size) { - my_spi_erase(addr, size); - return SPIFFS_OK; - } - -Redirect the config in my_spiffs_mount to the wrappers instead: - - cfg.hal_read_f = my_spiffs_read; - cfg.hal_write_f = my_spiffs_write; - cfg.hal_erase_f = my_spiffs_erase; - -Ok, now you should be able to build and run. However, you get this output: - - mount res: -1 - -but you wanted - - mount res: 0 - -This is probably due to you having experimented with your SPI flash, so it -contains rubbish from spiffs's point of view. Do a mass erase and run again. - -If all is ok now, you're good to go. Try creating a file and read it back: - - static void test_spiffs() { - char buf[12]; - - // Surely, I've mounted spiffs before entering here - - spiffs_file fd = SPIFFS_open(&fs, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); - if (SPIFFS_write(&fs, fd, (u8_t *)"Hello world", 12) < 0) printf("errno %i\n", SPIFFS_errno(&fs)); - SPIFFS_close(&fs, fd); - - fd = SPIFFS_open(&fs, "my_file", SPIFFS_RDWR, 0); - if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) printf("errno %i\n", SPIFFS_errno(&fs)); - SPIFFS_close(&fs, fd); - - printf("--> %s <--\n", buf); - } - -Compile, run, cross fingers hard, and you'll get the output: - - --> Hello world <-- - -Got errors? Check spiffs.h for error definitions to get a clue what went voodoo. - - -* THINGS TO CHECK - -When you alter the spiffs_config values, make sure you also check the typedefs -in spiffs_config.h: - - - spiffs_block_ix - - spiffs_page_ix - - spiffs_obj_id - - spiffs_span_ix - -The sizes of these typedefs must not underflow, else spiffs might end up in -eternal loops. Each typedef is commented what check for. - -Also, if you alter the code or just want to verify your configuration, you can -run - - > make test - -in the spiffs folder. This will run all testcases using the configuration in -default/spiffs_config.h and test/params_test.h. The tests are written for linux -but should run under cygwin also. - - -* INTEGRATING SPIFFS - -In order to integrate spiffs to your embedded target, you will basically need: - - A SPI flash device which your processor can communicate with - - An implementation for reading, writing and erasing the flash - - Memory (flash or ram) for the code - - Memory (ram) for the stack - -Other stuff may be needed, threaded systems might need mutexes and so on. - -** Logical structure - -First and foremost, one must decide how to divide up the SPI flash for spiffs. -Having the datasheet for the actual SPI flash in hand will help. Spiffs can be -defined to use all or only parts of the SPI flash. - -If following seems arcane, read the "HOW TO CONFIG" chapter first. - - - Decide the logical size of blocks. This must be a multiple of the biggest - physical SPI flash block size. To go safe, use the physical block size - - which in many cases is 65536 bytes. - - Decide the logical size of pages. This must be a 2nd logarithm part of the - logical block size. To go safe, use 256 bytes to start with. - - Decide how much of the SPI flash memory to be used for spiffs. This must be - on logical block boundary. If unsafe, use 1 megabyte to start with. - - Decide where on the SPI flash memory the spiffs area should start. This must - be on physical block/sector boundary. If unsafe, use address 0. - -** SPI flash API - -The target must provide three functions to spiffs: - - - s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst) - - s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src) - - s32_t (*spiffs_erase)(u32_t addr, u32_t size) - -These functions define the only communication between the SPI flash and the -spiffs stack. - -On success these must return 0 (or SPIFFS_OK). Anything else will be considered -an error. - -The size for read and write requests will never exceed the logical page size, -but it may be less. - -The address and size on erase requests will always be on physical block size -boundaries. - -** Mount specification - -In spiffs.h, there is a SPIFFS_mount function defined, used to mount spiffs on -the SPI flash. - -s32_t SPIFFS_mount( - spiffs *fs, - spiffs_config *config, - u8_t *work, - u8_t *fd_space, - u32_t fd_space_size, - void *cache, - u32_t cache_size, - spiffs_check_callback check_cb_f) - - - fs Points to a spiffs struct. This may be totally uninitialized. - - config Points to a spiffs_config struct. This struct must be - initialized when mounting. See below. - - work A ram memory buffer being double the size of the logical page - size. This buffer is used excessively by the spiffs stack. If - logical page size is 256, this buffer must be 512 bytes. - - fd_space A ram memory buffer used for file descriptors. - - fd_space_size The size of the file descriptor buffer. A file descriptor - normally is around 32 bytes depending on the build config - - the bigger the buffer, the more file descriptors are - available. - - cache A ram memory buffer used for cache. Ignored if cache is - disabled in build config. - - cache_size The size of the cache buffer. Ignored if cache is disabled in - build config. One cache page will be slightly larger than the - logical page size. The more ram, the more cache pages, the - quicker the system. - - check_cb_f Callback function for monitoring spiffs consistency checks and - mending operations. May be null. - -The config struct must be initialized prior to mounting. One must always -define the SPI flash access functions: - - spiffs_config.hal_read_f - pointing to the function reading the SPI flash - - spiffs_config.hal_write_f - pointing to the function writing the SPI flash - - spiffs_config.hal_erase_f - pointing to the function erasing the SPI flash - -Depending on the build config - if SPIFFS_SINGLETON is set to zero - following -parameters must be defined: - - spiffs_config.phys_size - the physical number of bytes accounted for - spiffs on the SPI flash - - spiffs_config.phys_addr - the physical starting address on the SPI flash - - spiffs_config.phys_erase_block - the physical size of the largest block/sector - on the SPI flash found within the spiffs - usage address space - - spiffs_config.log_block_size - the logical size of a spiffs block - - spiffs_config.log_page_size - the logical size of a spiffs page - -If SPIFFS_SINGLETON is set to one, above parameters must be set ny defines in -the config header file, spiffs_config.h. - - -** Build config - -makefile: The files needed to be compiled to your target resides in files.mk to -be included in your makefile, either by cut and paste or by inclusion. - -Types: spiffs uses the types u8_t, s8_t, u16_t, s16_t, u32_t, s32_t; these must -be typedeffed. - -spiffs_config.h: you also need to define a spiffs_config.h header. Example of -this is found in the default/ directory. - - -** RAM - -Spiffs needs ram. It needs a working buffer being double the size of the -logical page size. It also needs at least one file descriptor. If cache is -enabled (highly recommended), it will also need a bunch of cache pages. - -Say you have a logical page size of 256 bytes. You want to be able to have four -files open simultaneously, and you can give spiffs four cache pages. This -roughly sums up to: - -256*2 (work buffer) + -32*4 (file descriptors) + -(256+32)*4 (cache pages) + 40 (cache metadata) - -i.e. 1832 bytes. - -This is apart from call stack usage. - -To get the exact amount of bytes needed on your specific target, enable -SPIFFS_BUFFER_HELP in spiffs_config.h, rebuild and call: - - SPIFFS_buffer_bytes_for_filedescs - SPIFFS_buffer_bytes_for_cache - -Having these figures you can disable SPIFFS_BUFFER_HELP again to save flash. - - -* HOW TO CONFIG - -TODO