diff --git a/samples/boards/esp32/flash_memory_mapped/CMakeLists.txt b/samples/boards/esp32/flash_memory_mapped/CMakeLists.txt new file mode 100644 index 00000000000..3cdbfb0e0b1 --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(flash_memory_mapped) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/esp32/flash_memory_mapped/README.rst b/samples/boards/esp32/flash_memory_mapped/README.rst new file mode 100644 index 00000000000..17940504fc0 --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/README.rst @@ -0,0 +1,66 @@ +.. _flash_memory_mapped: + +Espressif ESP32 Flash Memory-Mapped +################################### + +Overview +******** + +ESP32 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. + +Mapping happens in 64 KB pages. Memory mapping hardware can map flash into the data address space +and the instruction address space. See the technical reference manual for more details and +limitations about memory mapping hardware. For more information, check `_ESP32 Flash Memory-Mapping`. + +Supported SoCs +************** + +All ESP32 SoCs support flash memory-mapped feature. + +Building and Running +******************** + +Make sure you have your board connected over USB port. + +.. code-block:: console + + west build -b esp32s3_devkitm samples/boards/esp32/flash_memory_mapped + west flash + +Sample Output +============= + +To check the output of this sample, run ``west espressif monitor`` or any other serial +console program (e.g., minicom, putty, screen, etc). +This example uses ``west espressif monitor``, which automatically detects the serial +port at ``/dev/ttyUSB0``: + +.. code-block:: console + + $ west espressif monitor + +The sample code erases the scratch area defined in DTS file and writes a 32-bytes data buffer in it. +Next, it prints that region content using flash API read and also using memory-mapped pointer. +Both readings should return the same value. Important to notice that writing using memory-mapped pointer +is not allowed. + + +.. code-block:: console + + *** Booting Zephyr OS build v3.5.0-rc3-10-g3118724fa268 *** + [00:00:00.255,000] flash_memory_mapped: memory-mapped pointer address: 0x3c040000 + [00:00:01.122,000] flash_memory_mapped: flash read using memory-mapped pointer + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........ + [00:00:01.122,000] flash_memory_mapped: writing 32-bytes data using flash API + [00:00:01.122,000] flash_memory_mapped: flash read using flash API + 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |........ ........ + 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |........ ........ + [00:00:01.122,000] flash_memory_mapped: flash read using memory-mapped pointer + 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |........ ........ + 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |........ ........ + +.. _ESP32 Flash Memory-Mapping: + https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_flash/index.html#memory-mapping-api diff --git a/samples/boards/esp32/flash_memory_mapped/prj.conf b/samples/boards/esp32/flash_memory_mapped/prj.conf new file mode 100644 index 00000000000..83a00f200cf --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/prj.conf @@ -0,0 +1,3 @@ +CONFIG_LOG=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y diff --git a/samples/boards/esp32/flash_memory_mapped/sample.yaml b/samples/boards/esp32/flash_memory_mapped/sample.yaml new file mode 100644 index 00000000000..c8601961d94 --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/sample.yaml @@ -0,0 +1,10 @@ +sample: + description: Sample application to test memory-mapped flash region + name: flash_memory_mapped +tests: + sample.board.esp32.flash_memory_mapped: + platform_allow: + - esp32_devkitc_wroom + - esp32c3_devkitm + - esp32s3_devkitm + tags: esp32 diff --git a/samples/boards/esp32/flash_memory_mapped/src/main.c b/samples/boards/esp32/flash_memory_mapped/src/main.c new file mode 100644 index 00000000000..a29d6db08ec --- /dev/null +++ b/samples/boards/esp32/flash_memory_mapped/src/main.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(flash_memory_mapped, CONFIG_LOG_DEFAULT_LEVEL); + +int main(void) +{ + uint8_t buffer[32]; + const struct device *flash_device; + const void *mem_ptr; + spi_flash_mmap_handle_t handle; + off_t address = FIXED_PARTITION_OFFSET(scratch_partition); + size_t size = FIXED_PARTITION_SIZE(scratch_partition); + + flash_device = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); + if (!device_is_ready(flash_device)) { + printk("%s: device not ready.\n", flash_device->name); + return 0; + } + + /* map selected region */ + spi_flash_mmap(address, size, SPI_FLASH_MMAP_DATA, &mem_ptr, &handle); + LOG_INF("memory-mapped pointer address: %p", mem_ptr); + + /* erase and read flash */ + flash_erase(flash_device, address, size); + LOG_HEXDUMP_INF(mem_ptr, 32, "flash read using memory-mapped pointer"); + + LOG_INF("writing 32-bytes data using flash API"); + memset(buffer, 0, sizeof(buffer)); + for (int k = 0; k < 32; k++) { + buffer[k] = k; + } + flash_write(flash_device, address, buffer, 32); + + /* read using flash API */ + memset(buffer, 0, sizeof(buffer)); + flash_read(flash_device, address, buffer, 32); + LOG_HEXDUMP_INF(buffer, 32, "flash read using flash API"); + + LOG_HEXDUMP_INF(mem_ptr, 32, "flash read using memory-mapped pointer"); + + /* unmap mapped region */ + spi_flash_munmap(handle); + + return 0; +}