5.2.1 - Updated I2C files

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Committer:
jacobjohnson
Date:
Mon Feb 27 17:45:05 2017 +0000
Revision:
1:f30bdcd2b33b
Parent:
0:098463de4c5d
changed the inputscale from 1 to 7 in analogin_api.c.  This will need to be changed later, and accessed from the main level, but for now this allows the  adc to read a value from 0 to 3.7V, instead of just up to 1V.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
group-onsemi 0:098463de4c5d 1 #!/usr/bin/env python
group-onsemi 0:098463de4c5d 2
group-onsemi 0:098463de4c5d 3 """Memory Map File Analyser for ARM mbed"""
group-onsemi 0:098463de4c5d 4
group-onsemi 0:098463de4c5d 5 import sys
group-onsemi 0:098463de4c5d 6 import os
group-onsemi 0:098463de4c5d 7 import re
group-onsemi 0:098463de4c5d 8 import csv
group-onsemi 0:098463de4c5d 9 import json
group-onsemi 0:098463de4c5d 10 import argparse
group-onsemi 0:098463de4c5d 11 from prettytable import PrettyTable
group-onsemi 0:098463de4c5d 12
group-onsemi 0:098463de4c5d 13 from utils import argparse_filestring_type, \
group-onsemi 0:098463de4c5d 14 argparse_lowercase_hyphen_type, argparse_uppercase_type
group-onsemi 0:098463de4c5d 15
group-onsemi 0:098463de4c5d 16 DEBUG = False
group-onsemi 0:098463de4c5d 17
group-onsemi 0:098463de4c5d 18 RE_ARMCC = re.compile(
group-onsemi 0:098463de4c5d 19 r'^\s+0x(\w{8})\s+0x(\w{8})\s+(\w+)\s+(\w+)\s+(\d+)\s+[*]?.+\s+(.+)$')
group-onsemi 0:098463de4c5d 20 RE_IAR = re.compile(
group-onsemi 0:098463de4c5d 21 r'^\s+(.+)\s+(zero|const|ro code|inited|uninit)\s'
group-onsemi 0:098463de4c5d 22 r'+0x(\w{8})\s+0x(\w+)\s+(.+)\s.+$')
group-onsemi 0:098463de4c5d 23
group-onsemi 0:098463de4c5d 24 class MemapParser(object):
group-onsemi 0:098463de4c5d 25 """An object that represents parsed results, parses the memory map files,
group-onsemi 0:098463de4c5d 26 and writes out different file types of memory results
group-onsemi 0:098463de4c5d 27 """
group-onsemi 0:098463de4c5d 28
group-onsemi 0:098463de4c5d 29 print_sections = ('.text', '.data', '.bss')
group-onsemi 0:098463de4c5d 30
group-onsemi 0:098463de4c5d 31 misc_flash_sections = ('.interrupts', '.flash_config')
group-onsemi 0:098463de4c5d 32
group-onsemi 0:098463de4c5d 33 other_sections = ('.interrupts_ram', '.init', '.ARM.extab',
group-onsemi 0:098463de4c5d 34 '.ARM.exidx', '.ARM.attributes', '.eh_frame',
group-onsemi 0:098463de4c5d 35 '.init_array', '.fini_array', '.jcr', '.stab',
group-onsemi 0:098463de4c5d 36 '.stabstr', '.ARM.exidx', '.ARM')
group-onsemi 0:098463de4c5d 37
group-onsemi 0:098463de4c5d 38 # sections to print info (generic for all toolchains)
group-onsemi 0:098463de4c5d 39 sections = ('.text', '.data', '.bss', '.heap', '.stack')
group-onsemi 0:098463de4c5d 40
group-onsemi 0:098463de4c5d 41 def __init__(self, detailed_misc=False):
group-onsemi 0:098463de4c5d 42 """ General initialization
group-onsemi 0:098463de4c5d 43 """
group-onsemi 0:098463de4c5d 44 #
group-onsemi 0:098463de4c5d 45 self.detailed_misc = detailed_misc
group-onsemi 0:098463de4c5d 46
group-onsemi 0:098463de4c5d 47 # list of all modules and their sections
group-onsemi 0:098463de4c5d 48 self.modules = dict()
group-onsemi 0:098463de4c5d 49
group-onsemi 0:098463de4c5d 50 # sections must be defined in this order to take irrelevant out
group-onsemi 0:098463de4c5d 51 self.all_sections = self.sections + self.other_sections + \
group-onsemi 0:098463de4c5d 52 self.misc_flash_sections + ('unknown', 'OUTPUT')
group-onsemi 0:098463de4c5d 53
group-onsemi 0:098463de4c5d 54 # list of all object files and mappting to module names
group-onsemi 0:098463de4c5d 55 self.object_to_module = dict()
group-onsemi 0:098463de4c5d 56
group-onsemi 0:098463de4c5d 57 # Memory report (sections + summary)
group-onsemi 0:098463de4c5d 58 self.mem_report = []
group-onsemi 0:098463de4c5d 59
group-onsemi 0:098463de4c5d 60 # Just the memory summary section
group-onsemi 0:098463de4c5d 61 self.mem_summary = dict()
group-onsemi 0:098463de4c5d 62
group-onsemi 0:098463de4c5d 63 self.subtotal = dict()
group-onsemi 0:098463de4c5d 64
group-onsemi 0:098463de4c5d 65 def module_add(self, module_name, size, section):
group-onsemi 0:098463de4c5d 66 """ Adds a module / section to the list
group-onsemi 0:098463de4c5d 67
group-onsemi 0:098463de4c5d 68 Positional arguments:
group-onsemi 0:098463de4c5d 69 module_name - name of the module to add
group-onsemi 0:098463de4c5d 70 size - the size of the module being added
group-onsemi 0:098463de4c5d 71 section - the section the module contributes to
group-onsemi 0:098463de4c5d 72 """
group-onsemi 0:098463de4c5d 73
group-onsemi 0:098463de4c5d 74 if module_name in self.modules:
group-onsemi 0:098463de4c5d 75 self.modules[module_name][section] += size
group-onsemi 0:098463de4c5d 76 else:
group-onsemi 0:098463de4c5d 77 temp_dic = dict()
group-onsemi 0:098463de4c5d 78 for section_idx in self.all_sections:
group-onsemi 0:098463de4c5d 79 temp_dic[section_idx] = 0
group-onsemi 0:098463de4c5d 80 temp_dic[section] = size
group-onsemi 0:098463de4c5d 81 self.modules[module_name] = temp_dic
group-onsemi 0:098463de4c5d 82
group-onsemi 0:098463de4c5d 83 def check_new_section_gcc(self, line):
group-onsemi 0:098463de4c5d 84 """ Check whether a new section in a map file has been detected (only
group-onsemi 0:098463de4c5d 85 applies to gcc)
group-onsemi 0:098463de4c5d 86
group-onsemi 0:098463de4c5d 87 Positional arguments:
group-onsemi 0:098463de4c5d 88 line - the line to check for a new section
group-onsemi 0:098463de4c5d 89 """
group-onsemi 0:098463de4c5d 90
group-onsemi 0:098463de4c5d 91 for i in self.all_sections:
group-onsemi 0:098463de4c5d 92 if line.startswith(i):
group-onsemi 0:098463de4c5d 93 # should name of the section (assuming it's a known one)
group-onsemi 0:098463de4c5d 94 return i
group-onsemi 0:098463de4c5d 95
group-onsemi 0:098463de4c5d 96 if line.startswith('.'):
group-onsemi 0:098463de4c5d 97 return 'unknown' # all others are classified are unknown
group-onsemi 0:098463de4c5d 98 else:
group-onsemi 0:098463de4c5d 99 return False # everything else, means no change in section
group-onsemi 0:098463de4c5d 100
group-onsemi 0:098463de4c5d 101
group-onsemi 0:098463de4c5d 102 def path_object_to_module_name(self, txt):
group-onsemi 0:098463de4c5d 103 """ Parse a path to object file to extract it's module and object data
group-onsemi 0:098463de4c5d 104
group-onsemi 0:098463de4c5d 105 Positional arguments:
group-onsemi 0:098463de4c5d 106 txt - the path to parse the object and module name from
group-onsemi 0:098463de4c5d 107 """
group-onsemi 0:098463de4c5d 108
group-onsemi 0:098463de4c5d 109 txt = txt.replace('\\', '/')
group-onsemi 0:098463de4c5d 110 rex_mbed_os_name = r'^.+mbed-os\/(.+)\/(.+\.o)$'
group-onsemi 0:098463de4c5d 111 test_rex_mbed_os_name = re.match(rex_mbed_os_name, txt)
group-onsemi 0:098463de4c5d 112
group-onsemi 0:098463de4c5d 113 if test_rex_mbed_os_name:
group-onsemi 0:098463de4c5d 114
group-onsemi 0:098463de4c5d 115 object_name = test_rex_mbed_os_name.group(2)
group-onsemi 0:098463de4c5d 116 data = test_rex_mbed_os_name.group(1).split('/')
group-onsemi 0:098463de4c5d 117 ndata = len(data)
group-onsemi 0:098463de4c5d 118
group-onsemi 0:098463de4c5d 119 if ndata == 1:
group-onsemi 0:098463de4c5d 120 module_name = data[0]
group-onsemi 0:098463de4c5d 121 else:
group-onsemi 0:098463de4c5d 122 module_name = data[0] + '/' + data[1]
group-onsemi 0:098463de4c5d 123
group-onsemi 0:098463de4c5d 124 return [module_name, object_name]
group-onsemi 0:098463de4c5d 125
group-onsemi 0:098463de4c5d 126 elif self.detailed_misc:
group-onsemi 0:098463de4c5d 127 rex_obj_name = r'^.+\/(.+\.o\)*)$'
group-onsemi 0:098463de4c5d 128 test_rex_obj_name = re.match(rex_obj_name, txt)
group-onsemi 0:098463de4c5d 129 if test_rex_obj_name:
group-onsemi 0:098463de4c5d 130 object_name = test_rex_obj_name.group(1)
group-onsemi 0:098463de4c5d 131 return ['Misc/' + object_name, ""]
group-onsemi 0:098463de4c5d 132
group-onsemi 0:098463de4c5d 133 return ['Misc', ""]
group-onsemi 0:098463de4c5d 134 else:
group-onsemi 0:098463de4c5d 135 return ['Misc', ""]
group-onsemi 0:098463de4c5d 136
group-onsemi 0:098463de4c5d 137 def parse_section_gcc(self, line):
group-onsemi 0:098463de4c5d 138 """ Parse data from a section of gcc map file
group-onsemi 0:098463de4c5d 139
group-onsemi 0:098463de4c5d 140 examples:
group-onsemi 0:098463de4c5d 141 0x00004308 0x7c ./BUILD/K64F/GCC_ARM/mbed-os/hal/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/spi_api.o
group-onsemi 0:098463de4c5d 142 .text 0x00000608 0x198 ./BUILD/K64F/GCC_ARM/mbed-os/core/mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.o
group-onsemi 0:098463de4c5d 143
group-onsemi 0:098463de4c5d 144 Positional arguments:
group-onsemi 0:098463de4c5d 145 line - the line to parse a section from
group-onsemi 0:098463de4c5d 146 """
group-onsemi 0:098463de4c5d 147 rex_address_len_name = re.compile(
group-onsemi 0:098463de4c5d 148 r'^\s+.*0x(\w{8,16})\s+0x(\w+)\s(.+)$')
group-onsemi 0:098463de4c5d 149
group-onsemi 0:098463de4c5d 150 test_address_len_name = re.match(rex_address_len_name, line)
group-onsemi 0:098463de4c5d 151
group-onsemi 0:098463de4c5d 152 if test_address_len_name:
group-onsemi 0:098463de4c5d 153
group-onsemi 0:098463de4c5d 154 if int(test_address_len_name.group(2), 16) == 0: # size == 0
group-onsemi 0:098463de4c5d 155 return ["", 0] # no valid entry
group-onsemi 0:098463de4c5d 156 else:
group-onsemi 0:098463de4c5d 157 m_name, _ = self.path_object_to_module_name(
group-onsemi 0:098463de4c5d 158 test_address_len_name.group(3))
group-onsemi 0:098463de4c5d 159 m_size = int(test_address_len_name.group(2), 16)
group-onsemi 0:098463de4c5d 160 return [m_name, m_size]
group-onsemi 0:098463de4c5d 161
group-onsemi 0:098463de4c5d 162 else: # special corner case for *fill* sections
group-onsemi 0:098463de4c5d 163 # example
group-onsemi 0:098463de4c5d 164 # *fill* 0x0000abe4 0x4
group-onsemi 0:098463de4c5d 165 rex_address_len = r'^\s+\*fill\*\s+0x(\w{8,16})\s+0x(\w+).*$'
group-onsemi 0:098463de4c5d 166 test_address_len = re.match(rex_address_len, line)
group-onsemi 0:098463de4c5d 167
group-onsemi 0:098463de4c5d 168 if test_address_len:
group-onsemi 0:098463de4c5d 169 if int(test_address_len.group(2), 16) == 0: # size == 0
group-onsemi 0:098463de4c5d 170 return ["", 0] # no valid entry
group-onsemi 0:098463de4c5d 171 else:
group-onsemi 0:098463de4c5d 172 m_name = 'Fill'
group-onsemi 0:098463de4c5d 173 m_size = int(test_address_len.group(2), 16)
group-onsemi 0:098463de4c5d 174 return [m_name, m_size]
group-onsemi 0:098463de4c5d 175 else:
group-onsemi 0:098463de4c5d 176 return ["", 0] # no valid entry
group-onsemi 0:098463de4c5d 177
group-onsemi 0:098463de4c5d 178 def parse_map_file_gcc(self, file_desc):
group-onsemi 0:098463de4c5d 179 """ Main logic to decode gcc map files
group-onsemi 0:098463de4c5d 180
group-onsemi 0:098463de4c5d 181 Positional arguments:
group-onsemi 0:098463de4c5d 182 file_desc - a stream object to parse as a gcc map file
group-onsemi 0:098463de4c5d 183 """
group-onsemi 0:098463de4c5d 184
group-onsemi 0:098463de4c5d 185 current_section = 'unknown'
group-onsemi 0:098463de4c5d 186
group-onsemi 0:098463de4c5d 187 with file_desc as infile:
group-onsemi 0:098463de4c5d 188
group-onsemi 0:098463de4c5d 189 # Search area to parse
group-onsemi 0:098463de4c5d 190 for line in infile:
group-onsemi 0:098463de4c5d 191 if line.startswith('Linker script and memory map'):
group-onsemi 0:098463de4c5d 192 current_section = "unknown"
group-onsemi 0:098463de4c5d 193 break
group-onsemi 0:098463de4c5d 194
group-onsemi 0:098463de4c5d 195 # Start decoding the map file
group-onsemi 0:098463de4c5d 196 for line in infile:
group-onsemi 0:098463de4c5d 197
group-onsemi 0:098463de4c5d 198 change_section = self.check_new_section_gcc(line)
group-onsemi 0:098463de4c5d 199
group-onsemi 0:098463de4c5d 200 if change_section == "OUTPUT": # finish parsing file: exit
group-onsemi 0:098463de4c5d 201 break
group-onsemi 0:098463de4c5d 202 elif change_section != False:
group-onsemi 0:098463de4c5d 203 current_section = change_section
group-onsemi 0:098463de4c5d 204
group-onsemi 0:098463de4c5d 205 [module_name, module_size] = self.parse_section_gcc(line)
group-onsemi 0:098463de4c5d 206
group-onsemi 0:098463de4c5d 207 if module_size == 0 or module_name == "":
group-onsemi 0:098463de4c5d 208 pass
group-onsemi 0:098463de4c5d 209 else:
group-onsemi 0:098463de4c5d 210 self.module_add(module_name, module_size, current_section)
group-onsemi 0:098463de4c5d 211
group-onsemi 0:098463de4c5d 212 if DEBUG:
group-onsemi 0:098463de4c5d 213 print "Line: %s" % line,
group-onsemi 0:098463de4c5d 214 print "Module: %s\tSection: %s\tSize: %s" % \
group-onsemi 0:098463de4c5d 215 (module_name, current_section, module_size)
group-onsemi 0:098463de4c5d 216 raw_input("----------")
group-onsemi 0:098463de4c5d 217
group-onsemi 0:098463de4c5d 218 def parse_section_armcc(self, line):
group-onsemi 0:098463de4c5d 219 """ Parse data from an armcc map file
group-onsemi 0:098463de4c5d 220
group-onsemi 0:098463de4c5d 221 Examples of armcc map file:
group-onsemi 0:098463de4c5d 222 Base_Addr Size Type Attr Idx E Section Name Object
group-onsemi 0:098463de4c5d 223 0x00000000 0x00000400 Data RO 11222 RESET startup_MK64F12.o
group-onsemi 0:098463de4c5d 224 0x00000410 0x00000008 Code RO 49364 * !!!main c_w.l(__main.o)
group-onsemi 0:098463de4c5d 225
group-onsemi 0:098463de4c5d 226 Positional arguments:
group-onsemi 0:098463de4c5d 227 line - the line to parse the section data from
group-onsemi 0:098463de4c5d 228 """
group-onsemi 0:098463de4c5d 229
group-onsemi 0:098463de4c5d 230 test_rex_armcc = re.match(RE_ARMCC, line)
group-onsemi 0:098463de4c5d 231
group-onsemi 0:098463de4c5d 232 if test_rex_armcc:
group-onsemi 0:098463de4c5d 233
group-onsemi 0:098463de4c5d 234 size = int(test_rex_armcc.group(2), 16)
group-onsemi 0:098463de4c5d 235
group-onsemi 0:098463de4c5d 236 if test_rex_armcc.group(4) == 'RO':
group-onsemi 0:098463de4c5d 237 section = '.text'
group-onsemi 0:098463de4c5d 238 else:
group-onsemi 0:098463de4c5d 239 if test_rex_armcc.group(3) == 'Data':
group-onsemi 0:098463de4c5d 240 section = '.data'
group-onsemi 0:098463de4c5d 241 elif test_rex_armcc.group(3) == 'Zero':
group-onsemi 0:098463de4c5d 242 section = '.bss'
group-onsemi 0:098463de4c5d 243 else:
group-onsemi 0:098463de4c5d 244 print "BUG armcc map parser"
group-onsemi 0:098463de4c5d 245 raw_input()
group-onsemi 0:098463de4c5d 246
group-onsemi 0:098463de4c5d 247 # lookup object in dictionary and return module name
group-onsemi 0:098463de4c5d 248 object_name = test_rex_armcc.group(6)
group-onsemi 0:098463de4c5d 249 if object_name in self.object_to_module:
group-onsemi 0:098463de4c5d 250 module_name = self.object_to_module[object_name]
group-onsemi 0:098463de4c5d 251 else:
group-onsemi 0:098463de4c5d 252 module_name = 'Misc'
group-onsemi 0:098463de4c5d 253
group-onsemi 0:098463de4c5d 254 return [module_name, size, section]
group-onsemi 0:098463de4c5d 255
group-onsemi 0:098463de4c5d 256 else:
group-onsemi 0:098463de4c5d 257 return ["", 0, ""] # no valid entry
group-onsemi 0:098463de4c5d 258
group-onsemi 0:098463de4c5d 259 def parse_section_iar(self, line):
group-onsemi 0:098463de4c5d 260 """ Parse data from an IAR map file
group-onsemi 0:098463de4c5d 261
group-onsemi 0:098463de4c5d 262 Examples of IAR map file:
group-onsemi 0:098463de4c5d 263 Section Kind Address Size Object
group-onsemi 0:098463de4c5d 264 .intvec ro code 0x00000000 0x198 startup_MK64F12.o [15]
group-onsemi 0:098463de4c5d 265 .rodata const 0x00000198 0x0 zero_init3.o [133]
group-onsemi 0:098463de4c5d 266 .iar.init_table const 0x00008384 0x2c - Linker created -
group-onsemi 0:098463de4c5d 267 Initializer bytes const 0x00000198 0xb2 <for P3 s0>
group-onsemi 0:098463de4c5d 268 .data inited 0x20000000 0xd4 driverAtmelRFInterface.o [70]
group-onsemi 0:098463de4c5d 269 .bss zero 0x20000598 0x318 RTX_Conf_CM.o [4]
group-onsemi 0:098463de4c5d 270 .iar.dynexit uninit 0x20001448 0x204 <Block tail>
group-onsemi 0:098463de4c5d 271 HEAP uninit 0x20001650 0x10000 <Block tail>
group-onsemi 0:098463de4c5d 272
group-onsemi 0:098463de4c5d 273 Positional_arguments:
group-onsemi 0:098463de4c5d 274 line - the line to parse section data from
group-onsemi 0:098463de4c5d 275 """
group-onsemi 0:098463de4c5d 276
group-onsemi 0:098463de4c5d 277 test_rex_iar = re.match(RE_IAR, line)
group-onsemi 0:098463de4c5d 278
group-onsemi 0:098463de4c5d 279 if test_rex_iar:
group-onsemi 0:098463de4c5d 280
group-onsemi 0:098463de4c5d 281 size = int(test_rex_iar.group(4), 16)
group-onsemi 0:098463de4c5d 282
group-onsemi 0:098463de4c5d 283 if test_rex_iar.group(2) == 'const' or \
group-onsemi 0:098463de4c5d 284 test_rex_iar.group(2) == 'ro code':
group-onsemi 0:098463de4c5d 285 section = '.text'
group-onsemi 0:098463de4c5d 286 elif test_rex_iar.group(2) == 'zero' or \
group-onsemi 0:098463de4c5d 287 test_rex_iar.group(2) == 'uninit':
group-onsemi 0:098463de4c5d 288 if test_rex_iar.group(1)[0:4] == 'HEAP':
group-onsemi 0:098463de4c5d 289 section = '.heap'
group-onsemi 0:098463de4c5d 290 elif test_rex_iar.group(1)[0:6] == 'CSTACK':
group-onsemi 0:098463de4c5d 291 section = '.stack'
group-onsemi 0:098463de4c5d 292 else:
group-onsemi 0:098463de4c5d 293 section = '.bss' # default section
group-onsemi 0:098463de4c5d 294
group-onsemi 0:098463de4c5d 295 elif test_rex_iar.group(2) == 'inited':
group-onsemi 0:098463de4c5d 296 section = '.data'
group-onsemi 0:098463de4c5d 297 else:
group-onsemi 0:098463de4c5d 298 print "BUG IAR map parser"
group-onsemi 0:098463de4c5d 299 raw_input()
group-onsemi 0:098463de4c5d 300
group-onsemi 0:098463de4c5d 301 # lookup object in dictionary and return module name
group-onsemi 0:098463de4c5d 302 object_name = test_rex_iar.group(5)
group-onsemi 0:098463de4c5d 303 if object_name in self.object_to_module:
group-onsemi 0:098463de4c5d 304 module_name = self.object_to_module[object_name]
group-onsemi 0:098463de4c5d 305 else:
group-onsemi 0:098463de4c5d 306 module_name = 'Misc'
group-onsemi 0:098463de4c5d 307
group-onsemi 0:098463de4c5d 308 return [module_name, size, section]
group-onsemi 0:098463de4c5d 309
group-onsemi 0:098463de4c5d 310 else:
group-onsemi 0:098463de4c5d 311 return ["", 0, ""] # no valid entry
group-onsemi 0:098463de4c5d 312
group-onsemi 0:098463de4c5d 313 def parse_map_file_armcc(self, file_desc):
group-onsemi 0:098463de4c5d 314 """ Main logic to decode armc5 map files
group-onsemi 0:098463de4c5d 315
group-onsemi 0:098463de4c5d 316 Positional arguments:
group-onsemi 0:098463de4c5d 317 file_desc - a file like object to parse as an armc5 map file
group-onsemi 0:098463de4c5d 318 """
group-onsemi 0:098463de4c5d 319
group-onsemi 0:098463de4c5d 320 with file_desc as infile:
group-onsemi 0:098463de4c5d 321
group-onsemi 0:098463de4c5d 322 # Search area to parse
group-onsemi 0:098463de4c5d 323 for line in infile:
group-onsemi 0:098463de4c5d 324 if line.startswith(' Base Addr Size'):
group-onsemi 0:098463de4c5d 325 break
group-onsemi 0:098463de4c5d 326
group-onsemi 0:098463de4c5d 327 # Start decoding the map file
group-onsemi 0:098463de4c5d 328 for line in infile:
group-onsemi 0:098463de4c5d 329
group-onsemi 0:098463de4c5d 330 [name, size, section] = self.parse_section_armcc(line)
group-onsemi 0:098463de4c5d 331
group-onsemi 0:098463de4c5d 332 if size == 0 or name == "" or section == "":
group-onsemi 0:098463de4c5d 333 pass
group-onsemi 0:098463de4c5d 334 else:
group-onsemi 0:098463de4c5d 335 self.module_add(name, size, section)
group-onsemi 0:098463de4c5d 336
group-onsemi 0:098463de4c5d 337 def parse_map_file_iar(self, file_desc):
group-onsemi 0:098463de4c5d 338 """ Main logic to decode IAR map files
group-onsemi 0:098463de4c5d 339
group-onsemi 0:098463de4c5d 340 Positional arguments:
group-onsemi 0:098463de4c5d 341 file_desc - a file like object to parse as an IAR map file
group-onsemi 0:098463de4c5d 342 """
group-onsemi 0:098463de4c5d 343
group-onsemi 0:098463de4c5d 344 with file_desc as infile:
group-onsemi 0:098463de4c5d 345
group-onsemi 0:098463de4c5d 346 # Search area to parse
group-onsemi 0:098463de4c5d 347 for line in infile:
group-onsemi 0:098463de4c5d 348 if line.startswith(' Section '):
group-onsemi 0:098463de4c5d 349 break
group-onsemi 0:098463de4c5d 350
group-onsemi 0:098463de4c5d 351 # Start decoding the map file
group-onsemi 0:098463de4c5d 352 for line in infile:
group-onsemi 0:098463de4c5d 353
group-onsemi 0:098463de4c5d 354 [name, size, section] = self.parse_section_iar(line)
group-onsemi 0:098463de4c5d 355
group-onsemi 0:098463de4c5d 356 if size == 0 or name == "" or section == "":
group-onsemi 0:098463de4c5d 357 pass
group-onsemi 0:098463de4c5d 358 else:
group-onsemi 0:098463de4c5d 359 self.module_add(name, size, section)
group-onsemi 0:098463de4c5d 360
group-onsemi 0:098463de4c5d 361 def search_objects(self, path):
group-onsemi 0:098463de4c5d 362 """ Searches for object files and creates mapping: object --> module
group-onsemi 0:098463de4c5d 363
group-onsemi 0:098463de4c5d 364 Positional arguments:
group-onsemi 0:098463de4c5d 365 path - the path to an object file
group-onsemi 0:098463de4c5d 366 """
group-onsemi 0:098463de4c5d 367
group-onsemi 0:098463de4c5d 368 path = path.replace('\\', '/')
group-onsemi 0:098463de4c5d 369
group-onsemi 0:098463de4c5d 370 # check location of map file
group-onsemi 0:098463de4c5d 371 rex = r'^(.+)' + r'\/(.+\.map)$'
group-onsemi 0:098463de4c5d 372 test_rex = re.match(rex, path)
group-onsemi 0:098463de4c5d 373
group-onsemi 0:098463de4c5d 374 if test_rex:
group-onsemi 0:098463de4c5d 375 search_path = test_rex.group(1) + '/mbed-os/'
group-onsemi 0:098463de4c5d 376 else:
group-onsemi 0:098463de4c5d 377 print "Warning: this doesn't look like an mbed project"
group-onsemi 0:098463de4c5d 378 return
group-onsemi 0:098463de4c5d 379
group-onsemi 0:098463de4c5d 380 for root, _, obj_files in os.walk(search_path):
group-onsemi 0:098463de4c5d 381 for obj_file in obj_files:
group-onsemi 0:098463de4c5d 382 if obj_file.endswith(".o"):
group-onsemi 0:098463de4c5d 383 module_name, object_name = self.path_object_to_module_name(
group-onsemi 0:098463de4c5d 384 os.path.join(root, obj_file))
group-onsemi 0:098463de4c5d 385
group-onsemi 0:098463de4c5d 386 if object_name in self.object_to_module:
group-onsemi 0:098463de4c5d 387 if DEBUG:
group-onsemi 0:098463de4c5d 388 print "WARNING: multiple usages of object file: %s"\
group-onsemi 0:098463de4c5d 389 % object_name
group-onsemi 0:098463de4c5d 390 print " Current: %s" % \
group-onsemi 0:098463de4c5d 391 self.object_to_module[object_name]
group-onsemi 0:098463de4c5d 392 print " New: %s" % module_name
group-onsemi 0:098463de4c5d 393 print " "
group-onsemi 0:098463de4c5d 394 else:
group-onsemi 0:098463de4c5d 395 self.object_to_module.update({object_name:module_name})
group-onsemi 0:098463de4c5d 396
group-onsemi 0:098463de4c5d 397 export_formats = ["json", "csv-ci", "table"]
group-onsemi 0:098463de4c5d 398
group-onsemi 0:098463de4c5d 399 def generate_output(self, export_format, file_output=None):
group-onsemi 0:098463de4c5d 400 """ Generates summary of memory map data
group-onsemi 0:098463de4c5d 401
group-onsemi 0:098463de4c5d 402 Positional arguments:
group-onsemi 0:098463de4c5d 403 export_format - the format to dump
group-onsemi 0:098463de4c5d 404
group-onsemi 0:098463de4c5d 405 Keyword arguments:
group-onsemi 0:098463de4c5d 406 file_desc - descriptor (either stdout or file)
group-onsemi 0:098463de4c5d 407
group-onsemi 0:098463de4c5d 408 Returns: generated string for the 'table' format, otherwise None
group-onsemi 0:098463de4c5d 409 """
group-onsemi 0:098463de4c5d 410
group-onsemi 0:098463de4c5d 411 try:
group-onsemi 0:098463de4c5d 412 if file_output:
group-onsemi 0:098463de4c5d 413 file_desc = open(file_output, 'wb')
group-onsemi 0:098463de4c5d 414 else:
group-onsemi 0:098463de4c5d 415 file_desc = sys.stdout
group-onsemi 0:098463de4c5d 416 except IOError as error:
group-onsemi 0:098463de4c5d 417 print "I/O error({0}): {1}".format(error.errno, error.strerror)
group-onsemi 0:098463de4c5d 418 return False
group-onsemi 0:098463de4c5d 419
group-onsemi 0:098463de4c5d 420 to_call = {'json': self.generate_json,
group-onsemi 0:098463de4c5d 421 'csv-ci': self.generate_csv,
group-onsemi 0:098463de4c5d 422 'table': self.generate_table}[export_format]
group-onsemi 0:098463de4c5d 423 output = to_call(file_desc)
group-onsemi 0:098463de4c5d 424
group-onsemi 0:098463de4c5d 425 if file_desc is not sys.stdout:
group-onsemi 0:098463de4c5d 426 file_desc.close()
group-onsemi 0:098463de4c5d 427
group-onsemi 0:098463de4c5d 428 return output
group-onsemi 0:098463de4c5d 429
group-onsemi 0:098463de4c5d 430 def generate_json(self, file_desc):
group-onsemi 0:098463de4c5d 431 """Generate a json file from a memory map
group-onsemi 0:098463de4c5d 432
group-onsemi 0:098463de4c5d 433 Positional arguments:
group-onsemi 0:098463de4c5d 434 file_desc - the file to write out the final report to
group-onsemi 0:098463de4c5d 435 """
group-onsemi 0:098463de4c5d 436 file_desc.write(json.dumps(self.mem_report, indent=4))
group-onsemi 0:098463de4c5d 437 file_desc.write('\n')
group-onsemi 0:098463de4c5d 438
group-onsemi 0:098463de4c5d 439 return None
group-onsemi 0:098463de4c5d 440
group-onsemi 0:098463de4c5d 441 def generate_csv(self, file_desc):
group-onsemi 0:098463de4c5d 442 """Generate a CSV file from a memoy map
group-onsemi 0:098463de4c5d 443
group-onsemi 0:098463de4c5d 444 Positional arguments:
group-onsemi 0:098463de4c5d 445 file_desc - the file to write out the final report to
group-onsemi 0:098463de4c5d 446 """
group-onsemi 0:098463de4c5d 447 csv_writer = csv.writer(file_desc, delimiter=',',
group-onsemi 0:098463de4c5d 448 quoting=csv.QUOTE_MINIMAL)
group-onsemi 0:098463de4c5d 449
group-onsemi 0:098463de4c5d 450 csv_module_section = []
group-onsemi 0:098463de4c5d 451 csv_sizes = []
group-onsemi 0:098463de4c5d 452 for i in sorted(self.modules):
group-onsemi 0:098463de4c5d 453 for k in self.print_sections:
group-onsemi 0:098463de4c5d 454 csv_module_section += [i+k]
group-onsemi 0:098463de4c5d 455 csv_sizes += [self.modules[i][k]]
group-onsemi 0:098463de4c5d 456
group-onsemi 0:098463de4c5d 457 csv_module_section += ['static_ram']
group-onsemi 0:098463de4c5d 458 csv_sizes += [self.mem_summary['static_ram']]
group-onsemi 0:098463de4c5d 459
group-onsemi 0:098463de4c5d 460 csv_module_section += ['heap']
group-onsemi 0:098463de4c5d 461 if self.mem_summary['heap'] == 0:
group-onsemi 0:098463de4c5d 462 csv_sizes += ['unknown']
group-onsemi 0:098463de4c5d 463 else:
group-onsemi 0:098463de4c5d 464 csv_sizes += [self.mem_summary['heap']]
group-onsemi 0:098463de4c5d 465
group-onsemi 0:098463de4c5d 466 csv_module_section += ['stack']
group-onsemi 0:098463de4c5d 467 if self.mem_summary['stack'] == 0:
group-onsemi 0:098463de4c5d 468 csv_sizes += ['unknown']
group-onsemi 0:098463de4c5d 469 else:
group-onsemi 0:098463de4c5d 470 csv_sizes += [self.mem_summary['stack']]
group-onsemi 0:098463de4c5d 471
group-onsemi 0:098463de4c5d 472 csv_module_section += ['total_ram']
group-onsemi 0:098463de4c5d 473 csv_sizes += [self.mem_summary['total_ram']]
group-onsemi 0:098463de4c5d 474
group-onsemi 0:098463de4c5d 475 csv_module_section += ['total_flash']
group-onsemi 0:098463de4c5d 476 csv_sizes += [self.mem_summary['total_flash']]
group-onsemi 0:098463de4c5d 477
group-onsemi 0:098463de4c5d 478 csv_writer.writerow(csv_module_section)
group-onsemi 0:098463de4c5d 479 csv_writer.writerow(csv_sizes)
group-onsemi 0:098463de4c5d 480
group-onsemi 0:098463de4c5d 481 return None
group-onsemi 0:098463de4c5d 482
group-onsemi 0:098463de4c5d 483 def generate_table(self, file_desc):
group-onsemi 0:098463de4c5d 484 """Generate a table from a memoy map
group-onsemi 0:098463de4c5d 485
group-onsemi 0:098463de4c5d 486 Positional arguments:
group-onsemi 0:098463de4c5d 487 file_desc - the file to write out the final report to
group-onsemi 0:098463de4c5d 488
group-onsemi 0:098463de4c5d 489 Returns: string of the generated table
group-onsemi 0:098463de4c5d 490 """
group-onsemi 0:098463de4c5d 491 # Create table
group-onsemi 0:098463de4c5d 492 columns = ['Module']
group-onsemi 0:098463de4c5d 493 columns.extend(self.print_sections)
group-onsemi 0:098463de4c5d 494
group-onsemi 0:098463de4c5d 495 table = PrettyTable(columns)
group-onsemi 0:098463de4c5d 496 table.align["Module"] = "l"
group-onsemi 0:098463de4c5d 497 for col in self.print_sections:
group-onsemi 0:098463de4c5d 498 table.align[col] = 'r'
group-onsemi 0:098463de4c5d 499
group-onsemi 0:098463de4c5d 500 for i in list(self.print_sections):
group-onsemi 0:098463de4c5d 501 table.align[i] = 'r'
group-onsemi 0:098463de4c5d 502
group-onsemi 0:098463de4c5d 503 for i in sorted(self.modules):
group-onsemi 0:098463de4c5d 504 row = [i]
group-onsemi 0:098463de4c5d 505
group-onsemi 0:098463de4c5d 506 for k in self.print_sections:
group-onsemi 0:098463de4c5d 507 row.append(self.modules[i][k])
group-onsemi 0:098463de4c5d 508
group-onsemi 0:098463de4c5d 509 table.add_row(row)
group-onsemi 0:098463de4c5d 510
group-onsemi 0:098463de4c5d 511 subtotal_row = ['Subtotals']
group-onsemi 0:098463de4c5d 512 for k in self.print_sections:
group-onsemi 0:098463de4c5d 513 subtotal_row.append(self.subtotal[k])
group-onsemi 0:098463de4c5d 514
group-onsemi 0:098463de4c5d 515 table.add_row(subtotal_row)
group-onsemi 0:098463de4c5d 516
group-onsemi 0:098463de4c5d 517 output = table.get_string()
group-onsemi 0:098463de4c5d 518 output += '\n'
group-onsemi 0:098463de4c5d 519
group-onsemi 0:098463de4c5d 520 if self.mem_summary['heap'] == 0:
group-onsemi 0:098463de4c5d 521 output += "Allocated Heap: unknown\n"
group-onsemi 0:098463de4c5d 522 else:
group-onsemi 0:098463de4c5d 523 output += "Allocated Heap: %s bytes\n" % \
group-onsemi 0:098463de4c5d 524 str(self.mem_summary['heap'])
group-onsemi 0:098463de4c5d 525
group-onsemi 0:098463de4c5d 526 if self.mem_summary['stack'] == 0:
group-onsemi 0:098463de4c5d 527 output += "Allocated Stack: unknown\n"
group-onsemi 0:098463de4c5d 528 else:
group-onsemi 0:098463de4c5d 529 output += "Allocated Stack: %s bytes\n" % \
group-onsemi 0:098463de4c5d 530 str(self.mem_summary['stack'])
group-onsemi 0:098463de4c5d 531
group-onsemi 0:098463de4c5d 532 output += "Total Static RAM memory (data + bss): %s bytes\n" % \
group-onsemi 0:098463de4c5d 533 str(self.mem_summary['static_ram'])
group-onsemi 0:098463de4c5d 534 output += "Total RAM memory (data + bss + heap + stack): %s bytes\n" % \
group-onsemi 0:098463de4c5d 535 str(self.mem_summary['total_ram'])
group-onsemi 0:098463de4c5d 536 output += "Total Flash memory (text + data + misc): %s bytes\n" % \
group-onsemi 0:098463de4c5d 537 str(self.mem_summary['total_flash'])
group-onsemi 0:098463de4c5d 538
group-onsemi 0:098463de4c5d 539 return output
group-onsemi 0:098463de4c5d 540
group-onsemi 0:098463de4c5d 541 toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"]
group-onsemi 0:098463de4c5d 542
group-onsemi 0:098463de4c5d 543 def compute_report(self):
group-onsemi 0:098463de4c5d 544 for k in self.sections:
group-onsemi 0:098463de4c5d 545 self.subtotal[k] = 0
group-onsemi 0:098463de4c5d 546
group-onsemi 0:098463de4c5d 547 for i in sorted(self.modules):
group-onsemi 0:098463de4c5d 548 for k in self.sections:
group-onsemi 0:098463de4c5d 549 self.subtotal[k] += self.modules[i][k]
group-onsemi 0:098463de4c5d 550
group-onsemi 0:098463de4c5d 551 # Calculate misc flash sections
group-onsemi 0:098463de4c5d 552 self.misc_flash_mem = 0
group-onsemi 0:098463de4c5d 553 for i in self.modules:
group-onsemi 0:098463de4c5d 554 for k in self.misc_flash_sections:
group-onsemi 0:098463de4c5d 555 if self.modules[i][k]:
group-onsemi 0:098463de4c5d 556 self.misc_flash_mem += self.modules[i][k]
group-onsemi 0:098463de4c5d 557
group-onsemi 0:098463de4c5d 558 self.mem_summary = {
group-onsemi 0:098463de4c5d 559 'static_ram': (self.subtotal['.data'] + self.subtotal['.bss']),
group-onsemi 0:098463de4c5d 560 'heap': (self.subtotal['.heap']),
group-onsemi 0:098463de4c5d 561 'stack': (self.subtotal['.stack']),
group-onsemi 0:098463de4c5d 562 'total_ram': (self.subtotal['.data'] + self.subtotal['.bss'] +
group-onsemi 0:098463de4c5d 563 self.subtotal['.heap']+self.subtotal['.stack']),
group-onsemi 0:098463de4c5d 564 'total_flash': (self.subtotal['.text'] + self.subtotal['.data'] +
group-onsemi 0:098463de4c5d 565 self.misc_flash_mem),
group-onsemi 0:098463de4c5d 566 }
group-onsemi 0:098463de4c5d 567
group-onsemi 0:098463de4c5d 568 self.mem_report = []
group-onsemi 0:098463de4c5d 569 for i in sorted(self.modules):
group-onsemi 0:098463de4c5d 570 self.mem_report.append({
group-onsemi 0:098463de4c5d 571 "module":i,
group-onsemi 0:098463de4c5d 572 "size":{
group-onsemi 0:098463de4c5d 573 k:self.modules[i][k] for k in self.print_sections
group-onsemi 0:098463de4c5d 574 }
group-onsemi 0:098463de4c5d 575 })
group-onsemi 0:098463de4c5d 576
group-onsemi 0:098463de4c5d 577 self.mem_report.append({
group-onsemi 0:098463de4c5d 578 'summary': self.mem_summary
group-onsemi 0:098463de4c5d 579 })
group-onsemi 0:098463de4c5d 580
group-onsemi 0:098463de4c5d 581 def parse(self, mapfile, toolchain):
group-onsemi 0:098463de4c5d 582 """ Parse and decode map file depending on the toolchain
group-onsemi 0:098463de4c5d 583
group-onsemi 0:098463de4c5d 584 Positional arguments:
group-onsemi 0:098463de4c5d 585 mapfile - the file name of the memory map file
group-onsemi 0:098463de4c5d 586 toolchain - the toolchain used to create the file
group-onsemi 0:098463de4c5d 587 """
group-onsemi 0:098463de4c5d 588
group-onsemi 0:098463de4c5d 589 result = True
group-onsemi 0:098463de4c5d 590 try:
group-onsemi 0:098463de4c5d 591 with open(mapfile, 'r') as file_input:
group-onsemi 0:098463de4c5d 592 if toolchain == "ARM" or toolchain == "ARM_STD" or\
group-onsemi 0:098463de4c5d 593 toolchain == "ARM_MICRO":
group-onsemi 0:098463de4c5d 594 self.search_objects(os.path.abspath(mapfile))
group-onsemi 0:098463de4c5d 595 self.parse_map_file_armcc(file_input)
group-onsemi 0:098463de4c5d 596 elif toolchain == "GCC_ARM":
group-onsemi 0:098463de4c5d 597 self.parse_map_file_gcc(file_input)
group-onsemi 0:098463de4c5d 598 elif toolchain == "IAR":
group-onsemi 0:098463de4c5d 599 self.search_objects(os.path.abspath(mapfile))
group-onsemi 0:098463de4c5d 600 self.parse_map_file_iar(file_input)
group-onsemi 0:098463de4c5d 601 else:
group-onsemi 0:098463de4c5d 602 result = False
group-onsemi 0:098463de4c5d 603
group-onsemi 0:098463de4c5d 604 self.compute_report()
group-onsemi 0:098463de4c5d 605
group-onsemi 0:098463de4c5d 606 except IOError as error:
group-onsemi 0:098463de4c5d 607 print "I/O error({0}): {1}".format(error.errno, error.strerror)
group-onsemi 0:098463de4c5d 608 result = False
group-onsemi 0:098463de4c5d 609 return result
group-onsemi 0:098463de4c5d 610
group-onsemi 0:098463de4c5d 611 def main():
group-onsemi 0:098463de4c5d 612 """Entry Point"""
group-onsemi 0:098463de4c5d 613
group-onsemi 0:098463de4c5d 614 version = '0.3.12'
group-onsemi 0:098463de4c5d 615
group-onsemi 0:098463de4c5d 616 # Parser handling
group-onsemi 0:098463de4c5d 617 parser = argparse.ArgumentParser(
group-onsemi 0:098463de4c5d 618 description="Memory Map File Analyser for ARM mbed\nversion %s" %
group-onsemi 0:098463de4c5d 619 version)
group-onsemi 0:098463de4c5d 620
group-onsemi 0:098463de4c5d 621 parser.add_argument(
group-onsemi 0:098463de4c5d 622 'file', type=argparse_filestring_type, help='memory map file')
group-onsemi 0:098463de4c5d 623
group-onsemi 0:098463de4c5d 624 parser.add_argument(
group-onsemi 0:098463de4c5d 625 '-t', '--toolchain', dest='toolchain',
group-onsemi 0:098463de4c5d 626 help='select a toolchain used to build the memory map file (%s)' %
group-onsemi 0:098463de4c5d 627 ", ".join(MemapParser.toolchains),
group-onsemi 0:098463de4c5d 628 required=True,
group-onsemi 0:098463de4c5d 629 type=argparse_uppercase_type(MemapParser.toolchains, "toolchain"))
group-onsemi 0:098463de4c5d 630
group-onsemi 0:098463de4c5d 631 parser.add_argument(
group-onsemi 0:098463de4c5d 632 '-o', '--output', help='output file name', required=False)
group-onsemi 0:098463de4c5d 633
group-onsemi 0:098463de4c5d 634 parser.add_argument(
group-onsemi 0:098463de4c5d 635 '-e', '--export', dest='export', required=False, default='table',
group-onsemi 0:098463de4c5d 636 type=argparse_lowercase_hyphen_type(MemapParser.export_formats,
group-onsemi 0:098463de4c5d 637 'export format'),
group-onsemi 0:098463de4c5d 638 help="export format (examples: %s: default)" %
group-onsemi 0:098463de4c5d 639 ", ".join(MemapParser.export_formats))
group-onsemi 0:098463de4c5d 640
group-onsemi 0:098463de4c5d 641 parser.add_argument('-v', '--version', action='version', version=version)
group-onsemi 0:098463de4c5d 642
group-onsemi 0:098463de4c5d 643 parser.add_argument('-d', '--detailed', action='store_true', help='Displays the elements in "Misc" in a detailed fashion', required=False)
group-onsemi 0:098463de4c5d 644
group-onsemi 0:098463de4c5d 645 # Parse/run command
group-onsemi 0:098463de4c5d 646 if len(sys.argv) <= 1:
group-onsemi 0:098463de4c5d 647 parser.print_help()
group-onsemi 0:098463de4c5d 648 sys.exit(1)
group-onsemi 0:098463de4c5d 649
group-onsemi 0:098463de4c5d 650
group-onsemi 0:098463de4c5d 651 args = parser.parse_args()
group-onsemi 0:098463de4c5d 652
group-onsemi 0:098463de4c5d 653 # Create memap object
group-onsemi 0:098463de4c5d 654 memap = MemapParser(detailed_misc=args.detailed)
group-onsemi 0:098463de4c5d 655
group-onsemi 0:098463de4c5d 656 # Parse and decode a map file
group-onsemi 0:098463de4c5d 657 if args.file and args.toolchain:
group-onsemi 0:098463de4c5d 658 if memap.parse(args.file, args.toolchain) is False:
group-onsemi 0:098463de4c5d 659 sys.exit(0)
group-onsemi 0:098463de4c5d 660
group-onsemi 0:098463de4c5d 661 returned_string = None
group-onsemi 0:098463de4c5d 662 # Write output in file
group-onsemi 0:098463de4c5d 663 if args.output != None:
group-onsemi 0:098463de4c5d 664 returned_string = memap.generate_output(args.export, args.output)
group-onsemi 0:098463de4c5d 665 else: # Write output in screen
group-onsemi 0:098463de4c5d 666 returned_string = memap.generate_output(args.export)
group-onsemi 0:098463de4c5d 667
group-onsemi 0:098463de4c5d 668 if args.export == 'table' and returned_string:
group-onsemi 0:098463de4c5d 669 print returned_string
group-onsemi 0:098463de4c5d 670
group-onsemi 0:098463de4c5d 671 sys.exit(0)
group-onsemi 0:098463de4c5d 672
group-onsemi 0:098463de4c5d 673 if __name__ == "__main__":
group-onsemi 0:098463de4c5d 674 main()