samples: boards: esp32: add memory-mapped sample code

This sample shows how to use flash_mmap() call to enable custom flash
area to be mapped into data region.

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
This commit is contained in:
Sylvio Alves 2023-10-19 09:06:53 -03:00 committed by Carles Cufí
parent 3f5ea785f2
commit c179f17836
5 changed files with 147 additions and 0 deletions

View File

@ -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)

View File

@ -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] <inf> flash_memory_mapped: memory-mapped pointer address: 0x3c040000
[00:00:01.122,000] <inf> 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] <inf> flash_memory_mapped: writing 32-bytes data using flash API
[00:00:01.122,000] <inf> 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] <inf> 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

View File

@ -0,0 +1,3 @@
CONFIG_LOG=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y

View File

@ -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

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/device.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>
#include <esp_spi_flash.h>
#include <soc.h>
#include <zephyr/logging/log.h>
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;
}