summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2021-01-07 02:12:00 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2021-01-07 02:12:00 +0100
commitd4244f3d52f276337b44b0bab8c85094c985682f (patch)
tree26732a0db12d0b856d450409312536e8a1969e37
parentba807914e4f6afe9f95aad7aa4e634d47193ba5c (diff)
build: Add platform spec framework.
-rw-r--r--build/env.py2
-rw-r--r--build/rules.py127
-rw-r--r--build/scons_tools/tool_platform_spec.py112
-rw-r--r--build/scons_tools/tool_selectmcu.py126
-rw-r--r--platforms/cortex-m.yaml13
-rw-r--r--platforms/index.yaml9
-rw-r--r--platforms/stm32/f4.yaml30
-rw-r--r--platforms/stm32/index.yaml8
8 files changed, 196 insertions, 231 deletions
diff --git a/build/env.py b/build/env.py
index 6bc23e8..082195d 100644
--- a/build/env.py
+++ b/build/env.py
@@ -2,6 +2,7 @@ import os
env = Environment(
ENV = os.environ,
+ LAKS_PATH = Dir('..'),
toolpath = ['scons_tools'],
tools = [
@@ -9,6 +10,7 @@ env = Environment(
'tool_selectmcu',
'tool_firmware',
'tool_jinja2',
+ 'tool_platform_spec',
],
)
diff --git a/build/rules.py b/build/rules.py
deleted file mode 100644
index 80a4d10..0000000
--- a/build/rules.py
+++ /dev/null
@@ -1,127 +0,0 @@
-laks_dir = Dir('..')
-ld_dir = Dir('../ld_scripts')
-main_sconscript = File('../SConscript')
-
-def select_arm(env, family):
- env.SetDefault(
- TOOLCHAIN = 'arm-none-eabi-',
- )
-
- if family == 'cortex-m4f':
- family = 'cortex-m4'
- has_mcu = True
- else:
- has_mcu = False
-
- env.Replace(
- CC = '${TOOLCHAIN}gcc',
- CXX = '${TOOLCHAIN}g++',
- AS = '${TOOLCHAIN}gcc',
- LINK = '${TOOLCHAIN}gcc',
- AR = '${TOOLCHAIN}ar',
- RANLIB = '${TOOLCHAIN}ranlib',
-
- CCFLAGS = Split('-O2 -Wall -ggdb -mcpu=${CPU_FAMILY} -mthumb -ffunction-sections'),
- CXXFLAGS = Split('-std=c++20 -fno-exceptions -fno-rtti -Wno-pmf-conversions'),
- ASFLAGS = Split('-c -x assembler-with-cpp -mcpu=${CPU_FAMILY} -mthumb'),
- LINKFLAGS = Split('-Wall -mcpu=${CPU_FAMILY} -mthumb -nostartfiles -Wl,-T${LINK_SCRIPT} -Wl,--gc-sections'),
-
- CPPPATH = [laks_dir],
- LIBPATH = [ld_dir],
-
- LIB_SOURCES = [],
-
- CPU_FAMILY = family,
- )
-
- if has_mcu:
- env.Append(CCFLAGS = Split('-mfloat-abi=hard -mfpu=fpv4-sp-d16'))
- env.Append(LINKFLAGS = Split('-mfloat-abi=hard -mfpu=fpv4-sp-d16'))
- env.Append(CPPDEFINES = ['HAS_FPU'])
-
-def select_stm32(env, variant):
- family = variant[5:9]
- pin_count = variant[9]
- flash = variant[10]
-
- if family.startswith('f0'):
- select_arm(env, 'cortex-m0')
- env.Append(CPPDEFINES = ['STM32F0'])
-
- sram = family[2]
-
- env['LINK_SCRIPT'] = {
- ('4', '6'): 'stm32_f04_6.ld',
- ('5', '8'): 'stm32_f05_8.ld',
- }[sram, flash]
-
- elif family == 'f103':
- select_arm(env, 'cortex-m3')
- env.Append(CPPDEFINES = ['STM32F1'])
-
- env['LINK_SCRIPT'] = {
- '8': 'stm32_f1_8.ld',
- 'b': 'stm32_f1_b.ld',
- }[flash]
-
- elif family == 'f303':
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F3'])
-
- env['LINK_SCRIPT'] = {
- 'b': 'stm32_f303_b.ld',
- 'c': 'stm32_f303_c.ld',
- }[flash]
-
- elif family == 'f373':
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F3'])
-
- env['LINK_SCRIPT'] = {
- '8': 'stm32_f373_8.ld',
- 'b': 'stm32_f373_b.ld',
- 'c': 'stm32_f373_c.ld',
- }[flash]
-
- elif family in ('f401'):
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F4'])
-
- env['LINK_SCRIPT'] = {
- 'e': 'stm32_f401_e.ld',
- }[flash]
-
- elif family in ('f405', 'f407'):
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F4'])
-
- env['LINK_SCRIPT'] = {
- 'e': 'stm32_f4_e.ld',
- 'g': 'stm32_f4_g.ld',
- }[flash]
-
- elif family in ('l051', 'l052', 'l053'):
- select_arm(env, 'cortex-m0plus')
- env.Append(CPPDEFINES = ['STM32L0'])
-
- env['LINK_SCRIPT'] = {
- '8': 'stm32_l0_8.ld',
- }[flash]
-
- else:
- print('Unknown stm32 family: %s' % family)
- Exit(1)
-
-def SelectMCU(env, mcu, variant_dir = None):
- mcu = mcu.lower()
-
- if mcu.startswith('stm32'):
- select_stm32(env, mcu)
-
- else:
- print('Unknown MCU: %s' % mcu)
- Exit(1)
-
- SConscript(main_sconscript, variant_dir = variant_dir, exports = 'env')
-
-AddMethod(Environment, SelectMCU)
diff --git a/build/scons_tools/tool_platform_spec.py b/build/scons_tools/tool_platform_spec.py
new file mode 100644
index 0000000..a532036
--- /dev/null
+++ b/build/scons_tools/tool_platform_spec.py
@@ -0,0 +1,112 @@
+from SCons.Script import *
+
+import yaml
+import re
+import os.path
+
+def load(fn):
+ return yaml.load(open(fn), Loader = yaml.FullLoader)
+
+class Matcher:
+ pass
+
+class ReMatcher(Matcher):
+ def __init__(self, pattern):
+ self.pattern = pattern
+
+ def match(self, meta, key):
+ m = re.match(self.pattern, meta.get(key, ''))
+
+ if m:
+ meta.update(m.groupdict())
+ return True
+
+ return False
+
+class Import:
+ def __init__(self, fn):
+ self.fn = fn
+ self.data = None
+
+ def _load(self):
+ if self.data is None:
+ self.data = load(self.fn)
+
+ def __iter__(self):
+ self._load()
+ return iter(self.data or [])
+
+yaml.add_constructor('!re', (lambda loader, node: ReMatcher(loader.construct_scalar(node))))
+
+def construct_import(loader, node):
+ fn = loader.construct_scalar(node)
+ path = os.path.split(loader.stream.name)[0]
+
+ return Import(os.path.join(path, fn))
+
+yaml.add_constructor('!import', construct_import)
+
+def unprefix(s):
+ return int(s[:-1]) * 1024**(' kMG'.index(s[-1]))
+
+yaml.add_constructor('!prefixed', (lambda loader, node: unprefix(loader.construct_scalar(node))))
+yaml.add_implicit_resolver('!prefixed', re.compile(r'^\d+[kMG]$'))
+
+def match(meta, name, value):
+ if isinstance(value, Matcher):
+ return value.match(meta, name)
+
+ return meta.get(name) == value
+
+def merge(parent, key, value):
+ if key in parent:
+ target = parent[key]
+ if isinstance(target, dict):
+ for k, v in value.items():
+ merge(target, k, v)
+ return
+
+ elif isinstance(target, list):
+ target.extend(value)
+ return
+
+ parent[key] = value
+
+def parse(state, data):
+ for obj in data:
+ if not obj:
+ continue
+
+ m = obj.get('match')
+ if m:
+ if not all(match(state['meta'], name, value) for name, value in m.items()):
+ continue
+
+ for key, value in obj.items():
+ if key in ('match', '-'):
+ continue
+
+ #state[key] = obj[key]
+ merge(state, key, obj[key])
+
+ if '-' in obj:
+ parse(state, obj['-'])
+
+ return state
+
+def PlatformSpec(env, **kwargs):
+ state = {
+ 'meta': kwargs
+ }
+
+ fn = str(env.File('${LAKS_PATH}/platforms/index.yaml'))
+
+ data = yaml.load(open(fn), Loader = yaml.FullLoader)
+
+ return parse(state, data)
+
+def exists():
+ return True
+
+def generate(env):
+ env.AddMethod(PlatformSpec) \ No newline at end of file
diff --git a/build/scons_tools/tool_selectmcu.py b/build/scons_tools/tool_selectmcu.py
index 1e2b0ee..da4b38d 100644
--- a/build/scons_tools/tool_selectmcu.py
+++ b/build/scons_tools/tool_selectmcu.py
@@ -1,20 +1,17 @@
from SCons.Script import *
-laks_dir = Dir('..')
-ld_dir = Dir('../ld_scripts')
-main_sconscript = File('../SConscript')
+def SelectMCU(env, mcu, variant_dir = None):
+
+ spec = env.PlatformSpec(mcu = mcu)
+
+ if len(spec) <= 1:
+ print('Unknown MCU: %s' % mcu)
+ Exit(1)
-def select_arm(env, family):
env.SetDefault(
- TOOLCHAIN = 'arm-none-eabi-',
+ TOOLCHAIN = '%s-' % spec['toolchains'][0],
)
- if family == 'cortex-m4f':
- family = 'cortex-m4'
- has_mcu = True
- else:
- has_mcu = False
-
env.Replace(
CC = '${TOOLCHAIN}gcc',
CXX = '${TOOLCHAIN}g++',
@@ -23,108 +20,29 @@ def select_arm(env, family):
AR = '${TOOLCHAIN}ar',
RANLIB = '${TOOLCHAIN}ranlib',
- CCFLAGS = Split('-O2 -Wall -ggdb -mcpu=${CPU_FAMILY} -mthumb -ffunction-sections'),
+ CCFLAGS = Split('-O2 -Wall -ggdb -ffunction-sections'),
CXXFLAGS = Split('-std=c++20 -fno-exceptions -fno-rtti -Wno-pmf-conversions'),
- ASFLAGS = Split('-c -x assembler-with-cpp -mcpu=${CPU_FAMILY} -mthumb'),
- LINKFLAGS = Split('-Wall -mcpu=${CPU_FAMILY} -mthumb -nostartfiles -Wl,-T${LINK_SCRIPT} -Wl,--gc-sections'),
+ ASFLAGS = Split('-c -x assembler-with-cpp'),
+ LINKFLAGS = Split('-Wall -nostartfiles -Wl,-T${LINK_SCRIPT} -Wl,--gc-sections'),
- CPPPATH = [laks_dir],
- LIBPATH = [ld_dir],
+ CPPPATH = ['${LAKS_PATH}'],
+ LIBPATH = ['${LAKS_PATH}/ld_scripts'],
LIB_SOURCES = [],
-
- CPU_FAMILY = family,
)
-
- if has_mcu:
- env.Append(CCFLAGS = Split('-mfloat-abi=hard -mfpu=fpv4-sp-d16'))
- env.Append(LINKFLAGS = Split('-mfloat-abi=hard -mfpu=fpv4-sp-d16'))
- env.Append(CPPDEFINES = ['HAS_FPU'])
-def select_stm32(env, variant):
- family = variant[5:9]
- pin_count = variant[9]
- flash = variant[10]
-
- if family.startswith('f0'):
- select_arm(env, 'cortex-m0')
- env.Append(CPPDEFINES = ['STM32F0'])
+ env.Replace(
+ LINK_SCRIPT = spec.get('ld_script'),
+ )
- sram = family[2]
-
- env['LINK_SCRIPT'] = {
- ('4', '6'): 'stm32_f04_6.ld',
- ('5', '8'): 'stm32_f05_8.ld',
- }[sram, flash]
-
- elif family == 'f103':
- select_arm(env, 'cortex-m3')
- env.Append(CPPDEFINES = ['STM32F1'])
-
- env['LINK_SCRIPT'] = {
- '8': 'stm32_f1_8.ld',
- 'b': 'stm32_f1_b.ld',
- }[flash]
-
- elif family == 'f303':
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F3'])
-
- env['LINK_SCRIPT'] = {
- 'b': 'stm32_f303_b.ld',
- 'c': 'stm32_f303_c.ld',
- }[flash]
-
- elif family == 'f373':
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F3'])
-
- env['LINK_SCRIPT'] = {
- '8': 'stm32_f373_8.ld',
- 'b': 'stm32_f373_b.ld',
- 'c': 'stm32_f373_c.ld',
- }[flash]
-
- elif family in ('f401'):
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F4'])
-
- env['LINK_SCRIPT'] = {
- 'e': 'stm32_f401_e.ld',
- }[flash]
-
- elif family in ('f405', 'f407'):
- select_arm(env, 'cortex-m4f')
- env.Append(CPPDEFINES = ['STM32F4'])
-
- env['LINK_SCRIPT'] = {
- 'e': 'stm32_f4_e.ld',
- 'g': 'stm32_f4_g.ld',
- }[flash]
-
- elif family in ('l051', 'l052', 'l053'):
- select_arm(env, 'cortex-m0plus')
- env.Append(CPPDEFINES = ['STM32L0'])
-
- env['LINK_SCRIPT'] = {
- '8': 'stm32_l0_8.ld',
- }[flash]
+ env.Append(
+ CCFLAGS = spec.get('cflags', []),
+ LINKFLAGS = spec.get('cflags', []),
+ CPPDEFINES = spec.get('define', []),
+ )
- else:
- print('Unknown stm32 family: %s' % family)
- Exit(1)
+ env.SConscript('${LAKS_PATH}/SConscript', variant_dir = variant_dir, exports = 'env')
-def SelectMCU(env, mcu, variant_dir = None):
- mcu = mcu.lower()
-
- if mcu.startswith('stm32'):
- select_stm32(env, mcu)
-
- else:
- print('Unknown MCU: %s' % mcu)
- Exit(1)
-
- SConscript(main_sconscript, variant_dir = variant_dir, exports = 'env')
def exists():
return True
diff --git a/platforms/cortex-m.yaml b/platforms/cortex-m.yaml
new file mode 100644
index 0000000..d1612b2
--- /dev/null
+++ b/platforms/cortex-m.yaml
@@ -0,0 +1,13 @@
+- match:
+ cpu: cortex-m4f
+
+ cflags:
+ - -mcpu=cortex-m4
+ - -mfloat-abi=hard
+ - -mfpu=fpv4-sp-d16
+
+ define:
+ - HAS_FPU
+
+ toolchains:
+ - arm-none-eabi
diff --git a/platforms/index.yaml b/platforms/index.yaml
new file mode 100644
index 0000000..558b535
--- /dev/null
+++ b/platforms/index.yaml
@@ -0,0 +1,9 @@
+- match:
+ mcu: !re stm32
+
+ -: !import stm32/index.yaml
+
+- match:
+ cpu: !re cortex-m
+
+ -: !import cortex-m.yaml
diff --git a/platforms/stm32/f4.yaml b/platforms/stm32/f4.yaml
new file mode 100644
index 0000000..0d336ce
--- /dev/null
+++ b/platforms/stm32/f4.yaml
@@ -0,0 +1,30 @@
+- match:
+ mem: e
+ mem:
+ flash:
+ origin: 0x08000000
+ size: 512k
+ ld_script: stm32_f4_e.ld
+
+- match:
+ mem: g
+ mem:
+ flash:
+ origin: 0x08000000
+ size: 1M
+ ld_script: stm32_f4_g.ld
+
+- mem:
+ ram:
+ origin: 0x20000000
+ size: 128k
+
+ ccm:
+ origin: 0x10000000
+ size: 64k
+
+ define:
+ - STM32F4
+
+ meta:
+ cpu: cortex-m4f \ No newline at end of file
diff --git a/platforms/stm32/index.yaml b/platforms/stm32/index.yaml
new file mode 100644
index 0000000..a8cb56f
--- /dev/null
+++ b/platforms/stm32/index.yaml
@@ -0,0 +1,8 @@
+- match:
+ mcu: !re stm32(?P<family>..)(?P<variant>..).(?P<mem>.)
+
+ -:
+ - match:
+ family: f4
+
+ -: !import f4.yaml