mirror of https://github.com/ARMmbed/mbed-os.git
Added toolchain hooks and support for LPC4088_EA binary generation
A new hooks mechanism (hooks.py) allows various targets to customize part(s) of the build process. This was implemented to allow generation of custom binary images for the EA LPC4088 target, but it should be generic enough to allow other such customizations in the future. For now, only the 'binary' step is hooked in toolchains/arm.py.pull/46/merge
parent
2cdd41d9b1
commit
e870a90ff2
|
@ -0,0 +1,24 @@
|
|||
; *************************************************************
|
||||
; *** Scatter-Loading Description File generated by uVision ***
|
||||
; *************************************************************
|
||||
|
||||
LR_IROM1 0x00000000 0x00080000 { ; load region size_region
|
||||
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
}
|
||||
RW_IRAM1 0x100000E8 0x0000FF18 { ; RW data
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
RW_IRAM2 0x20000000 0x00008000 {
|
||||
.ANY (AHBSRAM1)
|
||||
}
|
||||
}
|
||||
|
||||
LR_IROM2 0x28000000 0x01000000 {
|
||||
ER_IROM2 0x28000000 0x01000000 { ; load address = execution address
|
||||
.ANY (+RO)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
# Configurable hooks in the build system. Can be used by various platforms
|
||||
# to customize the build process.
|
||||
|
||||
################################################################################
|
||||
# Hooks for the various parts of the build process
|
||||
|
||||
# Internal mapping of hooks per tool
|
||||
_hooks = {}
|
||||
|
||||
# Internal mapping of running hooks
|
||||
_running_hooks = {}
|
||||
|
||||
# Available hook types
|
||||
_hook_types = ["binary"]
|
||||
|
||||
# Available hook steps
|
||||
_hook_steps = ["pre", "replace", "post"]
|
||||
|
||||
# Hook the given function. Use this function as a decorator
|
||||
def hook_tool(function):
|
||||
tool = function.__name__
|
||||
tool_flag = "_" + tool + "_done"
|
||||
def wrapper(t_self, *args, **kwargs):
|
||||
# if a hook for this tool is already running, it's most likely
|
||||
# coming from a derived class, so don't hook the super class version
|
||||
if _running_hooks.get(tool, False):
|
||||
return function(t_self, *args, **kwargs)
|
||||
_running_hooks[tool] = True
|
||||
# If this tool isn't hooked, return original function
|
||||
if not _hooks.has_key(tool):
|
||||
res = function(t_self, *args, **kwargs)
|
||||
_running_hooks[tool] = False
|
||||
return res
|
||||
tooldesc = _hooks[tool]
|
||||
setattr(t_self, tool_flag, False)
|
||||
# If there is a replace hook, execute the replacement instead
|
||||
if tooldesc.has_key("replace"):
|
||||
res = tooldesc["replace"](t_self, *args, **kwargs)
|
||||
# If the replacement has set the "done" flag, exit now
|
||||
# Otherwise continue as usual
|
||||
if getattr(t_self, tool_flag, False):
|
||||
_running_hooks[tool] = False
|
||||
return res
|
||||
# Execute pre-function before main function if specified
|
||||
if tooldesc.has_key("pre"):
|
||||
tooldesc["pre"](t_self, *args, **kwargs)
|
||||
# Execute the main function now
|
||||
res = function(t_self, *args, **kwargs)
|
||||
# Execute post-function after main function if specified
|
||||
if tooldesc.has_key("post"):
|
||||
post_res = tooldesc["post"](t_self, *args, **kwargs)
|
||||
_running_hooks[tool] = False
|
||||
return post_res or res
|
||||
else:
|
||||
_running_hooks[tool] = False
|
||||
return res
|
||||
return wrapper
|
||||
|
||||
class Hook:
|
||||
def __init__(self, target, toolchain):
|
||||
_hooks.clear()
|
||||
self.toolchain = toolchain
|
||||
target.init_hooks(self, toolchain.__class__.__name__)
|
||||
|
||||
def hook_add(self, hook_type, hook_step, function):
|
||||
if not hook_type in _hook_types or not hook_step in _hook_steps:
|
||||
return False
|
||||
if not hook_type in _hooks:
|
||||
_hooks[hook_type] = {}
|
||||
_hooks[hook_type][hook_step] = function
|
||||
return True
|
||||
|
||||
def hook_add_binary(self, hook_step, function):
|
||||
return self.hook_add("binary", hook_step, function)
|
||||
|
||||
################################################################################
|
||||
|
|
@ -23,6 +23,8 @@ CORE_LABELS = {
|
|||
"Cortex-M4" : "M4"
|
||||
}
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
class Target:
|
||||
def __init__(self):
|
||||
|
@ -46,6 +48,8 @@ class Target:
|
|||
def get_labels(self):
|
||||
return [self.name, CORE_LABELS[self.core]] + self.extra_labels
|
||||
|
||||
def init_hooks(self, hook, toolchain_name):
|
||||
pass
|
||||
|
||||
class LPC2368(Target):
|
||||
def __init__(self):
|
||||
|
@ -140,6 +144,42 @@ class LPC4088(Target):
|
|||
|
||||
self.supported_toolchains = ["ARM", "GCC_CR"]
|
||||
|
||||
# Use this target to generate the custom binary image for LPC4088 EA boards
|
||||
class LPC4088_EA(LPC4088):
|
||||
def __init__(self):
|
||||
LPC4088.__init__(self)
|
||||
|
||||
def init_hooks(self, hook, toolchain_name):
|
||||
if toolchain_name in ['ARM_STD', 'ARM_MICRO']:
|
||||
hook.hook_add_binary("post", self.binary_hook)
|
||||
|
||||
@staticmethod
|
||||
def binary_hook(t_self, elf, binf):
|
||||
if not os.path.isdir(binf):
|
||||
# Regular binary file, nothing to do
|
||||
return
|
||||
outbin = open(binf + ".temp", "wb")
|
||||
partf = open(os.path.join(binf, "ER_IROM1"), "rb")
|
||||
# Pad the fist part (internal flash) with 0xFF to 512k
|
||||
data = partf.read()
|
||||
outbin.write(data)
|
||||
outbin.write('\xFF' * (512*1024 - len(data)))
|
||||
partf.close()
|
||||
# Read and append the second part (external flash) in chunks of fixed size
|
||||
chunksize = 128 * 1024
|
||||
partf = open(os.path.join(binf, "ER_IROM2"), "rb")
|
||||
while True:
|
||||
data = partf.read(chunksize)
|
||||
outbin.write(data)
|
||||
if len(data) < chunksize:
|
||||
break
|
||||
partf.close()
|
||||
outbin.close()
|
||||
# Remove the directory with the binary parts and rename the temporary
|
||||
# file to 'binf'
|
||||
shutil.rmtree(binf, True)
|
||||
os.rename(binf + '.temp', binf)
|
||||
t_self.debug("Generated custom binary file (internal flash + SPIFI)")
|
||||
|
||||
class LPC4330_M4(Target):
|
||||
def __init__(self):
|
||||
|
@ -254,7 +294,8 @@ TARGETS = [
|
|||
LPC1347(),
|
||||
LPC1114(),
|
||||
LPC11C24(),
|
||||
LPC11U35_401()
|
||||
LPC11U35_401(),
|
||||
LPC4088_EA()
|
||||
]
|
||||
|
||||
# Map each target name to its unique instance
|
||||
|
|
|
@ -25,6 +25,7 @@ from workspace_tools.utils import run_cmd, mkdir, rel_path, ToolException, split
|
|||
from workspace_tools.patch import patch
|
||||
from workspace_tools.settings import BUILD_OPTIONS
|
||||
|
||||
import workspace_tools.hooks as hooks
|
||||
|
||||
def print_notify(event):
|
||||
# Default command line notification
|
||||
|
@ -144,6 +145,7 @@ class mbedToolchain:
|
|||
def __init__(self, target, options=None, notify=None):
|
||||
self.target = target
|
||||
self.name = self.__class__.__name__
|
||||
self.hook = hooks.Hook(target, self)
|
||||
|
||||
self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]])
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ from os.path import join
|
|||
|
||||
from workspace_tools.toolchains import mbedToolchain
|
||||
from workspace_tools.settings import ARM_BIN, ARM_INC, ARM_LIB, MY_ARM_CLIB, ARM_CPPLIB
|
||||
|
||||
from workspace_tools.hooks import hook_tool
|
||||
|
||||
class ARM(mbedToolchain):
|
||||
LINKER_EXT = '.sct'
|
||||
|
@ -97,12 +97,13 @@ class ARM(mbedToolchain):
|
|||
self.default_cmd([self.ar, '-r', lib_path] + objects)
|
||||
|
||||
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
||||
args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--list=.link_totals.txt"]
|
||||
args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--list=.link_totals.txt", "--any_placement=first_fit"]
|
||||
if mem_map:
|
||||
args.extend(["--scatter", mem_map])
|
||||
|
||||
self.default_cmd(self.ld + args + objects + libraries + self.sys_libs)
|
||||
|
||||
@hook_tool
|
||||
def binary(self, elf, bin):
|
||||
self.default_cmd([self.elf2bin, '--bin', '-o', bin, elf])
|
||||
|
||||
|
|
Loading…
Reference in New Issue