kopia lustrzana https://github.com/espressif/esp-idf
example: Add SPIFFS image generation from build system example
rodzic
4d9c3a262d
commit
09d7383180
|
@ -0,0 +1,6 @@
|
|||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(spiffsgen)
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := spiffsgen
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
# Create a SPIFFS image from the contents of the 'spiffs_image' directory
|
||||
# that fits the partition named 'storage'. FLASH_IN_PROJECT indicates that
|
||||
# the generated image should be flashed when the entire project is flashed to
|
||||
# the target with 'make flash'.
|
||||
$(eval $(call spiffs_create_partition_image,storage,spiffs_image,FLASH_IN_PROJECT))
|
|
@ -0,0 +1,59 @@
|
|||
# SPIFFS Image Generation on Build Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use the SPIFFS image generation tool [spiffsgen.py](../../../components/spiffs/spiffsgen.py) to automatically create a SPIFFS
|
||||
filesystem image from the contents of a host folder during build, with an option of
|
||||
automatically flashing the created image on invocation of `idf.py flash` or `make flash`.
|
||||
For more information, see description of `spiffsgen.py` on the ESP-IDF Programming Guide under API Reference > Storage > SPIFFS Filesystem.
|
||||
|
||||
The following gives an overview of the example:
|
||||
|
||||
1. There is a directory `spiffs_image` from which the SPIFFS filesystem image will be created.
|
||||
|
||||
2. The function `spiffs_create_partition_image` is used to specify that a SPIFFS image
|
||||
should be created during build for the `storage` partition. For CMake, it is called from [the main component's CMakeLists.txt](./main/CMakeLists.txt);
|
||||
for Make, from the [project Makefile](./Makefile). `FLASH_IN_PROJECT` specifies that the created image
|
||||
should be flashed on invocation of `idf.py flash` or `make flash` together with app, bootloader, partition table, etc.
|
||||
For both build systems, the image is created on the example's build directory with the output filename `storage.bin`.
|
||||
|
||||
3. Upon invocation of `idf.py flash monitor` or `make flash monitor`, application loads and
|
||||
finds there is already a valid SPIFFS filesystem in the `storage` partition with files same as those in `spiffs_image` directory. The application is then
|
||||
able to read those files.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Build and flash
|
||||
|
||||
To run the example, type the following command:
|
||||
|
||||
```Makefile
|
||||
# Make
|
||||
make flash monitor
|
||||
```
|
||||
or
|
||||
```CMake
|
||||
# CMake
|
||||
idf.py flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is the example's console output:
|
||||
|
||||
```
|
||||
...
|
||||
I (10) example: Initializing SPIFFS
|
||||
I (110) example: Partition size: total: 896321, used: 171935
|
||||
I (110) example: Reading hello.txt
|
||||
I (110) example: Read from hello.txt: Hello World!
|
||||
I (110) example: Computing alice.txt MD5 hash
|
||||
I (330) example: Computed MD5 hash of alice.txt: deeb71f585cbb3ae5f7976d5127faf2a
|
||||
I (330) example: SPIFFS unmounted
|
||||
```
|
||||
|
||||
The logic of the example is contained in a [single source file](./main/spiffsgen_example_main.c), and it should be relatively simple to match points in its execution with the log outputs above.
|
|
@ -0,0 +1,34 @@
|
|||
from __future__ import print_function
|
||||
import os
|
||||
import sys
|
||||
import hashlib
|
||||
|
||||
try:
|
||||
import IDF
|
||||
except ImportError:
|
||||
test_fw_path = os.getenv('TEST_FW_PATH')
|
||||
if test_fw_path and test_fw_path not in sys.path:
|
||||
sys.path.insert(0, test_fw_path)
|
||||
import IDF
|
||||
|
||||
|
||||
@IDF.idf_example_test(env_tag='Example_WIFI')
|
||||
def test_examples_spiffsgen(env, extra_data):
|
||||
# Test with default build configurations
|
||||
dut = env.get_dut('spiffsgen', 'examples/build_system/spiffsgen')
|
||||
dut.start_app()
|
||||
|
||||
base_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'spiffs_image')
|
||||
|
||||
# Expect hello.txt is read successfully
|
||||
with open(os.path.join(base_dir, 'hello.txt'), 'r') as hello_txt:
|
||||
dut.expect('Read from hello.txt: ' + hello_txt.read())
|
||||
|
||||
# Expect alice.txt MD5 hash is computed accurately
|
||||
with open(os.path.join(base_dir, 'sub', 'alice.txt'), 'rb') as alice_txt:
|
||||
alice_md5 = hashlib.md5(alice_txt.read()).hexdigest()
|
||||
dut.expect('Computed MD5 hash of alice.txt: ' + alice_md5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_spiffsgen()
|
|
@ -0,0 +1,10 @@
|
|||
set(COMPONENT_SRCS "spiffsgen_example_main.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
register_component()
|
||||
|
||||
# Create a SPIFFS image from the contents of the 'spiffs_image' directory
|
||||
# that fits the partition named 'storage'. FLASH_IN_PROJECT indicates that
|
||||
# the generated image should be flashed when the entire project is flashed to
|
||||
# the target with 'idf.py flash'.
|
||||
spiffs_create_partition_image(storage ../spiffs_image FLASH_IN_PROJECT)
|
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
|
@ -0,0 +1,130 @@
|
|||
/* SPIFFS Image Generation on Build Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_spiffs.h"
|
||||
#include "esp32/rom/md5_hash.h"
|
||||
|
||||
static const char *TAG = "example";
|
||||
|
||||
static void read_hello_txt()
|
||||
{
|
||||
ESP_LOGI(TAG, "Reading hello.txt");
|
||||
|
||||
// Open for reading hello.txt
|
||||
FILE* f = fopen("/spiffs/hello.txt", "r");
|
||||
if (f == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to open hello.txt");
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[64];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
fread(buf, 1, sizeof(buf), f);
|
||||
fclose(f);
|
||||
|
||||
// Display the read contents from the file
|
||||
ESP_LOGI(TAG, "Read from hello.txt: %s", buf);
|
||||
}
|
||||
|
||||
static void compute_alice_txt_md5()
|
||||
{
|
||||
ESP_LOGI(TAG, "Computing alice.txt MD5 hash");
|
||||
|
||||
// The file alice.txt lives under a subdirectory, though SPIFFS itself is flat
|
||||
FILE* f = fopen("/spiffs/sub/alice.txt", "r");
|
||||
if (f == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to open alice.txt");
|
||||
return;
|
||||
}
|
||||
|
||||
// Read file and compute the digest chunk by chunk
|
||||
#define MD5_MAX_LEN 16
|
||||
|
||||
char buf[64];
|
||||
struct MD5Context ctx;
|
||||
unsigned char digest[MD5_MAX_LEN];
|
||||
|
||||
MD5Init(&ctx);
|
||||
|
||||
size_t read;
|
||||
|
||||
do {
|
||||
read = fread((void*) buf, 1, sizeof(buf), f);
|
||||
MD5Update(&ctx, (unsigned const char*) buf, read);
|
||||
} while(read == sizeof(buf));
|
||||
|
||||
MD5Final(digest, &ctx);
|
||||
|
||||
// Create a string of the digest
|
||||
char digest_str[MD5_MAX_LEN * 2];
|
||||
|
||||
for (int i = 0; i < MD5_MAX_LEN; i++) {
|
||||
sprintf(&digest_str[i * 2], "%02x", (unsigned int)digest[i]);
|
||||
}
|
||||
|
||||
// For reference, MD5 should be deeb71f585cbb3ae5f7976d5127faf2a
|
||||
ESP_LOGI(TAG, "Computed MD5 hash of alice.txt: %s", digest_str);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initializing SPIFFS");
|
||||
|
||||
esp_vfs_spiffs_conf_t conf = {
|
||||
.base_path = "/spiffs",
|
||||
.partition_label = NULL,
|
||||
.max_files = 5,
|
||||
.format_if_mount_failed = false
|
||||
};
|
||||
|
||||
// Use settings defined above to initialize and mount SPIFFS filesystem.
|
||||
// Note: esp_vfs_spiffs_register is an all-in-one convenience function.
|
||||
esp_err_t ret = esp_vfs_spiffs_register(&conf);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
if (ret == ESP_FAIL) {
|
||||
ESP_LOGE(TAG, "Failed to mount or format filesystem");
|
||||
} else if (ret == ESP_ERR_NOT_FOUND) {
|
||||
ESP_LOGE(TAG, "Failed to find SPIFFS partition");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
size_t total = 0, used = 0;
|
||||
ret = esp_spiffs_info(NULL, &total, &used);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
|
||||
}
|
||||
|
||||
/* The following calls demonstrate reading files from the generated SPIFFS
|
||||
* image. The images should contain the same files and contents as the spiffs_image directory.
|
||||
*/
|
||||
|
||||
// Read and display the contents of a small text file (hello.txt)
|
||||
read_hello_txt();
|
||||
|
||||
// Compute and display the MD5 hash of a large text file (alice.txt)
|
||||
compute_alice_txt_md5();
|
||||
|
||||
// All done, unmount partition and disable SPIFFS
|
||||
esp_vfs_spiffs_unregister(NULL);
|
||||
ESP_LOGI(TAG, "SPIFFS unmounted");
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1M,
|
||||
storage, data, spiffs, , 0xF0000,
|
|
|
@ -0,0 +1,5 @@
|
|||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
|
||||
CONFIG_APP_OFFSET=0x10000
|
|
@ -0,0 +1 @@
|
|||
Hello World!
|
Plik diff jest za duży
Load Diff
Ładowanie…
Reference in New Issue