README.rst 7.3 KB

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