diff --git a/docs/locales/zh-Hans/tmap/firmware-reader.md b/docs/locales/zh-Hans/tmap/firmware-reader.md index ff3379fc..1529bfa9 100644 --- a/docs/locales/zh-Hans/tmap/firmware-reader.md +++ b/docs/locales/zh-Hans/tmap/firmware-reader.md @@ -49,7 +49,7 @@ RGB565 瓦片直接建立 LVGL RGB565 图像描述符,跳过 PNG 解码。RGBA 原生像素的队列和显示缓存共享 **3 MiB** 分配预算,包含引用计数头。预算不足时发布可重试事件。该预算不包含工作缓冲、目录、独立标注、其他页面及旧 PNG 解码缓存,因此不能称为整机 PSRAM 上限。大块新分配显式要求 PSRAM,不回退到内部 RAM。 -离开地图且没有活动视口后,工作线程释放工作缓冲、包目录及读取工作区。显示缓存是否保留仍遵循已有硬件内存配置;保留的原生像素仍计入预算,缓存淘汰时回收。介质会话改变时重建包目录,并在 UI 地图同步时取消旧代请求、重置地图对象和显示缓存。旧会话的缺失记录不阻挡新卡读取。 +离开地图且没有活动视口后,工作线程释放工作缓冲、包目录及读取工作区。显示缓存是否保留仍遵循已有硬件内存配置;保留的原生像素仍计入预算,缓存淘汰时回收。介质会话改变时重建包目录、清除旧 POI 策略,并在 UI 地图同步时取消旧代请求、重置地图对象和显示缓存。旧会话的缺失记录不阻挡新卡读取。工作线程的存在性查询和实际读取都优先访问 TMAP;生成的 POI 载荷大小尚未确定时,存在性查询返回 size=0,不用底图像素大小代替。 详见 [固件资源约束](firmware-resource-budget.md)。 @@ -96,7 +96,7 @@ tmap_source_probe 2026-10-08 的当前验证记录: - `tlora_pager_sx1262` 完整 PlatformIO 构建成功,最终进程退出码 0;生成 `.pio/build/tlora_pager_sx1262/firmware.bin`。 -- 构建报告静态 RAM 为 100,172 B / 327,680 B,Flash 为 4,568,221 B / 6,291,456 B。这些数值包含整份固件,不是 TMAP 增量,更不是运行时堆/PSRAM 峰值。 +- 构建报告静态 RAM 为 100,172 B / 327,680 B,Flash 为 4,568,385 B / 6,291,456 B。这些数值包含整份固件,不是 TMAP 增量,更不是运行时堆/PSRAM 峰值。 - 使用现有 ESP-IDF ESP32-P4 的真实构建参数及 GCC 14 工具链,对当前地图显示文件、IDF SD 适配器、Reader、搜索和地图源五个编译单元进行交叉编译,全部退出码 0。这不等于 P4 完整固件链接或真机验证。 - LVGL 的原有 PNG 和新增原生显示两项测试、原有地图流水线九项测试通过;原生显示验证完全透明、半透明和不透明 RGBA,并确认 LVGL 解码器仍借用原生像素,而非创建完整像素副本。独立地图源实包探针追加了 CRC 损坏、容量溢出、精确/前缀/片段搜索分批、Busy 与取消验证,全部通过。 - 真机内存和任务栈验收尚待确认测试设备及刷入固件;代码已加入资源统计日志,不能将尚未采集的运行时数值当作已验证结果。 diff --git a/modules/ui_map_runtime/src/map_tiles/tmap_map_tile_source.cpp b/modules/ui_map_runtime/src/map_tiles/tmap_map_tile_source.cpp index 10f131f8..b9452fd2 100644 --- a/modules/ui_map_runtime/src/map_tiles/tmap_map_tile_source.cpp +++ b/modules/ui_map_runtime/src/map_tiles/tmap_map_tile_source.cpp @@ -258,11 +258,17 @@ MapTileLookupResult TmapMapTileSource::lookup(const MapTileRef& ref) const { tmap::Tile tile{}; const auto status = select(ref, tile); - return {status == tmap::Status::Ok ? MapTileStatus::Available : status == tmap::Status::Missing ? MapTileStatus::Missing - : MapTileStatus::Error, - ref.layer == MapTileLayer::Poi ? MapTileFormat::PoiRecords : tile.codec == 1 ? MapTileFormat::Rgb565 - : MapTileFormat::Rgba8888, - tile.bytes}; + MapTileLookupResult info{}; + info.status = status == tmap::Status::Ok ? MapTileStatus::Available : status == tmap::Status::Missing ? MapTileStatus::Missing + : MapTileStatus::Error; + if (ref.layer == MapTileLayer::Poi) + info.format = MapTileFormat::PoiRecords; // Generated record count is known only after read. + else if (status == tmap::Status::Ok) + { + info.format = tile.codec == 1 ? MapTileFormat::Rgb565 : MapTileFormat::Rgba8888; + info.size = tile.bytes; + } + return info; } MapTileReadResult TmapMapTileSource::read(const MapTileRef& ref, uint8_t* output, size_t capacity) const { diff --git a/platform/esp/arduino_common/src/ui/widgets/map/map_tiles.cpp b/platform/esp/arduino_common/src/ui/widgets/map/map_tiles.cpp index 30077527..bb209d06 100644 --- a/platform/esp/arduino_common/src/ui/widgets/map/map_tiles.cpp +++ b/platform/esp/arduino_common/src/ui/widgets/map/map_tiles.cpp @@ -744,6 +744,12 @@ class EspMapTileWorkerBackend final : public ui::map_tiles::IMapTileWorkerBacken ui::map_tiles::MapTileLookupResult lookup( const ui::map_tiles::MapTileRef& ref) override { + if (media_session_ != ::platform::esp::arduino_common::storage::sd_media_session()) resetMetadata(); + const auto packaged = tmap_source_.lookup(ref); + if (packaged.status != ui::map_tiles::MapTileStatus::Missing) return packaged; +#if defined(TRAIL_MATE_MAP_POI_AVAILABLE) + if (ref.layer == ui::map_tiles::MapTileLayer::Poi) return poi_source_.lookup(ref); +#endif return source_.lookup(ref); } @@ -754,6 +760,7 @@ class EspMapTileWorkerBackend final : public ui::map_tiles::IMapTileWorkerBacken { // Always try packages before the legacy missing cache. A new media // session invalidates the package catalog inside this source. + if (media_session_ != ::platform::esp::arduino_common::storage::sd_media_session()) resetMetadata(); auto packaged = tmap_source_.read(ref, buffer, capacity); if (packaged.status != ui::map_tiles::MapTileReadStatus::Missing) return packaged; #if defined(TRAIL_MATE_MAP_POI_AVAILABLE) @@ -801,12 +808,14 @@ class EspMapTileWorkerBackend final : public ui::map_tiles::IMapTileWorkerBacken #if defined(TRAIL_MATE_MAP_POI_AVAILABLE) poi_source_.reset(); #endif + media_session_ = ::platform::esp::arduino_common::storage::sd_media_session(); } private: ui::map_tiles::IMapTileSource& source_; platform::esp::map_tiles::SdTmapStorage tmap_storage_; ui::map_tiles::TmapMapTileSource tmap_source_{tmap_storage_}; + uint32_t media_session_ = 0; #if defined(TRAIL_MATE_MAP_POI_AVAILABLE) SdMapTileFileSystem poi_files_; platform::esp::arduino_common::map_poi::CJsonPoiParser poi_parser_; diff --git a/tests/tmap/source_probe.cpp b/tests/tmap/source_probe.cpp index addb14b3..683d1000 100644 --- a/tests/tmap/source_probe.cpp +++ b/tests/tmap/source_probe.cpp @@ -133,9 +133,13 @@ int main(int argc, char** argv) assert(storage.opens == opens); auto second = source.read(china, pixels, 256 * 1024); assert(second.status == MapTileReadStatus::Ready && tmap::Reader::crc32c(pixels, second.size) == 0xa4e01293); + const auto located = source.lookup(china); + assert(located.status == MapTileStatus::Available && located.format == MapTileFormat::Rgb565 && located.size == 131072); auto poi = china; poi.layer = MapTileLayer::Poi; auto annotations = source.read(poi, pixels, 256 * 1024); + const auto poi_info = source.lookup(poi); + assert(poi_info.status == MapTileStatus::Available && poi_info.format == MapTileFormat::PoiRecords && poi_info.size == 0); assert(annotations.status == MapTileReadStatus::Ready && annotations.format == MapTileFormat::PoiRecords); assert(ui::map_poi::validPayload(pixels, annotations.size)); const auto* header = reinterpret_cast(pixels);