From 0fc30f437919f13f4de4701c946f1169a5bea6eb Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 30 Sep 2019 16:11:09 +0200 Subject: [PATCH 1/2] spi_flash: load partition table before adding an external partition esp_partition_register_external did not call load_partitions, so if it was called before any call to esp_partition_find, then the main partition table would never be loaded. Introduce new function, ensure_partitions_loaded, and call it both from esp_partition_find and esp_partition_register_external. Closes https://github.com/espressif/esp-idf/issues/4116 --- components/spi_flash/partition.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index f31705c81c..2855df90ab 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -55,27 +55,38 @@ typedef struct esp_partition_iterator_opaque_ { static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, esp_partition_subtype_t subtype, const char* label); static esp_err_t load_partitions(); +static esp_err_t ensure_partitions_loaded(void); +static const char* TAG = "partition"; static SLIST_HEAD(partition_list_head_, partition_list_item_) s_partition_list = SLIST_HEAD_INITIALIZER(s_partition_list); static _lock_t s_partition_list_lock; -esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, - esp_partition_subtype_t subtype, const char* label) +static esp_err_t ensure_partitions_loaded(void) { + esp_err_t err = ESP_OK; if (SLIST_EMPTY(&s_partition_list)) { // only lock if list is empty (and check again after acquiring lock) _lock_acquire(&s_partition_list_lock); - esp_err_t err = ESP_OK; if (SLIST_EMPTY(&s_partition_list)) { + ESP_LOGD(TAG, "Loading the partition table"); err = load_partitions(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "load_partitions returned 0x%x", err); + } } _lock_release(&s_partition_list_lock); - if (err != ESP_OK) { - return NULL; - } + } + return err; +} + +esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, + esp_partition_subtype_t subtype, const char* label) +{ + if (ensure_partitions_loaded() != ESP_OK) { + return NULL; } // create an iterator pointing to the start of the list // (next item will be the first one) @@ -233,6 +244,11 @@ esp_err_t esp_partition_register_external(esp_flash_t* flash_chip, size_t offset return ESP_ERR_INVALID_SIZE; } + esp_err_t err = ensure_partitions_loaded(); + if (err != ESP_OK) { + return err; + } + partition_list_item_t* item = (partition_list_item_t*) calloc(sizeof(partition_list_item_t), 1); if (item == NULL) { return ESP_ERR_NO_MEM; From 92adc524a2bf517a9bfc9140f83a21602bb0da73 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 30 Sep 2019 16:26:34 +0200 Subject: [PATCH 2/2] examples/ext_flash_fatfs: print out data partitions, add CI test --- .../storage/ext_flash_fatfs/example_test.py | 27 +++++++++++++++++++ .../main/ext_flash_fatfs_example_main.c | 18 +++++++++++++ tools/ci/config/target-test.yml | 6 +++++ 3 files changed, 51 insertions(+) create mode 100644 examples/storage/ext_flash_fatfs/example_test.py diff --git a/examples/storage/ext_flash_fatfs/example_test.py b/examples/storage/ext_flash_fatfs/example_test.py new file mode 100644 index 0000000000..a66ad8c3a4 --- /dev/null +++ b/examples/storage/ext_flash_fatfs/example_test.py @@ -0,0 +1,27 @@ +from __future__ import print_function +import os +import sys + +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_ExtFlash') +def test_examples_storage_ext_flash_fatfs(env, extra_data): + dut = env.get_dut('ext_flash_fatfs', 'examples/storage/ext_flash_fatfs') + dut.start_app() + + dut.expect('Initialized external Flash') + dut.expect('partition \'nvs\'') + dut.expect('partition \'storage\'') + dut.expect('File written') + dut.expect('Read from file: \'Written using ESP-IDF') + + +if __name__ == '__main__': + test_examples_storage_ext_flash_fatfs() diff --git a/examples/storage/ext_flash_fatfs/main/ext_flash_fatfs_example_main.c b/examples/storage/ext_flash_fatfs/main/ext_flash_fatfs_example_main.c index c64fb76ad1..8c390b9071 100644 --- a/examples/storage/ext_flash_fatfs/main/ext_flash_fatfs_example_main.c +++ b/examples/storage/ext_flash_fatfs/main/ext_flash_fatfs_example_main.c @@ -30,6 +30,7 @@ const char *base_path = "/extflash"; static esp_flash_t* example_init_ext_flash(); static const esp_partition_t* example_add_partition(esp_flash_t* ext_flash, const char* partition_label); +static void example_list_data_partitions(void); static bool example_mount_fatfs(const char* partition_label); static void example_get_fatfs_usage(size_t* out_total_bytes, size_t* out_free_bytes); @@ -45,6 +46,9 @@ void app_main(void) const char *partition_label = "storage"; example_add_partition(flash, partition_label); + // List the available partitions + example_list_data_partitions(); + // Initialize FAT FS in the partition if (!example_mount_fatfs(partition_label)) { return; @@ -139,6 +143,20 @@ static const esp_partition_t* example_add_partition(esp_flash_t* ext_flash, cons return fat_partition; } +static void example_list_data_partitions(void) +{ + ESP_LOGI(TAG, "Listing data partitions:"); + esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL); + + for (; it != NULL; it = esp_partition_next(it)) { + const esp_partition_t *part = esp_partition_get(it); + ESP_LOGI(TAG, "- partition '%s', subtype %d, offset 0x%x, size %d kB", + part->label, part->subtype, part->address, part->size / 1024); + } + + esp_partition_iterator_release(it); +} + static bool example_mount_fatfs(const char* partition_label) { ESP_LOGI(TAG, "Mounting FAT filesystem"); diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index 61cf8dd098..e73065235c 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -202,6 +202,12 @@ example_test_008: - ESP32 - Example_Flash_Encryption +example_test_009: + extends: .example_test_template + tags: + - ESP32 + - Example_ExtFlash + UT_001: extends: .unit_test_template parallel: 50