Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 #!/usr/bin/env python
kadonotakashi 0:8fdf9a60065b 2 """
kadonotakashi 0:8fdf9a60065b 3 mbed
kadonotakashi 0:8fdf9a60065b 4 Copyright (c) 2017-2017 ARM Limited
kadonotakashi 0:8fdf9a60065b 5
kadonotakashi 0:8fdf9a60065b 6 Licensed under the Apache License, Version 2.0 (the "License");
kadonotakashi 0:8fdf9a60065b 7 you may not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 8 You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 9
kadonotakashi 0:8fdf9a60065b 10 http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 11
kadonotakashi 0:8fdf9a60065b 12 Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 13 distributed under the License is distributed on an "AS IS" BASIS,
kadonotakashi 0:8fdf9a60065b 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 15 See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 16 limitations under the License.
kadonotakashi 0:8fdf9a60065b 17 """
kadonotakashi 0:8fdf9a60065b 18
kadonotakashi 0:8fdf9a60065b 19 from __future__ import print_function
kadonotakashi 0:8fdf9a60065b 20 import os
kadonotakashi 0:8fdf9a60065b 21 import struct
kadonotakashi 0:8fdf9a60065b 22 import binascii
kadonotakashi 0:8fdf9a60065b 23 import argparse
kadonotakashi 0:8fdf9a60065b 24 import logging
kadonotakashi 0:8fdf9a60065b 25 try:
kadonotakashi 0:8fdf9a60065b 26 from StringIO import StringIO
kadonotakashi 0:8fdf9a60065b 27 except ImportError:
kadonotakashi 0:8fdf9a60065b 28 from io import StringIO
kadonotakashi 0:8fdf9a60065b 29 import jinja2
kadonotakashi 0:8fdf9a60065b 30 from collections import namedtuple
kadonotakashi 0:8fdf9a60065b 31 from itertools import count
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 from elftools.common.py3compat import bytes2str
kadonotakashi 0:8fdf9a60065b 34 from elftools.elf.elffile import ELFFile
kadonotakashi 0:8fdf9a60065b 35 from elftools.elf.sections import SymbolTableSection
kadonotakashi 0:8fdf9a60065b 36
kadonotakashi 0:8fdf9a60065b 37 logger = logging.getLogger(__name__)
kadonotakashi 0:8fdf9a60065b 38 logger.addHandler(logging.NullHandler())
kadonotakashi 0:8fdf9a60065b 39
kadonotakashi 0:8fdf9a60065b 40
kadonotakashi 0:8fdf9a60065b 41 def main():
kadonotakashi 0:8fdf9a60065b 42 parser = argparse.ArgumentParser(description="Algo Extracter")
kadonotakashi 0:8fdf9a60065b 43 parser.add_argument("input", help="File to extract flash algo from")
kadonotakashi 0:8fdf9a60065b 44 parser.add_argument("template", default="py_blob.tmpl",
kadonotakashi 0:8fdf9a60065b 45 help="Template to use")
kadonotakashi 0:8fdf9a60065b 46 parser.add_argument("output", help="Output file")
kadonotakashi 0:8fdf9a60065b 47 args = parser.parse_args()
kadonotakashi 0:8fdf9a60065b 48
kadonotakashi 0:8fdf9a60065b 49 with open(args.input, "rb") as file_handle:
kadonotakashi 0:8fdf9a60065b 50 data = file_handle.read()
kadonotakashi 0:8fdf9a60065b 51 algo = PackFlashAlgo(data)
kadonotakashi 0:8fdf9a60065b 52 algo.process_template(args.template, args.output)
kadonotakashi 0:8fdf9a60065b 53
kadonotakashi 0:8fdf9a60065b 54
kadonotakashi 0:8fdf9a60065b 55 class PackFlashAlgo(object):
kadonotakashi 0:8fdf9a60065b 56 """
kadonotakashi 0:8fdf9a60065b 57 Class to wrap a flash algo
kadonotakashi 0:8fdf9a60065b 58
kadonotakashi 0:8fdf9a60065b 59 This class is intended to provide easy access to the information
kadonotakashi 0:8fdf9a60065b 60 provided by a flash algorithm, such as symbols and the flash
kadonotakashi 0:8fdf9a60065b 61 algorithm itself.
kadonotakashi 0:8fdf9a60065b 62 """
kadonotakashi 0:8fdf9a60065b 63
kadonotakashi 0:8fdf9a60065b 64 REQUIRED_SYMBOLS = set([
kadonotakashi 0:8fdf9a60065b 65 "Init",
kadonotakashi 0:8fdf9a60065b 66 "UnInit",
kadonotakashi 0:8fdf9a60065b 67 "EraseSector",
kadonotakashi 0:8fdf9a60065b 68 "ProgramPage",
kadonotakashi 0:8fdf9a60065b 69 ])
kadonotakashi 0:8fdf9a60065b 70
kadonotakashi 0:8fdf9a60065b 71 EXTRA_SYMBOLS = set([
kadonotakashi 0:8fdf9a60065b 72 "BlankCheck",
kadonotakashi 0:8fdf9a60065b 73 "EraseChip",
kadonotakashi 0:8fdf9a60065b 74 "Verify",
kadonotakashi 0:8fdf9a60065b 75 ])
kadonotakashi 0:8fdf9a60065b 76
kadonotakashi 0:8fdf9a60065b 77 def __init__(self, data):
kadonotakashi 0:8fdf9a60065b 78 """Construct a PackFlashAlgorithm from an ElfFileSimple"""
kadonotakashi 0:8fdf9a60065b 79 self.elf = ElfFileSimple(data)
kadonotakashi 0:8fdf9a60065b 80 self.flash_info = PackFlashInfo(self.elf)
kadonotakashi 0:8fdf9a60065b 81
kadonotakashi 0:8fdf9a60065b 82 self.flash_start = self.flash_info.start
kadonotakashi 0:8fdf9a60065b 83 self.flash_size = self.flash_info.size
kadonotakashi 0:8fdf9a60065b 84 self.page_size = self.flash_info.page_size
kadonotakashi 0:8fdf9a60065b 85 self.sector_sizes = self.flash_info.sector_info_list
kadonotakashi 0:8fdf9a60065b 86
kadonotakashi 0:8fdf9a60065b 87 symbols = {}
kadonotakashi 0:8fdf9a60065b 88 symbols.update(_extract_symbols(self.elf, self.REQUIRED_SYMBOLS))
kadonotakashi 0:8fdf9a60065b 89 symbols.update(_extract_symbols(self.elf, self.EXTRA_SYMBOLS,
kadonotakashi 0:8fdf9a60065b 90 default=0xFFFFFFFF))
kadonotakashi 0:8fdf9a60065b 91 self.symbols = symbols
kadonotakashi 0:8fdf9a60065b 92
kadonotakashi 0:8fdf9a60065b 93 sections_to_find = (
kadonotakashi 0:8fdf9a60065b 94 ("PrgCode", "SHT_PROGBITS"),
kadonotakashi 0:8fdf9a60065b 95 ("PrgData", "SHT_PROGBITS"),
kadonotakashi 0:8fdf9a60065b 96 ("PrgData", "SHT_NOBITS"),
kadonotakashi 0:8fdf9a60065b 97 )
kadonotakashi 0:8fdf9a60065b 98
kadonotakashi 0:8fdf9a60065b 99 ro_rw_zi = _find_sections(self.elf, sections_to_find)
kadonotakashi 0:8fdf9a60065b 100 ro_rw_zi = _algo_fill_zi_if_missing(ro_rw_zi)
kadonotakashi 0:8fdf9a60065b 101 error_msg = _algo_check_for_section_problems(ro_rw_zi)
kadonotakashi 0:8fdf9a60065b 102 if error_msg is not None:
kadonotakashi 0:8fdf9a60065b 103 raise Exception(error_msg)
kadonotakashi 0:8fdf9a60065b 104
kadonotakashi 0:8fdf9a60065b 105 sect_ro, sect_rw, sect_zi = ro_rw_zi
kadonotakashi 0:8fdf9a60065b 106 self.ro_start = sect_ro["sh_addr"]
kadonotakashi 0:8fdf9a60065b 107 self.ro_size = sect_ro["sh_size"]
kadonotakashi 0:8fdf9a60065b 108 self.rw_start = sect_rw["sh_addr"]
kadonotakashi 0:8fdf9a60065b 109 self.rw_size = sect_rw["sh_size"]
kadonotakashi 0:8fdf9a60065b 110 self.zi_start = sect_zi["sh_addr"]
kadonotakashi 0:8fdf9a60065b 111 self.zi_size = sect_zi["sh_size"]
kadonotakashi 0:8fdf9a60065b 112
kadonotakashi 0:8fdf9a60065b 113 self.algo_data = _create_algo_bin(ro_rw_zi)
kadonotakashi 0:8fdf9a60065b 114
kadonotakashi 0:8fdf9a60065b 115 def format_algo_data(self, spaces, group_size, fmt):
kadonotakashi 0:8fdf9a60065b 116 """"
kadonotakashi 0:8fdf9a60065b 117 Return a string representing algo_data suitable for use in a template
kadonotakashi 0:8fdf9a60065b 118
kadonotakashi 0:8fdf9a60065b 119 The string is intended for use in a template.
kadonotakashi 0:8fdf9a60065b 120
kadonotakashi 0:8fdf9a60065b 121 :param spaces: The number of leading spaces for each line
kadonotakashi 0:8fdf9a60065b 122 :param group_size: number of elements per line (element type
kadonotakashi 0:8fdf9a60065b 123 depends of format)
kadonotakashi 0:8fdf9a60065b 124 :param fmt: - format to create - can be either "hex" or "c"
kadonotakashi 0:8fdf9a60065b 125 """
kadonotakashi 0:8fdf9a60065b 126 padding = " " * spaces
kadonotakashi 0:8fdf9a60065b 127 if fmt == "hex":
kadonotakashi 0:8fdf9a60065b 128 blob = binascii.b2a_hex(self.algo_data)
kadonotakashi 0:8fdf9a60065b 129 line_list = []
kadonotakashi 0:8fdf9a60065b 130 for i in range(0, len(blob), group_size):
kadonotakashi 0:8fdf9a60065b 131 line_list.append('"' + blob[i:i + group_size] + '"')
kadonotakashi 0:8fdf9a60065b 132 return ("\n" + padding).join(line_list)
kadonotakashi 0:8fdf9a60065b 133 elif fmt == "c":
kadonotakashi 0:8fdf9a60065b 134 blob = self.algo_data[:]
kadonotakashi 0:8fdf9a60065b 135 pad_size = 0 if len(blob) % 4 == 0 else 4 - len(blob) % 4
kadonotakashi 0:8fdf9a60065b 136 blob = blob + "\x00" * pad_size
kadonotakashi 0:8fdf9a60065b 137 integer_list = struct.unpack("<" + "L" * (len(blob) / 4), blob)
kadonotakashi 0:8fdf9a60065b 138 line_list = []
kadonotakashi 0:8fdf9a60065b 139 for pos in range(0, len(integer_list), group_size):
kadonotakashi 0:8fdf9a60065b 140 group = ["0x%08x" % value for value in
kadonotakashi 0:8fdf9a60065b 141 integer_list[pos:pos + group_size]]
kadonotakashi 0:8fdf9a60065b 142 line_list.append(", ".join(group))
kadonotakashi 0:8fdf9a60065b 143 return (",\n" + padding).join(line_list)
kadonotakashi 0:8fdf9a60065b 144 else:
kadonotakashi 0:8fdf9a60065b 145 raise Exception("Unsupported format %s" % fmt)
kadonotakashi 0:8fdf9a60065b 146
kadonotakashi 0:8fdf9a60065b 147 def process_template(self, template_path, output_path, data_dict=None):
kadonotakashi 0:8fdf9a60065b 148 """
kadonotakashi 0:8fdf9a60065b 149 Generate output from the supplied template
kadonotakashi 0:8fdf9a60065b 150
kadonotakashi 0:8fdf9a60065b 151 All the public methods and fields of this class can be accessed from
kadonotakashi 0:8fdf9a60065b 152 the template via "algo".
kadonotakashi 0:8fdf9a60065b 153
kadonotakashi 0:8fdf9a60065b 154 :param template_path: Relative or absolute file path to the template
kadonotakashi 0:8fdf9a60065b 155 :param output_path: Relative or absolute file path to create
kadonotakashi 0:8fdf9a60065b 156 :param data_dict: Additional data to use when generating
kadonotakashi 0:8fdf9a60065b 157 """
kadonotakashi 0:8fdf9a60065b 158 if data_dict is None:
kadonotakashi 0:8fdf9a60065b 159 data_dict = {}
kadonotakashi 0:8fdf9a60065b 160 else:
kadonotakashi 0:8fdf9a60065b 161 assert isinstance(data_dict, dict)
kadonotakashi 0:8fdf9a60065b 162 data_dict = dict(data_dict)
kadonotakashi 0:8fdf9a60065b 163 assert "algo" not in data_dict, "algo already set by user data"
kadonotakashi 0:8fdf9a60065b 164 data_dict["algo"] = self
kadonotakashi 0:8fdf9a60065b 165
kadonotakashi 0:8fdf9a60065b 166 with open(template_path) as file_handle:
kadonotakashi 0:8fdf9a60065b 167 template_text = file_handle.read()
kadonotakashi 0:8fdf9a60065b 168
kadonotakashi 0:8fdf9a60065b 169 template = jinja2.Template(template_text)
kadonotakashi 0:8fdf9a60065b 170 target_text = template.render(data_dict)
kadonotakashi 0:8fdf9a60065b 171
kadonotakashi 0:8fdf9a60065b 172 with open(output_path, "wb") as file_handle:
kadonotakashi 0:8fdf9a60065b 173 file_handle.write(target_text)
kadonotakashi 0:8fdf9a60065b 174
kadonotakashi 0:8fdf9a60065b 175
kadonotakashi 0:8fdf9a60065b 176 def _extract_symbols(simple_elf, symbols, default=None):
kadonotakashi 0:8fdf9a60065b 177 """Fill 'symbols' field with required flash algo symbols"""
kadonotakashi 0:8fdf9a60065b 178 to_ret = {}
kadonotakashi 0:8fdf9a60065b 179 for symbol in symbols:
kadonotakashi 0:8fdf9a60065b 180 if symbol not in simple_elf.symbols:
kadonotakashi 0:8fdf9a60065b 181 if default is not None:
kadonotakashi 0:8fdf9a60065b 182 to_ret[symbol] = default
kadonotakashi 0:8fdf9a60065b 183 continue
kadonotakashi 0:8fdf9a60065b 184 raise Exception("Missing symbol %s" % symbol)
kadonotakashi 0:8fdf9a60065b 185 to_ret[symbol] = simple_elf.symbols[symbol].value
kadonotakashi 0:8fdf9a60065b 186 return to_ret
kadonotakashi 0:8fdf9a60065b 187
kadonotakashi 0:8fdf9a60065b 188
kadonotakashi 0:8fdf9a60065b 189 def _find_sections(elf, name_type_pairs):
kadonotakashi 0:8fdf9a60065b 190 """Return a list of sections the same length and order of the input list"""
kadonotakashi 0:8fdf9a60065b 191 sections = [None] * len(name_type_pairs)
kadonotakashi 0:8fdf9a60065b 192 for section in elf.iter_sections():
kadonotakashi 0:8fdf9a60065b 193 section_name = bytes2str(section.name)
kadonotakashi 0:8fdf9a60065b 194 section_type = section["sh_type"]
kadonotakashi 0:8fdf9a60065b 195 for i, name_and_type in enumerate(name_type_pairs):
kadonotakashi 0:8fdf9a60065b 196 if name_and_type != (section_name, section_type):
kadonotakashi 0:8fdf9a60065b 197 continue
kadonotakashi 0:8fdf9a60065b 198 if sections[i] is not None:
kadonotakashi 0:8fdf9a60065b 199 raise Exception("Elf contains duplicate section %s attr %s" %
kadonotakashi 0:8fdf9a60065b 200 (section_name, section_type))
kadonotakashi 0:8fdf9a60065b 201 sections[i] = section
kadonotakashi 0:8fdf9a60065b 202 return sections
kadonotakashi 0:8fdf9a60065b 203
kadonotakashi 0:8fdf9a60065b 204
kadonotakashi 0:8fdf9a60065b 205 def _algo_fill_zi_if_missing(ro_rw_zi):
kadonotakashi 0:8fdf9a60065b 206 """Create an empty zi section if it is missing"""
kadonotakashi 0:8fdf9a60065b 207 s_ro, s_rw, s_zi = ro_rw_zi
kadonotakashi 0:8fdf9a60065b 208 if s_rw is None:
kadonotakashi 0:8fdf9a60065b 209 return ro_rw_zi
kadonotakashi 0:8fdf9a60065b 210 if s_zi is not None:
kadonotakashi 0:8fdf9a60065b 211 return ro_rw_zi
kadonotakashi 0:8fdf9a60065b 212 s_zi = {
kadonotakashi 0:8fdf9a60065b 213 "sh_addr": s_rw["sh_addr"] + s_rw["sh_size"],
kadonotakashi 0:8fdf9a60065b 214 "sh_size": 0
kadonotakashi 0:8fdf9a60065b 215 }
kadonotakashi 0:8fdf9a60065b 216 return s_ro, s_rw, s_zi
kadonotakashi 0:8fdf9a60065b 217
kadonotakashi 0:8fdf9a60065b 218
kadonotakashi 0:8fdf9a60065b 219 def _algo_check_for_section_problems(ro_rw_zi):
kadonotakashi 0:8fdf9a60065b 220 """Return a string describing any errors with the layout or None if good"""
kadonotakashi 0:8fdf9a60065b 221 s_ro, s_rw, s_zi = ro_rw_zi
kadonotakashi 0:8fdf9a60065b 222 if s_ro is None:
kadonotakashi 0:8fdf9a60065b 223 return "RO section is missing"
kadonotakashi 0:8fdf9a60065b 224 if s_rw is None:
kadonotakashi 0:8fdf9a60065b 225 return "RW section is missing"
kadonotakashi 0:8fdf9a60065b 226 if s_zi is None:
kadonotakashi 0:8fdf9a60065b 227 return "ZI section is missing"
kadonotakashi 0:8fdf9a60065b 228 if s_ro["sh_addr"] != 0:
kadonotakashi 0:8fdf9a60065b 229 return "RO section does not start at address 0"
kadonotakashi 0:8fdf9a60065b 230 if s_ro["sh_addr"] + s_ro["sh_size"] != s_rw["sh_addr"]:
kadonotakashi 0:8fdf9a60065b 231 return "RW section does not follow RO section"
kadonotakashi 0:8fdf9a60065b 232 if s_rw["sh_addr"] + s_rw["sh_size"] != s_zi["sh_addr"]:
kadonotakashi 0:8fdf9a60065b 233 return "ZI section does not follow RW section"
kadonotakashi 0:8fdf9a60065b 234 return None
kadonotakashi 0:8fdf9a60065b 235
kadonotakashi 0:8fdf9a60065b 236
kadonotakashi 0:8fdf9a60065b 237 def _create_algo_bin(ro_rw_zi):
kadonotakashi 0:8fdf9a60065b 238 """Create a binary blob of the flash algo which can execute from ram"""
kadonotakashi 0:8fdf9a60065b 239 sect_ro, sect_rw, sect_zi = ro_rw_zi
kadonotakashi 0:8fdf9a60065b 240 algo_size = sect_ro["sh_size"] + sect_rw["sh_size"] + sect_zi["sh_size"]
kadonotakashi 0:8fdf9a60065b 241 algo_data = bytearray(algo_size)
kadonotakashi 0:8fdf9a60065b 242 for section in (sect_ro, sect_rw):
kadonotakashi 0:8fdf9a60065b 243 start = section["sh_addr"]
kadonotakashi 0:8fdf9a60065b 244 size = section["sh_size"]
kadonotakashi 0:8fdf9a60065b 245 data = section.data()
kadonotakashi 0:8fdf9a60065b 246 assert len(data) == size
kadonotakashi 0:8fdf9a60065b 247 algo_data[start:start + size] = data
kadonotakashi 0:8fdf9a60065b 248 return algo_data
kadonotakashi 0:8fdf9a60065b 249
kadonotakashi 0:8fdf9a60065b 250
kadonotakashi 0:8fdf9a60065b 251 class PackFlashInfo(object):
kadonotakashi 0:8fdf9a60065b 252 """Wrapper class for the non-executable information in an FLM file"""
kadonotakashi 0:8fdf9a60065b 253
kadonotakashi 0:8fdf9a60065b 254 FLASH_DEVICE_STRUCT = "<H128sHLLLLBxxxLL"
kadonotakashi 0:8fdf9a60065b 255 FLASH_SECTORS_STRUCT = "<LL"
kadonotakashi 0:8fdf9a60065b 256 FLASH_SECTORS_STRUCT_SIZE = struct.calcsize(FLASH_SECTORS_STRUCT)
kadonotakashi 0:8fdf9a60065b 257 SECTOR_END = 0xFFFFFFFF
kadonotakashi 0:8fdf9a60065b 258
kadonotakashi 0:8fdf9a60065b 259 def __init__(self, elf_simple):
kadonotakashi 0:8fdf9a60065b 260 dev_info = elf_simple.symbols["FlashDevice"]
kadonotakashi 0:8fdf9a60065b 261 info_start = dev_info.value
kadonotakashi 0:8fdf9a60065b 262 info_size = struct.calcsize(self.FLASH_DEVICE_STRUCT)
kadonotakashi 0:8fdf9a60065b 263 data = elf_simple.read(info_start, info_size)
kadonotakashi 0:8fdf9a60065b 264 values = struct.unpack(self.FLASH_DEVICE_STRUCT, data)
kadonotakashi 0:8fdf9a60065b 265
kadonotakashi 0:8fdf9a60065b 266 self.version = values[0]
kadonotakashi 0:8fdf9a60065b 267 self.name = values[1].strip("\x00")
kadonotakashi 0:8fdf9a60065b 268 self.type = values[2]
kadonotakashi 0:8fdf9a60065b 269 self.start = values[3]
kadonotakashi 0:8fdf9a60065b 270 self.size = values[4]
kadonotakashi 0:8fdf9a60065b 271 self.page_size = values[5]
kadonotakashi 0:8fdf9a60065b 272 self.value_empty = values[7]
kadonotakashi 0:8fdf9a60065b 273 self.prog_timeout_ms = values[8]
kadonotakashi 0:8fdf9a60065b 274 self.erase_timeout_ms = values[9]
kadonotakashi 0:8fdf9a60065b 275
kadonotakashi 0:8fdf9a60065b 276 sector_gen = self._sector_and_sz_itr(elf_simple,
kadonotakashi 0:8fdf9a60065b 277 info_start + info_size)
kadonotakashi 0:8fdf9a60065b 278 self.sector_info_list = list(sector_gen)
kadonotakashi 0:8fdf9a60065b 279
kadonotakashi 0:8fdf9a60065b 280 def __str__(self):
kadonotakashi 0:8fdf9a60065b 281 desc = ""
kadonotakashi 0:8fdf9a60065b 282 desc += "Flash Device:" + os.linesep
kadonotakashi 0:8fdf9a60065b 283 desc += " name=%s" % self.name + os.linesep
kadonotakashi 0:8fdf9a60065b 284 desc += " version=0x%x" % self.version + os.linesep
kadonotakashi 0:8fdf9a60065b 285 desc += " type=%i" % self.type + os.linesep
kadonotakashi 0:8fdf9a60065b 286 desc += " start=0x%x" % self.start + os.linesep
kadonotakashi 0:8fdf9a60065b 287 desc += " size=0x%x" % self.size + os.linesep
kadonotakashi 0:8fdf9a60065b 288 desc += " page_size=0x%x" % self.page_size + os.linesep
kadonotakashi 0:8fdf9a60065b 289 desc += " value_empty=0x%x" % self.value_empty + os.linesep
kadonotakashi 0:8fdf9a60065b 290 desc += " prog_timeout_ms=%i" % self.prog_timeout_ms + os.linesep
kadonotakashi 0:8fdf9a60065b 291 desc += " erase_timeout_ms=%i" % self.erase_timeout_ms + os.linesep
kadonotakashi 0:8fdf9a60065b 292 desc += " sectors:" + os.linesep
kadonotakashi 0:8fdf9a60065b 293 for sector_start, sector_size in self.sector_info_list:
kadonotakashi 0:8fdf9a60065b 294 desc += (" start=0x%x, size=0x%x" %
kadonotakashi 0:8fdf9a60065b 295 (sector_start, sector_size) + os.linesep)
kadonotakashi 0:8fdf9a60065b 296 return desc
kadonotakashi 0:8fdf9a60065b 297
kadonotakashi 0:8fdf9a60065b 298 def _sector_and_sz_itr(self, elf_simple, data_start):
kadonotakashi 0:8fdf9a60065b 299 """Iterator which returns starting address and sector size"""
kadonotakashi 0:8fdf9a60065b 300 for entry_start in count(data_start, self.FLASH_SECTORS_STRUCT_SIZE):
kadonotakashi 0:8fdf9a60065b 301 data = elf_simple.read(entry_start, self.FLASH_SECTORS_STRUCT_SIZE)
kadonotakashi 0:8fdf9a60065b 302 size, start = struct.unpack(self.FLASH_SECTORS_STRUCT, data)
kadonotakashi 0:8fdf9a60065b 303 start_and_size = start, size
kadonotakashi 0:8fdf9a60065b 304 if start_and_size == (self.SECTOR_END, self.SECTOR_END):
kadonotakashi 0:8fdf9a60065b 305 return
kadonotakashi 0:8fdf9a60065b 306 yield start_and_size
kadonotakashi 0:8fdf9a60065b 307
kadonotakashi 0:8fdf9a60065b 308
kadonotakashi 0:8fdf9a60065b 309 SymbolSimple = namedtuple("SymbolSimple", "name, value, size")
kadonotakashi 0:8fdf9a60065b 310
kadonotakashi 0:8fdf9a60065b 311
kadonotakashi 0:8fdf9a60065b 312 class ElfFileSimple(ELFFile):
kadonotakashi 0:8fdf9a60065b 313 """Wrapper for elf object which allows easy access to symbols and rom"""
kadonotakashi 0:8fdf9a60065b 314
kadonotakashi 0:8fdf9a60065b 315 def __init__(self, data):
kadonotakashi 0:8fdf9a60065b 316 """Construct a ElfFileSimple from bytes or a bytearray"""
kadonotakashi 0:8fdf9a60065b 317 super(ElfFileSimple, self).__init__(StringIO(data))
kadonotakashi 0:8fdf9a60065b 318 self.symbols = self._read_symbol_table()
kadonotakashi 0:8fdf9a60065b 319
kadonotakashi 0:8fdf9a60065b 320 def _read_symbol_table(self):
kadonotakashi 0:8fdf9a60065b 321 """Read the symbol table into the field "symbols" for easy use"""
kadonotakashi 0:8fdf9a60065b 322 section = self.get_section_by_name(b".symtab")
kadonotakashi 0:8fdf9a60065b 323 if not section:
kadonotakashi 0:8fdf9a60065b 324 raise Exception("Missing symbol table")
kadonotakashi 0:8fdf9a60065b 325
kadonotakashi 0:8fdf9a60065b 326 if not isinstance(section, SymbolTableSection):
kadonotakashi 0:8fdf9a60065b 327 raise Exception("Invalid symbol table section")
kadonotakashi 0:8fdf9a60065b 328
kadonotakashi 0:8fdf9a60065b 329 symbols = {}
kadonotakashi 0:8fdf9a60065b 330 for symbol in section.iter_symbols():
kadonotakashi 0:8fdf9a60065b 331 name_str = bytes2str(symbol.name)
kadonotakashi 0:8fdf9a60065b 332 if name_str in symbols:
kadonotakashi 0:8fdf9a60065b 333 logging.debug("Duplicate symbol %s", name_str)
kadonotakashi 0:8fdf9a60065b 334 symbols[name_str] = SymbolSimple(name_str, symbol["st_value"],
kadonotakashi 0:8fdf9a60065b 335 symbol["st_size"])
kadonotakashi 0:8fdf9a60065b 336 return symbols
kadonotakashi 0:8fdf9a60065b 337
kadonotakashi 0:8fdf9a60065b 338 def read(self, addr, size):
kadonotakashi 0:8fdf9a60065b 339 """Read program data from the elf file
kadonotakashi 0:8fdf9a60065b 340
kadonotakashi 0:8fdf9a60065b 341 :param addr: physical address (load address) to read from
kadonotakashi 0:8fdf9a60065b 342 :param size: number of bytes to read
kadonotakashi 0:8fdf9a60065b 343 :return: Requested data or None if address is unmapped
kadonotakashi 0:8fdf9a60065b 344 """
kadonotakashi 0:8fdf9a60065b 345 for segment in self.iter_segments():
kadonotakashi 0:8fdf9a60065b 346 seg_addr = segment["p_paddr"]
kadonotakashi 0:8fdf9a60065b 347 seg_size = min(segment["p_memsz"], segment["p_filesz"])
kadonotakashi 0:8fdf9a60065b 348 if addr >= seg_addr + seg_size:
kadonotakashi 0:8fdf9a60065b 349 continue
kadonotakashi 0:8fdf9a60065b 350 if addr + size <= seg_addr:
kadonotakashi 0:8fdf9a60065b 351 continue
kadonotakashi 0:8fdf9a60065b 352 # There is at least some overlap
kadonotakashi 0:8fdf9a60065b 353
kadonotakashi 0:8fdf9a60065b 354 if addr >= seg_addr and addr + size <= seg_addr + seg_size:
kadonotakashi 0:8fdf9a60065b 355 # Region is fully contained
kadonotakashi 0:8fdf9a60065b 356 data = segment.data()
kadonotakashi 0:8fdf9a60065b 357 start = addr - seg_addr
kadonotakashi 0:8fdf9a60065b 358 return data[start:start + size]
kadonotakashi 0:8fdf9a60065b 359
kadonotakashi 0:8fdf9a60065b 360
kadonotakashi 0:8fdf9a60065b 361 if __name__ == '__main__':
kadonotakashi 0:8fdf9a60065b 362 main()