using the external flash

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

using the external flash

Postby mzimmers » Tue Apr 24, 2018 8:25 pm

From my reading, I understand that the ESP32 has 4MB of external flash. This area is mapped to address space 0x3F40_0000:0x3F7F_FFFF.

I assume that this flash is used for storing the OS, my application, and probably some other things. A couple of questions:

1. Is the Spi_flash component the recommended method of accessing this area? I also came across the non-volatile storage (NVS) library, which looks interesting, but probably not what I need.
2. How do I go about determining what part of the flash is available to me? Do I traverse the partition table mentioned in the docs?

My needs are fairly simple. I was thinking of defining a struct containing everything I want to store, then I could just access (read) it using pointers.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: using the external flash

Postby WiFive » Tue Apr 24, 2018 8:43 pm

Reserve an area using the partition table
esp_partition_read(), esp_partition_write(), esp_partition_erase_range() are equivalent to spi_flash_read(), spi_flash_write(), spi_flash_erase_range(), but operate within partition boundaries
https://esp-idf.readthedocs.io/en/lates ... flash.html

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: using the external flash

Postby mzimmers » Tue Apr 24, 2018 8:58 pm

I did see that doc...so, if I want to know what portion of the flash is available, is it a matter of running through the partition table, collecting starting addresses and sizes, and whatever is left over is available to me?

Is there a menuconfig parameter for indicating that I want to "reserve" an area for my own purposes, so it won't try to use that area for program flashing?

Thanks.

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: using the external flash

Postby mzimmers » Tue Apr 24, 2018 9:39 pm

Here's a code snippet:

Code: Select all

    esp_partition_iterator_t it;
    esp_partition_t *pPart;
    it = esp_partition_find(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, nullptr);
    while (it != nullptr)
    {
        pPart = (esp_partition_t *) esp_partition_get(it);
        printf("main: partition type = %d.\n", pPart->type);
        printf("main: partition subtype = %d.\n", pPart->subtype);
        printf("main: partition starting address = %x.\n", pPart->address);
        printf("main: partition size = %x.\n", pPart->size);
        printf("main: partition label = %s.\n", pPart->label);
        printf("main: partition subtype = %d.\n", pPart->encrypted);
        printf("\n");
        it = esp_partition_next(it);
    }
    it = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, nullptr);
    while (it != nullptr)
    {
        pPart = (esp_partition_t *) esp_partition_get(it);
        printf("main: partition type = %d.\n", pPart->type);
        printf("main: partition subtype = %d.\n", pPart->subtype);
        printf("main: partition starting address = %x.\n", pPart->address);
        printf("main: partition size = %x.\n", pPart->size);
        printf("main: partition label = %s.\n", pPart->label);
        printf("main: partition subtype = %d.\n", pPart->encrypted);
        printf("\n");
        it = esp_partition_next(it);
    }
    esp_partition_iterator_release(it);
And the results:
main: partition type = 0.
main: partition subtype = 0.
main: partition starting address = 10000.
main: partition size = 100000.
main: partition label = factory.
main: partition subtype = 0.

main: partition type = 1.
main: partition subtype = 2.
main: partition starting address = 9000.
main: partition size = 6000.
main: partition label = nvs.
main: partition subtype = 0.

main: partition type = 1.
main: partition subtype = 1.
main: partition starting address = f000.
main: partition size = 1000.
main: partition label = phy_init.
main: partition subtype = 0.
So, do I correctly understand this to mean that I can use anything below 9000 or above (10000 + 100000)? And, if true, do I do this using a custom table (imported into menuconfig via CSV) as described in the document? Then I use the functions to read/write?

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: using the external flash

Postby mzimmers » Tue Apr 24, 2018 10:27 pm

Further experimentation: I created a .csv file:

Code: Select all

# Espressif ESP32 Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,16K,
otadata,data,ota,0xd000,8K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1M,
ota_0,app,ota_0,0x110000,1M,
ota_1,app,ota_1,0x210000,1M,
appdata,data,nvs,0x3f0000,64K
which is identical to one of the standard tables, with an entry at the end for my data partition.

I ran the conversion utility which generated a .bin file.

I went into menuconfig --> Partition Table --> Partition Table and selected Custom partition table CSV
I went into menuconfig --> Partition Table --> Custom partition CSV file and entered my file name.

I ran "make menuconfig" and got the following error:
make: *** No rule to make target '/c/esp32_projects/wifibutton/partitions_two_ota_and_appdata.csv', needed by '/c/esp32_projects/wifibutton/build/partitions_two_ota_and_appdata.bin'. Stop.
Any ideas what I did wrong? Thanks.

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: using the external flash

Postby ESP_igrr » Wed Apr 25, 2018 12:38 am

Did you enter the name of CSV file in menuconfig, or the bin file? Normally you should not need to run the partition table generation tool manually. I you set the name of CSV file in menuconfig, build system will generate the .bin out of it automatically.
If you did enter the name of your CSV, is this a full path or a relative path?

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: using the external flash

Postby mzimmers » Wed Apr 25, 2018 2:06 pm

Hi igrr -

I entered the name of the CSV file. Just the file name, not the path.

EDIT: I just realized the pathname for the .csv file in the error message is not the same as the pathname of the .bin file. I added the build/ subdirectory to the filename in menuconfig, and it now works. Thanks for the assistance.

User avatar
mzimmers
Posts: 643
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: using the external flash

Postby mzimmers » Wed Apr 25, 2018 7:44 pm

I just noticed that my device gives the following message at boot:

I (41) boot: SPI Mode : DIO
I (45) boot: SPI Flash Size : 4MB
I (49) boot: Partition Table:
I (53) boot: ## Label Usage Type ST Offset Length
I (60) boot: 0 nvs WiFi data 01 02 00009000 00004000
I (68) boot: 1 otadata OTA data 01 00 0000d000 00002000
I (75) boot: 2 phy_init RF data 01 01 0000f000 00001000
I (83) boot: 3 factory factory app 00 00 00010000 00100000
I (90) boot: 4 ota_0 OTA app 00 10 00110000 00100000
I (97) boot: 5 ota_1 OTA app 00 11 00210000 00100000
I (105) boot: End of partition table
I (109) boot: Defaulting to factory image
I (114) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x2266c (140908) map
I (172) esp_image: segment 1: paddr=0x00032694 vaddr=0x3ffb0000 size=0x037e8 ( 14312) load
I (178) esp_image: segment 2: paddr=0x00035e84 vaddr=0x40080000 size=0x00400 ( 1024) load
0x40080000: _WindowOverflow4 at C:/esp-idf-release-v3.0/components/freertos/xtensa_vectors.S:1685

Is this something that should be remedied?

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: using the external flash

Postby ESP_igrr » Wed Apr 25, 2018 11:07 pm

No, idf_monitor decodes all addresses which are seen on the console, and look like code addresses. In this case the address is close to the location of Window Overflow exception handler. It doesn't indicate any issue.

Who is online

Users browsing this forum: Majestic-12 [Bot] and 95 guests