🩹 Fix memory visualizer, ProUI conditionals (#28360)

This commit is contained in:
Andrew
2026-03-13 03:48:41 -04:00
committed by GitHub
parent 7cc8b157c0
commit 9139c1bd0d
6 changed files with 48 additions and 46 deletions
+20 -23
View File
@@ -1,15 +1,15 @@
#!/usr/bin/env python3
#
# Visualize memory map
#
# Memory Map Visualizer for Marlin Firmware (AVR and ARM/STM32)
# Generates an interactive HTML page showing memory layout with color coding
# Uses nm to extract symbols from ELF file
#
# Author: Dust
# Additional contributor: Thomas Toka (Windows support)
# Implementation assistance: Claude Sonnet 4.5
#
"""
Visualize memory map
Memory Map Visualizer for Marlin Firmware (AVR and ARM/STM32)
Generates an interactive HTML page showing memory layout with color coding
Uses nm to extract symbols from ELF file
Author: Dust
Additional contributor: Thomas Toka (Windows support)
Implementation assistance: Claude Sonnet 4.5
"""
import re
import sys
@@ -20,7 +20,6 @@ import os
import shutil
from pathlib import Path
from collections import defaultdict
import glob
def parse_size(size_str):
"""Parse size string with optional KB/MB suffix to bytes.
@@ -391,7 +390,6 @@ def categorize_symbol(name, warn_conflicts=False):
# Warn if multiple categories match
if warn_conflicts and len(matches) > 1:
categories = [m[0] for m in matches]
patterns_matched = [m[1] for m in matches]
print(f" ⚠ Ambiguous: '{name}' matches {len(matches)} categories: {', '.join([f'{c} ({p})' for c, p in matches])} → using {categories[0]}")
# Return first match or 'Other'
@@ -403,15 +401,15 @@ def categorize_symbol(name, warn_conflicts=False):
def categorize_section(section_name):
"""Categorize section for color coding"""
if section_name.startswith('.text'):
return 'code', '#4CAF50', 'flash' # Green for code
return 'code', '#4CAF50', 'flash' # Green code
elif section_name.startswith('.data'):
return 'data', '#2196F3', 'ram' # Blue for initialized data
return 'data', '#2196F3', 'ram' # Blue initialized data
elif section_name.startswith('.bss'):
return 'bss', '#FF9800', 'ram' # Orange for uninitialized data
return 'bss', '#FF9800', 'ram' # Orange uninitialized data
elif section_name.startswith('.rodata'):
return 'rodata', '#9C27B0', 'flash' # Purple for read-only data
return 'rodata', '#9C27B0', 'flash' # Purple read-only data
else:
return 'other', '#757575', 'flash' # Gray for other
return 'other', '#757575', 'flash' # Gray other
def generate_memory_blocks_html(items, module_colors, zoom_level=1, total_memory_size=None, special_symbols=None, arch='avr'):
"""Generate HTML for memory blocks as a byte-by-byte map
@@ -425,7 +423,6 @@ def generate_memory_blocks_html(items, module_colors, zoom_level=1, total_memory
# Calculate actual pixels per byte and delimiter size
pixels_per_byte = zoom_level * 2
delimiter_width = zoom_level * 1
# Find memory range
min_addr = min(item['addr'] for item in items)
@@ -557,14 +554,14 @@ def generate_memory_blocks_html(items, module_colors, zoom_level=1, total_memory
# Unused space at end
if needs_delimiter:
html += f' <div class="memory-pixel" style="flex-grow: {count}; background: #1a1a1a;" data-unused="true" data-addr="0x{display_addr:08x}" data-size="{count}" title="Unused: {count} bytes"></div>\n'
html += f' <div class="memory-delimiter"></div>\n'
html += ' <div class="memory-delimiter"></div>\n'
else:
html += f' <div class="memory-pixel" style="flex-grow: {count}; background: #1a1a1a;" data-unused="true" data-addr="0x{display_addr:08x}" data-size="{count}" title="Unused: {count} bytes"></div>\n'
else:
# Gap between symbols - likely linker-inserted code, padding, or alignment
if needs_delimiter:
html += f' <div class="memory-pixel" style="flex-grow: {count}; background: #3a3a3a;" data-unallocated="true" data-addr="0x{display_addr:08x}" data-size="{count}" title="Linker code/padding: {count} bytes"></div>\n'
html += f' <div class="memory-delimiter"></div>\n'
html += ' <div class="memory-delimiter"></div>\n'
else:
html += f' <div class="memory-pixel" style="flex-grow: {count}; background: #3a3a3a;" data-unallocated="true" data-addr="0x{display_addr:08x}" data-size="{count}" title="Linker code/padding: {count} bytes"></div>\n'
else:
@@ -645,7 +642,7 @@ def check_pattern_conflicts():
if conflicts:
print("Pattern conflict analysis:")
for p1, c1, p2, c2, conflict_type in conflicts:
for p1, c1, p2, c2 in conflicts:
print(f" '{p1}' ({c1}) vs '{p2}' ({c2}) - '{p1}' has priority")
return len(conflicts)
@@ -719,7 +716,7 @@ def generate_html(symbols, special_symbols, output_path, flash_size, ram_size, a
ram_items = []
for item in symbols:
cat, color, mem_type = categorize_section(item['section'])
color, mem_type = categorize_section(item['section'])
if mem_type == 'flash':
total_flash += item['size']
module_stats[item['module']]['flash'] += item['size']