1SPI Flash API (Legacy)
2========================
3
4Overview
5--------
6
7This is the readme for the APIs before IDF v4.0. Enable the kconfig option ``SPI_FLASH_USE_LEGACY_IMPL`` to use the
8legacy implementation.
9
10The spi_flash component contains API functions related to reading, writing, erasing, memory mapping for data in the external SPI flash. The spi_flash component also has higher-level API functions which work with partitions defined in the :doc:`partition table </api-guides/partition-tables>`.
11
12Note that all the functionality is limited to the "main" SPI flash chip, the same SPI flash chip from which programs are runs. For ``spi_flash_*`` functions, this is a software limitation. The underlying ROM functions which work with SPI flash do not have provisions for working with flash chips attached to SPI peripherals other than SPI0.
13
14SPI flash access API
15--------------------
16
17This is the set of API functions for working with data in flash:
18
19- :cpp:func:`spi_flash_read` reads data from flash to RAM
20- :cpp:func:`spi_flash_write` writes data from RAM to flash
21- :cpp:func:`spi_flash_erase_sector` erases individual sectors of flash
22- :cpp:func:`spi_flash_erase_range` erases ranges of addresses in flash
23- :cpp:func:`spi_flash_get_chip_size` returns flash chip size, in bytes, as configured in menuconfig
24
25Generally, try to avoid using the raw SPI flash functions in favor of :ref:`partition-specific functions <flash-partition-apis>`.
26
27SPI Flash Size
28--------------
29
30The SPI flash size is configured by writing a field in the software bootloader image header, flashed at offset 0x1000.
31
32By default, the SPI flash size is detected by esptool.py when this bootloader is written to flash, and the header is updated with the correct size. Alternatively, it is possible to generate a fixed flash size by setting :envvar:`CONFIG_ESPTOOLPY_FLASHSIZE` in project configuration.
33
34If it is necessary to override the configured flash size at runtime, it is possible to set the ``chip_size`` member of the ``g_rom_flashchip`` structure. This size is used by ``spi_flash_*`` functions (in both software & ROM) to check the bounds.
35
36Concurrency Constraints
37-----------------------
38
39Because the SPI flash is also used for firmware execution via the instruction & data caches, these caches must be disabled while reading/writing/erasing. This means that both CPUs must be running code from IRAM and must only be reading data from DRAM while flash write operations occur.
40
41If you use the API functions documented here, then these constraints are applied automatically and transparently. However, note that it will have some performance impact on other tasks in the system.
42
43For differences between IRAM, DRAM, and flash cache, please refer to the :ref:`application memory layout <memory-layout>` documentation.
44
45To avoid reading flash cache accidentally, when one CPU initiates a flash write or erase operation, the other CPU is put into a blocked state, and all non-IRAM-safe interrupts are disabled on both CPUs until the flash operation completes.
46
47If one CPU initiates a flash write or erase operation, the other CPU is put into a blocked state to avoid reading flash cache accidentally. All interrupts not safe for IRAM are disabled on both CPUs until the flash operation completes.
48
49.. _iram-safe-interrupt-handlers:
50
51IRAM-Safe Interrupt Handlers
52^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53
54If you have an interrupt handler that you want to execute while a flash operation is in progress (for example, for low latency operations), set the ``ESP_INTR_FLAG_IRAM`` flag when the :doc:`interrupt handler is registered </api-reference/system/intr_alloc>`.
55
56You must ensure that all data and functions accessed by these interrupt handlers, including the ones that handlers call, are located in IRAM or DRAM. See :ref:`how-to-place-code-in-iram`.
57
58If a function or symbol is not correctly put into IRAM/DRAM, and the interrupt handler reads from the flash cache during a flash operation, it will cause a crash due to Illegal Instruction exception (for code which should be in IRAM) or garbage data to be read (for constant data which should be in DRAM).
59
60.. _flash-partition-apis:
61
62Partition table API
63-------------------
64
65ESP-IDF projects use a partition table to maintain information about various regions of SPI flash memory (bootloader, various application binaries, data, filesystems). More information on partition tables can be found :doc:`here </api-guides/partition-tables>`.
66
67This component provides API functions to enumerate partitions found in the partition table and perform operations on them. These functions are declared in ``esp_partition.h``:
68
69- :cpp:func:`esp_partition_find` checks a partition table for entries with specific type, returns an opaque iterator.
70- :cpp:func:`esp_partition_get` returns a structure describing the partition for a given iterator.
71- :cpp:func:`esp_partition_next` shifts the iterator to the next found partition.
72- :cpp:func:`esp_partition_iterator_release` releases iterator returned by ``esp_partition_find``.
73- :cpp:func:`esp_partition_find_first` - a convenience function which returns the structure describing the first partition found by ``esp_partition_find``.
74- :cpp:func:`esp_partition_read`, :cpp:func:`esp_partition_write`, :cpp:func:`esp_partition_erase_range` are equivalent to :cpp:func:`spi_flash_read`, :cpp:func:`spi_flash_write`, :cpp:func:`spi_flash_erase_range`, but operate within partition boundaries.
75
76.. note::
77    Application code should mostly use these ``esp_partition_*`` API functions instead of lower level ``spi_flash_*`` API functions. Partition table API functions do bounds checking and calculate correct offsets in flash, based on data stored in a partition table.
78
79SPI Flash Encryption
80--------------------
81
82It is possible to encrypt the contents of SPI flash and have it transparently decrypted by hardware.
83
84Refer to the :doc:`Flash Encryption documentation </security/flash-encryption>` for more details.
85
86Memory mapping API
87------------------
88
89ESP32 features memory hardware which allows regions of flash memory to be mapped into instruction and data address spaces. This mapping works only for read operations. It is not possible to modify contents of flash memory by writing to a mapped memory region.
90
91Mapping happens in 64KB pages. Memory mapping hardware can map up to four megabytes of flash into data address space and up to 16 megabytes of flash into instruction address space. See the technical reference manual for more details about memory mapping hardware.
92
93Note that some 64KB pages are used to map the application itself into memory, so the actual number of available 64KB pages may be less.
94
95Reading data from flash using a memory mapped region is the only way to decrypt contents of flash when :doc:`flash encryption </security/flash-encryption>` is enabled. Decryption is performed at the hardware level.
96
97Memory mapping API are declared in ``esp_spi_flash.h`` and ``esp_partition.h``:
98
99- :cpp:func:`spi_flash_mmap` maps a region of physical flash addresses into instruction space or data space of the CPU.
100- :cpp:func:`spi_flash_munmap` unmaps previously mapped region.
101- :cpp:func:`esp_partition_mmap` maps part of a partition into the instruction space or data space of the CPU.
102
103Differences between :cpp:func:`spi_flash_mmap` and :cpp:func:`esp_partition_mmap` are as follows:
104
105- :cpp:func:`spi_flash_mmap` must be given a 64KB aligned physical address.
106- :cpp:func:`esp_partition_mmap` may be given any arbitrary offset within the partition, it will adjust the returned pointer to mapped memory as necessary
107
108Note that since memory mapping happens in 64KB blocks, it may be possible to read data outside of the partition provided to ``esp_partition_mmap``.
109