From f15f5e93340203496221e38fd1d19b3febbacb3e Mon Sep 17 00:00:00 2001 From: Siddharth Purohit Date: Sun, 13 Jun 2021 17:24:36 +0530 Subject: [PATCH] waf: create separate image sections for internal and external flash --- Tools/ardupilotwaf/boards.py | 1 + Tools/ardupilotwaf/chibios.py | 98 ++++++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 8 deletions(-) diff --git a/Tools/ardupilotwaf/boards.py b/Tools/ardupilotwaf/boards.py index ed6e85bee1..a0e0c0367a 100644 --- a/Tools/ardupilotwaf/boards.py +++ b/Tools/ardupilotwaf/boards.py @@ -322,6 +322,7 @@ class Board: ] else: env.LINKFLAGS += [ + '-fno-exceptions', '-Wl,--gc-sections', ] diff --git a/Tools/ardupilotwaf/chibios.py b/Tools/ardupilotwaf/chibios.py index a2c0b9dd75..cf652408f7 100644 --- a/Tools/ardupilotwaf/chibios.py +++ b/Tools/ardupilotwaf/chibios.py @@ -5,7 +5,7 @@ Waf tool for ChibiOS build """ -from waflib import Errors, Logs, Task, Utils +from waflib import Errors, Logs, Task, Utils, Context from waflib.TaskGen import after_method, before_method, feature import os @@ -91,10 +91,80 @@ class set_default_parameters(Task.Task): class generate_bin(Task.Task): color='CYAN' - run_str="${OBJCOPY} -O binary ${SRC} ${TGT}" + # run_str="${OBJCOPY} -O binary ${SRC} ${TGT}" always_run = True + EXTF_MEMORY_START = 0x90000000 + EXTF_MEMORY_END = 0x90FFFFFF + INTF_MEMORY_START = 0x08000000 + INTF_MEMORY_END = 0x08FFFFFF def keyword(self): return "Generating" + def run(self): + if self.env.HAS_EXTERNAL_FLASH_SECTIONS: + ret = self.split_sections() + if (ret < 0): + return ret + return ret + else: + cmd = "{} -O binary {} {}".format(self.env.get_flat('OBJCOPY'), self.inputs[0], self.outputs[0]) + self.exec_command(cmd) + + '''list sections and split into two binaries based on section's location in internal, external or in ram''' + def split_sections(self): + # get a list of sections + cmd = "{} -A -x {}".format(self.env.get_flat('SIZE'), self.inputs[0]) + out = self.generator.bld.cmd_and_log(cmd, quiet=Context.BOTH) + extf_sections = [] + intf_sections = [] + is_text_in_extf = False + found_text_section = False + ramsections = [] + for line in out.splitlines(): + section_line = line.split() + if (len(section_line) < 3): + continue + try: + if int(section_line[2], 0) == 0: + continue + else: + addr = int(section_line[2], 0) + except ValueError: + continue + if (addr >= self.EXTF_MEMORY_START) and (addr <= self.EXTF_MEMORY_END): + extf_sections.append("--only-section=%s" % section_line[0]) + if section_line[0] == '.text': + is_text_in_extf = True + found_text_section = True + elif (addr >= self.INTF_MEMORY_START) and (addr <= self.INTF_MEMORY_END): + intf_sections.append("--only-section=%s" % section_line[0]) + if section_line[0] == '.text': + is_text_in_extf = False + found_text_section = True + else: # most likely RAM data, we place it in the same bin as text + ramsections.append(section_line[0]) + + if found_text_section: + for section in ramsections: + if is_text_in_extf: + extf_sections.append("--only-section=%s" % section) + else: + intf_sections.append("--only-section=%s" % section) + else: + Logs.error("Couldn't find .text section") + # create intf binary + if len(intf_sections): + cmd = "{} {} -O binary {} {}".format(self.env.get_flat('OBJCOPY'), + ' '.join(intf_sections), self.inputs[0], self.outputs[0]) + else: + cmd = "cp /dev/null {}".format(self.outputs[0]) + ret = self.exec_command(cmd) + if (ret < 0): + return ret + # create extf binary + cmd = "{} {} -O binary {} {}".format(self.env.get_flat('OBJCOPY'), + ' '.join(extf_sections), self.inputs[0], self.outputs[1]) + return self.exec_command(cmd) + def __str__(self): return self.outputs[0].path_from(self.generator.bld.bldnode) @@ -149,17 +219,25 @@ class generate_apj(Task.Task): return "apj_gen" def run(self): import json, time, base64, zlib - img = open(self.inputs[0].abspath(),'rb').read() + intf_img = open(self.inputs[0].abspath(),'rb').read() + if self.env.HAS_EXTERNAL_FLASH_SECTIONS: + extf_img = open(self.inputs[1].abspath(),'rb').read() + else: + extf_img = b"" d = { "board_id": int(self.env.APJ_BOARD_ID), "magic": "APJFWv1", "description": "Firmware for a %s board" % self.env.APJ_BOARD_TYPE, - "image": base64.b64encode(zlib.compress(img,9)).decode('utf-8'), + "image": base64.b64encode(zlib.compress(intf_img,9)).decode('utf-8'), + "extf_image": base64.b64encode(zlib.compress(extf_img,9)).decode('utf-8'), "summary": self.env.BOARD, "version": "0.1", - "image_size": len(img), + "image_size": len(intf_img), + "extf_image_size": len(extf_img), "flash_total": int(self.env.FLASH_TOTAL), - "flash_free": int(self.env.FLASH_TOTAL) - len(img), + "flash_free": int(self.env.FLASH_TOTAL) - len(intf_img), + "extflash_total": int(self.env.EXTERNAL_PROG_FLASH_MB * 1024 * 1024), + "extflash_free": int(self.env.EXTERNAL_PROG_FLASH_MB * 1024 * 1024) - len(extf_img), "git_identity": self.generator.bld.git_head_hash(short=True), "board_revision": 0, "USBID": self.env.USBID @@ -201,7 +279,11 @@ def chibios_firmware(self): link_output = self.link_task.outputs[0] hex_task = None - bin_target = self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('.bin').name) + if self.bld.env.HAS_EXTERNAL_FLASH_SECTIONS: + bin_target = [self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('.bin').name), + self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('_extf.bin').name)] + else: + bin_target = [self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('.bin').name)] apj_target = self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('.apj').name) generate_bin_task = self.create_task('generate_bin', src=link_output, tgt=bin_target) @@ -219,7 +301,7 @@ def chibios_firmware(self): if self.bld.env.HAVE_INTEL_HEX: if os.path.exists(bootloader_bin.abspath()): hex_target = self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('.hex').name) - hex_task = self.create_task('build_intel_hex', src=[bin_target, bootloader_bin], tgt=hex_target) + hex_task = self.create_task('build_intel_hex', src=[bin_target[0], bootloader_bin], tgt=hex_target) hex_task.set_run_after(generate_bin_task) else: print("Not embedding bootloader; %s does not exist" % bootloader_bin)