waf: create separate image sections for internal and external flash

This commit is contained in:
Siddharth Purohit 2021-06-13 17:24:36 +05:30 committed by Andrew Tridgell
parent 4ba2835de1
commit f15f5e9334
2 changed files with 91 additions and 8 deletions

View File

@ -322,6 +322,7 @@ class Board:
]
else:
env.LINKFLAGS += [
'-fno-exceptions',
'-Wl,--gc-sections',
]

View File

@ -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)