samples/soc_flash_nrf: Adjust for non-Flash SoC devices

The sample has been modified to work with devices that have
no explicit erase capability.
For that purpose printf messages have been modified to use
"Internal storage" rather than "Flash" when reporting status.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
This commit is contained in:
Dominik Ermel 2024-02-05 15:56:16 +00:00 committed by Henrik Brix Andersen
commit c7037532b8
2 changed files with 74 additions and 44 deletions

View file

@ -1,5 +1,5 @@
.. zephyr:code-sample:: soc-flash-nrf
:name: nRF SoC flash
:name: nRF SoC Internal Storage
:relevant-api: flash_interface flash_area_api
Use the flash API to interact with the SoC flash.
@ -7,10 +7,11 @@
Overview
********
This sample demonstrates using the :ref:`Flash API <flash_api>` on an SoC internal flash.
The sample uses :ref:`Flash map API <flash_map_api>` to obtain device for flash, using
DTS node label, and then directly uses :ref:`Flash API <flash_api>` to perform
flash operations.
This sample demonstrates using the :ref:`Flash API <flash_api>` on an SoC internal storage.
The sample uses :ref:`Flash map API <flash_map_api>` to obtain a device that has
partition defined with label `storage_partition`, then uses :ref:`Flash API <flash_api>`
to directly access and modify contents of a device, within area defined for said
partition.
Within the sample, user may observe how read/write/erase operations
are performed on a device, and how to first check whether device is
@ -19,11 +20,9 @@ ready for operation.
Building and Running
********************
The application will build for any SoC with internal flash memory
access enabled, as it is default for SoC devices, and fixed-partition
defined over that internal flash labeled `slot1_partition`, when
:kconfig:option:`CONFIG_TRUSTED_EXECUTION_NONSECURE` is not selected,
or `slot1_ns_partition`, when the Kconfig option is selected.
The application will build for any SoC with internal storage
access enabled, as it is default for SoC devices with defined
fixed-partition, over that internal storage, labeled `storage_partition`.
.. zephyr-app-commands::
:zephyr-app: samples/drivers/soc_flash_nrf
@ -38,8 +37,8 @@ Sample Output
*** Booting Zephyr OS build v2.7.99-17621-g54832687bcbb ***
Nordic nRF5 Flash Testing
=========================
Nordic nRF5 Internal Storage Sample
===================================
Test 1: Flash erase page at 0x82000
Flash erase succeeded!

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2016 Linaro Limited
* 2016 Intel Corporation.
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -27,9 +28,45 @@
#define FLASH_TEST_OFFSET2 0x41234
#define FLASH_TEST_PAGE_IDX 37
#if IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && \
IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE)
#define FLASH_PE_RUNTIME_CHECK(cond) (cond)
#elif IS_ENABLED(CONFIG_FLASH_HAS_EXPLICIT_ERASE)
#define FLASH_PE_RUNTIME_CHECK(cond) (true)
#else
/* Assumed IS_ENABLED(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) */
#define FLASH_PE_RUNTIME_CHECK(cond) (false)
#endif
/**
* Depending on value of condition erase a device or not. The condition
* is supposed to be value of erase_requirement picked up from
* flash_parameters.flags for device.
*/
static void erase_when_needed(const struct device *dev, bool condition,
uint32_t off, uint32_t size)
{
/*
* Alwayes invoke erase when there are only erase requiring devices,
* never invoke erase when there are no devices requiring erase,
* always check condition if there are both kind of devices.
*/
if (FLASH_PE_RUNTIME_CHECK(condition)) {
if (flash_erase(dev, off, size) != 0) {
printf(" Erase failed!\n");
} else {
printf(" Erase succeeded!\n");
}
} else {
(void)condition;
printf(" Erase not required by device\n");
}
}
int main(void)
{
const struct device *flash_dev = TEST_PARTITION_DEVICE;
struct flash_parameters flash_params;
uint32_t buf_array_1[4] = { TEST_DATA_WORD_0, TEST_DATA_WORD_1,
TEST_DATA_WORD_2, TEST_DATA_WORD_3 };
uint32_t buf_array_2[4] = { TEST_DATA_WORD_3, TEST_DATA_WORD_1,
@ -41,35 +78,35 @@ int main(void)
uint32_t buf_word = 0U;
uint32_t i, offset;
printf("\nNordic nRF5 Flash Testing\n");
printf("=========================\n");
memcpy(&flash_params, flash_get_parameters(flash_dev), sizeof(flash_params));
printf("\nNordic nRF5 Internal Storage Sample\n");
printf("=====================================\n");
if (!device_is_ready(flash_dev)) {
printf("Flash device not ready\n");
printf("Internal storage device not ready\n");
return 0;
}
printf("\nTest 1: Flash erase page at 0x%x\n", TEST_PARTITION_OFFSET);
if (flash_erase(flash_dev, TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE) != 0) {
printf(" Flash erase failed!\n");
} else {
printf(" Flash erase succeeded!\n");
}
printf("\nTest 1: Internal storage erase page at 0x%x\n", TEST_PARTITION_OFFSET);
erase_when_needed(flash_dev,
flash_params_get_erase_cap(&flash_params) & FLASH_ERASE_C_EXPLICIT,
TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE);
printf("\nTest 2: Flash write (word array 1)\n");
printf("\nTest 2: Internal storage write (word array 1)\n");
for (i = 0U; i < ARRAY_SIZE(buf_array_1); i++) {
offset = TEST_PARTITION_OFFSET + (i << 2);
printf(" Attempted to write %x at 0x%x\n", buf_array_1[i],
offset);
if (flash_write(flash_dev, offset, &buf_array_1[i],
sizeof(uint32_t)) != 0) {
printf(" Flash write failed!\n");
printf(" Write failed!\n");
return 0;
}
printf(" Attempted to read 0x%x\n", offset);
if (flash_read(flash_dev, offset, &buf_word,
sizeof(uint32_t)) != 0) {
printf(" Flash read failed!\n");
printf(" Read failed!\n");
return 0;
}
printf(" Data read: %x\n", buf_word);
@ -81,27 +118,24 @@ int main(void)
}
offset = TEST_PARTITION_OFFSET;
printf("\nTest 3: Flash erase (2 pages at 0x%x)\n", offset);
if (flash_erase(flash_dev, offset, FLASH_PAGE_SIZE * 2) != 0) {
printf(" Flash erase failed!\n");
} else {
printf(" Flash erase succeeded!\n");
}
printf("\nTest 4: Flash write (word array 2)\n");
printf("\nTest 3: Internal storage erase (2 pages at 0x%x)\n", offset);
erase_when_needed(flash_dev,
flash_params_get_erase_cap(&flash_params) & FLASH_ERASE_C_EXPLICIT,
offset, FLASH_PAGE_SIZE * 2);
printf("\nTest 4: Internal storage write (word array 2)\n");
for (i = 0U; i < ARRAY_SIZE(buf_array_2); i++) {
offset = TEST_PARTITION_OFFSET + (i << 2);
printf(" Attempted to write %x at 0x%x\n", buf_array_2[i],
offset);
if (flash_write(flash_dev, offset, &buf_array_2[i],
sizeof(uint32_t)) != 0) {
printf(" Flash write failed!\n");
printf(" Write failed!\n");
return 0;
}
printf(" Attempted to read 0x%x\n", offset);
if (flash_read(flash_dev, offset, &buf_word,
sizeof(uint32_t)) != 0) {
printf(" Flash read failed!\n");
printf(" Read failed!\n");
return 0;
}
printf(" Data read: %x\n", buf_word);
@ -112,12 +146,10 @@ int main(void)
}
}
printf("\nTest 5: Flash erase page at 0x%x\n", TEST_PARTITION_OFFSET);
if (flash_erase(flash_dev, TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE) != 0) {
printf(" Flash erase failed!\n");
} else {
printf(" Flash erase succeeded!\n");
}
printf("\nTest 5: Internal storage erase page at 0x%x\n", TEST_PARTITION_OFFSET);
erase_when_needed(flash_dev,
flash_params_get_erase_cap(&flash_params) & FLASH_ERASE_C_EXPLICIT,
TEST_PARTITION_OFFSET, FLASH_PAGE_SIZE);
printf("\nTest 6: Non-word aligned write (word array 3)\n");
for (i = 0U; i < ARRAY_SIZE(buf_array_3); i++) {
@ -126,13 +158,13 @@ int main(void)
offset);
if (flash_write(flash_dev, offset, &buf_array_3[i],
sizeof(uint32_t)) != 0) {
printf(" Flash write failed!\n");
printf(" Write failed!\n");
return 0;
}
printf(" Attempted to read 0x%x\n", offset);
if (flash_read(flash_dev, offset, &buf_word,
sizeof(uint32_t)) != 0) {
printf(" Flash read failed!\n");
printf(" Read failed!\n");
return 0;
}
printf(" Data read: %x\n", buf_word);
@ -185,8 +217,7 @@ int main(void)
#endif
printf("\nTest 8: Write block size API\n");
printf(" write-block-size = %u\n",
flash_get_write_block_size(flash_dev));
printf(" write-block-size = %u\n", flash_params.write_block_size);
printf("\nFinished!\n");
return 0;