Skip to content

Commit

Permalink
Improve type hints, don't write out a JSON file as a side effect
Browse files Browse the repository at this point in the history
  • Loading branch information
multiplemonomials committed Sep 10, 2024
1 parent 266ed1a commit 13ed6ec
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 37 deletions.
73 changes: 48 additions & 25 deletions tools/python/mbed_tools/build/_internal/memory_banks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
# SPDX-License-Identifier: Apache-2.0
#

from typing import Dict, Any, Set
from __future__ import annotations

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Dict, Any, Set, TypedDict, NotRequired

import pathlib
import copy
import json
Expand All @@ -18,6 +23,27 @@
logger = logging.getLogger(__name__)


if TYPE_CHECKING:
# Type hints for memory bank config
class MemoryBankInfo(TypedDict):
"""
Info about one memory bank
"""
size: int
start: int
default: NotRequired[bool]
startup: NotRequired[bool]
access: Dict[str, bool]


class BanksByType(TypedDict):
"""
Info about all memory banks, ROM and RAM
"""
ROM: Dict[str, MemoryBankInfo]
RAM: Dict[str, MemoryBankInfo]


# Deprecated memory configuration properties from old (Mbed CLI 1) configuration system
DEPRECATED_MEM_CONFIG_PROPERTIES = {
"mbed_rom_start",
Expand Down Expand Up @@ -65,20 +91,7 @@ def incorporate_memory_bank_data_from_cmsis(target_attributes: Dict[str, Any],
target_attributes["memory_banks"] = target_memory_banks_section


def _pretty_print_size(size: int) -> str:
"""
Pretty-print a memory size as MiB/KiB/B
"""
if size >= 1024*1024 and (size % (1024*1024)) == 0:
return f"{size//(1024*1024)} MiB"
elif size >= 1024 and (size % 1024) == 0:
return f"{size//1024} kiB"
else:
return f"{size} B"


def _apply_configured_overrides(banks_by_type: Dict[str, Dict[str, Dict[str, Any]]],
bank_config: Dict[str, Dict[str, int]]) -> Dict[str, Dict[str, Dict[str, Any]]]:
def _apply_configured_overrides(banks_by_type: BanksByType, bank_config: Dict[str, Dict[str, int]]) -> BanksByType:

"""
Apply overrides from configuration to the physical memory bank information, producing the configured
Expand Down Expand Up @@ -108,8 +121,19 @@ def _apply_configured_overrides(banks_by_type: Dict[str, Dict[str, Dict[str, Any
return configured_memory_banks


def _print_mem_bank_summary(banks_by_type: Dict[str, Dict[str, Dict[str, Any]]],
configured_banks_by_type: Dict[str, Dict[str, Dict[str, Any]]]) -> None:
def _pretty_print_size(size: int) -> str:
"""
Pretty-print a memory size as MiB/KiB/B
"""
if size >= 1024*1024 and (size % (1024*1024)) == 0:
return f"{size//(1024*1024)} MiB"
elif size >= 1024 and (size % 1024) == 0:
return f"{size//1024} kiB"
else:
return f"{size} B"


def _print_mem_bank_summary(banks_by_type: BanksByType, configured_banks_by_type: BanksByType) -> None:

"""
Print a summary of the memory banks to the console
Expand Down Expand Up @@ -151,8 +175,8 @@ def _print_mem_bank_summary(banks_by_type: Dict[str, Dict[str, Dict[str, Any]]],
print()


def _generate_macros_for_memory_banks(banks_by_type: Dict[str, Dict[str, Dict[str, Any]]],
configured_banks_by_type: Dict[str, Dict[str, Dict[str, Any]]]) -> Set[str]:
def _generate_macros_for_memory_banks(banks_by_type: BanksByType,
configured_banks_by_type: BanksByType) -> Set[str]:

"""
Generate a set of macros to define to pass the memory bank information into Mbed.
Expand Down Expand Up @@ -186,13 +210,13 @@ def _generate_macros_for_memory_banks(banks_by_type: Dict[str, Dict[str, Dict[st
return all_macros


def process_memory_banks(config: Config, mem_banks_json_file: pathlib.Path) -> None:
def process_memory_banks(config: Config) -> Dict[str, BanksByType]:
"""
Process memory bank information in the config. Reads the 'memory_banks' and
'memory_bank_config' sections and adds the memory_bank_macros section accordingly.
:param config: Config structure containing merged data from every JSON file (app, lib, and targets)
:param mem_banks_json_file: Memory banks JSON file is written here
:return: Memory bank information structure that shall be written to memory_banks.json
"""

memory_banks = config.get("memory_banks", {})
Expand All @@ -206,7 +230,7 @@ def process_memory_banks(config: Config, mem_banks_json_file: pathlib.Path) -> N
"https://github.com/mbed-ce/mbed-os/wiki/Mbed-Memory-Bank-Information", property_name)

# Check attributes, sort into rom and ram
banks_by_type: Dict[str, Dict[str, Dict[str, Any]]] = {"ROM": {}, "RAM": {}}
banks_by_type: BanksByType = {"ROM": {}, "RAM": {}}
for bank_name, bank_data in memory_banks.items():
if "access" not in bank_data or "start" not in bank_data or "size" not in bank_data:
raise MbedBuildError(f"Memory bank '{bank_name}' must contain 'access', 'size', and 'start' elements")
Expand All @@ -229,9 +253,8 @@ def process_memory_banks(config: Config, mem_banks_json_file: pathlib.Path) -> N
config["memory_bank_macros"] = _generate_macros_for_memory_banks(banks_by_type, configured_banks_by_type)

# Write out JSON file
memory_banks_json_content = {
return {
"memory_banks": banks_by_type,
"configured_memory_banks": configured_banks_by_type
}
mem_banks_json_file.parent.mkdir(parents=True, exist_ok=True)
mem_banks_json_file.write_text(json.dumps(memory_banks_json_content, indent=4))

8 changes: 7 additions & 1 deletion tools/python/mbed_tools/build/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pathlib

from typing import Any, Tuple
import json

from mbed_tools.lib.json_helpers import decode_json_file
from mbed_tools.project import MbedProgram
Expand Down Expand Up @@ -39,7 +40,12 @@ def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> T
config = assemble_config(
target_build_attributes, [program.root, program.mbed_os.root], program.files.app_config_file
)
process_memory_banks(config, program.files.cmake_build_dir / MEMORY_BANKS_JSON_FILE)

# Process memory banks and save JSON data for other tools (e.g. memap) to use
memory_banks_json_content = process_memory_banks(config)
program.files.cmake_build_dir.mkdir(parents=True, exist_ok=True)
(program.files.cmake_build_dir / MEMORY_BANKS_JSON_FILE).write_text(json.dumps(memory_banks_json_content, indent=4))

cmake_file_contents = render_mbed_config_cmake_template(
target_name=target_name, config=config, toolchain_name=toolchain,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
# SPDX-License-Identifier: Apache-2.0
#

import pathlib

from mbed_tools.build._internal.memory_banks import process_memory_banks


class TestMemoryBankProcessing:
def test_simple_memory_layout(self, tmp_path: pathlib.Path):
def test_simple_memory_layout(self):
"""
Test a simple memory layout to ensure we process it correctly.
"""
Expand Down Expand Up @@ -52,8 +50,7 @@ def test_simple_memory_layout(self, tmp_path: pathlib.Path):
}
}

memory_banks_json_path = tmp_path / "memory_banks.json"
process_memory_banks(config, memory_banks_json_path)
print(repr(process_memory_banks(config)))

assert config["memory_bank_macros"] == {
# New style definitions (ROM)
Expand Down Expand Up @@ -81,7 +78,7 @@ def test_simple_memory_layout(self, tmp_path: pathlib.Path):
'MBED_CONFIGURED_RAM_SIZE=0x100000',
}

def test_memory_configuration(self, tmp_path: pathlib.Path):
def test_memory_configuration(self):
"""
Test configuring the size and address of a memory bank
"""
Expand Down Expand Up @@ -135,8 +132,7 @@ def test_memory_configuration(self, tmp_path: pathlib.Path):
}
}

memory_banks_json_path = tmp_path / "memory_banks.json"
process_memory_banks(config, memory_banks_json_path)
process_memory_banks(config)

assert config["memory_bank_macros"] == {
# New style definitions (ROM)
Expand Down Expand Up @@ -164,7 +160,7 @@ def test_memory_configuration(self, tmp_path: pathlib.Path):
'MBED_CONFIGURED_RAM_SIZE=0xa0000',
}

def test_two_ram_banks(self, tmp_path: pathlib.Path):
def test_two_ram_banks(self):
"""
Test to see if two RAM banks are handled correctly.
"""
Expand Down Expand Up @@ -221,8 +217,7 @@ def test_two_ram_banks(self, tmp_path: pathlib.Path):
}
}

memory_banks_json_path = tmp_path / "memory_banks.json"
process_memory_banks(config, memory_banks_json_path)
process_memory_banks(config)

# Note: IRAM2 should become MBED_RAM1 because it is listed second
# in the dictionary
Expand Down

0 comments on commit 13ed6ec

Please sign in to comment.