Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ports/analog/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ $(BUILD)/firmware.elf: $(OBJ)
$(STEPECHO) "LINK $@"
$(Q)echo $^ > $(BUILD)/firmware.objs
$(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LINKERFILE) $(BUILD)
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)

$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
$(STEPECHO) "Create $@"
Expand Down
2 changes: 1 addition & 1 deletion ports/atmel-samd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE)
$(STEPECHO) "LINK $@"
$(Q)echo $(OBJ) > $(BUILD)/firmware.objs
$(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) $(BUILD)
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)
endif

$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
Expand Down
2 changes: 1 addition & 1 deletion ports/litex/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ else
$(BUILD)/firmware.elf: $(OBJ)
$(STEPECHO) "LINK $@"
$(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LD_FILE) $(BUILD)
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)
endif

$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
Expand Down
1 change: 1 addition & 0 deletions ports/mimxrt10xx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ else
$(BUILD)/firmware.elf: $(OBJ) $(LD_FILES)
$(STEPECHO) "LINK $@"
$(Q)$(CC) -o $@ $(LDFLAGS) $(filter-out %.ld, $^) -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)
endif

# -R excludes sections from the output files.
Expand Down
2 changes: 1 addition & 1 deletion ports/nordic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE)
$(STEPECHO) "LINK $@"
$(Q)echo $(OBJ) > $(BUILD)/firmware.objs
$(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) $(BUILD)
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)
endif

$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
Expand Down
1 change: 1 addition & 0 deletions ports/raspberrypi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(BOARD_LD) link-$(CHIP_VARIANT_LOWER).ld
$(Q)echo $(OBJ) > $(BUILD)/firmware.objs
$(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags
$(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags $(LINKER_SCRIPTS) -Wl,--print-memory-usage -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs -Wl,-lc
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)
ifneq ($(CORE1_CHECK_ROOTS),)
$(STEPECHO) "CHECK core1 flash calls"
$(Q)$(PYTHON) $(TOP)/tools/check_core1_flash_calls.py $@ $(CORE1_CHECK_ROOTS)
Expand Down
1 change: 1 addition & 0 deletions ports/renode/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(BOARD_LD) link.ld
$(Q)echo $(OBJ) > $(BUILD)/firmware.objs
$(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags
$(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags $(LINKER_SCRIPTS) -Wl,--print-memory-usage -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs -Wl,-lc
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)
endif

$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
Expand Down
3 changes: 2 additions & 1 deletion ports/silabs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ $(SILABS_BUILD)/$(PROJECTNAME).Makefile: | $(HEADER_BUILD)/mpversion.h
$(OUTPUT_DIR)/firmware.out: $(SILABS_BUILD)/pin_functions.h $(SILABS_BUILD)/pins.c $(OBJ) $(OBJS) $(LIB_FILES)
$(STEPECHO) 'Linking $(OUTPUT_DIR)/firmware.out'
$(Q)echo "$(OBJS) $(OBJ)" > $(OUTPUT_DIR)/linker_objs
$(Q)$(CC) $(LD_FLAGS) @$(OUTPUT_DIR)/linker_objs -Wl,--print-memory-usage $(LIBS) -o $(OUTPUT_DIR)/firmware.out
$(Q)$(CC) $(LD_FLAGS) @$(OUTPUT_DIR)/linker_objs -Wl,--print-memory-usage -Wl,-Map=$(OUTPUT_DIR)/firmware.out.map $(LIBS) -o $(OUTPUT_DIR)/firmware.out
$(Q)$(SIZE) $(OUTPUT_DIR)/firmware.out | $(PYTHON) $(TOP)/tools/build_memory_info.py $(OUTPUT_DIR)/firmware.out.map $(BUILD)
$(Q)$(OBJCOPY) $(OUTPUT_DIR)/firmware.out -O binary $(OUTPUT_DIR)/firmware.bin

flash: $(OUTPUT_DIR)/firmware.bin
Expand Down
2 changes: 1 addition & 1 deletion ports/stm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ $(BUILD)/firmware.elf: $(OBJ)
$(STEPECHO) "LINK $@"
$(Q)echo $^ > $(BUILD)/firmware.objs
$(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LD_FILE) $(BUILD)
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $@.map $(BUILD)
endif

$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
Expand Down
1 change: 1 addition & 0 deletions ports/zephyr-cp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export BSIM_OUT_PATH := $(CURDIR)/tools/bsim
$(BUILD)/zephyr-cp/zephyr/zephyr.elf:
python cptools/pre_zephyr_build_prep.py $(BOARD)
west build -b $(BOARD) -d $(BUILD) $(WEST_SHIELD_ARGS) --sysbuild -- $(WEST_CMAKE_ARGS)
python ../../tools/build_memory_info.py $(BUILD)/zephyr-cp/zephyr/zephyr.map $(BUILD) --image $(BUILD)/zephyr-cp/zephyr/zephyr.bin

$(BUILD)/firmware.elf: $(BUILD)/zephyr-cp/zephyr/zephyr.elf
cp $^ $@
Expand Down
127 changes: 86 additions & 41 deletions tools/build_memory_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,105 @@
#
# SPDX-License-Identifier: MIT

import os
import re
import sys
import json


# Handle size constants with K or M suffixes (allowed in .ld but not in Python).
K_PATTERN = re.compile(r"([0-9]+)[kK]")
K_REPLACE = r"(\1*1024)"
# A linker map lists every region with the lengths already resolved:
# Name Origin Length Attributes
# FLASH_FIRMWARE 0x10000000 0x0017f000 xr
MAP_REGION = re.compile(r"^(\w+)\s+0x[0-9a-f]+\s+0x([0-9a-f]+)\s+\S*$", re.MULTILINE)

M_PATTERN = re.compile(r"([0-9]+)[mM]")
M_REPLACE = r"(\1*1024*1024)"
argv = sys.argv[1:]
flash_names = ["FLASH_FIRMWARE", "FLASH"]
if "--region" in argv:
i = argv.index("--region")
flash_names = argv[i + 1].split(",")
del argv[i : i + 2]

# Ports whose toolchain this makefile cannot reach pass the image instead of piping
# size(1) in; what it occupies in flash is its size on disk.
image = None
if "--image" in argv:
i = argv.index("--image")
image = argv[i + 1]
del argv[i : i + 2]

text = 0
data = 0
bss = 0

# stdin is the linker output.
for line in sys.stdin:
# Uncomment to see linker output.
# print(line)
line = line.strip()
if not line.startswith("text"):
text, data, bss = map(int, line.split()[:3])
if image is None:
# stdin is the linker output.
for line in sys.stdin:
# Uncomment to see linker output.
# print(line)
line = line.strip()
if not line.startswith("text"):
text, data, bss = map(int, line.split()[:3])

regions = {}

# This file is the linker script.
with open(sys.argv[1], "r") as f:
for line in f:
line = line.strip()
if line.startswith(("FLASH_FIRMWARE", "RAM")):
regions[line.split()[0]] = line.split("=")[-1]
def regions_from_map(contents):
"""Region sizes from the Memory Configuration table of a linker map."""
start = contents.find("Memory Configuration")
if start < 0:
return None
end = contents.find("Linker script and memory map", start)
table = contents[start : end if end > 0 else len(contents)]
regions = {}
for name, length in MAP_REGION.findall(table):
if name not in ("Name", "Origin", "Length"):
regions[name] = int(length, 16)
return regions or None

for region, space in regions.items():
if "/*" in space:
space = space.split("/*")[0]
space = K_PATTERN.sub(K_REPLACE, space)
space = M_PATTERN.sub(M_REPLACE, space)
regions[region] = int(eval(space))

firmware_region = regions["FLASH_FIRMWARE"]
ram_region = regions["RAM"]
# The linker map lists the regions with every size the script computed resolved.
try:
with open(argv[0], "r") as f:
contents = f.read()
except FileNotFoundError:
print()
print(f"No {argv[0]} to read the flash region from.")
print()
sys.exit(0)
regions = regions_from_map(contents) or {}

firmware_region = None
for name in flash_names:
if name in regions:
firmware_region = regions[name]
break

if image is not None:
try:
text = os.stat(image).st_size
except FileNotFoundError:
print()
print(f"No {image} to measure.")
print()
sys.exit(0)

used_flash = data + text
free_flash = firmware_region - used_flash
used_ram = data + bss
free_ram = ram_region - used_ram

with open(f"{sys.argv[2]}/firmware.size.json", "w") as f:
if firmware_region is None:
# Not knowing the size is not worth failing a build over: the tools that read
# firmware.size.json fall back to assuming there is no headroom.
print()
print(
"No {} region in {}. Regions found: {}.".format(
" or ".join(flash_names), argv[0], ", ".join(sorted(regions)) or "none"
)
)
print("{} bytes used in flash firmware space.".format(used_flash))
print()
sys.exit(0)

free_flash = firmware_region - used_flash

with open(f"{argv[1]}/firmware.size.json", "w") as f:
json.dump({"used_flash": used_flash, "firmware_region": firmware_region}, f)

print()
Expand All @@ -62,16 +112,11 @@
used_flash, free_flash, firmware_region, firmware_region / 1024
)
)
print(
"{} bytes used, {} bytes free in ram for stack and heap out of {} bytes ({}kB).".format(
used_ram, free_ram, ram_region, ram_region / 1024
if image is None and "RAM" in regions:
ram_region = regions["RAM"]
print(
"{} bytes used, {} bytes free in ram for stack and heap out of {} bytes ({}kB).".format(
used_ram, ram_region - used_ram, ram_region, ram_region / 1024
)
)
)
print()

# Check that we have free flash space. GCC doesn't fail when the text + data
# sections don't fit in FLASH. It only counts data in RAM.
if free_flash < 0:
print("Too little flash!!!")
print()
sys.exit(-1)
Loading