diff --git a/TESTS/mbed_platform/stats_sys/main.cpp b/TESTS/mbed_platform/stats_sys/main.cpp index 9cbd898e56..ae3fb3e0c3 100644 --- a/TESTS/mbed_platform/stats_sys/main.cpp +++ b/TESTS/mbed_platform/stats_sys/main.cpp @@ -45,6 +45,48 @@ void test_sys_info() TEST_ASSERT_EQUAL(GCC_ARM, stats.compiler_id); #endif TEST_ASSERT_NOT_EQUAL(0, stats.compiler_version); + + // RAM / ROM sizes should not be zero and should match the define +#if defined(MBED_ROM_START) && defined(MBED_ROM_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.rom_size[0]); + TEST_ASSERT_EQUAL(MBED_ROM_SIZE, stats.rom_size[0]); + TEST_ASSERT_EQUAL(MBED_ROM_START, stats.rom_start[0]); +#endif +#if defined(MBED_RAM_START) && defined(MBED_RAM_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.ram_size[0]); + TEST_ASSERT_EQUAL(MBED_RAM_START, stats.ram_start[0]); + TEST_ASSERT_EQUAL(MBED_RAM_SIZE, stats.ram_size[0]); +#endif +#if defined(MBED_RAM1_START) && defined(MBED_RAM1_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.ram_size[1]); + TEST_ASSERT_EQUAL(MBED_RAM1_SIZE, stats.ram_size[1]); + TEST_ASSERT_EQUAL(MBED_RAM1_START, stats.ram_start[1]); +#endif +#if defined(MBED_RAM2_START) && defined(MBED_RAM2_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.ram_size[2]); + TEST_ASSERT_EQUAL(MBED_RAM2_SIZE, stats.ram_size[2]); + TEST_ASSERT_EQUAL(MBED_RAM2_START, stats.ram_start[2]); +#endif +#if defined(MBED_RAM3_START) && defined(MBED_RAM3_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.ram_size[3]); + TEST_ASSERT_EQUAL(MBED_RAM3_SIZE, stats.ram_size[3]); + TEST_ASSERT_EQUAL(MBED_RAM3_START, stats.ram_start[3]); +#endif +#if defined(MBED_ROM1_START) && defined(MBED_ROM1_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.rom_size[1]); + TEST_ASSERT_EQUAL(MBED_ROM1_SIZE, stats.rom_size[1]); + TEST_ASSERT_EQUAL(MBED_ROM1_START, stats.rom_start[1]); +#endif +#if defined(MBED_ROM2_START) && defined(MBED_ROM2_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.rom_size[2]); + TEST_ASSERT_EQUAL(MBED_ROM2_SIZE, stats.rom_size[2]); + TEST_ASSERT_EQUAL(MBED_ROM2_START, stats.rom_start[2]); +#endif +#if defined(MBED_ROM3_START) && defined(MBED_ROM3_SIZE) + TEST_ASSERT_NOT_EQUAL(0, stats.rom_size[3]); + TEST_ASSERT_EQUAL(MBED_ROM3_SIZE, stats.rom_size[3]); + TEST_ASSERT_EQUAL(MBED_ROM3_START, stats.rom_start[3]); +#endif } Case cases[] = { diff --git a/platform/mbed_stats.c b/platform/mbed_stats.c index 81b1a6a3ce..b4a3d3de32 100644 --- a/platform/mbed_stats.c +++ b/platform/mbed_stats.c @@ -131,6 +131,39 @@ void mbed_stats_sys_get(mbed_stats_sys_t *stats) #if defined(MBED_SYS_STATS_ENABLED) stats->os_version = MBED_VERSION; +#if defined(MBED_RAM_START) && defined(MBED_RAM_SIZE) + stats->ram_start[0] = MBED_RAM_START; + stats->ram_size[0] = MBED_RAM_SIZE; +#endif +#if defined(MBED_ROM_START) && defined(MBED_ROM_SIZE) + stats->rom_start[0] = MBED_ROM_START; + stats->rom_size[0] = MBED_ROM_SIZE; +#endif +#if defined(MBED_RAM1_START) && defined(MBED_RAM1_SIZE) + stats->ram_start[1] = MBED_RAM1_START; + stats->ram_size[1] = MBED_RAM1_SIZE; +#endif +#if defined(MBED_RAM2_START) && defined(MBED_RAM2_SIZE) + stats->ram_start[2] = MBED_RAM2_START; + stats->ram_size[2] = MBED_RAM2_SIZE; +#endif +#if defined(MBED_RAM3_START) && defined(MBED_RAM3_SIZE) + stats->ram_start[3] = MBED_RAM3_START; + stats->ram_size[3] = MBED_RAM3_SIZE; +#endif +#if defined(MBED_ROM1_START) && defined(MBED_ROM1_SIZE) + stats->rom_start[1] = MBED_ROM1_START; + stats->rom_size[1] = MBED_ROM1_SIZE; +#endif +#if defined(MBED_ROM2_START) && defined(MBED_ROM2_SIZE) + stats->rom_start[2] = MBED_ROM2_START; + stats->rom_size[2] = MBED_ROM2_SIZE; +#endif +#if defined(MBED_ROM3_START) && defined(MBED_ROM3_SIZE) + stats->rom_start[3] = MBED_ROM3_START; + stats->rom_size[3] = MBED_ROM3_SIZE; +#endif + #if defined(__CORTEX_M) stats->cpu_id = SCB->CPUID; #endif diff --git a/platform/mbed_stats.h b/platform/mbed_stats.h index fb975f5f29..daf4092b49 100644 --- a/platform/mbed_stats.h +++ b/platform/mbed_stats.h @@ -38,6 +38,9 @@ extern "C" { #define MBED_THREAD_STATS_ENABLED 1 #endif +/** Maximum memory regions reported by mbed-os memory statistics */ +#define MBED_MAX_MEM_REGIONS 4 + /** * struct mbed_stats_heap_t definition */ @@ -144,6 +147,10 @@ typedef struct { uint32_t cpu_id; /**< CPUID register data (Cortex-M only supported) */ mbed_compiler_id_t compiler_id; /**< Compiler ID \ref mbed_compiler_id_t */ uint32_t compiler_version; /**< Compiler version */ + uint32_t ram_start[MBED_MAX_MEM_REGIONS];/**< Start addresses of all internal RAM memories */ + uint32_t ram_size[MBED_MAX_MEM_REGIONS];/**< Size of all internal RAM memories in target */ + uint32_t rom_start[MBED_MAX_MEM_REGIONS];/**< Start addresses of all internal ROM memories */ + uint32_t rom_size[MBED_MAX_MEM_REGIONS];/**< Size of all internal ROM memories in target */ } mbed_stats_sys_t; /** diff --git a/tools/config/__init__.py b/tools/config/__init__.py index 6806a52669..ccc0240bac 100644 --- a/tools/config/__init__.py +++ b/tools/config/__init__.py @@ -72,6 +72,14 @@ ALLOWED_FEATURES = [ "ETHERNET_HOST", ] +# List of all possible ram memories that can be available for a target +RAM_ALL_MEMORIES = ['IRAM1', 'IRAM2', 'IRAM3', 'IRAM4', 'SRAM_OC', \ + 'SRAM_ITC', 'SRAM_DTC', 'SRAM_UPPER', 'SRAM_LOWER', \ + 'SRAM'] + +# List of all possible rom memories that can be available for a target +ROM_ALL_MEMORIES = ['IROM1', 'PROGRAM_FLASH', 'IROM2'] + # Base class for all configuration exceptions class ConfigException(Exception): """Config system only exception. Makes it easier to distinguish config @@ -593,8 +601,6 @@ class Config(object): raise ConfigException("No sector info available") def _get_cmsis_part(self): - if not getattr(self.target, "bootloader_supported", False): - raise ConfigException("Bootloader not supported on this target.") if not hasattr(self.target, "device_name"): raise ConfigException("Bootloader not supported on this target: " "targets.json `device_name` not specified.") @@ -615,24 +621,68 @@ class Config(object): continue raise ConfigException(exception_text) - @property - def rom(self): - """Get rom information as a pair of start_addr, size""" + def get_all_active_memories(self, memory_list): + """Get information of all available rom/ram memories in the form of dictionary + {Memory: [start_addr, size]}. Takes in the argument, a list of all available + regions within the ram/rom memory""" # Override rom_start/rom_size # # This is usually done for a target which: # 1. Doesn't support CMSIS pack, or # 2. Supports TrustZone and user needs to change its flash partition - cmsis_part = self._get_cmsis_part() - rom_start, rom_size = self._get_mem_specs( - ["IROM1", "PROGRAM_FLASH"], - cmsis_part, - "Not enough information in CMSIS packs to build a bootloader " - "project" - ) - rom_start = int(getattr(self.target, "mbed_rom_start", False) or rom_start, 0) - rom_size = int(getattr(self.target, "mbed_rom_size", False) or rom_size, 0) - return (rom_start, rom_size) + + available_memories = {} + # Counter to keep track of ROM/RAM memories supported by target + active_memory_counter = 0 + # Find which memory we are dealing with, RAM/ROM + active_memory = 'ROM' if any('ROM' in mem_list for mem_list in memory_list) else 'RAM' + + try: + cmsis_part = self._get_cmsis_part() + except ConfigException: + """ If the target doesn't exits in cmsis, but present in targets.json + with ram and rom start/size defined""" + if getattr(self.target, "mbed_ram_start") and \ + getattr(self.target, "mbed_rom_start"): + mem_start = int(getattr(self.target, "mbed_" + active_memory.lower() + "_start"), 0) + mem_size = int(getattr(self.target, "mbed_" + active_memory.lower() + "_size"), 0) + available_memories[active_memory] = [mem_start, mem_size] + return available_memories + else: + raise ConfigException("Bootloader not supported on this target. " + "ram/rom start/size not found in " + "targets.json.") + + present_memories = set(cmsis_part['memory'].keys()) + valid_memories = set(memory_list).intersection(present_memories) + + for memory in valid_memories: + mem_start, mem_size = self._get_mem_specs( + [memory], + cmsis_part, + "Not enough information in CMSIS packs to build a bootloader " + "project" + ) + if memory=='IROM1' or memory=='PROGRAM_FLASH': + mem_start = getattr(self.target, "mbed_rom_start", False) or mem_start + mem_size = getattr(self.target, "mbed_rom_size", False) or mem_size + memory = 'ROM' + elif memory == 'IRAM1' or memory == 'SRAM_OC' or \ + memory == 'SRAM_UPPER' or memory == 'SRAM': + if (self.has_ram_regions): + continue + mem_start = getattr(self.target, "mbed_ram_start", False) or mem_start + mem_size = getattr(self.target, "mbed_ram_size", False) or mem_size + memory = 'RAM' + else: + active_memory_counter += 1 + memory = active_memory + str(active_memory_counter) + + mem_start = int(mem_start, 0) + mem_size = int(mem_size, 0) + available_memories[memory] = [mem_start, mem_size] + + return available_memories @property def ram_regions(self): @@ -654,17 +704,19 @@ class Config(object): @property def regions(self): + if not getattr(self.target, "bootloader_supported", False): + raise ConfigException("Bootloader not supported on this target.") """Generate a list of regions from the config""" if ((self.target.bootloader_img or self.target.restrict_size) and (self.target.mbed_app_start or self.target.mbed_app_size)): raise ConfigException( - "target.bootloader_img and target.restirct_size are " + "target.bootloader_img and target.restrict_size are " "incompatible with target.mbed_app_start and " "target.mbed_app_size") if self.target.bootloader_img or self.target.restrict_size: - return self._generate_bootloader_build(*self.rom) + return self._generate_bootloader_build(self.get_all_active_memories(ROM_ALL_MEMORIES)) else: - return self._generate_linker_overrides(*self.rom) + return self._generate_linker_overrides(self.get_all_active_memories(ROM_ALL_MEMORIES)) @staticmethod def header_member_size(member): @@ -701,7 +753,8 @@ class Config(object): "Can not place % region inside previous region" % region_name) return newstart - def _generate_bootloader_build(self, rom_start, rom_size): + def _generate_bootloader_build(self, rom_memories): + rom_start, rom_size = rom_memories.get('ROM') start = rom_start rom_end = rom_start + rom_size if self.target.bootloader_img: @@ -785,7 +838,8 @@ class Config(object): return {'app_config': self.app_config_location, 'library_configs': list(map(relpath, self.processed_configs.keys()))} - def _generate_linker_overrides(self, rom_start, rom_size): + def _generate_linker_overrides(self, rom_memories): + rom_start, rom_size = rom_memories.get('ROM') if self.target.mbed_app_start is not None: start = int(self.target.mbed_app_start, 0) else: diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 9a200e8088..0d4ac8289d 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -40,7 +40,7 @@ from .. import hooks from ..notifier.term import TerminalNotifier from ..resources import FileType from ..memap import MemapParser -from ..config import ConfigException +from ..config import (ConfigException, RAM_ALL_MEMORIES, ROM_ALL_MEMORIES) #Disables multiprocessing if set to higher number than the host machine CPUs @@ -699,14 +699,19 @@ class mbedToolchain: return None - def _add_defines_from_region(self, region, suffixes=['_ADDR', '_SIZE']): + def _add_defines_from_region(self, region, linker_define=False, suffixes=['_ADDR', '_SIZE']): for define in [(region.name.upper() + suffixes[0], region.start), (region.name.upper() + suffixes[1], region.size)]: define_string = "-D%s=0x%x" % define self.cc.append(define_string) self.cppc.append(define_string) self.flags["common"].append(define_string) - + if linker_define: + ld_string = ("%s" % define[0], "0x%x" % define[1]) + ld_string = self.make_ld_define(*ld_string) + self.ld.append(ld_string) + self.flags["ld"].append(ld_string) + def _add_all_regions(self, region_list, active_region_name): for region in region_list: self._add_defines_from_region(region) @@ -725,26 +730,51 @@ class mbedToolchain: """Add regions to the build profile, if there are any. """ if self.config.has_regions: - regions = list(self.config.regions) - self.notify.info("Using ROM region%s %s in this build." % ( - "s" if len(regions) > 1 else "", - ", ".join(r.name for r in regions) - )) - self._add_all_regions(regions, "MBED_APP") + try: + regions = list(self.config.regions) + self.notify.info("Using ROM region%s %s in this build." % ( + "s" if len(regions) > 1 else "", + ", ".join(r.name for r in regions) + )) + self._add_all_regions(regions, "MBED_APP") + except ConfigException: + pass + if self.config.has_ram_regions: - regions = list(self.config.ram_regions) - self.notify.info("Using RAM region%s %s in this build." % ( - "s" if len(regions) > 1 else "", - ", ".join(r.name for r in regions) - )) - self._add_all_regions(regions, "MBED_RAM") + try: + regions = list(self.config.ram_regions) + self.notify.info("Using RAM region%s %s in this build." % ( + "s" if len(regions) > 1 else "", + ", ".join(r.name for r in regions) + )) + self._add_all_regions(regions, "MBED_RAM") + except ConfigException: + pass + + Region = namedtuple("Region", "name start size") + try: - rom_start, rom_size = self.config.rom - Region = namedtuple("Region", "name start size") - self._add_defines_from_region( - Region("MBED_ROM", rom_start, rom_size), - suffixes=["_START", "_SIZE"] - ) + # Add all available ROM regions to build profile + rom_available_regions = self.config.get_all_active_memories(ROM_ALL_MEMORIES) + for key, value in rom_available_regions.items(): + rom_start, rom_size = value + self._add_defines_from_region( + Region("MBED_" + key, rom_start, rom_size), + True, + suffixes=["_START", "_SIZE"] + ) + except ConfigException: + pass + try: + # Add all available RAM regions to build profile + ram_available_regions = self.config.get_all_active_memories(RAM_ALL_MEMORIES) + for key, value in ram_available_regions.items(): + ram_start, ram_size = value + self._add_defines_from_region( + Region("MBED_" + key, ram_start, ram_size), + True, + suffixes=["_START", "_SIZE"] + ) except ConfigException: pass