This builds, but does not produce a useful binary.
--- /dev/null
+.sconsign.dblite
+build-target
--- /dev/null
+Import('env')
+env = env.Clone()
+
+source_files_rs = [
+ 'src/common/lib.rs', # Must be listed first (see below).
+]
+
+source_files_c = [
+ 'src/common/startup.c',
+]
+
+libcommon_rlib = env.Rustc('libcommon.rlib', source_files_rs[0])
+
+for f in source_files_rs:
+ Depends(libcommon_rlib, f)
+
+libcommon_a = env.Library('libcommon.a', source_files_c)
+
+for f in source_files_c:
+ Depends(libcommon_a, f)
--- /dev/null
+import os
+
+Import('env')
+env = env.Clone()
+
+host = os.environ.get('HOST', 'arm-none-eabi-')
+
+d = {
+ 'CC': 'gcc',
+ 'LD': 'ld',
+ 'AR': 'ar',
+ 'RANLIB': 'ranlib',
+ 'OBJCOPY': 'objcopy',
+}
+
+for k, v in d.items():
+ env[k] = host + v
+
+env.Append(CCFLAGS = [
+ '-mcpu=cortex-m0plus',
+ '-mthumb',
+ '-ffunction-sections',
+ '-fdata-sections',
+ '-Os',
+])
+
+env.Append(LINKFLAGS = [
+ '-mcpu=cortex-m0plus',
+ '-mthumb',
+ '-specs=nano.specs',
+ '-specs=nosys.specs',
+ '-nostdlib',
+ '-nostartfiles',
+])
+
+env.Append(RUSTCFLAGS = [
+ '-C', 'opt-level=s',
+ '--target=thumbv6m-none-eabi',
+ '-L', '$LIBPATH',
+])
+
+env.Append(LINKFLAGS = [
+ '-Wl,--gc-sections'
+])
+
+SConscript('SConscript.libcommon', exports='env', duplicate=0)
+
+libbootloader_source_files = [
+ 'src/bootloader/main.rs', # Must be listed first (see below).
+]
+
+libbootloader = env.Rustc('libbootloader.a', libbootloader_source_files[0])
+
+for f in libbootloader_source_files:
+ Depends(libbootloader, f)
+
+Depends(libbootloader, 'libcommon.rlib')
+Depends(libbootloader, 'libcommon.a')
+
+bootloader_env = env.Clone()
+
+bootloader_env.Append(LINKFLAGS = [
+ '-Tsrc/bootloader/bootloader.ld',
+])
+
+bootloader_elf = bootloader_env.Program('gps-watch-bootloader.elf', 'src/bootloader/start.c', LIBS = ['bootloader', 'common'])
+
+bootloader_bin = bootloader_env.Objcopy(bootloader_elf)
+
+Default(bootloader_bin)
--- /dev/null
+import SCons
+import os
+
+root_env = Environment(ENV = {'PATH': os.environ['PATH']})
+
+# Beautify output.
+if ARGUMENTS.get('V', '0') != '1':
+ root_env['CCCOMSTR'] = ' CC $TARGET'
+ root_env['RUSTCCOMSTR'] = ' RUSTC $TARGET'
+ root_env['LINKCOMSTR'] = ' LINK $TARGET'
+ root_env['ARCOMSTR'] = ' AR $TARGET'
+ root_env['RANLIBCOMSTR'] = ' RANLIB $TARGET'
+ root_env['OBJCOPYCOMSTR'] = ' OBJCOPY $TARGET'
+
+# Make colored output of e.g. gcc work.
+root_env['ENV']['TERM'] = os.environ.get('TERM')
+
+root_env.Append(CCFLAGS = [
+ '-std=gnu99',
+ '-Wall',
+ '-Wextra',
+ '-Wwrite-strings',
+])
+
+root_env.Append(RUSTC = 'rustc')
+
+root_env.Append(BUILDERS = { 'Rustc': Builder(
+ action=Action('$RUSTC $RUSTCFLAGS -o $TARGET $SOURCE', '$RUSTCCOMSTR'))})
+
+root_env.Append(BUILDERS = { 'Objcopy': Builder(
+ action=Action('$OBJCOPY -O binary $OBJCOPYFLAGS $SOURCES $TARGET', '$OBJCOPYCOMSTR'),
+ suffix='.bin',
+ src_suffix='.elf')})
+
+env = root_env.Clone()
+env['variant_dir'] = 'build-target'
+env['LIBPATH'] = env['variant_dir']
+SConscript('SConscript.target', exports='env', variant_dir=env['variant_dir'], duplicate=0)
--- /dev/null
+/* This is a copy of
+ * CMSIS/Device/ARM/ARMCM0plus/Source/GCC/gcc_arm.ld
+ * taken from
+ * git://github.com/ARM-software/CMSIS
+ */
+
+/* Linker script to configure memory regions. */
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000 /* 256k */
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x08000 /* 32k */
+}
+
+/* Library configurations */
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ * Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ * __exidx_start
+ * __exidx_end
+ * __copy_table_start__
+ * __copy_table_end__
+ * __zero_table_start__
+ * __zero_table_end__
+ * __etext
+ * __data_start__
+ * __preinit_array_start
+ * __preinit_array_end
+ * __init_array_start
+ * __init_array_end
+ * __fini_array_start
+ * __fini_array_end
+ * __data_end__
+ * __bss_start__
+ * __bss_end__
+ * __end__
+ * end
+ * __HeapLimit
+ * __StackLimit
+ * __StackTop
+ * __stack
+ * __Vectors_End
+ * __Vectors_Size
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+ .text :
+ {
+ KEEP(*(.vectors))
+ __Vectors_End = .;
+ __Vectors_Size = __Vectors_End - __Vectors;
+ __end__ = .;
+
+ *(.text*)
+
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ /* .ctors */
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+
+ /* .dtors */
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+ *(.rodata*)
+
+ KEEP(*(.eh_frame*))
+ } > FLASH
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > FLASH
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > FLASH
+ __exidx_end = .;
+
+ /* To copy multiple ROM to RAM sections,
+ * uncomment .copy.table section and,
+ * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
+ /*
+ .copy.table :
+ {
+ . = ALIGN(4);
+ __copy_table_start__ = .;
+ LONG (__etext)
+ LONG (__data_start__)
+ LONG (__data_end__ - __data_start__)
+ LONG (__etext2)
+ LONG (__data2_start__)
+ LONG (__data2_end__ - __data2_start__)
+ __copy_table_end__ = .;
+ } > FLASH
+ */
+
+ /* To clear multiple BSS sections,
+ * uncomment .zero.table section and,
+ * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
+ /*
+ .zero.table :
+ {
+ . = ALIGN(4);
+ __zero_table_start__ = .;
+ LONG (__bss_start__)
+ LONG (__bss_end__ - __bss_start__)
+ LONG (__bss2_start__)
+ LONG (__bss2_end__ - __bss2_start__)
+ __zero_table_end__ = .;
+ } > FLASH
+ */
+
+ __etext = .;
+
+ .data : AT (__etext)
+ {
+ __data_start__ = .;
+ *(vtable)
+ *(.data*)
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+ /* All data end */
+ __data_end__ = .;
+
+ } > RAM
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > RAM
+
+ .heap (COPY):
+ {
+ __HeapBase = .;
+ __end__ = .;
+ end = __end__;
+ KEEP(*(.heap*))
+ __HeapLimit = .;
+ } > RAM
+
+ /* .stack_dummy section doesn't contains any symbols. It is only
+ * used for linker to calculate size of stack sections, and assign
+ * values to stack symbols later */
+ .stack_dummy (COPY):
+ {
+ KEEP(*(.stack*))
+ } > RAM
+
+ /* Set stack top to end of RAM, and stack limit move down by
+ * size of stack_dummy section */
+ __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+ __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+ PROVIDE(__stack = __StackTop);
+
+ /* Check if data + heap + stack exceeds RAM limit */
+ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#![no_std]
+#![crate_type="staticlib"]
+#[link(name="libcommon.rlib")]
+
+extern crate common;
+
+#[no_mangle]
+pub unsafe extern fn main() {
+ loop {
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+extern void main();
+
+__attribute__((noreturn)) void
+_start (void)
+{
+ main();
+
+ for (;;) {
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#![no_std]
+#![crate_name="common"]
+#![crate_type="rlib"]
+#![feature(lang_items)]
+
+#[lang="eh_personality"]
+extern fn eh_personality() {
+}
+
+#[lang="panic_fmt"]
+#[no_mangle]
+pub fn rust_begin_unwind(_fmt: &core::fmt::Arguments, _file_line: &(&'static str, usize)) -> ! {
+ loop {
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+void Reset_Handler (void);
+void NMI_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void HardFault_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SVC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PendSV_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SysTick_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+
+void DMA0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DMA1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DMA2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DMA3_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void FTFA_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PMC_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void LLWU_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void I2C0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void I2C1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SPI0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SPI1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void UART0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void UART1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void UART2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void ADC0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void CMP0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TPM0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TPM1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TPM2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void RTC_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void RTC_Seconds_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PIT_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void I2S0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void USB0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DAC0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TSI0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void MCG_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void LPTMR0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PORTA_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PORTC_PORTD_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+
+extern void _start (void) __attribute__((noreturn));
+
+extern uint32_t __etext;
+extern uint32_t __data_start__;
+extern uint32_t __data_end__;
+extern uint32_t __bss_start__;
+extern uint32_t __bss_end__;
+extern uint32_t __StackTop;
+
+__attribute__ ((section(".vectors")))
+const void * __Vectors[48] =
+{
+ &__StackTop, /* Initial stack pointer */
+
+ (void *) Reset_Handler,
+ (void *) NMI_Handler,
+ (void *) HardFault_Handler,
+ (void *) (0UL), /* Reserved */
+ (void *) (0UL), /* Reserved */
+ (void *) (0UL), /* Reserved */
+ (void *) (0UL), /* Reserved */
+ (void *) (0UL), /* Reserved */
+ (void *) (0UL), /* Reserved */
+ (void *) (0UL), /* Reserved */
+ (void *) SVC_Handler,
+ (void *) (0UL), /* Reserved */
+ (void *) (0UL), /* Reserved */
+ (void *) PendSV_Handler,
+ (void *) SysTick_Handler,
+
+ (void *) DMA0_IRQHandler,
+ (void *) DMA1_IRQHandler,
+ (void *) DMA2_IRQHandler,
+ (void *) DMA3_IRQHandler,
+ (void *) (0UL), /* Reserved */
+ (void *) FTFA_IRQHandler,
+ (void *) PMC_IRQHandler,
+ (void *) LLWU_IRQHandler,
+ (void *) I2C0_IRQHandler,
+ (void *) I2C1_IRQHandler,
+ (void *) SPI0_IRQHandler,
+ (void *) SPI1_IRQHandler,
+ (void *) UART0_IRQHandler,
+ (void *) UART1_IRQHandler,
+ (void *) UART2_IRQHandler,
+ (void *) ADC0_IRQHandler,
+ (void *) CMP0_IRQHandler,
+ (void *) TPM0_IRQHandler,
+ (void *) TPM1_IRQHandler,
+ (void *) TPM2_IRQHandler,
+ (void *) RTC_IRQHandler,
+ (void *) RTC_Seconds_IRQHandler,
+ (void *) PIT_IRQHandler,
+ (void *) I2S0_IRQHandler,
+ (void *) USB0_IRQHandler,
+ (void *) DAC0_IRQHandler,
+ (void *) TSI0_IRQHandler,
+ (void *) MCG_IRQHandler,
+ (void *) LPTMR0_IRQHandler,
+ (void *) (0UL), /* Reserved */
+ (void *) PORTA_IRQHandler,
+ (void *) PORTC_PORTD_IRQHandler,
+};
+
+void
+Reset_Handler (void)
+{
+ uint32_t *src, *dst;
+
+ src = &__etext;
+ dst = &__data_start__;
+
+ /* Initialize data. */
+ while (dst < &__data_end__)
+ *dst++ = *src++;
+
+ /* Clear bss. */
+ for (dst = &__bss_start__; dst < &__bss_end__; dst++)
+ *dst = 0;
+
+ _start();
+}
+
+void
+Dummy_Handler (void)
+{
+ for (;;) {
+ }
+}
--- /dev/null
+{
+ "arch": "arm",
+ "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
+ "executables": true,
+ "os": "none",
+ "pre-link-args": ["-Wl,-("],
+ "post-link-args": ["-Wl,-)"],
+ "target-endian": "little",
+ "target-pointer-width": "32",
+ "cpu": "cortex-m0",
+ "llvm-target": "thumbv6m-none-eabi",
+ "features": "+strict-align",
+ "relocation-model": "static",
+ "no-compiler-rt": true
+}