From 9472f845b80c6b36c83bf8b298a5513d4a2b2901 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Thu, 21 Dec 2023 01:07:24 +0200 Subject: [PATCH] samples: Add read_bindesc sample Added a sample to demonstrate how to read binary descriptors. Signed-off-by: Yonatan Schachter --- .../bindesc/read_bindesc/CMakeLists.txt | 8 ++ .../subsys/bindesc/read_bindesc/README.rst | 23 ++++ samples/subsys/bindesc/read_bindesc/VERSION | 5 + samples/subsys/bindesc/read_bindesc/prj.conf | 24 ++++ .../subsys/bindesc/read_bindesc/sample.yaml | 13 ++ .../subsys/bindesc/read_bindesc/src/main.c | 126 ++++++++++++++++++ 6 files changed, 199 insertions(+) create mode 100644 samples/subsys/bindesc/read_bindesc/CMakeLists.txt create mode 100644 samples/subsys/bindesc/read_bindesc/README.rst create mode 100644 samples/subsys/bindesc/read_bindesc/VERSION create mode 100644 samples/subsys/bindesc/read_bindesc/prj.conf create mode 100644 samples/subsys/bindesc/read_bindesc/sample.yaml create mode 100644 samples/subsys/bindesc/read_bindesc/src/main.c diff --git a/samples/subsys/bindesc/read_bindesc/CMakeLists.txt b/samples/subsys/bindesc/read_bindesc/CMakeLists.txt new file mode 100644 index 00000000000000..3e70363ba31291 --- /dev/null +++ b/samples/subsys/bindesc/read_bindesc/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(hello_bindesc) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/subsys/bindesc/read_bindesc/README.rst b/samples/subsys/bindesc/read_bindesc/README.rst new file mode 100644 index 00000000000000..f1b27e578712ad --- /dev/null +++ b/samples/subsys/bindesc/read_bindesc/README.rst @@ -0,0 +1,23 @@ +.. zephyr:code-sample:: read-bindesc + :name: Binary descriptors read + :relevant-api: bindesc_read + + Define some binary descriptors and read them. + +Overview +******** + +A simple sample of :ref:`binary descriptor ` definition and reading. + +Building and Running +******************** + +Follow these steps to build the ``read_bindesc`` sample application: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/bindesc/read_bindesc + :board: + :goals: build + :compact: + +For more details see :ref:`binary_descriptors` and :ref:`west-bindesc`. diff --git a/samples/subsys/bindesc/read_bindesc/VERSION b/samples/subsys/bindesc/read_bindesc/VERSION new file mode 100644 index 00000000000000..16a13732e3adf1 --- /dev/null +++ b/samples/subsys/bindesc/read_bindesc/VERSION @@ -0,0 +1,5 @@ +VERSION_MAJOR = 1 +VERSION_MINOR = 0 +PATCHLEVEL = 0 +VERSION_TWEAK = 0 +EXTRAVERSION = diff --git a/samples/subsys/bindesc/read_bindesc/prj.conf b/samples/subsys/bindesc/read_bindesc/prj.conf new file mode 100644 index 00000000000000..a2051bb785dd9d --- /dev/null +++ b/samples/subsys/bindesc/read_bindesc/prj.conf @@ -0,0 +1,24 @@ +# Enable binary descriptors +CONFIG_BINDESC=y + +# Enable definition of binary descriptors +CONFIG_BINDESC_DEFINE=y + +# Enable default version binary descriptors +CONFIG_BINDESC_DEFINE_VERSION=y +CONFIG_BINDESC_KERNEL_VERSION_STRING=y +CONFIG_BINDESC_KERNEL_VERSION_MAJOR=y + +CONFIG_BINDESC_APP_VERSION_STRING=y + +# Enable default host info binary descriptors +CONFIG_BINDESC_DEFINE_HOST_INFO=y +CONFIG_BINDESC_C_COMPILER_NAME=y +CONFIG_BINDESC_C_COMPILER_VERSION=y + +# Enable bindesc reading +CONFIG_BINDESC_READ=y +CONFIG_FLASH=y +CONFIG_BINDESC_READ_FLASH=y +CONFIG_BINDESC_READ_RAM=y +CONFIG_BINDESC_READ_MEMORY_MAPPED_FLASH=y diff --git a/samples/subsys/bindesc/read_bindesc/sample.yaml b/samples/subsys/bindesc/read_bindesc/sample.yaml new file mode 100644 index 00000000000000..d6fafc34a745be --- /dev/null +++ b/samples/subsys/bindesc/read_bindesc/sample.yaml @@ -0,0 +1,13 @@ +sample: + name: Bindesc read + +common: + build_only: true + platform_exclude: + - nucleo_c031c6 + +tests: + sample.bindesc.read_bindesc: + tags: bindesc + filter: dt_chosen_enabled("zephyr,flash-controller") and CONFIG_FLASH_HAS_DRIVER_ENABLED + and CONFIG_ARCH_SUPPORTS_ROM_START diff --git a/samples/subsys/bindesc/read_bindesc/src/main.c b/samples/subsys/bindesc/read_bindesc/src/main.c new file mode 100644 index 00000000000000..f44d314e50d543 --- /dev/null +++ b/samples/subsys/bindesc/read_bindesc/src/main.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2023 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +BINDESC_STR_DEFINE(my_string, 1, "Hello world!"); +BINDESC_UINT_DEFINE(my_int, 2, 5); +BINDESC_BYTES_DEFINE(my_bytes, 3, ({1, 2, 3, 4})); + +const struct device *flash = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); + +void dump_bytes(const uint8_t *buffer, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) { + printk("%02x ", buffer[i]); + } + printk("\n"); +} + +int dump_descriptors_callback(const struct bindesc_entry *entry, void *user_data) +{ + ARG_UNUSED(user_data); + + printk("tag: %hu len: %hu data: ", entry->tag, entry->len); + + switch (BINDESC_GET_TAG_TYPE(entry->tag)) { + case BINDESC_TYPE_UINT: + printk("%u\n", *(const uint32_t *)entry->data); + break; + case BINDESC_TYPE_STR: + printk("%s\n", (const char *)entry->data); + break; + case BINDESC_TYPE_BYTES: + dump_bytes((const uint8_t *)entry->data, entry->len); + break; + case BINDESC_TYPE_DESCRIPTORS_END: + printk("Descriptors terminator\n"); + break; + default: + printk("\n"); + break; + } + + return 0; +} + +int main(void) +{ + size_t bindesc_offset = UINT16_MAX; + const uint32_t *version_number; + struct bindesc_handle handle; + uint8_t buffer[0x100]; + const uint8_t *bytes; + const char *version; + size_t size; + int retval; + size_t i; + + /* + * In a normal application, the offset of the descriptors should be constant and known, + * usually right after the vector table. It can easily be retrieved using + * ``west bindesc get_offset path/to/zephyr.bin``. + * This sample however is intended for multiple devices, and therefore just searches for + * the descriptors in order to remain generic. + */ + for (i = 0; i < UINT16_MAX; i += sizeof(void *)) { + if (*(uint64_t *)(CONFIG_FLASH_BASE_ADDRESS + i) == BINDESC_MAGIC) { + printk("Found descriptors at 0x%x\n", i); + bindesc_offset = i; + break; + } + } + if (i == UINT16_MAX) { + printk("Descriptors not found\n"); + return 1; + } + + printk("\n##################################\n"); + printk("Reading using memory mapped flash:\n"); + printk("##################################\n"); + + bindesc_open_memory_mapped_flash(&handle, bindesc_offset); + bindesc_foreach(&handle, dump_descriptors_callback, NULL); + + bindesc_find_str(&handle, BINDESC_ID_KERNEL_VERSION_STRING, &version); + printk("Zephyr version: %s\n", version); + + bindesc_get_size(&handle, &size); + printk("Bindesc size: %u\n", size); + + printk("\n##################\n"); + printk("Reading using RAM:\n"); + printk("##################\n"); + + flash_read(flash, bindesc_offset, buffer, sizeof(buffer)); + + bindesc_open_ram(&handle, buffer, sizeof(buffer)); + + /* Search for a non-existent descriptor */ + retval = bindesc_find_str(&handle, 123, &version); + if (retval) { + printk("Descriptor not found!\n"); + } + + bindesc_find_uint(&handle, BINDESC_ID_KERNEL_VERSION_MAJOR, &version_number); + printk("Zephyr version number: %u\n", *version_number); + + printk("\n####################\n"); + printk("Reading using flash:\n"); + printk("####################\n"); + + bindesc_open_flash(&handle, bindesc_offset, flash); + + bindesc_find_bytes(&handle, 3, &bytes, &size); + printk("my_bytes: "); + dump_bytes(bytes, size); + + return 0; +}