You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2026/10/28 16:25:55 UTC
(mynewt-core) 04/04: msc_fat_view: Build README.TXT from link table
This is an automated email from the ASF dual-hosted git repository.
kasjer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit b01f0d58ba398a74d114c4f59a235f193d0aebc1
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Tue Oct 27 19:48:16 2026 +0100
msc_fat_view: Build README.TXT from link table
README.TXT content was hardcoded in entry_readme.c and generated
with baselibc specific fmemopen_w(). Only first sector was ever
generated so longer content was read as zeros.
Now README.TXT is assembled from entries in msc_fat_view_readme
link table. Any package can add content with macros from
msc_fat_view/readme.h:
README_TEXT(pri, "text") - adds line of text
README_ENTRY(pri, fn, arg) - fn(out, arg) writes to out_stream
README_SYSCFG_STRING(pri, NAME) - adds line "NAME: <syscfg value>"
README_SYSCFG_INT(pri, NAME) - same for integer value
README_SYSCFG_HEX(pri, NAME) - same for integer value in hex
README_INT(pri, var) - adds line "var: <current value>"
README_HEX(pri, var) - same in hex
Each table entry is just a function and its argument, so rendering
calls entries in order without checking entry type. README_SYSCFG_xxx
and README_INT/HEX pass compound literal with name and value (or
variable address and size). Build fails if syscfg value or variable
type does not match the macro used.
pri becomes section name suffix so entries are sorted by linker
(e.g. 00, 01_1, 50).
README.TXT implementation is moved to msc_fat_view/readme package
pulled in when MSC_FAT_VIEW_DEFAULT_README is set. The package
defines constant MSC_FAT_VIEW_README, without it macros produce
nothing (only type checks remain), so they can be used
unconditionally. MSC_FAT_VIEW_DEFAULT_README_HEADER allows to skip
default header line and provide own with README_TEXT(00, ...).
Content is generated with util/stream so it works with any libc
and files longer than one sector are read correctly.
Default content is the same as before except:
- mcumgr hash is removed (mcumgr is no longer external repository)
- nimble line is only present when nimble repository is used
- 'Huge file' and firmware upgrade notes are added by
entry_huge_file.c and update_handler.c, upgrade note is now
shown only when update handler is present
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Jerzy Kasenberg <je...@codecoup.pl>
---
.../msc_fat_view/include/msc_fat_view/readme.h | 257 +++++++++++++++++++++
hw/usb/tinyusb/msc_fat_view/pkg.yml | 6 +-
hw/usb/tinyusb/msc_fat_view/readme/pkg.yml | 37 +++
hw/usb/tinyusb/msc_fat_view/readme/src/readme.c | 219 ++++++++++++++++++
hw/usb/tinyusb/msc_fat_view/readme/syscfg.yml | 39 ++++
hw/usb/tinyusb/msc_fat_view/src/entry_huge_file.c | 3 +
hw/usb/tinyusb/msc_fat_view/src/entry_readme.c | 168 --------------
hw/usb/tinyusb/msc_fat_view/src/update_handler.c | 5 +
hw/usb/tinyusb/msc_fat_view/syscfg.yml | 15 +-
9 files changed, 565 insertions(+), 184 deletions(-)
diff --git a/hw/usb/tinyusb/msc_fat_view/include/msc_fat_view/readme.h b/hw/usb/tinyusb/msc_fat_view/include/msc_fat_view/readme.h
new file mode 100644
index 000000000..9bbb2d0aa
--- /dev/null
+++ b/hw/usb/tinyusb/msc_fat_view/include/msc_fat_view/readme.h
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MSC_FAT_VIEW_README_H__
+#define __MSC_FAT_VIEW_README_H__
+
+#include <stdint.h>
+#include <syscfg/syscfg.h>
+#include <os/link_tables.h>
+#include <stream/stream.h>
+
+/*
+ * README.TXT content
+ *
+ * README.TXT is assembled from entries placed in link table
+ * msc_fat_view_readme. Any package can add entries with:
+ *
+ * README_TEXT(pri, "text") - adds line "text"
+ * README_ENTRY(pri, fn, arg) - fn(out, arg) writes content to stream
+ * README_SYSCFG_STRING(pri, NAME) - adds line "NAME: <value of syscfg NAME>"
+ * README_SYSCFG_INT(pri, NAME) - same for integer value (decimal)
+ * README_SYSCFG_HEX(pri, NAME) - same for integer value (hexadecimal)
+ * README_INT(pri, var) - adds line "var: <current value of var>"
+ * README_HEX(pri, var) - same in hexadecimal
+ *
+ * Entries are sorted by linker using pri as section name suffix.
+ * pri is any preprocessing number (00, 01_1, 30), it is compared as string,
+ * so numbers should have same number of digits. Order of entries with same
+ * pri is not specified, use README_ENTRY() for multi line content.
+ * Suggested values:
+ * 00 - header
+ * 10..19 - versions
+ * 50.. - syscfg values, application content
+ * 90.. - footer
+ *
+ * Entry is present only if object file that defines it is linked in.
+ * Entries are created only when msc_fat_view/readme package is in the
+ * build (MSC_FAT_VIEW_DEFAULT_README), otherwise macros produce nothing.
+ */
+
+/**
+ * Function that generates part of README.TXT
+ *
+ * Function is called every time README.TXT size or sector is computed,
+ * it must produce same output on each call.
+ *
+ * @param out - stream to write content to
+ * @param arg - argument from table entry
+ * @return number of bytes written, negative on error
+ */
+typedef int (*msc_fat_view_readme_fn_t)(struct out_stream *out, const void *arg);
+
+struct msc_fat_view_readme_entry {
+ /** Function that writes entry content */
+ msc_fat_view_readme_fn_t fn;
+ /** Argument passed to fn */
+ const void *arg;
+};
+
+LINK_TABLE(struct msc_fat_view_readme_entry, msc_fat_view_readme)
+
+/*
+ * Syscfg value check.
+ * Adjacent string literals concatenate, anything else is a syntax error.
+ * Bitwise or is not allowed for pointers.
+ */
+#define MSC_FAT_VIEW_README_STR_VAL(v) ("" v)
+#define MSC_FAT_VIEW_README_INT_VAL(v) ((v) | 0)
+
+/*
+ * Size of integer variable.
+ * Build fails (negative array size) if variable is wider than long,
+ * bitwise or fails if it is not an integer.
+ */
+#define MSC_FAT_VIEW_README_VAR_SIZE(var) \
+ (sizeof(var) + \
+ 0 * sizeof(char[sizeof((var) | 0) && sizeof(var) <= sizeof(long) ? 1 : -1]))
+
+#if MYNEWT_VAL(MSC_FAT_VIEW_README)
+
+struct msc_fat_view_readme_syscfg_str {
+ const char *name;
+ const char *value;
+};
+
+struct msc_fat_view_readme_syscfg_int {
+ const char *name;
+ long value;
+};
+
+struct msc_fat_view_readme_var {
+ const char *name;
+ const volatile void *ptr;
+ uint8_t size;
+ uint8_t is_signed;
+};
+
+/* Writes arg (const char *) followed by new line */
+int msc_fat_view_readme_text(struct out_stream *out, const void *arg);
+/* Writes "name: value" for struct msc_fat_view_readme_syscfg_str */
+int msc_fat_view_readme_syscfg_str(struct out_stream *out, const void *arg);
+/* Writes "name: value" for struct msc_fat_view_readme_syscfg_int */
+int msc_fat_view_readme_syscfg_int(struct out_stream *out, const void *arg);
+/* Writes "name: 0xvalue" for struct msc_fat_view_readme_syscfg_int */
+int msc_fat_view_readme_syscfg_hex(struct out_stream *out, const void *arg);
+/* Writes "name: value" for struct msc_fat_view_readme_var */
+int msc_fat_view_readme_var_int(struct out_stream *out, const void *arg);
+/* Writes "name: 0xvalue" for struct msc_fat_view_readme_var */
+int msc_fat_view_readme_var_hex(struct out_stream *out, const void *arg);
+
+#define MSC_FAT_VIEW_CAT_(a, b) a ## b
+#define MSC_FAT_VIEW_CAT(a, b) MSC_FAT_VIEW_CAT_(a, b)
+
+/* Explicit alignment prevents compiler from padding entries in table */
+#define MSC_FAT_VIEW_README_ELEMENT(pri, _fn, _arg) \
+ static const struct msc_fat_view_readme_entry \
+ MSC_FAT_VIEW_CAT(msc_fat_view_readme_, __COUNTER__) \
+ __attribute__((section(".msc_fat_view_readme." #pri), used, \
+ aligned(__alignof__(struct msc_fat_view_readme_entry)))) = \
+ { \
+ .fn = (_fn), \
+ .arg = (_arg) \
+ }
+
+/**
+ * Add text line to README.TXT
+ *
+ * @param pri - entry order
+ * @param text - text of the line (new line is added)
+ */
+#define README_TEXT(pri, text) \
+ MSC_FAT_VIEW_README_ELEMENT(pri, msc_fat_view_readme_text, text)
+
+/**
+ * Add generated content to README.TXT
+ *
+ * @param pri - entry order
+ * @param fn - function of type msc_fat_view_readme_fn_t
+ * @param arg - argument passed to fn
+ */
+#define README_ENTRY(pri, fn, arg) \
+ MSC_FAT_VIEW_README_ELEMENT(pri, fn, arg)
+
+#define MSC_FAT_VIEW_README_SYSCFG(pri, _fn, type, name, val) \
+ MSC_FAT_VIEW_README_ELEMENT(pri, _fn, (&(const struct type) { name, val }))
+
+/*
+ * README_SYSCFG_xxx paste setting name directly (MYNEWT_VAL_ ## name)
+ * so it works even when the same name is also defined as macro
+ * (e.g. OS_MAIN_STACK_SIZE).
+ */
+
+/**
+ * Add line "NAME: value" with string syscfg value to README.TXT
+ *
+ * Build fails if value is not a string.
+ *
+ * @param pri - entry order
+ * @param name - syscfg setting name (without MYNEWT_VAL)
+ */
+#define README_SYSCFG_STRING(pri, name) \
+ MSC_FAT_VIEW_README_SYSCFG(pri, msc_fat_view_readme_syscfg_str, \
+ msc_fat_view_readme_syscfg_str, #name, \
+ MSC_FAT_VIEW_README_STR_VAL(MYNEWT_VAL_ ## name))
+
+/**
+ * Add line "NAME: value" with decimal syscfg value to README.TXT
+ *
+ * Build fails if value is not an integer.
+ *
+ * @param pri - entry order
+ * @param name - syscfg setting name (without MYNEWT_VAL)
+ */
+#define README_SYSCFG_INT(pri, name) \
+ MSC_FAT_VIEW_README_SYSCFG(pri, msc_fat_view_readme_syscfg_int, \
+ msc_fat_view_readme_syscfg_int, #name, \
+ MSC_FAT_VIEW_README_INT_VAL(MYNEWT_VAL_ ## name))
+
+/**
+ * Add line "NAME: 0xvalue" with hexadecimal syscfg value to README.TXT
+ *
+ * Build fails if value is not an integer.
+ *
+ * @param pri - entry order
+ * @param name - syscfg setting name (without MYNEWT_VAL)
+ */
+#define README_SYSCFG_HEX(pri, name) \
+ MSC_FAT_VIEW_README_SYSCFG(pri, msc_fat_view_readme_syscfg_hex, \
+ msc_fat_view_readme_syscfg_int, #name, \
+ MSC_FAT_VIEW_README_INT_VAL(MYNEWT_VAL_ ## name))
+
+#define MSC_FAT_VIEW_README_VAR(pri, _fn, var) \
+ MSC_FAT_VIEW_README_ELEMENT(pri, _fn, \
+ (&(const struct msc_fat_view_readme_var) { \
+ #var, &(var), MSC_FAT_VIEW_README_VAR_SIZE(var), \
+ (__typeof__(var))-1 < 0 }))
+
+/**
+ * Add line "var: value" with decimal value of integer variable to README.TXT
+ *
+ * Variable is read every time README.TXT is generated, so line shows
+ * current value. Build fails if var is not an integer variable or is
+ * wider than long.
+ *
+ * @param pri - entry order
+ * @param var - integer variable (e.g. SystemCoreClock)
+ */
+#define README_INT(pri, var) \
+ MSC_FAT_VIEW_README_VAR(pri, msc_fat_view_readme_var_int, var)
+
+/**
+ * Add line "var: 0xvalue" with hexadecimal value of integer variable
+ * to README.TXT
+ *
+ * @param pri - entry order
+ * @param var - integer variable
+ */
+#define README_HEX(pri, var) \
+ MSC_FAT_VIEW_README_VAR(pri, msc_fat_view_readme_var_hex, var)
+
+#else
+
+/* fn and arg are referenced so they are not reported as unused */
+#define README_TEXT(pri, text) _Static_assert(1, "")
+#define README_ENTRY(pri, fn, arg) \
+ _Static_assert(sizeof(&(fn)) && sizeof(arg), "")
+/* Values are still checked so mismatch is reported in every build */
+#define README_SYSCFG_STRING(pri, name) \
+ _Static_assert(sizeof(MSC_FAT_VIEW_README_STR_VAL(MYNEWT_VAL_ ## name)), "")
+#define README_SYSCFG_INT(pri, name) \
+ _Static_assert(sizeof(MSC_FAT_VIEW_README_INT_VAL(MYNEWT_VAL_ ## name)), "")
+#define README_SYSCFG_HEX(pri, name) \
+ _Static_assert(sizeof(MSC_FAT_VIEW_README_INT_VAL(MYNEWT_VAL_ ## name)), "")
+#define README_INT(pri, var) \
+ _Static_assert(MSC_FAT_VIEW_README_VAR_SIZE(var), "")
+#define README_HEX(pri, var) \
+ _Static_assert(MSC_FAT_VIEW_README_VAR_SIZE(var), "")
+
+#endif
+
+#endif /* __MSC_FAT_VIEW_README_H__ */
diff --git a/hw/usb/tinyusb/msc_fat_view/pkg.yml b/hw/usb/tinyusb/msc_fat_view/pkg.yml
index 97d72b9e8..198628afc 100644
--- a/hw/usb/tinyusb/msc_fat_view/pkg.yml
+++ b/hw/usb/tinyusb/msc_fat_view/pkg.yml
@@ -36,6 +36,9 @@ pkg.deps:
pkg.deps.MSC_FAT_VIEW_CONFIG:
- "@apache-mynewt-core/sys/config"
+pkg.deps.MSC_FAT_VIEW_DEFAULT_README:
+ - "@apache-mynewt-core/hw/usb/tinyusb/msc_fat_view/readme"
+
pkg.deps.MSC_FAT_VIEW_COREDUMP_FILES:
- "@apache-mynewt-core/sys/coredump"
@@ -47,9 +50,6 @@ pkg.whole_archive: true
pkg.source_files.MSC_FAT_VIEW_COREDUMP_FILES:
- src/coredump_files.c
-pkg.source_files.MSC_FAT_VIEW_DEFAULT_README:
- - src/entry_readme.c
-
pkg.source_files.MSC_FAT_VIEW_HUGE_FILE:
- src/entry_huge_file.c
diff --git a/hw/usb/tinyusb/msc_fat_view/readme/pkg.yml b/hw/usb/tinyusb/msc_fat_view/readme/pkg.yml
new file mode 100644
index 000000000..9d594bfd3
--- /dev/null
+++ b/hw/usb/tinyusb/msc_fat_view/readme/pkg.yml
@@ -0,0 +1,37 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/usb/tinyusb/msc_fat_view/readme
+pkg.description: README.TXT file for msc_fat_view assembled from link table
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+ - msc
+ - usb
+
+pkg.deps:
+ - "@apache-mynewt-core/hw/usb/tinyusb/msc_fat_view"
+ - "@apache-mynewt-core/sys/flash_map"
+ - "@apache-mynewt-core/util/stream"
+ - "@mcuboot/boot/bootutil"
+
+pkg.whole_archive: true
+
+pkg.link_tables:
+ - msc_fat_view_readme
diff --git a/hw/usb/tinyusb/msc_fat_view/readme/src/readme.c b/hw/usb/tinyusb/msc_fat_view/readme/src/readme.c
new file mode 100644
index 000000000..afa9de949
--- /dev/null
+++ b/hw/usb/tinyusb/msc_fat_view/readme/src/readme.c
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string.h>
+#include <sysflash/sysflash.h>
+#include <flash_map/flash_map.h>
+#include <bootutil/image.h>
+#include <stream/stream.h>
+#include <msc_fat_view/msc_fat_view.h>
+#include <msc_fat_view/readme.h>
+#include <modlog/modlog.h>
+
+#if MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README_HEADER)
+README_TEXT(00, "This device runs " MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README_APP_NAME)
+ " on " MYNEWT_VAL(BSP_NAME));
+#endif
+
+#if MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README_VERSION)
+static int
+readme_app_version(struct out_stream *out, const void *arg)
+{
+ struct image_header image_header;
+ const struct flash_area *fa;
+ int rc = 0;
+
+ if (flash_area_open(FLASH_AREA_IMAGE_0, &fa) == 0) {
+ if (flash_area_read(fa, 0, &image_header, sizeof(image_header)) == 0 &&
+ image_header.ih_magic == IMAGE_MAGIC) {
+ rc = ostream_printf(out, "\nApp version: %u.%u.%u.%u\n",
+ image_header.ih_ver.iv_major,
+ image_header.ih_ver.iv_minor,
+ image_header.ih_ver.iv_revision,
+ (unsigned)image_header.ih_ver.iv_build_num);
+ }
+ flash_area_close(fa);
+ }
+
+ return rc;
+}
+
+README_ENTRY(10, readme_app_version, NULL);
+#endif
+
+#if MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README_INCLUDE_HASHES)
+
+#if defined MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE
+#define REPO_VERSION_APACHE_MYNEWT_CORE MYNEWT_VAL(REPO_VERSION_APACHE_MYNEWT_CORE)
+#else
+#define REPO_VERSION_APACHE_MYNEWT_CORE "unknown"
+#endif
+
+#if defined MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE
+#define REPO_HASH_APACHE_MYNEWT_CORE MYNEWT_VAL(REPO_HASH_APACHE_MYNEWT_CORE)
+#else
+#define REPO_HASH_APACHE_MYNEWT_CORE ""
+#endif
+
+#if defined MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE
+#define REPO_HASH_APACHE_MYNEWT_NIMBLE MYNEWT_VAL(REPO_HASH_APACHE_MYNEWT_NIMBLE)
+#else
+#define REPO_HASH_APACHE_MYNEWT_NIMBLE ""
+#endif
+
+#if defined MYNEWT_VAL_REPO_VERSION_TINYUSB
+#define REPO_VERSION_TINYUSB MYNEWT_VAL(REPO_VERSION_TINYUSB)
+#else
+#define REPO_VERSION_TINYUSB "unknown"
+#endif
+
+#if defined MYNEWT_VAL_REPO_HASH_TINYUSB
+#define REPO_HASH_TINYUSB MYNEWT_VAL(REPO_HASH_TINYUSB)
+#else
+#define REPO_HASH_TINYUSB ""
+#endif
+
+static const char readme_hashes[] =
+ "\nmynewt: " REPO_VERSION_APACHE_MYNEWT_CORE " " REPO_HASH_APACHE_MYNEWT_CORE "\n"
+#if defined MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE
+ "nimble: " MYNEWT_VAL(REPO_VERSION_APACHE_MYNEWT_NIMBLE) " " REPO_HASH_APACHE_MYNEWT_NIMBLE "\n"
+#endif
+ "tinyusb: " REPO_VERSION_TINYUSB " " REPO_HASH_TINYUSB "\n";
+
+static int
+readme_repo_hashes(struct out_stream *out, const void *arg)
+{
+ return ostream_write(out, (const uint8_t *)readme_hashes,
+ sizeof(readme_hashes) - 1, false);
+}
+
+README_ENTRY(20, readme_repo_hashes, NULL);
+#endif
+
+int
+msc_fat_view_readme_text(struct out_stream *out, const void *arg)
+{
+ ostream_write_str(out, arg);
+
+ return ostream_write_str(out, "\n");
+}
+
+int
+msc_fat_view_readme_syscfg_str(struct out_stream *out, const void *arg)
+{
+ const struct msc_fat_view_readme_syscfg_str *syscfg = arg;
+
+ ostream_write_str(out, syscfg->name);
+ ostream_write_str(out, ": ");
+ ostream_write_str(out, syscfg->value);
+
+ return ostream_write_str(out, "\n");
+}
+
+int
+msc_fat_view_readme_syscfg_int(struct out_stream *out, const void *arg)
+{
+ const struct msc_fat_view_readme_syscfg_int *syscfg = arg;
+
+ return ostream_printf(out, "%s: %ld\n", syscfg->name, syscfg->value);
+}
+
+int
+msc_fat_view_readme_syscfg_hex(struct out_stream *out, const void *arg)
+{
+ const struct msc_fat_view_readme_syscfg_int *syscfg = arg;
+
+ return ostream_printf(out, "%s: 0x%lx\n", syscfg->name,
+ (unsigned long)syscfg->value);
+}
+
+/* Variable value zero extended to unsigned long */
+static unsigned long
+readme_var_read(const struct msc_fat_view_readme_var *var)
+{
+ switch (var->size) {
+ case 1:
+ return *(const volatile uint8_t *)var->ptr;
+ case 2:
+ return *(const volatile uint16_t *)var->ptr;
+ case 4:
+ return *(const volatile uint32_t *)var->ptr;
+ default:
+ return *(const volatile unsigned long *)var->ptr;
+ }
+}
+
+int
+msc_fat_view_readme_var_int(struct out_stream *out, const void *arg)
+{
+ const struct msc_fat_view_readme_var *var = arg;
+ unsigned long value = readme_var_read(var);
+ unsigned int bits = var->size * 8;
+
+ if (var->is_signed) {
+ /* Sign extend values narrower than long */
+ if (bits < sizeof(long) * 8 && (value >> (bits - 1)) & 1) {
+ value |= ~0UL << bits;
+ }
+ return ostream_printf(out, "%s: %ld\n", var->name, (long)value);
+ }
+
+ return ostream_printf(out, "%s: %lu\n", var->name, value);
+}
+
+int
+msc_fat_view_readme_var_hex(struct out_stream *out, const void *arg)
+{
+ const struct msc_fat_view_readme_var *var = arg;
+
+ return ostream_printf(out, "%s: 0x%lx\n", var->name, readme_var_read(var));
+}
+
+static void
+readme_render(struct out_stream *out)
+{
+ LINK_TABLE_FOREACH(entry, msc_fat_view_readme) {
+ entry->fn(out, entry->arg);
+ }
+}
+
+static uint32_t
+readme_size(const file_entry_t *file_entry)
+{
+ struct mem_out_stream mem;
+
+ msc_fat_view_sector_stream_init(&mem, NULL, 0);
+ readme_render((struct out_stream *)&mem);
+
+ return mem.write_ptr;
+}
+
+static void
+readme_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512])
+{
+ struct mem_out_stream mem;
+
+ MSC_FAT_VIEW_LOG_DEBUG("Readme read %d\n", file_sector);
+ memset(buffer, 0, 512);
+ msc_fat_view_sector_stream_init(&mem, buffer, file_sector);
+ readme_render((struct out_stream *)&mem);
+}
+
+ROOT_DIR_ENTRY(readme, "README.TXT", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY,
+ readme_size, readme_read, NULL, NULL, NULL);
diff --git a/hw/usb/tinyusb/msc_fat_view/readme/syscfg.yml b/hw/usb/tinyusb/msc_fat_view/readme/syscfg.yml
new file mode 100644
index 000000000..4f85e0ed6
--- /dev/null
+++ b/hw/usb/tinyusb/msc_fat_view/readme/syscfg.yml
@@ -0,0 +1,39 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+ MSC_FAT_VIEW_README: 1
+ MSC_FAT_VIEW_DEFAULT_README_HEADER:
+ description: >
+ If set to 1, README.TXT starts with default header line
+ "This device runs <MSC_FAT_VIEW_DEFAULT_README_APP_NAME> on <BSP_NAME>".
+ Set to 0 to provide own header with README_TEXT(00, "...").
+ value: 1
+ MSC_FAT_VIEW_DEFAULT_README_VERSION:
+ description: >
+ If set to 1, README.TXT will have application version number.
+ value: 1
+ MSC_FAT_VIEW_DEFAULT_README_APP_NAME:
+ description: >
+ Application name that will be put in default README.TXT.
+ value: MYNEWT_VAL(APP_NAME)
+ MSC_FAT_VIEW_DEFAULT_README_INCLUDE_HASHES:
+ description: >
+ Add git hashes into README.TXT.
+ value: 1
diff --git a/hw/usb/tinyusb/msc_fat_view/src/entry_huge_file.c b/hw/usb/tinyusb/msc_fat_view/src/entry_huge_file.c
index 371ebb532..d7321457c 100644
--- a/hw/usb/tinyusb/msc_fat_view/src/entry_huge_file.c
+++ b/hw/usb/tinyusb/msc_fat_view/src/entry_huge_file.c
@@ -21,6 +21,7 @@
#include <string.h>
#include <sysflash/sysflash.h>
#include <msc_fat_view/msc_fat_view.h>
+#include <msc_fat_view/readme.h>
#include <bootutil/image.h>
#if MYNEWT_VAL(MSC_FAT_VIEW_HUGE_FILE_SIZE) > 0
@@ -51,3 +52,5 @@ huge_file_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buf
}
ROOT_DIR_ENTRY(huge_file, "Huge file", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, huge_file_size, huge_file_read, NULL, NULL, NULL);
+
+README_TEXT(80, "\n'Huge file' can be used to verify USB performance.");
diff --git a/hw/usb/tinyusb/msc_fat_view/src/entry_readme.c b/hw/usb/tinyusb/msc_fat_view/src/entry_readme.c
deleted file mode 100644
index fcd59efb0..000000000
--- a/hw/usb/tinyusb/msc_fat_view/src/entry_readme.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <assert.h>
-#include <ctype.h>
-#include <os/endian.h>
-#include <bsp/bsp.h>
-#include <sysflash/sysflash.h>
-#include <hal/hal_gpio.h>
-#include <os/util.h>
-#include <tusb.h>
-#include <class/msc/msc.h>
-#include <class/msc/msc_device.h>
-#include <tinyusb/tinyusb.h>
-#include <msc_fat_view/msc_fat_view.h>
-#include <img_mgmt/img_mgmt.h>
-#include <bootutil/image.h>
-#include <modlog/modlog.h>
-#include <hal/hal_flash.h>
-#include <console/console.h>
-#include "coredump_files.h"
-
-#if MYNEWT_VAL(BOOT_LOADER)
-#define BOOT_LOADER 1
-#define FLASH_AREA_IMAGE FLASH_AREA_IMAGE_0
-#else
-#define BOOT_LOADER 0
-#ifdef FLASH_AREA_IMAGE_1
-#define FLASH_AREA_IMAGE FLASH_AREA_IMAGE_1
-#endif
-#endif
-
-static const char readme_text[] = "This device runs "
- MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README_APP_NAME) " on "
- MYNEWT_VAL(BSP_NAME);
-
-#if defined MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE
-#define REPO_VERSION_APACHE_MYNEWT_CORE MYNEWT_VAL(REPO_VERSION_APACHE_MYNEWT_CORE)
-#else
-#define REPO_VERSION_APACHE_MYNEWT_CORE "unknown"
-#endif
-
-#if defined MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE
-#define REPO_HASH_APACHE_MYNEWT_CORE MYNEWT_VAL(REPO_HASH_APACHE_MYNEWT_CORE)
-#else
-#define REPO_HASH_APACHE_MYNEWT_CORE ""
-#endif
-
-#if defined MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE
-#define REPO_VERSION_APACHE_MYNEWT_NIMBLE MYNEWT_VAL(REPO_VERSION_APACHE_MYNEWT_NIMBLE)
-#else
-#define REPO_VERSION_APACHE_MYNEWT_NIMBLE "unknown"
-#endif
-
-#if defined MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE
-#define REPO_HASH_APACHE_MYNEWT_NIMBLE MYNEWT_VAL(REPO_HASH_APACHE_MYNEWT_NIMBLE)
-#else
-#define REPO_HASH_APACHE_MYNEWT_NIMBLE ""
-#endif
-
-#if defined MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_MCUMGR
-#define REPO_VERSION_APACHE_MYNEWT_MCUMGR MYNEWT_VAL(REPO_VERSION_APACHE_MYNEWT_MCUMGR)
-#else
-#define REPO_VERSION_APACHE_MYNEWT_MCUMGR "unknown"
-#endif
-
-#if defined MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR
-#define REPO_HASH_APACHE_MYNEWT_MCUMGR MYNEWT_VAL(REPO_HASH_APACHE_MYNEWT_MCUMGR)
-#else
-#define REPO_HASH_APACHE_MYNEWT_MCUMGR ""
-#endif
-
-#if defined MYNEWT_VAL_REPO_VERSION_TINYUSB
-#define REPO_VERSION_TINYUSB MYNEWT_VAL(REPO_VERSION_TINYUSB)
-#else
-#define REPO_VERSION_TINYUSB "unknown"
-#endif
-
-#if defined MYNEWT_VAL_REPO_HASH_TINYUSB
-#define REPO_HASH_TINYUSB MYNEWT_VAL(REPO_HASH_TINYUSB)
-#else
-#define REPO_HASH_TINYUSB ""
-#endif
-
-static int
-readme_create_content(struct MemFile *file)
-{
- struct image_header image_header;
- const struct flash_area *fa;
-
- fwrite(readme_text, 1, sizeof(readme_text) - 1, &file->file);
-
- if (MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README_VERSION) && 0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) {
- flash_area_read(fa, 0, &image_header, sizeof(image_header));
- if (image_header.ih_magic == IMAGE_MAGIC) {
- fprintf(&file->file, "\n\nApp version: %u.%u.%u.%u\n", image_header.ih_ver.iv_major,
- image_header.ih_ver.iv_minor,
- image_header.ih_ver.iv_revision,
- (unsigned)image_header.ih_ver.iv_build_num);
- }
- flash_area_close(fa);
- }
-
- if (MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README_INCLUDE_HASHES)) {
- fprintf(&file->file, "\n\nmynewt: " REPO_VERSION_APACHE_MYNEWT_CORE " " REPO_HASH_APACHE_MYNEWT_CORE);
- fprintf(&file->file, "\nnimble: " REPO_VERSION_APACHE_MYNEWT_NIMBLE " " REPO_HASH_APACHE_MYNEWT_NIMBLE);
- fprintf(&file->file, "\nmcumgr: " REPO_VERSION_APACHE_MYNEWT_MCUMGR " " REPO_HASH_APACHE_MYNEWT_MCUMGR);
- fprintf(&file->file, "\ntinyusb: " REPO_VERSION_TINYUSB " " REPO_HASH_TINYUSB);
- }
- if (MYNEWT_VAL(MSC_FAT_VIEW_HUGE_FILE)) {
- fprintf(&file->file, "\n\n'Huge file' can be used to verify USB performance.\n");
- }
-
-#ifdef FLASH_AREA_IMAGE
- fprintf(&file->file, "\n\nNew firmware can be copied to this drive (drag-drop .img file to upgrade device).\n");
-#endif
-
- return file->bytes_written;
-}
-
-static uint32_t
-readme_size(const file_entry_t *file_entry)
-{
- (void)file_entry;
- struct MemFile empty_mem_file;
- uint32_t len;
-
- fmemopen_w(&empty_mem_file, (char *)NULL, 0);
- len = readme_create_content(&empty_mem_file);
-
- return len;
-}
-
-static void
-readme_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512])
-{
- struct MemFile sector_file;
- int written = 0;
- (void)entry;
-
- MSC_FAT_VIEW_LOG_DEBUG("Readme read %d\n", file_sector);
- if (file_sector == 0) {
- fmemopen_w(§or_file, (char *)buffer, 512);
- readme_create_content(§or_file);
- written = sector_file.bytes_written;
- }
-
- memset(buffer + written, 0, 512 - written);
-}
-
-ROOT_DIR_ENTRY(readme, "README.TXT", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, readme_size, readme_read, NULL, NULL, NULL);
-
diff --git a/hw/usb/tinyusb/msc_fat_view/src/update_handler.c b/hw/usb/tinyusb/msc_fat_view/src/update_handler.c
index 517c6c6b3..96cd2fec7 100644
--- a/hw/usb/tinyusb/msc_fat_view/src/update_handler.c
+++ b/hw/usb/tinyusb/msc_fat_view/src/update_handler.c
@@ -25,6 +25,7 @@
#include <tusb.h>
#include <class/msc/msc.h>
#include <msc_fat_view/msc_fat_view.h>
+#include <msc_fat_view/readme.h>
#include <img_mgmt/img_mgmt.h>
#include <bootutil/image.h>
#include <modlog/modlog.h>
@@ -313,3 +314,7 @@ invalid_fun(const struct file_entry *entry)
}
ROOT_DIR_ENTRY(ghost_entry, "", 0, NULL, NULL, NULL, NULL, invalid_fun);
+
+#ifdef FLASH_AREA_IMAGE
+README_TEXT(90, "\nNew firmware can be copied to this drive (drag-drop .img file to upgrade device).");
+#endif
diff --git a/hw/usb/tinyusb/msc_fat_view/syscfg.yml b/hw/usb/tinyusb/msc_fat_view/syscfg.yml
index 2635bbec3..608229cf8 100644
--- a/hw/usb/tinyusb/msc_fat_view/syscfg.yml
+++ b/hw/usb/tinyusb/msc_fat_view/syscfg.yml
@@ -87,19 +87,8 @@ syscfg.defs:
value: 1
MSC_FAT_VIEW_DEFAULT_README:
description: >
- If set to 1, adds default 'README.TXT' file with some basic information about firmware.
- value: 1
- MSC_FAT_VIEW_DEFAULT_README_VERSION:
- description: >
- If set to 1, README.TXT will have application version number.
- value: 1
- MSC_FAT_VIEW_DEFAULT_README_APP_NAME:
- description: >
- Application name that will be put in default README.TXT.
- value: MYNEWT_VAL(APP_NAME)
- MSC_FAT_VIEW_DEFAULT_README_INCLUDE_HASHES:
- description: >
- Add git hashes into README.TXT.
+ If set to 1, adds default 'README.TXT' file with some basic information
+ about firmware (pulls in msc_fat_view/readme package).
value: 1
MSC_FAT_VIEW_DROP_IMAGE_HERE:
description: >