From 5c75a234907daed975a530f51f5ab9638acc77ae Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 25 Apr 2024 15:27:16 +0200 Subject: [PATCH 1/3] tinyusb/msc_fat_view: Use link_tables for root entries This change extract several FAT root entries definitions to separate files so it's easier to see how to make custom entries. This feature utilized newt tool features: - link time tables (used for root dir entries) - pkg.whole_archive switch that forces to search whole archive - pkg.source_files (now package files are selected separately) Signed-off-by: Jerzy Kasenberg --- .../include/msc_fat_view/msc_fat_view.h | 16 + hw/usb/tinyusb/msc_fat_view/pkg.yml | 20 ++ .../msc_fat_view/src/entry_huge_file.c | 52 +++ .../msc_fat_view/src/entry_mynewt_htm.c | 54 +++ .../tinyusb/msc_fat_view/src/entry_readme.c | 168 ++++++++++ hw/usb/tinyusb/msc_fat_view/src/entry_slot0.c | 61 ++++ .../msc_fat_view/src/entry_slot0_hex.c | 83 +++++ .../tinyusb/msc_fat_view/src/msc_fat_view.c | 316 +----------------- 8 files changed, 462 insertions(+), 308 deletions(-) create mode 100644 hw/usb/tinyusb/msc_fat_view/src/entry_huge_file.c create mode 100644 hw/usb/tinyusb/msc_fat_view/src/entry_mynewt_htm.c create mode 100644 hw/usb/tinyusb/msc_fat_view/src/entry_readme.c create mode 100644 hw/usb/tinyusb/msc_fat_view/src/entry_slot0.c create mode 100644 hw/usb/tinyusb/msc_fat_view/src/entry_slot0_hex.c diff --git a/hw/usb/tinyusb/msc_fat_view/include/msc_fat_view/msc_fat_view.h b/hw/usb/tinyusb/msc_fat_view/include/msc_fat_view/msc_fat_view.h index 9b7f23cf34..77e4252891 100644 --- a/hw/usb/tinyusb/msc_fat_view/include/msc_fat_view/msc_fat_view.h +++ b/hw/usb/tinyusb/msc_fat_view/include/msc_fat_view/msc_fat_view.h @@ -71,4 +71,20 @@ void msc_fat_view_media_eject(void); */ void msc_fat_view_media_insert(void); +/* Section name for root entries */ +#define ROOT_DIR_SECTION __attribute__((section(".msc_fat_view_root_entry"), used)) + +/** + * Macro to add static root entries + */ +#define ROOT_DIR_ENTRY(entry, file_name, attr, size_fun, read_fun, write_fun, delete_fun) \ +const file_entry_t entry ROOT_DIR_SECTION = { \ + .name = file_name, \ + .attributes = attr, \ + .size = size_fun, \ + .read_sector = read_fun, \ + .write_sector = write_fun, \ + .delete_entry = delete_fun, \ +} + #endif /* __MSC_FAT_VIEW_H__ */ diff --git a/hw/usb/tinyusb/msc_fat_view/pkg.yml b/hw/usb/tinyusb/msc_fat_view/pkg.yml index a831a43843..51355fdf1a 100644 --- a/hw/usb/tinyusb/msc_fat_view/pkg.yml +++ b/hw/usb/tinyusb/msc_fat_view/pkg.yml @@ -38,9 +38,29 @@ pkg.deps.MSC_FAT_VIEW_COREDUMP_FILES: pkg.source_files: - src/msc_fat_view.c +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 + +pkg.source_files.MSC_FAT_VIEW_SLOT0_IMAGE: + - src/entry_slot0.c + +pkg.source_files.MSC_FAT_VIEW_SLOT0_HEX: + - src/entry_slot0_hex.c + +pkg.source_files.MSC_FAT_VIEW_MYNEWT_SHORTCUT: + - src/entry_mynewt_htm.c + +pkg.link_tables: + - msc_fat_view_root_entry + pkg.init.'(!BOOT_LOADER && TINYUSB_AUTO_START!=0)': msc_fat_view_pkg_init: $before:tinyusb_start 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 new file mode 100644 index 0000000000..c6888f21f5 --- /dev/null +++ b/hw/usb/tinyusb/msc_fat_view/src/entry_huge_file.c @@ -0,0 +1,52 @@ +/* + * 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 +#include +#include +#include + +#if MYNEWT_VAL(MSC_FAT_VIEW_HUGE_FILE_SIZE) > 0 +#define HUGE_FILE_SIZE MYNEWT_VAL(MSC_FAT_VIEW_HUGE_FILE_SIZE) +#if HUGE_FILE_SIZE > (MYNEWT_VAL(MSC_FAT_VIEW_DISK_SIZE) * 1024) + 2000000 +#error HUGE_FILE_SIZE is to big for specified disk size +#endif +#elif (MYNEWT_VAL(MSC_FAT_VIEW_DISK_SIZE) * 1024) < 2000000 +#error No space for huge file, increase MSC_FAT_VIEW_DISK_SIZE in syscfg +#else +#define HUGE_FILE_SIZE ((MYNEWT_VAL(MSC_FAT_VIEW_DISK_SIZE) * 1024) - 2000000) +#endif + +static uint32_t +huge_file_size(const file_entry_t *file) +{ + (void)file; + + return HUGE_FILE_SIZE; +} + +static void +huge_file_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) +{ + (void)entry; + + memset(buffer, (uint8_t)file_sector, 512); +} + +ROOT_DIR_ENTRY(huge_file, "Huge file", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, huge_file_size, huge_file_read, NULL, NULL); diff --git a/hw/usb/tinyusb/msc_fat_view/src/entry_mynewt_htm.c b/hw/usb/tinyusb/msc_fat_view/src/entry_mynewt_htm.c new file mode 100644 index 0000000000..b455e685b5 --- /dev/null +++ b/hw/usb/tinyusb/msc_fat_view/src/entry_mynewt_htm.c @@ -0,0 +1,54 @@ +/* + * 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 +#include + +static const char mynewt_htm_text[] = + "\n" + "\n" + "\n" + "\n" + "mynewt Website Shortcut\n" + "\n" + "\n" + ""; + +static uint32_t +mynewt_htm_size(const file_entry_t *file) +{ + (void)file; + + return strlen(mynewt_htm_text); +} + +static void +mynewt_htm_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) +{ + (void)entry; + + if (file_sector == 0) { + strcpy((char *)buffer, mynewt_htm_text); + memset(buffer + 512 - sizeof(mynewt_htm_text), 0, sizeof(mynewt_htm_text)); + } else { + memset(buffer, 0, 512); + } +} + +ROOT_DIR_ENTRY(mynew_htm, "MYNEWT.HTM", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, mynewt_htm_size, mynewt_htm_read, NULL, NULL); diff --git a/hw/usb/tinyusb/msc_fat_view/src/entry_readme.c b/hw/usb/tinyusb/msc_fat_view/src/entry_readme.c new file mode 100644 index 0000000000..673dfd75b0 --- /dev/null +++ b/hw/usb/tinyusb/msc_fat_view/src/entry_readme.c @@ -0,0 +1,168 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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); + diff --git a/hw/usb/tinyusb/msc_fat_view/src/entry_slot0.c b/hw/usb/tinyusb/msc_fat_view/src/entry_slot0.c new file mode 100644 index 0000000000..8e0d25d9cc --- /dev/null +++ b/hw/usb/tinyusb/msc_fat_view/src/entry_slot0.c @@ -0,0 +1,61 @@ +/* + * 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 +#include +#include +#include + +static uint32_t +slot0_img_size(const file_entry_t *file) +{ + struct image_header image_header; + struct image_tlv_info tlv_info; + uint32_t size = 0; + const struct flash_area *fa; + (void)file; + + if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { + flash_area_read(fa, 0, &image_header, sizeof(image_header)); + size = image_header.ih_img_size + image_header.ih_hdr_size; + flash_area_read(fa, size, &tlv_info, sizeof(tlv_info)); + if (tlv_info.it_magic == IMAGE_TLV_INFO_MAGIC) { + size += tlv_info.it_tlv_tot; + } + flash_area_close(fa); + } + + return size; +} + +static void +slot0_img_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) +{ + const struct flash_area *fa; + uint32_t addr; + (void)entry; + + if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { + addr = file_sector * 512; + flash_area_read(fa, addr, buffer, 512); + flash_area_close(fa); + } +} + +ROOT_DIR_ENTRY(slot0, "FIRMWARE.IMG", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, slot0_img_size, slot0_img_read, NULL, NULL); diff --git a/hw/usb/tinyusb/msc_fat_view/src/entry_slot0_hex.c b/hw/usb/tinyusb/msc_fat_view/src/entry_slot0_hex.c new file mode 100644 index 0000000000..4751d2486c --- /dev/null +++ b/hw/usb/tinyusb/msc_fat_view/src/entry_slot0_hex.c @@ -0,0 +1,83 @@ +/* + * 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 +#include +#include +#include + +static uint32_t +slot0_hex_size(const file_entry_t *file) +{ + uint32_t size = 0; + const struct flash_area *fa; + (void)file; + + if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { + size = fa->fa_size * 4; + flash_area_close(fa); + } + + return size; +} + +static uint8_t +hex_digit(int v) +{ + v &= 0xF; + + return (v < 10) ? (v + '0') : (v + 'A' - 10); +} + +static void +slot0_hex_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) +{ + const struct flash_area *fa; + int i; + int j; + int k; + uint32_t addr = (file_sector * 512) / 4; + uint32_t addr_buf; + (void)entry; + + if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { + flash_area_read(fa, addr, buffer, 512 / 4); + flash_area_close(fa); + for (i = 512, j = 128; i > 0;) { + buffer[--i] = '\n'; + buffer[--i] = '\r'; + for (k = 0; k < 16; ++k) { + buffer[--i] = hex_digit(buffer[--j]); + buffer[--i] = hex_digit(buffer[j] >> 4); + buffer[--i] = ' '; + } + for (k = 0; k < 5; ++k) { + buffer[--i] = ' '; + } + buffer[--i] = ':'; + addr_buf = addr + j; + for (k = 0; k < 8; ++k) { + buffer[--i] = hex_digit(addr_buf); + addr_buf >>= 4; + } + } + } +} + +ROOT_DIR_ENTRY(slot0_hex, "SLOT0.HEX", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, slot0_hex_size, slot0_hex_read, NULL, NULL); diff --git a/hw/usb/tinyusb/msc_fat_view/src/msc_fat_view.c b/hw/usb/tinyusb/msc_fat_view/src/msc_fat_view.c index 6fcedbcf6d..1cc6c7460d 100644 --- a/hw/usb/tinyusb/msc_fat_view/src/msc_fat_view.c +++ b/hw/usb/tinyusb/msc_fat_view/src/msc_fat_view.c @@ -41,9 +41,8 @@ #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 -#ifndef FLASH_AREA_IMAGE_1 -#error No FLASH_AREA_IMAGE_1 in bsp.yml #endif #endif @@ -265,275 +264,6 @@ static const file_entry_t volume_label = { .read_sector = empty_read, }; -static const char mynewt_htm_text[] = - "\n" - "\n" - "\n" - "\n" - "mynewt Website Shortcut\n" - "\n" - "\n" - ""; - -static uint32_t -mynewt_htm_size(const file_entry_t *file) -{ - (void)file; - - return strlen(mynewt_htm_text); -} - -static void -mynewt_htm_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) -{ - (void)entry; - - if (file_sector == 0) { - strcpy((char *)buffer, mynewt_htm_text); - memset(buffer + 512 - sizeof(mynewt_htm_text), 0, sizeof(mynewt_htm_text)); - } else { - memset(buffer, 0, 512); - } -} - -static const file_entry_t mynew_htm = { - .name = "MYNEWT.HTM", - .attributes = FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, - .size = mynewt_htm_size, - .read_sector = mynewt_htm_read, -}; - -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"); - } - - fprintf(&file->file, "\n\nNew firmware can be copied to this drive (drag-drop .img file to upgrade device).\n"); - - 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); -} - -static const file_entry_t readme = { - .name = "README.TXT", - .attributes = FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, - .size = readme_size, - .read_sector = readme_read, -}; - -static uint32_t -slot0_img_size(const file_entry_t *file) -{ - struct image_header image_header; - struct image_tlv_info tlv_info; - uint32_t size = 0; - const struct flash_area *fa; - (void)file; - - if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { - flash_area_read(fa, 0, &image_header, sizeof(image_header)); - size = image_header.ih_img_size + image_header.ih_hdr_size; - flash_area_read(fa, size, &tlv_info, sizeof(tlv_info)); - if (tlv_info.it_magic == IMAGE_TLV_INFO_MAGIC) { - size += tlv_info.it_tlv_tot; - } - flash_area_close(fa); - } - - return size; -} - -static void -slot0_img_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) -{ - const struct flash_area *fa; - uint32_t addr; - (void)entry; - - if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { - addr = file_sector * 512; - flash_area_read(fa, addr, buffer, 512); - flash_area_close(fa); - } -} - -static const file_entry_t slot0 = { - .name = "FIRMWARE.IMG", - .attributes = FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, - .size = slot0_img_size, - .read_sector = slot0_img_read, -}; - -static uint32_t -slot0_hex_size(const file_entry_t *file) -{ - uint32_t size = 0; - const struct flash_area *fa; - (void)file; - - if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { - size = fa->fa_size * 4; - flash_area_close(fa); - } - - return size; -} - -static uint8_t -hex_digit(int v) -{ - v &= 0xF; - - return (v < 10) ? (v + '0') : (v + 'A' - 10); -} - -static void -slot0_hex_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) -{ - const struct flash_area *fa; - int i; - int j; - int k; - uint32_t addr = (file_sector * 512) / 4; - uint32_t addr_buf; - (void)entry; - - if (0 == flash_area_open(FLASH_AREA_IMAGE_0, &fa)) { - flash_area_read(fa, addr, buffer, 512 / 4); - flash_area_close(fa); - for (i = 512, j = 128; i > 0;) { - buffer[--i] = '\n'; - buffer[--i] = '\r'; - for (k = 0; k < 16; ++k) { - buffer[--i] = hex_digit(buffer[--j]); - buffer[--i] = hex_digit(buffer[j] >> 4); - buffer[--i] = ' '; - } - for (k = 0; k < 5; ++k) { - buffer[--i] = ' '; - } - buffer[--i] = ':'; - addr_buf = addr + j; - for (k = 0; k < 8; ++k) { - buffer[--i] = hex_digit(addr_buf); - addr_buf >>= 4; - } - } - } -} - -static const file_entry_t slot0_hex = { - .name = "SLOT0.HEX", - .attributes = FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, - .size = slot0_hex_size, - .read_sector = slot0_hex_read, -}; - static const file_entry_t system_volume_information = { .name = "System Volume Information", .attributes = FAT_FILE_ENTRY_ATTRIBUTE_ARCHIVE | @@ -550,29 +280,6 @@ static const file_entry_t drop_image_here = { .read_sector = empty_read, }; -static uint32_t -huge_file_size(const file_entry_t *file) -{ - (void)file; - - return HUGE_FILE_SIZE; -} - -static void -huge_file_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) -{ - (void)entry; - - memset(buffer, (uint8_t)file_sector, 512); -} - -static const file_entry_t huge_file = { - .name = "Huge file", - .attributes = FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, - .size = huge_file_size, - .read_sector = huge_file_read, -}; - static int write_status; static const char *write_result_text[] = { "File that was written was not a valid image.", @@ -1495,6 +1202,7 @@ msc_fat_view_write_root_sector(uint32_t sector, const uint8_t *buffer) static int msc_fat_view_write_unallocated_sector(uint32_t sector, const uint8_t *buffer) { +#ifdef FLASH_AREA_IMAGE const struct flash_area *fa; uint32_t write_offset; int rc; @@ -1549,6 +1257,7 @@ msc_fat_view_write_unallocated_sector(uint32_t sector, const uint8_t *buffer) if (unallocated_write.write_status == WRITE_IN_PROGRESS) { unallocated_write.last_sector = sector; } +#endif return 512; } @@ -1596,23 +1305,14 @@ init_disk_data(void) msc_fat_view_add_dir_entry(&system_volume_information); } - if (MYNEWT_VAL(MSC_FAT_VIEW_MYNEWT_SHORTCUT)) { - msc_fat_view_add_dir_entry(&mynew_htm); - } - if (MYNEWT_VAL(MSC_FAT_VIEW_DEFAULT_README)) { - msc_fat_view_add_dir_entry(&readme); - } if (MYNEWT_VAL(MSC_FAT_VIEW_DROP_IMAGE_HERE)) { msc_fat_view_add_dir_entry(&drop_image_here); } - if (MYNEWT_VAL(MSC_FAT_VIEW_SLOT0_IMAGE)) { - msc_fat_view_add_dir_entry(&slot0); - } - if (MYNEWT_VAL(MSC_FAT_VIEW_SLOT0_HEX)) { - msc_fat_view_add_dir_entry(&slot0_hex); - } - if (MYNEWT_VAL(MSC_FAT_VIEW_HUGE_FILE)) { - msc_fat_view_add_dir_entry(&huge_file); + extern const file_entry_t __msc_fat_view_root_entry_start__[]; + extern const file_entry_t __msc_fat_view_root_entry_end__[]; + const file_entry_t *entry; + for (entry = __msc_fat_view_root_entry_start__; entry != __msc_fat_view_root_entry_end__; ++entry) { + msc_fat_view_add_dir_entry(entry); } if (MYNEWT_VAL(MSC_FAT_VIEW_COREDUMP_FILES)) { msc_fat_view_add_coredumps(); From eacf07990a697abb6874f04f05f18f9ca6f88a32 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 25 Apr 2024 15:36:55 +0200 Subject: [PATCH 2/3] sys/config: Add conf_export function While every config entry could specify export function there was no easy way to call those functions. Then only way to export config was to use shell command config dump Now new function conf_export takes allows to export configuration and conf_dump_running just uses it so functionality is preserved. Signed-off-by: Jerzy Kasenberg --- sys/config/include/config/config.h | 8 ++++++++ sys/config/src/config.c | 12 ++++++++++++ sys/config/src/config_cli.c | 8 +------- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sys/config/include/config/config.h b/sys/config/include/config/config.h index e492c5da4e..174fcbf80e 100644 --- a/sys/config/include/config/config.h +++ b/sys/config/include/config/config.h @@ -246,6 +246,14 @@ int conf_load_one(char *name); */ int conf_ensure_loaded(void); +/** + * Export configuration via user defined function. + * + * @param export_func function to receive configuration entry + * @param tgt - export target declaration + */ +void conf_export(conf_export_func_t export_func, enum conf_export_tgt tgt); + /** * Config setting comes as a result of conf_load(). * diff --git a/sys/config/src/config.c b/sys/config/src/config.c index d10a77abc7..200c46ff12 100644 --- a/sys/config/src/config.c +++ b/sys/config/src/config.c @@ -406,6 +406,18 @@ conf_export_cb(struct conf_handler *ch, conf_export_func_t export_func, return 0; } +void +conf_export(conf_export_func_t export_func, enum conf_export_tgt tgt) +{ + struct conf_handler *ch; + + conf_lock(); + SLIST_FOREACH(ch, &conf_handlers, ch_list) { + conf_export_cb(ch, export_func, tgt); + } + conf_unlock(); +} + int conf_set_value(char *name, char *val_str) { diff --git a/sys/config/src/config_cli.c b/sys/config/src/config_cli.c index bea89479ca..bd2fc07579 100644 --- a/sys/config/src/config_cli.c +++ b/sys/config/src/config_cli.c @@ -47,13 +47,7 @@ conf_running_one(char *name, char *val) static void conf_dump_running(void) { - struct conf_handler *ch; - - conf_lock(); - SLIST_FOREACH(ch, &conf_handlers, ch_list) { - conf_export_cb(ch, conf_running_one, CONF_EXPORT_SHOW); - } - conf_unlock(); + conf_export(conf_running_one, CONF_EXPORT_SHOW); } #endif From efd565bd9a528e8c110023b54b143195874e9522 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 25 Apr 2024 15:38:17 +0200 Subject: [PATCH 3/3] tinyusb/msc_fat_view: Add entry for sys/config Signed-off-by: Jerzy Kasenberg --- hw/usb/tinyusb/msc_fat_view/pkg.yml | 7 ++ .../tinyusb/msc_fat_view/src/entry_config.c | 112 ++++++++++++++++++ hw/usb/tinyusb/msc_fat_view/syscfg.yml | 5 + 3 files changed, 124 insertions(+) create mode 100644 hw/usb/tinyusb/msc_fat_view/src/entry_config.c diff --git a/hw/usb/tinyusb/msc_fat_view/pkg.yml b/hw/usb/tinyusb/msc_fat_view/pkg.yml index 51355fdf1a..e57fb4ba5a 100644 --- a/hw/usb/tinyusb/msc_fat_view/pkg.yml +++ b/hw/usb/tinyusb/msc_fat_view/pkg.yml @@ -30,8 +30,12 @@ pkg.deps: - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/hw/usb/tinyusb" - "@apache-mynewt-core/mgmt/imgmgr" + - "@apache-mynewt-core/util/stream" - "@mcuboot/boot/bootutil" +pkg.deps.MSC_FAT_VIEW_CONFIG: + - "@apache-mynewt-core/sys/config" + pkg.deps.MSC_FAT_VIEW_COREDUMP_FILES: - "@apache-mynewt-core/sys/coredump" @@ -58,6 +62,9 @@ pkg.source_files.MSC_FAT_VIEW_SLOT0_HEX: pkg.source_files.MSC_FAT_VIEW_MYNEWT_SHORTCUT: - src/entry_mynewt_htm.c +pkg.source_files.MSC_FAT_VIEW_CONFIG: + - src/entry_config.c + pkg.link_tables: - msc_fat_view_root_entry diff --git a/hw/usb/tinyusb/msc_fat_view/src/entry_config.c b/hw/usb/tinyusb/msc_fat_view/src/entry_config.c new file mode 100644 index 0000000000..be7f25a20d --- /dev/null +++ b/hw/usb/tinyusb/msc_fat_view/src/entry_config.c @@ -0,0 +1,112 @@ +/* + * 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 +#include +#include +#include +#include +#include + +struct config_export_stream { + struct out_stream out_stream; + uint8_t *buffer; + uint32_t buffer_start_offset; + uint16_t buffer_end_offset; + uint32_t write_offset; +}; + +static int +config_export_write(struct out_stream *ostream, const uint8_t *buf, uint32_t count) +{ + struct config_export_stream *str = (struct config_export_stream *)ostream; + uint32_t upper_limit = str->write_offset + count; + uint32_t lower_limit = str->write_offset; + int cnt = count; + + if (lower_limit < str->buffer_end_offset && upper_limit > str->buffer_start_offset) { + if (lower_limit < str->buffer_start_offset) { + cnt -= str->buffer_start_offset - lower_limit; + lower_limit = str->buffer_start_offset; + } + if (upper_limit > str->buffer_end_offset) { + cnt -= upper_limit - str->buffer_end_offset; + } + memcpy(str->buffer + lower_limit - str->buffer_start_offset, + buf + (lower_limit - str->write_offset), cnt); + } + str->write_offset += count; + + return count; +} + +static int +config_export_flush(struct out_stream *ostream) +{ + return 0; +} + +OSTREAM_DEF(config_export); + +static struct config_export_stream export_stream = { + .out_stream.vft = &config_export_vft, +}; + +static void +config_text_export(char *name, char *val) +{ + int name_len = strlen(name); + int val_len = 0; + if (val) { + val_len = strlen(val); + } + ostream_write(&export_stream.out_stream, (const uint8_t *)name, name_len, false); + ostream_write(&export_stream.out_stream, (const uint8_t *)" = ", 3, false); + if (val) { + ostream_write(&export_stream.out_stream, (const uint8_t *)val, val_len, false); + } + ostream_write(&export_stream.out_stream, (const uint8_t *)"\n", 1, false); +} + +static uint32_t +config_txt_size(const file_entry_t *file_entry) +{ + export_stream.buffer = NULL; + export_stream.buffer_start_offset = 0; + export_stream.buffer_end_offset = 0; + export_stream.write_offset = 0; + + conf_export(config_text_export, CONF_EXPORT_SHOW); + + return export_stream.write_offset; +} + +static void +config_txt_read(const struct file_entry *entry, uint32_t file_sector, uint8_t buffer[512]) +{ + export_stream.buffer = buffer; + export_stream.buffer_start_offset = 512 * file_sector; + export_stream.buffer_end_offset = export_stream.buffer_start_offset + 512; + export_stream.write_offset = 0; + + MSC_FAT_VIEW_LOG_DEBUG("Config.txt read %d\n", file_sector); + conf_export(config_text_export, CONF_EXPORT_SHOW); +} + +ROOT_DIR_ENTRY(config_txt, "CONFIG.TXT", FAT_FILE_ENTRY_ATTRIBUTE_READ_ONLY, config_txt_size, config_txt_read, NULL, NULL); diff --git a/hw/usb/tinyusb/msc_fat_view/syscfg.yml b/hw/usb/tinyusb/msc_fat_view/syscfg.yml index b1d0700ba9..a3c773d7ab 100644 --- a/hw/usb/tinyusb/msc_fat_view/syscfg.yml +++ b/hw/usb/tinyusb/msc_fat_view/syscfg.yml @@ -103,6 +103,11 @@ syscfg.defs: Normally this if folder (not file) generated by Windows. If this file is present Windows will not create folder saving time for writes. value: 0 + MSC_FAT_VIEW_CONFIG: + description: > + If set to 1, root directory will have CONFIG.TXT with content + of sys/config. + value: 0 MSC_FAT_VIEW_AUTO_INSERT: description: > If set to 1, media is reported as present during system init.