Merge pull request #9466 from vmedcy/psoc6-target-hook

Improve PSoC 6 post-build hooks, whitelist makefile export
pull/9526/head
Cruz Monrreal 2019-01-28 10:33:12 -06:00 committed by GitHub
commit 7f8ebc75cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 32 deletions

View File

@ -7839,12 +7839,11 @@
}, },
"FUTURE_SEQUANA": { "FUTURE_SEQUANA": {
"inherits": ["MCU_PSOC6_M4"], "inherits": ["MCU_PSOC6_M4"],
"sub_target": "FUTURE_SEQUANA_M0",
"supported_form_factors": ["ARDUINO"], "supported_form_factors": ["ARDUINO"],
"extra_labels_add": ["CY8C63XX", "CORDIO"], "extra_labels_add": ["CY8C63XX", "CORDIO"],
"macros_add": ["CY8C6347BZI_BLD53"], "macros_add": ["CY8C6347BZI_BLD53"],
"detect_code": ["6000"], "detect_code": ["6000"],
"m0_core_img": "psoc63_m0_default_1.02.hex", "hex_filename": "psoc63_m0_default_1.02.hex",
"post_binary_hook": { "post_binary_hook": {
"function": "PSOC6Code.complete" "function": "PSOC6Code.complete"
}, },
@ -7894,12 +7893,11 @@
}, },
"FUTURE_SEQUANA_PSA": { "FUTURE_SEQUANA_PSA": {
"inherits": ["NSPE_Target", "FUTURE_SEQUANA"], "inherits": ["NSPE_Target", "FUTURE_SEQUANA"],
"sub_target": "FUTURE_SEQUANA_M0_PSA",
"extra_labels_add": ["PSA"], "extra_labels_add": ["PSA"],
"extra_labels_remove": ["CORDIO"], "extra_labels_remove": ["CORDIO"],
"components_add": ["SPM_MAILBOX"], "components_add": ["SPM_MAILBOX"],
"macros_add": ["PSOC6_DYNSRM_DISABLE=1", "MBEDTLS_PSA_CRYPTO_C"], "macros_add": ["PSOC6_DYNSRM_DISABLE=1", "MBEDTLS_PSA_CRYPTO_C"],
"m0_core_img": "psa_release_1.0.hex", "hex_filename": "psa_release_1.0.hex",
"overrides": { "overrides": {
"secure-rom-start": "0x10000000", "secure-rom-start": "0x10000000",
"secure-rom-size": "0x80000", "secure-rom-size": "0x80000",

View File

@ -54,7 +54,8 @@ class Makefile(Exporter):
"MCU_NRF51Code.binary_hook", "MCU_NRF51Code.binary_hook",
"TEENSY3_1Code.binary_hook", "TEENSY3_1Code.binary_hook",
"LPCTargetCode.lpc_patch", "LPCTargetCode.lpc_patch",
"LPC4088Code.binary_hook" "LPC4088Code.binary_hook",
"PSOC6Code.complete"
]) ])
@classmethod @classmethod
@ -83,6 +84,11 @@ class Makefile(Exporter):
sys_libs = [self.prepare_sys_lib(lib) for lib sys_libs = [self.prepare_sys_lib(lib) for lib
in self.toolchain.sys_libs] in self.toolchain.sys_libs]
hex_files = self.resources.hex_files
if hasattr(self.toolchain.target, 'hex_filename'):
hex_filename = self.toolchain.target.hex_filename
hex_files = list(f for f in hex_files if basename(f) == hex_filename)
ctx = { ctx = {
'name': self.project_name, 'name': self.project_name,
'to_be_compiled': to_be_compiled, 'to_be_compiled': to_be_compiled,
@ -92,7 +98,7 @@ class Makefile(Exporter):
'linker_script': self.resources.linker_script, 'linker_script': self.resources.linker_script,
'libraries': libraries, 'libraries': libraries,
'ld_sys_libs': sys_libs, 'ld_sys_libs': sys_libs,
'hex_files': self.resources.hex_files, 'hex_files': hex_files,
'vpath': (["../../.."] 'vpath': (["../../.."]
if (basename(dirname(dirname(self.export_dir))) if (basename(dirname(dirname(self.export_dir)))
== "projectfiles") == "projectfiles")

View File

@ -1,5 +1,6 @@
# #
# Copyright (c) 2017-2018 Future Electronics # Copyright (c) 2017-2018 Future Electronics
# Copyright (c) 2018-2019 Cypress Semiconductor Corporation
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -20,13 +21,28 @@ import subprocess
import errno import errno
from array import array from array import array
from struct import (pack, unpack) from struct import (pack, unpack)
from distutils.spawn import find_executable
from shutil import copyfile from shutil import copyfile
from intelhex import IntelHex from intelhex import IntelHex
from intelhex.compat import asbytes from intelhex.compat import asbytes
from ..config import ConfigException from ..config import ConfigException
from ..targets import HookError
# The size of the program data in Cypress HEX files is limited to 0x80000000
# Higher addresses contain additional metadata (chip protection, eFuse data, etc..)
CY_PROGRAM_SIZE = 0x80000000
# The starting address of the program data checksum section
CY_CHECKSUM_ADDR = 0x90300000
# The starting address of the .cymeta section (12 bytes)
# Additional metadata include silicon revision, Silicon/JTAG ID, etc.
CY_META_ADDR = 0x90500000
# The address of the silicon ID (4 bytes)
CY_META_SILICON_ID_ADDR = 0x90500002
# The address of the metadata checksum (4 bytes)
CY_META_CHECKSUM_ADDR = 0x90500008
# Patch Cypress hex file: # Patch Cypress hex file:
@ -34,31 +50,42 @@ from ..targets import HookError
# - update metadata # - update metadata
# - align regions to page (256 bytes) boundary # - align regions to page (256 bytes) boundary
def patch(message_func, ihex, hexf, align=256): def patch(message_func, ihex, hexf, align=256):
#calculate checksum update_checksum = False
update_metadata = False
# calculate checksum of the program section, detect metadata
checksum = 0 checksum = 0
for start, end in ihex.segments(): for start, end in ihex.segments():
if start >= 0x090000000: if start == CY_CHECKSUM_ADDR:
# checksum section found in the original hex
update_checksum = True
if start == CY_META_ADDR:
# metadata section found in the original hex
update_metadata = True
if start >= CY_PROGRAM_SIZE:
continue continue
segment = ihex.tobinarray(start, end) segment = ihex.tobinarray(start, end)
checksum += sum(segment) checksum += sum(segment)
lowchecksum = checksum & 0x0FFFF # only update checksum if it was found in the original hex
message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum)) if update_checksum:
lowchecksum = checksum & 0x0FFFF
message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum))
# update checksum checksum_str = pack('>H', lowchecksum)
checksum_str = pack('>H', lowchecksum) ihex.frombytes(array('B', checksum_str), offset=CY_CHECKSUM_ADDR)
ihex.frombytes(array('B', checksum_str), offset=0x90300000)
# update metadata # only update metadata if it was found in the original hex
signature = unpack('>L', ihex.tobinstr(start=0x90500002, size=4))[0] if update_metadata:
sigcheck = pack('>L', (checksum + signature) & 0x0FFFF) signature = unpack('>L', ihex.tobinstr(start=CY_META_SILICON_ID_ADDR, size=4))[0]
ihex.frombytes(array('B',sigcheck), offset=0x90500008) sigcheck = pack('>L', (checksum + signature) & 0x0FFFF)
ihex.frombytes(array('B',sigcheck), offset=CY_META_CHECKSUM_ADDR)
# align flash segments # align flash segments
align_mask = align - 1 align_mask = align - 1
alignments = IntelHex() alignments = IntelHex()
for start, end in ihex.segments(): for start, end in ihex.segments():
if start >= 0x090000000: if start >= CY_PROGRAM_SIZE:
continue continue
aligned_start = start & ~align_mask aligned_start = start & ~align_mask
if start != aligned_start: if start != aligned_start:
@ -76,14 +103,8 @@ def merge_images(hexf0, hexf1=None):
ihex.padding = 0x00 ihex.padding = 0x00
ihex.loadfile(hexf0, "hex") ihex.loadfile(hexf0, "hex")
if hexf1 is not None: if hexf1 is not None:
# get chip ID from metadata and compare # Merge the CM0+ image
ihex1 = IntelHex(hexf1) ihex1 = IntelHex(hexf1)
type0 = ihex.tobinarray(start=0x90500002, size=4)
type1 = ihex1.tobinarray(start=0x90500002, size=4)
if type0 != type1:
raise HookError(
"Incompatible processor type: %s in '%s' and 0x%s in '%s'"
% (hexf0, type0, hexf1, type1))
ihex.merge(ihex1, 'ignore') ihex.merge(ihex1, 'ignore')
return ihex return ihex
@ -94,18 +115,18 @@ def complete_func(message_func, elf0, hexf0, hexf1=None, dest=None):
ihex.write_hex_file(dest if dest else hexf0, write_start_addr=False, byte_count=64) ihex.write_hex_file(dest if dest else hexf0, write_start_addr=False, byte_count=64)
# Find Cortex M0 image. # Find Cortex M0 image.
def find_cm0_image(toolchain, resources, elf, hexf): def find_cm0_image(toolchain, resources, elf, hexf, hex_filename):
# Locate user-specified image # Locate user-specified image
from tools.resources import FileType from tools.resources import FileType
hex_files = resources.get_file_paths(FileType.HEX) hex_files = resources.get_file_paths(FileType.HEX)
m0hexf = next((f for f in hex_files if os.path.basename(f) == toolchain.target.m0_core_img), None) m0hexf = next((f for f in hex_files if os.path.basename(f) == hex_filename), None)
if toolchain.target.name.endswith('_PSA'): if toolchain.target.name.endswith('_PSA'):
m0hexf = next((f for f in hex_files if os.path.basename(f) == os.path.basename(hexf)), m0hexf) m0hexf = next((f for f in hex_files if os.path.basename(f) == os.path.basename(hexf)), m0hexf)
if m0hexf: if m0hexf:
toolchain.notify.debug("M0 core image file found: %s." % os.path.basename(m0hexf)) toolchain.notify.debug("M0 core image file found: %s." % os.path.basename(m0hexf))
else: else:
toolchain.notify.debug("M0 core hex image file %s not found. Aborting." % toolchain.target.m0_core_img) toolchain.notify.debug("M0 core hex image file %s not found. Aborting." % hex_filename)
raise ConfigException("Required M0 core hex image not found.") raise ConfigException("Required M0 core hex image not found.")
return m0hexf return m0hexf

View File

@ -583,10 +583,11 @@ class PSOC6Code:
@staticmethod @staticmethod
def complete(t_self, resources, elf, binf): def complete(t_self, resources, elf, binf):
from tools.targets.PSOC6 import complete as psoc6_complete from tools.targets.PSOC6 import complete as psoc6_complete
if hasattr(t_self.target, "sub_target"): if hasattr(t_self.target, "hex_filename"):
hex_filename = t_self.target.hex_filename
# Completing main image involves merging M0 image. # Completing main image involves merging M0 image.
from tools.targets.PSOC6 import find_cm0_image from tools.targets.PSOC6 import find_cm0_image
m0hexf = find_cm0_image(t_self, resources, elf, binf) m0hexf = find_cm0_image(t_self, resources, elf, binf, hex_filename)
psoc6_complete(t_self, elf, binf, m0hexf) psoc6_complete(t_self, elf, binf, m0hexf)
else: else:
psoc6_complete(t_self, elf, binf) psoc6_complete(t_self, elf, binf)