]> granicus.if.org Git - esp-idf/blob - components/spi_flash/README.rst
console/linenoise: support buffered stdout
[esp-idf] / components / spi_flash / README.rst
1 SPI Flash APIs
2 ==============
3
4 Overview
5 --------
6 The spi_flash component contains APIs related to reading, writing, erasing,
7 memory mapping data in the external SPI flash. It also has higher-level
8 APIs which work with partitions defined in the :doc:`partition table </api-guides/partition-tables>`.
9
10 Note that all the functionality is limited to the "main" SPI flash chip,
11 the same SPI flash chip from which program runs. For ``spi_flash_*`` functions,
12 this is a software limitation. The underlying ROM functions which work with SPI flash
13 do not have provisions for working with flash chips attached to SPI peripherals
14 other than SPI0.
15
16 SPI flash access APIs
17 ---------------------
18
19 This is the set of APIs for working with data in flash:
20
21 - :cpp:func:`spi_flash_read` used to read data from flash to RAM
22 - :cpp:func:`spi_flash_write` used to write data from RAM to flash
23 - :cpp:func:`spi_flash_erase_sector` used to erase individual sectors of flash
24 - :cpp:func:`spi_flash_erase_range` used to erase range of addresses in flash
25 - :cpp:func:`spi_flash_get_chip_size` returns flash chip size, in bytes, as configured in menuconfig
26
27 Generally, try to avoid using the raw SPI flash functions in favour of
28 :ref:`partition-specific functions <flash-partition-apis>`.
29
30 SPI Flash Size
31 --------------
32
33 The SPI flash size is configured by writing a field in the software bootloader
34 image header, flashed at offset 0x1000.
35
36 By default, the SPI flash size is detected by esptool.py when this bootloader is
37 written to flash, and the header is updated with the correct
38 size. Alternatively, it is possible to generate a fixed flash size by setting
39 :envvar:`CONFIG_ESPTOOLPY_FLASHSIZE` in ``make menuconfig``.
40
41 If it is necessary to override the configured flash size at runtime, is is
42 possible to set the ``chip_size`` member of ``g_rom_flashchip`` structure. This
43 size is used by ``spi_flash_*`` functions (in both software & ROM) for bounds
44 checking.
45
46 Concurrency Constraints
47 -----------------------
48
49 Because the SPI flash is also used for firmware execution (via the instruction &
50 data caches), these caches must be disabled while reading/writing/erasing. This
51 means that both CPUs must be running code from IRAM and only reading data from
52 DRAM while flash write operations occur.
53
54 If you use the APIs documented here, then this happens automatically and
55 transparently. However note that it will have some performance impact on other
56 tasks in the system.
57
58 Refer to the :ref:`application memory layout <memory-layout>` documentation for
59 an explanation of the differences between IRAM, DRAM and flash cache.
60
61 To avoid reading flash cache accidentally, when one CPU commences a flash write
62 or erase operation the other CPU is put into a blocked state and all
63 non-IRAM-safe interrupts are disabled on both CPUs, until the flash operation
64 completes.
65
66 .. _iram-safe-interrupt-handlers:
67
68 IRAM-Safe Interrupt Handlers
69 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
70
71 If you have an interrupt handler that you want to execute even when a flash
72 operation is in progress (for example, for low latency operations), set the
73 ``ESP_INTR_FLAG_IRAM`` flag when the :doc:`interrupt handler is registered
74 </api-reference/system/intr_alloc>`.
75
76 You must ensure all data and functions accessed by these interrupt handlers are
77 located in IRAM or DRAM. This includes any functions that the handler calls.
78
79 Use the ``IRAM_ATTR`` attribute for functions::
80
81     #include "esp_attr.h"
82
83     void IRAM_ATTR gpio_isr_handler(void* arg)
84     {
85         // ...
86     }
87
88 Use the ``DRAM_ATTR`` and ``DRAM_STR`` attributes for constant data::
89
90     void IRAM_ATTR gpio_isr_handler(void* arg)
91     {
92        const static DRAM_ATTR uint8_t INDEX_DATA[] = { 45, 33, 12, 0 };
93        const static char *MSG = DRAM_STR("I am a string stored in RAM");
94     }
95
96 Note that knowing which data should be marked with ``DRAM_ATTR`` can be hard,
97 the compiler will sometimes recognise that a variable or expression is constant
98 (even if it is not marked ``const``) and optimise it into flash, unless it is
99 marked with ``DRAM_ATTR``.
100
101 If a function or symbol is not correctly put into IRAM/DRAM and the interrupt
102 handler reads from the flash cache during a flash operation, it will cause a
103 crash due to Illegal Instruction exception (for code which should be in IRAM) or
104 garbage data to be read (for constant data which should be in DRAM).
105
106 .. _flash-partition-apis:
107
108 Partition table APIs
109 --------------------
110
111 ESP-IDF projects use a partition table to maintain information about various regions of
112 SPI flash memory (bootloader, various application binaries, data, filesystems).
113 More information about partition tables can be found :doc:`here </api-guides/partition-tables>`.
114
115 This component provides APIs to enumerate partitions found in the partition table
116 and perform operations on them. These functions are declared in ``esp_partition.h``:
117
118 - :cpp:func:`esp_partition_find` used to search partition table for entries with
119   specific type, returns an opaque iterator
120 - :cpp:func:`esp_partition_get` returns a structure describing the partition, for the given iterator
121 - :cpp:func:`esp_partition_next` advances iterator to the next partition found
122 - :cpp:func:`esp_partition_iterator_release` releases iterator returned by ``esp_partition_find``
123 - :cpp:func:`esp_partition_find_first` is a convenience function which returns structure
124   describing the first partition found by ``esp_partition_find``
125 - :cpp:func:`esp_partition_read`, :cpp:func:`esp_partition_write`, :cpp:func:`esp_partition_erase_range`
126   are equivalent to :cpp:func:`spi_flash_read`, :cpp:func:`spi_flash_write`,
127   :cpp:func:`spi_flash_erase_range`, but operate within partition boundaries
128
129 .. note::
130     Most application code should use these ``esp_partition_*`` APIs instead of lower level
131     ``spi_flash_*`` APIs. Partition APIs do bounds checking and calculate correct
132     offsets in flash based on data stored in partition table.
133
134 SPI Flash Encryption
135 --------------------
136
137 It is possible to encrypt SPI flash contents, and have it transparenlty decrypted by hardware.
138
139 Refer to the :doc:`Flash Encryption documentation </security/flash-encryption>` for more details.
140
141 Memory mapping APIs
142 -------------------
143
144 ESP32 features memory hardware which allows regions of flash memory to be mapped
145 into instruction and data address spaces. This mapping works only for read operations,
146 it is not possible to modify contents of flash memory by writing to mapped memory
147 region. Mapping happens in 64KB pages. Memory mapping hardware can map up to
148 4 megabytes of flash into data address space, and up to 16 megabytes of flash into
149 instruction address space. See the technical reference manual for more details
150 about memory mapping hardware.
151
152 Note that some number of 64KB pages is used to map the application
153 itself into memory, so the actual number of available 64KB pages may be less.
154
155 Reading data from flash using a memory mapped region is the only way to decrypt
156 contents of flash when :doc:`flash encryption </security/flash-encryption>` is enabled.
157 Decryption is performed at hardware level.
158
159 Memory mapping APIs are declared in ``esp_spi_flash.h`` and ``esp_partition.h``:
160
161 - :cpp:func:`spi_flash_mmap` maps a region of physical flash addresses into instruction space or data space of the CPU
162 - :cpp:func:`spi_flash_munmap` unmaps previously mapped region
163 - :cpp:func:`esp_partition_mmap` maps part of a partition into the instruction space or data space of the CPU
164
165 Differences between :cpp:func:`spi_flash_mmap` and :cpp:func:`esp_partition_mmap` are as follows:
166
167 - :cpp:func:`spi_flash_mmap` must be given a 64KB aligned physical address
168 - :cpp:func:`esp_partition_mmap` may be given any arbitrary offset within the partition,
169   it will adjust returned pointer to mapped memory as necessary
170
171 Note that because memory mapping happens in 64KB blocks, it may be possible to
172 read data outside of the partition provided to ``esp_partition_mmap``.